Dead nozzle compensation
Summary by NHIP
Dead nozzle compensation
The method compensates for inoperative nozzles in a bi-lithic printhead by mapping dot data to a combination of operative nozzles based on a color model. This process minimizes perceived image error by selecting nozzles that print dots close to or immediately adjacent to the failed nozzle's intended position.
Claim Score by NHIP
Abstract
A printer controller for supplying dot data to a printhead in a predetermined order, the printhead comprising at least first and second printhead modules, each of which comprises a plurality of printing nozzles and being disposed adjacent each other such that a printing width of the printhead is wider than a printing width of either of the printhead modules, the printer controller being configured to order and time supply of the dot data to the printhead modules in accordance with their respective widths, such that a difference in relative widths of the printhead modules is at least partially compensated for.

Term
Term ended
Expired 26 March 2025, 1.5 years ago.
- Priority
- Filed
- Granted
- Expired
- Today
13 claims: 2 independent, 11 dependent
- 1Broadest claimClaim Score 46, average(NHIP)A method of compensating for an inoperative nozzle in a bi-lithic printhead, the bi-lithic printhead including a plurality of sets of nozzles for printing a corresponding plurality of channels of dot data, the method comprising the steps of:(a) rendering compressed pages to form a bi-level layer for a given print line intended for the bi-lithic printhead;(b) expanding the compressed bi-level layer;(c) compositing the bi-level layer to produce bi-level dots;(d) determining which combination of one or more available operative nozzles near the inoperative nozzle will minimize perceived error in an image that the dot data forms part of, the determination being performed on the basis of a color model;(e) mapping the dot data intended for the inoperative nozzle to that combination of one or more operative nozzles from the same set;and, (f) passing resultant bi-level channel dot data to the bi-lithic printhead.
- 4The method according to 1 , including the substeps of:(i) determining one or more operative nozzles capable of printing a dot on print media close to a position at which the inoperative nozzle would have printed a dot had it been operative;and (ii) mapping the dot data from the inoperative nozzle to an operative nozzle determined in substep (i).
Independent claims2
6,491 paragraphs in 38 sections, as filed
FIELD OF INVENTION
0001The present invention relates to techniques for compensating for one or more dead nozzles in a multi-nozzle printhead.
0002The invention has primarily been developed for use with a printhead comprising one or more printhead modules constructed using microelectromechanical systems (MEMS) techniques, and will be described with reference to this application. However, it will be appreciated that the invention can be applied to other types of printing technologies in which analogous problems are faced.
BACKGROUND OF INVENTION
0003Manufacturing a printhead that has relatively high resolution and print-speed raises a number of problems.
0004Difficulties in manufacturing pagewidth printheads of any substantial size arise due to the relatively small dimensions of standard silicon wafers that are used in printhead (or printhead module) manufacture. For example, if it is desired to make an 8 inch wide pagewidth printhead, only one such printhead can be laid out on a standard 8-inch wafer, since such wafers are circular in plan. Manufacturing a pagewidth printhead from two or more smaller modules can reduce this limitation to some extent, but raises other problems related to providing a joint between adjacent printhead modules that is precise enough to avoid visible artefacts (which would typically take the form of noticeable lines) when the printhead is used. The problem is exacerbated in relatively high-resolution applications because of the tight tolerances dictated by the small spacing between nozzles.
0005The quality of a joint region between adjacent printhead modules relies on factors including a precision with which the abutting ends of each module can be manufactured, the accuracy with which they can be aligned when assembled into a single printhead, and other more practical factors such as management of ink channels behind the nozzles. It will be appreciated that the difficulties include relative vertical displacement of the printhead modules with respect to each other.
0006Whilst some of these issues may be dealt with by careful design and manufacture, the level of precision required renders it relatively expensive to manufacture printheads within the required tolerances. It would be desirable to provide a solution to one or more of the problems associated with precision manufacture and assembly of multiple printhead modules to form a printhead, and especially a pagewidth printhead.
0007In some cases, it is desirable to produce a number of different printhead module types or lengths on a substrate to maximise usage of the substrate's surface area. However, different sizes and types of modules will have different numbers and layouts of print nozzles, potentially including different horizontal and vertical offsets. Where two or more modules are to be joined to form a single printhead, there is also the problem of dealing with different seam shapes between abutting ends of joined modules, which again may incorporate vertical or horizontal offsets between the modules. Printhead controllers are usually dedicated application specific integrated circuits (ASICs) designed for specific use with a single type of printhead module, that is used by itself rather than with other modules. It would be desirable to provide a way in which different lengths and types of printhead modules could be accounted for using a single printer controller.
0008Printer controllers face other difficulties when two or more printhead modules are involved, especially if it is desired to send dot data to each of the printheads directly (rather than via a single printhead connected to the controller). One concern is that data delivered to different length controllers at the same rate will cause the shorter of the modules to be ready for printing before any longer modules. Where there is little difference involved, the issue may not be of importance, but for large length differences, the result is that the bandwidth of a shared memory from which the dot data is supplied to the modules is effectively left idle once one of the modules is full and the remaining module or modules is still being filled. It would be desirable to provide a way of improving memory bandwidth usage in a system comprising a plurality of printhead modules of uneven length.
0009In any printing system that includes multiple nozzles on a printhead or printhead module, there is the possibility of one or more of the nozzles failing in the field, or being inoperative due to manufacturing defect. Given the relatively large size of a typical printhead module, it would be desirable to provide some form of compensation for one or more “dead” nozzles. Where the printhead also outputs fixative on a per-nozzle basis, it is also desirable that the fixative is provided in such a way that dead nozzles are compensated for.
0010A printer controller can take the form of an integrated circuit, comprising a processor and one or more peripheral hardware units for implementing specific data manipulation functions. A number of these units and the processor may need access to a common resource such as memory. One way of arbitrating between multiple access requests for a common resource is timeslot arbitration, in which access to the resource is guaranteed to a particular requestor during a predetermined timeslot.
0011One difficulty with this arrangement lies in the fact that not all access requests make the same demands on the resource in terms of timing and latency. For example, a memory read requires that data be fetched from memory, which may take a number of cycles, whereas a memory write can commence immediately. Timeslot arbitration does not take into account these differences, which may result in accesses being performed in a less efficient manner than might otherwise be the case. It would be desirable to provide a timeslot arbitration scheme that improved this efficiency as compared with prior art timeslot arbitration schemes.
0012Also of concern when allocating resources in a timeslot arbitration scheme is the fact that the priority of an access request may not be the same for all units. For example, it would be desirable to provide a timeslot arbitration scheme in which one requestor (typically the memory) is granted special priority such that its requests are dealt with earlier than would be the case in the absence of such priority.
0013In systems that use a memory and cache, a cache miss (in which an attempt to load data or an instruction from a cache fails) results in a memory access followed by a cache update. It is often desirable when updating the cache in this way to update data other than that which was actually missed. A typical example would be a cache miss for a byte resulting in an entire word or line of the cache associated with that byte being updated. However, this can have the effect of tying up bandwidth between the memory (or a memory manager) and the processor where the bandwidth is such that several cycles are required to transfer the entire word or line to the cache. It would be desirable to provide a mechanism for updating a cache that improved cache update speed and/or efficiency.
0014Most integrated circuits an externally provided signal as (or to generate) a clock, often provided from a dedicated clock generation circuit. This is often due to the difficulties of providing an onboard clock that can operate at a speed that is predictable. Manufacturing tolerances of such on-board clock generation circuitry can result in clock rates that vary by a factor of two, and operating temperatures can increase this margin by an additional factor of two. In some cases, the particular rate at which the clock operates is not of particular concern. However, where the integrated circuit will be writing to an internal circuit that is sensitive to the time over which a signal is provided, it may be undesirable to have the signal be applied for too long or short a time. For example, flash memory is sensitive to being written too for too long a period. It would be desirable to provide a mechanism for adjusting a rate of an on-chip system clock to take into account the impact of manufacturing variations on clockspeed.
0015One form of attacking a secure chip is to induce (usually by increasing) a clock speed that takes the logic outside its rated operating frequency. One way of doing this is to reduce the temperature of the integrated circuit, which can cause the clock to race. Above a certain frequency, some logic will start malfunctioning. In some cases, the malfunction can be such that information on the chip that would otherwise be secure may become available to an external connection. It would be desirable to protect an integrated circuit from such attacks.
0016In an integrated circuit comprising non-volatile memory, a power failure can result in unintentional behaviour. For example, if an address or data becomes unreliable due to falling voltage supplied to the circuit but there is still sufficient power to cause a write, incorrect data can be written. Even worse, the data (incorrect or not) could be written to the wrong memory. The problem is exacerbated with multi-word writes. It would be desirable to provide a mechanism for reducing or preventing spurious writes when power to an integrated circuit is failing.
0017In an integrated circuit, it is often desirable to reduce unauthorised access to the contents of memory. This is particularly the case where the memory includes a key or some other form of security information that allows the integrated circuit to communicate with another entity (such as another integrated circuit, for example) in a secure manner. It would be particularly advantageous to prevent attacks involving direct probing of memory addresses by physically investigating the chip (as distinct from electronic or logical attacks via manipulation of signals and power supplied to the integrated circuit).
0018It is also desirable to provide an environment where the manufacturer of the integrated circuit (or some other authorised entity) can verify or authorize code to be run on an integrated circuit.
0019Another desideratum would be the ability of two or more entities, such as integrated circuits, to communicate with each other in a secure manner. It would also be desirable to provide a mechanism for secure communication between a first entity and a second entity, where the two entities, whilst capable of some form of secure communication, are not able to establish such communication between themselves.
0020In a system that uses resources (such as a printer, which uses inks) it may be desirable to monitor and update a record related to resource usage. Authenticating ink quality can be a major issue, since the attributes of inks used by a given printhead can be quite specific. Use of incorrect ink can result in anything from misfiring or poor performance to damage or destruction of the printhead. It would therefore be desirable to provide a system that enables authentication of the correct ink being used, as well as providing various support systems secure enabling refilling of ink cartridges.
0021In a system that prevents unauthorized programs from being loaded onto or run on an integrated circuit, it can be laborious to allow developers of software to access the circuits during software development. Enabling access to integrated circuits of a particular type requires authenticating software with a relatively high-level key. Distributing the key for use by developers is inherently unsafe, since a single leak of the key outside the organization could endanger security of all chips that use a related key to authorize programs. Having a small number of people with high-security clearance available to authenticate programs for testing can be inconvenient, particularly in the case where frequent incremental changes in programs during development require testing. It would be desirable to provide a mechanism for allowing access to one or more integrated circuits without risking the security of other integrated circuits in a series of such integrated circuits.
0022In symmetric key security, a message, denoted by M, is plaintext. The process of transforming M into ciphertext C, where the substance of M is hidden, is called encryption. The process of transforming C back into M is called decryption. Referring to the encryption function as E, and the decryption function as D, we have the following identities: <br />E[M]=C<br />D[C]=M
0023Therefore the following identity is true: <br />D[E[M]]=M
0024A symmetric encryption algorithm is one where: <ul id="ul0001" list-style="none"><li id="ul0001-0001" num="0000"><ul id="ul0002" list-style="none"><li id="ul0002-0001" num="0025">the encryption function E relies on key K<sub>1</sub>,</li><li id="ul0002-0002" num="0026">the decryption function D relies on key K<sub>2</sub>,</li><li id="ul0002-0003" num="0027">K<sub>2 </sub>can be derived from K<sub>1</sub>, and</li><li id="ul0002-0004" num="0028">K<sub>1 </sub>can be derived from K<sub>2</sub>,</li></ul></li></ul>
0029In most symmetric algorithms, K<sub>1 </sub>equals K<sub>2</sub>. However, even if K<sub>1 </sub>does not equal K<sub>2</sub>, given that one key can be derived from the other, a single key K can suffice for the mathematical definition. Thus: <br />E<sub>K</sub>[M]=C<br />D<sub>K</sub>[C]=M
0030The security of these algorithms rests very much in the key K. Knowledge of K allows anyone to encrypt or decrypt. Consequently K must remain a secret for the duration of the value of M. For example, M may be a wartime message “My current position is grid position 123–456”. Once the war is over the value of M is greatly reduced, and if K is made public, the knowledge of the combat unit's position may be of no relevance whatsoever. The security of the particular symmetric algorithm is a function of two things: the strength of the algorithm and the length of the key.
0031An asymmetric encryption algorithm is one where: <ul id="ul0003" list-style="none"><li id="ul0003-0001" num="0000"><ul id="ul0004" list-style="none"><li id="ul0004-0001" num="0032">the encryption function E relies on key K<sub>1</sub>,</li><li id="ul0004-0002" num="0033">the decryption function D relies on key K<sub>2</sub>,</li><li id="ul0004-0003" num="0034">K<sub>2 </sub>cannot be derived from K<sub>1 </sub>in a reasonable amount of time, and</li><li id="ul0004-0004" num="0035">K<sub>1 </sub>cannot be derived from K<sub>2 </sub>in a reasonable amount of time.</li></ul></li></ul>
0036Thus: <br />E<sub>K1</sub>[M]=C<br />D<sub>K2</sub>[C]=M
0037These algorithms are also called public-key because one key K<sub>1 </sub>can be made public. Thus anyone can encrypt a message (using K<sub>1</sub>) but only the person with the corresponding decryption key (K<sub>2</sub>) can decrypt and thus read the message.
0038In most cases, the following identity also holds: <br />E<sub>K2</sub>[M]=C<br />D<sub>K1</sub>[C]=M
0039This identity is very important because it implies that anyone with the public key K<sub>1 </sub>can see M and know that it came from the owner of K<sub>2</sub>. No-one else could have generated C because to do so would imply knowledge of K<sub>2</sub>. This gives rise to a different application, unrelated to encryption—digital signatures.
0040A number of public key cryptographic algorithms exist. Most are impractical to implement, and many generate a very large C for a given M or require enormous keys. Still others, while secure, are far too slow to be practical for several years. Because of this, many public key systems are hybrid—a public key mechanism is used to transmit a symmetric session key, and then the session key is used for the actual messages.
0041All of the algorithms have a problem in terms of key selection. A random number is simply not secure enough. The two large primes p and q must be chosen carefully—there are certain weak combinations that can be factored more easily (some of the weak keys can be tested for). But nonetheless, key selection is not a simple matter of randomly selecting 1024 bits for example. Consequently the key selection process must also be secure.
0042Symmetric and asymmetric schemes both suffer from a difficulty in allowing establishment of multiple relationships between one entity and a two or more others, without the need to provide multiple sets of keys. For example, if a main entity wants to establish secure communications with two or more additional entities, it will need to maintain a different key for each of the additional entities. For practical reasons, it is desirable to avoid generating and storing large numbers of keys. To reduce key numbers, two or more of the entities may use the same key to communicate with the main entity. However, this means that the main entity cannot be sure which of the entities it is communicating with. Similarly, messages from the main entity to one of the entities can be decrypted by any of the other entities with the same key. It would be desirable if a mechanism could be provided to allow secure communication between a main entity and one or more other entities that overcomes at least some of the shortcomings of prior art.
0043In a system where a first entity is capable of secure communication of some form, it may be desirable to establish a relationship with another entity without providing the other entity with any information related the first entity's security features. Typically, the security features might include a key or a cryptographic function. It would be desirable to provide a mechanism for enabling secure communications between a first and second entity when they do not share the requisite secret function, key or other relationship to enable them to establish trust.
0044A number of other aspects, features, preferences and embodiments are disclosed in the Detailed Description of the Preferred Embodiment below.
SUMMARY OF THE INVENTION
0045In accordance with the invention, there is provided a method of compensating for an inoperative nozzle in a printhead, the method comprising the step of: <ul id="ul0005" list-style="none"><li id="ul0005-0001" num="0046">(a) mapping dot data intended for the inoperative nozzle into one or more operative nozzles of the printhead.</li></ul>
0047Preferably, step (a) includes the substep of mapping the dot data intended for the inoperative nozzle into a nozzle that will print a dot on print media close to a position at which the inoperative nozzle would have printed a dot had it been operative.
0048Preferably also, step (a) includes the substep of mapping the dot data intended for the inoperative nozzle into a nozzle that will print a dot on print media immediately adjacent a position at which the inoperative nozzle would have printed a dot had it been operative.
0049In a preferred embodiment, step (a) includes the substeps of: <ul id="ul0006" list-style="none"><li id="ul0006-0001" num="0050">(i) determining one or more operative nozzles capable of printing a dot on print media close to a position at which the inoperative nozzle would have printed a dot had it been operative; and</li><li id="ul0006-0002" num="0051">(ii) mapping the dot data from the inoperative nozzle to an operative nozzle determined in substep (i).</li></ul>
0052More preferably, in the event more than one operative nozzle is determined in substep (i), the dot data is remapped to one of the operative nozzles that will print a dot on print media closest to that which would have been printed by the inoperative nozzle.
0053It is preferred that during successive firings of the printhead, the dot data is remapped alternately to operative nozzles that will print a dot on print media either side of that which would have been printed by the inoperative nozzle.
0054In an alternative embodiment, during successive firings of the printhead, the dot data is remapped randomly, pseudo-randomly, or arbitrarily to operative nozzles that will print a dot on print media either side of that which would have been printed by the inoperative nozzle.
0055Preferably, the printhead including a plurality of sets of the nozzles for printing a corresponding plurality of channels of dot data, wherein step (a) includes the substep of mapping the dot data intended for the inoperative nozzle into one or more operative nozzles from the same set.
0056In one form, step (a) includes the substep of mapping the dot data into one or more operative nozzles that will print a dot on print media close to a position at which the inoperative nozzle would have printed a dot had it been operative.
0057In an alternative form, step (a) includes the substep of mapping the dot data intended for the inoperative nozzle into one or more operative nozzles including at least one nozzle from a different one of the sets.
0058In yet another embodiment, step (a) includes the substeps of: <ul id="ul0007" list-style="none"><li id="ul0007-0001" num="0000"><ul id="ul0008" list-style="none"><li id="ul0008-0001" num="0059">determining which combination of one or more available operative nozzles near the inoperative nozzle will minimise perceived error in an image that the dot data forms part of, the determination being performed on the basis of a color model; and</li><li id="ul0008-0002" num="0060">mapping the dot data intended for the inoperative nozzle to that combination of one or more operative nozzles.</li></ul></li></ul>
0061Preferably, the inoperative nozzle is associated with a black print channel, and wherein step (a) includes remapping the dot data intended for the inoperative nozzle into a plurality of operative nozzles in other color channels to produce a process black output at or adjacent a location on print media where the inoperative nozzle would have deposited a droplet of a black printing substance in accordance with the dot data.
0062In a preferred embodiment, a plurality of dot data intended for a corresponding plurality of inoperative nozzles are mapped to operative nozzles.
0063In accordance with a second aspect of the invention, there is provided a printer controller configured to implement the method of the first aspect.
0064In accordance with a third aspect of the invention, there is provided a printer controller configured to implement the method of the first aspect to a printhead comprising a plurality of the nozzles.
BRIEF DESCRIPTION OF THE DRAWINGS
Preferred and other embodiments of the invention will now be described, by way of example only,with reference to the accompanying drawings, in which:
<figref idref="DRAWINGS">FIG. 1</figref> is an example of state machine notation
<figref idref="DRAWINGS">FIG. 2</figref> shows document data flow in a printer
<figref idref="DRAWINGS">FIG. 3</figref> is an example of a single printer controller (hereinafter “SoPEC”) A4 simplex printer system
<figref idref="DRAWINGS">FIG. 4</figref> is an example of a dual SoPEC A4 duplex printer system
<figref idref="DRAWINGS">FIG. 5</figref> is an example of a dual SoPEC A3 simplex printer system
<figref idref="DRAWINGS">FIG. 6</figref> is an example of a quad SoPEC A3 duplex printer system
<figref idref="DRAWINGS">FIG. 7</figref> is an example of a SoPEC A4 simplex printing system with an extra SoPEC used as DRAM storage
<figref idref="DRAWINGS">FIG. 8</figref> is an example of an A3 duplex printing system featuring four printing SoPECs
<figref idref="DRAWINGS">FIG. 9</figref> shows pages containing different numbers of bands
<figref idref="DRAWINGS">FIG. 10</figref> shows the contents of a page band
<figref idref="DRAWINGS">FIG. 11</figref> illustrates a page data path from host to SoPEC
<figref idref="DRAWINGS">FIG. 12</figref> shows a page structure
<figref idref="DRAWINGS">FIG. 13</figref> shows a SoPEC system top level partition
<figref idref="DRAWINGS">FIG. 14</figref> shows a SoPEC CPU memory map (not to scale)
<figref idref="DRAWINGS">FIG. 15</figref> is a block diagram of CPU
<figref idref="DRAWINGS">FIG. 16</figref> shows CPU bus transactions
<figref idref="DRAWINGS">FIG. 17</figref> shows a state machine for a CPU subsystem slave
<figref idref="DRAWINGS">FIG. 18</figref> shows a SoPEC CPU memory map (not to scale)
<figref idref="DRAWINGS">FIG. 19</figref> shows an external signal view of a memory management unit (hereinafter “MMU”) sub-block partition
<figref idref="DRAWINGS">FIG. 20</figref> shows an internal signal view of an MMU sub-block partition
<figref idref="DRAWINGS">FIG. 21</figref> shows a DRAM write buffer
<figref idref="DRAWINGS">FIG. 22</figref> shows DIU waveforms for multiple transactions
<figref idref="DRAWINGS">FIG. 23</figref> shows a SoPEC LEON CPU core
<figref idref="DRAWINGS">FIG. 24</figref> shows a cache data RAM wrapper
<figref idref="DRAWINGS">FIG. 25</figref> shows a realtime debug unit block diagram
<figref idref="DRAWINGS">FIG. 26</figref> shows interrupt acknowledge cycles for single and pending interrupts
<figref idref="DRAWINGS">FIG. 27</figref> shows an A3 duplex system featuring four printing SoPECs with a single SoPEC DRAM device
<figref idref="DRAWINGS">FIG. 28</figref> is an SCB block diagram
<figref idref="DRAWINGS">FIG. 29</figref> is a logical view of the SCB of <figref idref="DRAWINGS">FIG. 28</figref>
<figref idref="DRAWINGS">FIG. 30</figref> shows an ISI configuration with four SoPEC devices
<figref idref="DRAWINGS">FIG. 31</figref> shows half-duplex interleaved transmission from ISIMaster to ISISlave
<figref idref="DRAWINGS">FIG. 32</figref> shows ISI transactions
<figref idref="DRAWINGS">FIG. 33</figref> shows an ISI long packet
<figref idref="DRAWINGS">FIG. 34</figref> shows an ISI ping packet
<figref idref="DRAWINGS">FIG. 35</figref> shows a short ISI packet
<figref idref="DRAWINGS">FIG. 36</figref> shows successful transmission of two long packets with sequence bit toggling
<figref idref="DRAWINGS">FIG. 37</figref> shows sequence bit operation with errored long packet
<figref idref="DRAWINGS">FIG. 38</figref> shows sequence bit operation with ACK error
<figref idref="DRAWINGS">FIG. 39</figref> shows an ISI sub-block partition
<figref idref="DRAWINGS">FIG. 40</figref> shows an ISI serial interface engine functional block diagram
<figref idref="DRAWINGS">FIG. 41</figref> is an SIE edge detection and data IO diagram
<figref idref="DRAWINGS">FIG. 42</figref> is an SIE Rx/Tx state machine Tx cycle state diagram
<figref idref="DRAWINGS">FIG. 43</figref> shows an SIE Rx/Tx state machine Tx bit stuff ‘0’ cycle state diagram
<figref idref="DRAWINGS">FIG. 44</figref> shows an SIE Rx/Tx state machine Tx bit stuff ‘1’ cycle state diagram
<figref idref="DRAWINGS">FIG. 45</figref> shows an SIE Rx/Tx state machine Rx cycle state diagram
<figref idref="DRAWINGS">FIG. 46</figref> shows an SIE Tx functional timing example
<figref idref="DRAWINGS">FIG. 47</figref> shows an SIE Rx functional timing example
<figref idref="DRAWINGS">FIG. 48</figref> shows an SIE Rx/Tx FIFO block diagram
<figref idref="DRAWINGS">FIG. 49</figref> shows SIE Rx/Tx FIFO control signal gating
<figref idref="DRAWINGS">FIG. 50</figref> shows an SIE bit stuffing state machine Tx cycle state diagram
<figref idref="DRAWINGS">FIG. 51</figref> shows an SIE bit stripping state machine Rx cycle state diagram
<figref idref="DRAWINGS">FIG. 52</figref> shows a CRC16 generation/checking shift register
<figref idref="DRAWINGS">FIG. 53</figref> shows circular buffer operation
<figref idref="DRAWINGS">FIG. 54</figref> shows duty cycle select
<figref idref="DRAWINGS">FIG. 55</figref> shows a GPIO partition
<figref idref="DRAWINGS">FIG. 56</figref> shows a motor control RTL diagram
<figref idref="DRAWINGS">FIG. 57</figref> is an input de-glitch RTL diagram
<figref idref="DRAWINGS">FIG. 58</figref> is a frequency analyser RTL diagram
<figref idref="DRAWINGS">FIG. 59</figref> shows a brushless DC controller
<figref idref="DRAWINGS">FIG. 60</figref> shows a period measure unit
<figref idref="DRAWINGS">FIG. 61</figref> shows line synch generation logic
<figref idref="DRAWINGS">FIG. 62</figref> shows an ICU partition
<figref idref="DRAWINGS">FIG. 63</figref> is an interrupt clear state diagram
<figref idref="DRAWINGS">FIG. 63A</figref> Timers sub-block partition diagram
<figref idref="DRAWINGS">FIG. 64</figref> is a watchdog timer RTL diagram
<figref idref="DRAWINGS">FIG. 65</figref> is a generic timer RTL diagram
<figref idref="DRAWINGS">FIG. 66</figref> is a schematic of a timing pulse generator
<figref idref="DRAWINGS">FIG. 67</figref> is a Pulse generator RTL diagram
<figref idref="DRAWINGS">FIG. 68</figref> shows a SoPEC clock relationship
<figref idref="DRAWINGS">FIG. 69</figref> shows a CPR block partition
<figref idref="DRAWINGS">FIG. 70</figref> shows reset deglitch logic
<figref idref="DRAWINGS">FIG. 71</figref> shows reset synchronizer logic
<figref idref="DRAWINGS">FIG. 72</figref> is a clock gate logic diagram
<figref idref="DRAWINGS">FIG. 73</figref> shows a PLL and Clock divider logic
<figref idref="DRAWINGS">FIG. 74</figref> shows a PLL control state machine diagram
<figref idref="DRAWINGS">FIG. 75</figref> shows a LSS master system-level interface
<figref idref="DRAWINGS">FIG. 76</figref> shows START and STOP conditions
<figref idref="DRAWINGS">FIG. 77</figref> shows an LSS transfer of 2 data bytes
<figref idref="DRAWINGS">FIG. 78</figref> is an example of an LSS write to a QA Chip
<figref idref="DRAWINGS">FIG. 79</figref> is an example of an LSS read from QA Chip
<figref idref="DRAWINGS">FIG. 80</figref> shows an LSS block diagram
<figref idref="DRAWINGS">FIG. 81</figref> shows an LSS multi-command transaction
<figref idref="DRAWINGS">FIG. 82</figref> shows start and stop generation based on previous bus state
<figref idref="DRAWINGS">FIG. 83</figref> shows an LSS master state machine
<figref idref="DRAWINGS">FIG. 84</figref> shows LSS master timing
<figref idref="DRAWINGS">FIG. 85</figref> shows a SoPEC system top level partition
<figref idref="DRAWINGS">FIG. 86</figref> shows an ead bus with 3 cycle random DRAM read accesses
<figref idref="DRAWINGS">FIG. 87</figref> shows interleaving of CPU and non-CPU read accesses
<figref idref="DRAWINGS">FIG. 88</figref> shows interleaving of read and write accesses with 3 cycle random DRAM accesses
<figref idref="DRAWINGS">FIG. 89</figref> shows interleaving of write accesses with 3 cycle random DRAM accesses
<figref idref="DRAWINGS">FIG. 90</figref> shows a read protocol for a SoPEC Unit making a single 256-bit access
<figref idref="DRAWINGS">FIG. 91</figref> shows a read protocol for a SoPEC Unit making a single 256-bit access
<figref idref="DRAWINGS">FIG. 92</figref> shows a write protocol for a SoPEC Unit making a single 256-bit access
<figref idref="DRAWINGS">FIG. 93</figref> shows a protocol for a posted, masked, 128-bit write by the CPU
<figref idref="DRAWINGS">FIG. 94</figref> shows a write protocol shown for CDU making four contiguous 64-bit accesses
<figref idref="DRAWINGS">FIG. 95</figref> shows timeslot-based arbitration
<figref idref="DRAWINGS">FIG. 96</figref> shows timeslot-based arbitration with separate pointers
<figref idref="DRAWINGS">FIG. 97</figref> shows a first example (a) of separate read and write arbitration
<figref idref="DRAWINGS">FIG. 98</figref> shows a second example (b) of separate read and write arbitration
<figref idref="DRAWINGS">FIG. 99</figref> shows a third example (c) of separate read and write arbitration
<figref idref="DRAWINGS">FIG. 100</figref> shows a DIU partition
<figref idref="DRAWINGS">FIG. 101</figref> shows a DIU partition
<figref idref="DRAWINGS">FIG. 102</figref> shows multiplexing and address translation logic for two memory instances
<figref idref="DRAWINGS">FIG. 103</figref> shows a timing of dau_dcu_valid, dcu_dau_adv and dcu_dau_wadv
<figref idref="DRAWINGS">FIG. 104</figref> shows a DCU state machine
<figref idref="DRAWINGS">FIG. 105</figref> shows random read timing
<figref idref="DRAWINGS">FIG. 106</figref> shows random write timing
<figref idref="DRAWINGS">FIG. 107</figref> shows refresh timing
<figref idref="DRAWINGS">FIG. 108</figref> shows page mode write timing
<figref idref="DRAWINGS">FIG. 109</figref> shows timing of non-CPU DIU read access
<figref idref="DRAWINGS">FIG. 110</figref> shows timing of CPU DIU read access
<figref idref="DRAWINGS">FIG. 111</figref> shows a CPU DIU read access
<figref idref="DRAWINGS">FIG. 112</figref> shows timing of CPU DIU write access
<figref idref="DRAWINGS">FIG. 113</figref> shows timing of a non-CDU/non-CPU DIU write access
<figref idref="DRAWINGS">FIG. 114</figref> shows timing of CDU DIU write access
<figref idref="DRAWINGS">FIG. 115</figref> shows command multiplexor sub-block partition
<figref idref="DRAWINGS">FIG. 116</figref> shows command multiplexor timing at DIU requesters interface
<figref idref="DRAWINGS">FIG. 117</figref> shows generation of re_arbitrate and re_arbitrate_wadv
<figref idref="DRAWINGS">FIG. 118</figref> shows CPU interface and arbitration logic
<figref idref="DRAWINGS">FIG. 119</figref> shows arbitration timing
<figref idref="DRAWINGS">FIG. 120</figref> shows setting RotationSync to enable a new rotation.
<figref idref="DRAWINGS">FIG. 121</figref> shows a timeslot based arbitration
<figref idref="DRAWINGS">FIG. 122</figref> shows a timeslot based arbitration with separate pointers
<figref idref="DRAWINGS">FIG. 123</figref> shows a CPU pre-access write lookahead pointer
<figref idref="DRAWINGS">FIG. 124</figref> shows arbitration hierarchy
<figref idref="DRAWINGS">FIG. 125</figref> shows hierarchical round-robin priority comparison
<figref idref="DRAWINGS">FIG. 126</figref> shows a read multiplexor partition
<figref idref="DRAWINGS">FIG. 127</figref> shows a read command queue (4 deep buffer)
<figref idref="DRAWINGS">FIG. 128</figref> shows state-machines for shared read bus accesses
<figref idref="DRAWINGS">FIG. 129</figref> shows a write multiplexor partition
<figref idref="DRAWINGS">FIG. 130</figref> shows a read multiplexer timing for back-to-back shared read bus transfer
<figref idref="DRAWINGS">FIG. 131</figref> shows a write multiplexer partition
<figref idref="DRAWINGS">FIG. 132</figref> shows a block diagram of a PCU
<figref idref="DRAWINGS">FIG. 133</figref> shows PCU accesses to PEP registers
<figref idref="DRAWINGS">FIG. 134</figref> shows command arbitration and execution
<figref idref="DRAWINGS">FIG. 135</figref> shows DRAM command access state machine
<figref idref="DRAWINGS">FIG. 136</figref> shows an outline of contone data flow with respect to CDU
<figref idref="DRAWINGS">FIG. 137</figref> shows a DRAM storage arrangement for a single line of JPEG 8×8 blocks in 4 colors
<figref idref="DRAWINGS">FIG. 138</figref> shows a read control unit state machine
<figref idref="DRAWINGS">FIG. 139</figref> shows a memory arrangement of JPEG blocks
<figref idref="DRAWINGS">FIG. 140</figref> shows a contone data write state machine
<figref idref="DRAWINGS">FIG. 141</figref> shows lead-in and lead-out clipping of contone data in multi-SoPEC environment
<figref idref="DRAWINGS">FIG. 142</figref> shows a block diagram of CFU
<figref idref="DRAWINGS">FIG. 143</figref> shows a DRAM storage arrangement for a single line of JPEG blocks in 4 colors
<figref idref="DRAWINGS">FIG. 144</figref> shows a block diagram of color space converter
<figref idref="DRAWINGS">FIG. 145</figref> shows a converter/invertor
<figref idref="DRAWINGS">FIG. 146</figref> shows a high-level block diagram of LBD in context
<figref idref="DRAWINGS">FIG. 147</figref> shows a schematic outline of the LBD and the SFU
<figref idref="DRAWINGS">FIG. 148</figref> shows a block diagram of lossless bi-level decoder
<figref idref="DRAWINGS">FIG. 149</figref> shows a stream decoder block diagram
<figref idref="DRAWINGS">FIG. 150</figref> shows a command controller block diagram
<figref idref="DRAWINGS">FIG. 151</figref> shows a state diagram for command controller (CC) state machine
<figref idref="DRAWINGS">FIG. 152</figref> shows a next edge unit block diagram
<figref idref="DRAWINGS">FIG. 153</figref> shows a next edge unit buffer diagram
<figref idref="DRAWINGS">FIG. 154</figref> shows a next edge unit edge detect diagram
<figref idref="DRAWINGS">FIG. 155</figref> shows a state diagram for the next edge unit state machine
<figref idref="DRAWINGS">FIG. 156</figref> shows a line fill unit block diagram
<figref idref="DRAWINGS">FIG. 157</figref> shows a state diagram for the Line Fill Unit (LFU) state machine
<figref idref="DRAWINGS">FIG. 158</figref> shows a bi-level DRAM buffer
<figref idref="DRAWINGS">FIG. 159</figref> shows interfaces between LBD/SFU/HCU
<figref idref="DRAWINGS">FIG. 160</figref> shows an SFU sub-block partition
<figref idref="DRAWINGS">FIG. 161</figref> shows an LBDPrevLineFifo sub-block
<figref idref="DRAWINGS">FIG. 162</figref> shows timing of signals on the LBDPrevLineFIFO interface to DIU and address generator
<figref idref="DRAWINGS">FIG. 163</figref> shows timing of signals on LBDPrevLineFIFO interface to DIU and address generator
<figref idref="DRAWINGS">FIG. 164</figref> shows LBDNextLineFifo sub-block
<figref idref="DRAWINGS">FIG. 165</figref> shows timing of signals on LBDNextLineFIFO interface to DIU and address generator
<figref idref="DRAWINGS">FIG. 166</figref> shows LBDNextLineFIFO DIU interface state diagram
<figref idref="DRAWINGS">FIG. 167</figref> shows an LDB to SFU write interface
<figref idref="DRAWINGS">FIG. 168</figref> shows an LDB to SFU read interface (within a line)
<figref idref="DRAWINGS">FIG. 169</figref> shows an HCUReadLineFifo Sub-block
<figref idref="DRAWINGS">FIG. 170</figref> shows a DIU write Interface
<figref idref="DRAWINGS">FIG. 171</figref> shows a DIU Read Interface multiplexing by select_hrfplf
<figref idref="DRAWINGS">FIG. 172</figref> shows DIU read request arbitration logic
<figref idref="DRAWINGS">FIG. 173</figref> shows address generation
<figref idref="DRAWINGS">FIG. 174</figref> shows an X scaling control unit
<figref idref="DRAWINGS">FIG. 175</figref> Y shows a scaling control unit
<figref idref="DRAWINGS">FIG. 176</figref> shows an overview of X and Y scaling at HCU interface
<figref idref="DRAWINGS">FIG. 177</figref> shows a high level block diagram of TE in context
<figref idref="DRAWINGS">FIG. 178</figref> shows a QR Code
<figref idref="DRAWINGS">FIG. 179</figref> shows Netpage tag structure
<figref idref="DRAWINGS">FIG. 180</figref> shows a Netpage tag with data rendered at 1600 dpi (magnified view)
<figref idref="DRAWINGS">FIG. 181</figref> shows an example of 2×2 dots for each block of QR code
<figref idref="DRAWINGS">FIG. 182</figref> shows placement of tags for portrait & landscape printing
<figref idref="DRAWINGS">FIG. 183</figref> shows agGeneral representation of tag placement
<figref idref="DRAWINGS">FIG. 184</figref> shows composition of SoPEC's tag format structure
<figref idref="DRAWINGS">FIG. 185</figref> shows a simple 3×3 tag structure
<figref idref="DRAWINGS">FIG. 186</figref> shows 3×3 tag redesigned for 21×21 area (not simple replication)
<figref idref="DRAWINGS">FIG. 187</figref> shows a TE Block Diagram
<figref idref="DRAWINGS">FIG. 188</figref> shows a TE Hierarchy
<figref idref="DRAWINGS">FIG. 189</figref> shows a block diagram of PCU accesses
<figref idref="DRAWINGS">FIG. 190</figref> shows a tag encoder top-level FSM
<figref idref="DRAWINGS">FIG. 191</figref> shows generated control signals
<figref idref="DRAWINGS">FIG. 192</figref> shows logic to combine dot information and encoded data
<figref idref="DRAWINGS">FIG. 193</figref> shows generation of Lastdotintag/1
<figref idref="DRAWINGS">FIG. 194</figref> shows generation of Dot Position Valid
<figref idref="DRAWINGS">FIG. 195</figref> shows generation of write enable to the TFU
<figref idref="DRAWINGS">FIG. 196</figref> shows generation of Tag Dot Number
<figref idref="DRAWINGS">FIG. 197</figref> shows TDI Architecture
<figref idref="DRAWINGS">FIG. 198</figref> shows data flow through the TDI
<figref idref="DRAWINGS">FIG. 199</figref> shows raw tag data interface block diagram
<figref idref="DRAWINGS">FIG. 200</figref> shows an RTDI State Flow Diagram
<figref idref="DRAWINGS">FIG. 201</figref> shows a relationship between TE_endoftagdata, cdu_startofbandstore and cdu_endofbandstore
<figref idref="DRAWINGS">FIG. 202</figref> shows a TDi State Flow Diagram
<figref idref="DRAWINGS">FIG. 203</figref> shows mapping of the tag data to codewords 0–7
<figref idref="DRAWINGS">FIG. 204</figref> shows coding and mapping of uncoded fixed tag data for (15,5) RS encoder
<figref idref="DRAWINGS">FIG. 205</figref> shows mapping of pre-coded fixed tag data
<figref idref="DRAWINGS">FIG. 206</figref> shows coding and mapping of variable tag data for (15,7) RS encoder
<figref idref="DRAWINGS">FIG. 207</figref> shows coding and mapping of uncoded fixed tag data for (15,7) RS encoder
<figref idref="DRAWINGS">FIG. 208</figref> shows mapping of 2D decoded variable tag data
<figref idref="DRAWINGS">FIG. 209</figref> shows a simple block diagram for an m=4 Reed Solomon encoder
<figref idref="DRAWINGS">FIG. 210</figref> shows an RS encoder I/O diagram
<figref idref="DRAWINGS">FIG. 211</figref> shows a (15,5) & (15,7) RS encoder block diagram
<figref idref="DRAWINGS">FIG. 212</figref> shows a (15,5) RS encoder timing diagram
<figref idref="DRAWINGS">FIG. 213</figref> shows a (15,7) RS encoder timing diagram
<figref idref="DRAWINGS">FIG. 214</figref> shows a circuit for multiplying by alpha<sup>3 </sup>
<figref idref="DRAWINGS">FIG. 215</figref> shows adding two field elements
<figref idref="DRAWINGS">FIG. 216</figref> shows an RS encoder implementation
<figref idref="DRAWINGS">FIG. 217</figref> shows an encoded tag data interface
<figref idref="DRAWINGS">FIG. 218</figref> shows an encoded fixed tag data interface
<figref idref="DRAWINGS">FIG. 219</figref> shows an encoded variable tag data interface
<figref idref="DRAWINGS">FIG. 220</figref> shows an encoded variable tag data sub-buffer
<figref idref="DRAWINGS">FIG. 221</figref> shows a breakdown of the tag format structure
<figref idref="DRAWINGS">FIG. 222</figref> shows a TFSI FSM state flow diagram
<figref idref="DRAWINGS">FIG. 223</figref> shows a TFS block diagram
<figref idref="DRAWINGS">FIG. 224</figref> shows a table A interface block diagram
<figref idref="DRAWINGS">FIG. 225</figref> shows a table A address generator
<figref idref="DRAWINGS">FIG. 226</figref> shows a table C interface block diagram
<figref idref="DRAWINGS">FIG. 227</figref> shows a table B interface block diagram
<figref idref="DRAWINGS">FIG. 228</figref> shows interfaces between TE, TFU and HCU
<figref idref="DRAWINGS">FIG. 229</figref> shows a 16-byte FIFO in TFU
<figref idref="DRAWINGS">FIG. 230</figref> shows a high level block diagram showing the HCU and its external interfaces
<figref idref="DRAWINGS">FIG. 231</figref> shows a block diagram of the HCU
<figref idref="DRAWINGS">FIG. 232</figref> shows a block diagram of the control unit
<figref idref="DRAWINGS">FIG. 233</figref> shows a block diagram of determine advdot unit
<figref idref="DRAWINGS">FIG. 234</figref> shows a page structure
<figref idref="DRAWINGS">FIG. 235</figref> shows a block diagram of a margin unit
<figref idref="DRAWINGS">FIG. 236</figref> shows a block diagram of a dither matrix table interface
<figref idref="DRAWINGS">FIG. 237</figref> shows an example of reading lines of dither matrix from DRAM
<figref idref="DRAWINGS">FIG. 238</figref> shows a state machine to read dither matrix table
<figref idref="DRAWINGS">FIG. 239</figref> shows a contone dotgen unit
<figref idref="DRAWINGS">FIG. 240</figref> shows a block diagram of dot reorg unit
<figref idref="DRAWINGS">FIG. 241</figref> shows an HCU to DNC interface (also used in DNC to DWU, LLU to PHI)
<figref idref="DRAWINGS">FIG. 242</figref> shows SFU to HCU interface (all feeders to HCU)
<figref idref="DRAWINGS">FIG. 243</figref> shows representative logic of the SFU to HCU interface
<figref idref="DRAWINGS">FIG. 244</figref> shows a high-level block diagram of DNC
<figref idref="DRAWINGS">FIG. 245</figref> shows a dead nozzle table format
<figref idref="DRAWINGS">FIG. 246</figref> shows set of dots operated on for error diffusion
<figref idref="DRAWINGS">FIG. 247</figref> shows a block diagram of DNC
<figref idref="DRAWINGS">FIG. 248</figref> shows a sub-block diagram of ink replacement unit
<figref idref="DRAWINGS">FIG. 249</figref> shows a dead nozzle table state machine
<figref idref="DRAWINGS">FIG. 250</figref> shows logic for dead nozzle removal and ink replacement
<figref idref="DRAWINGS">FIG. 251</figref> shows a sub-block diagram of error diffusion unit
<figref idref="DRAWINGS">FIG. 252</figref> shows a maximum length 32-bit LFSR used for random bit generation
<figref idref="DRAWINGS">FIG. 253</figref> shows a high-level data flow diagram of DWU in context
<figref idref="DRAWINGS">FIG. 254</figref> shows a printhead nozzle layout for 36-nozzle bi-lithic printhead
<figref idref="DRAWINGS">FIG. 255</figref> shows a printhead nozzle layout for a 36-nozzle bi-lithic printhead
<figref idref="DRAWINGS">FIG. 256</figref> shows a dot line store logical representation
<figref idref="DRAWINGS">FIG. 257</figref> shows a conceptual view of printhead row alignment
<figref idref="DRAWINGS">FIG. 258</figref> shows a conceptual view of printhead rows (as seen by the LLU and PHI)
<figref idref="DRAWINGS">FIG. 259</figref> shows a comparison of 1.5×v2× buffering
<figref idref="DRAWINGS">FIG. 260</figref> shows an even dot order in DRAM (increasing sense, 13320 dot wide line)
<figref idref="DRAWINGS">FIG. 261</figref> shows an even dot order in DRAM (decreasing sense, 13320 dot wide line)
<figref idref="DRAWINGS">FIG. 262</figref> shows a dotline FIFO data structure in DRAM
<figref idref="DRAWINGS">FIG. 263</figref> shows a DWU partition
<figref idref="DRAWINGS">FIG. 264</figref> shows a buffer address generator sub-block
<figref idref="DRAWINGS">FIG. 265</figref> shows a DIU Interface sub-block
<figref idref="DRAWINGS">FIG. 266</figref> shows an interface controller state diagram
<figref idref="DRAWINGS">FIG. 267</figref> shows a high level data flow diagram of LLU in context
<figref idref="DRAWINGS">FIG. 268</figref> shows paper and printhead nozzles relationship (example with D<sub>1</sub>=D<sub>2</sub>=5)
<figref idref="DRAWINGS">FIG. 269</figref> shows printhead structure and dot generate order
<figref idref="DRAWINGS">FIG. 270</figref> shows an order of dot data generation and transmission
<figref idref="DRAWINGS">FIG. 271</figref> shows a conceptual view of printhead rows
<figref idref="DRAWINGS">FIG. 272</figref> shows a dotline FIFO data structure in DRAM (LLU specification)
<figref idref="DRAWINGS">FIG. 273</figref> shows an LLU partition
<figref idref="DRAWINGS">FIG. 274</figref> shows a dot generator RTL diagram
<figref idref="DRAWINGS">FIG. 275</figref> shows a DIU interface
<figref idref="DRAWINGS">FIG. 276</figref> shows an interface controller state diagram
<figref idref="DRAWINGS">FIG. 277</figref> shows high-level data flow diagram of PHI in context
<figref idref="DRAWINGS">FIG. 278</figref> shows power on reset
<figref idref="DRAWINGS">FIG. 279</figref> shows printhead data rate equalization
<figref idref="DRAWINGS">FIG. 280</figref> shows a printhead structure and dot generate order
<figref idref="DRAWINGS">FIG. 281</figref> shows an order of dot data generation and transmission
<figref idref="DRAWINGS">FIG. 282</figref> shows an order of dot data generation and transmission (single printhead case)
<figref idref="DRAWINGS">FIG. 283</figref> shows printhead interface timing parameters
<figref idref="DRAWINGS">FIG. 284</figref> shows printhead timing with margining
<figref idref="DRAWINGS">FIG. 285</figref> shows a PHI block partition
<figref idref="DRAWINGS">FIG. 286</figref> shows a sync generator state diagram
<figref idref="DRAWINGS">FIG. 287</figref> shows a line sync de-glitch RTL diagram
<figref idref="DRAWINGS">FIG. 288</figref> shows a fire generator state diagram
<figref idref="DRAWINGS">FIG. 289</figref> shows a PHI controller state machine
<figref idref="DRAWINGS">FIG. 290</figref> shows a datapath unit partition
<figref idref="DRAWINGS">FIG. 291</figref> shows a dot order controller state diagram
<figref idref="DRAWINGS">FIG. 292</figref> shows a data generator state diagram
<figref idref="DRAWINGS">FIG. 293</figref> shows data serializer timing
<figref idref="DRAWINGS">FIG. 294</figref> shows a data serializer RTL Diagram
<figref idref="DRAWINGS">FIG. 295</figref> shows printhead types 0 to 7
<figref idref="DRAWINGS">FIG. 296</figref> shows an ideal join between two dilithic printhead segments
<figref idref="DRAWINGS">FIG. 297</figref> shows an example of a join between two bilithic printhead segments
<figref idref="DRAWINGS">FIG. 298</figref> shows printable vs non-printable area under new definition (looking at colors as if 1 row only)
<figref idref="DRAWINGS">FIG. 299</figref> shows identification of printhead nozzles and shift-register sequences for printheads in arrangement 1
<figref idref="DRAWINGS">FIG. 300</figref> shows demultiplexing of data within the printheads in arrangement 1
<figref idref="DRAWINGS">FIG. 301</figref> shows double data rate signalling for a type 0 printhead in arrangement 1
<figref idref="DRAWINGS">FIG. 302</figref> shows double data rate signalling for a type 1 printhead in arrangement 1
<figref idref="DRAWINGS">FIG. 303</figref> shows identification of printheads nozzles and shift-register sequences for printheads in arrangement 2
<figref idref="DRAWINGS">FIG. 304</figref> shows demultiplexing of data within the printheads in arrangement 2
<figref idref="DRAWINGS">FIG. 305</figref> shows double data rate signalling for a type 0 printhead in arrangement 2
<figref idref="DRAWINGS">FIG. 306</figref> shows double data rate signalling for a type 1 printhead in arrangement 2
<figref idref="DRAWINGS">FIG. 307</figref> shows all 8 printhead arrangements
<figref idref="DRAWINGS">FIG. 308</figref> shows a printhead structure
<figref idref="DRAWINGS">FIG. 309</figref> shows a column Structure
<figref idref="DRAWINGS">FIG. 310</figref> shows a printhead dot shift register dot mapping to page
<figref idref="DRAWINGS">FIG. 311</figref> shows data timing during printing
<figref idref="DRAWINGS">FIG. 312</figref> shows print quality
<figref idref="DRAWINGS">FIG. 313</figref> shows fire and select shift register setup for printing
<figref idref="DRAWINGS">FIG. 314</figref> shows a fire pattern across butt end of printhead chips
<figref idref="DRAWINGS">FIG. 315</figref> shows fire pattern generation
<figref idref="DRAWINGS">FIG. 316</figref> shows determination of select shift register value
<figref idref="DRAWINGS">FIG. 317</figref> shows timing for printing signals
<figref idref="DRAWINGS">FIG. 318</figref> shows initialisation of printheads
<figref idref="DRAWINGS">FIG. 319</figref> shows a nozzle test latching circuit
<figref idref="DRAWINGS">FIG. 320</figref> shows nozzle testing
<figref idref="DRAWINGS">FIG. 321</figref> shows a temperature reading
<figref idref="DRAWINGS">FIG. 322</figref> shows CMOS testing
<figref idref="DRAWINGS">FIG. 323</figref> shows a reticle layout
<figref idref="DRAWINGS">FIG. 324</figref> shows a stepper pattern on Wafer
<figref idref="DRAWINGS">FIG. 325</figref> shows relationship between datasets
<figref idref="DRAWINGS">FIG. 326</figref> shows a validation hierarchy
<figref idref="DRAWINGS">FIG. 327</figref> shows development of operating system code
<figref idref="DRAWINGS">FIG. 328</figref> shows protocol for directly verifying reads from ChipR
<figref idref="DRAWINGS">FIG. 329</figref> shows a protocol for signature translation protocol
<figref idref="DRAWINGS">FIG. 330</figref> shows a protocol for a direct authenticated write
<figref idref="DRAWINGS">FIG. 331</figref> shows an alternative protocol for a direct authenticated write
<figref idref="DRAWINGS">FIG. 332</figref> shows a protocol for basic update of permissions
<figref idref="DRAWINGS">FIG. 333</figref> shows a protocol for a multiple-key update
<figref idref="DRAWINGS">FIG. 334</figref> shows a protocol for a single-key authenticated read
<figref idref="DRAWINGS">FIG. 335</figref> shows a protocol for a single-key authenticated write
<figref idref="DRAWINGS">FIG. 336</figref> shows a protocol for a single-key update of permissions
<figref idref="DRAWINGS">FIG. 337</figref> shows a protocol for a single-key update
<figref idref="DRAWINGS">FIG. 338</figref> shows a protocol for a multiple-key single-M authenticated read
<figref idref="DRAWINGS">FIG. 339</figref> shows a protocol for a multiple-key authenticated write
<figref idref="DRAWINGS">FIG. 340</figref> shows a protocol for a multiple-key update of permissions
<figref idref="DRAWINGS">FIG. 341</figref> shows a protocol for a multiple-key update
<figref idref="DRAWINGS">FIG. 342</figref> shows a protocol for a multiple-key multiple-M authenticated read
<figref idref="DRAWINGS">FIG. 343</figref> shows a protocol for a multiple-key authenticated write
<figref idref="DRAWINGS">FIG. 344</figref> shows a protocol for a multiple-key update of permissions
<figref idref="DRAWINGS">FIG. 345</figref> shows a protocol for a multiple-key update
<figref idref="DRAWINGS">FIG. 346</figref> shows relationship of permissions bits to M[n] access bits
<figref idref="DRAWINGS">FIG. 347</figref> shows 160-bit maximal period LFSR
<figref idref="DRAWINGS">FIG. 348</figref> shows clock filter
<figref idref="DRAWINGS">FIG. 349</figref> shows tamper detection line
<figref idref="DRAWINGS">FIG. 350</figref> shows an oversize nMOS transistor layout of Tamper Detection Line
<figref idref="DRAWINGS">FIG. 351</figref> shows a Tamper Detection Line
<figref idref="DRAWINGS">FIG. 352</figref> shows how Tamper Detection Lines cover the Noise Generator
<figref idref="DRAWINGS">FIG. 353</figref> shows a prior art FET Implementation of CMOS inverter
<figref idref="DRAWINGS">FIG. 354</figref> shows non-flashing CMOS
<figref idref="DRAWINGS">FIG. 355</figref> shows components of a printer-based refill device
<figref idref="DRAWINGS">FIG. 356</figref> shows refilling of printers by printer-based refill device
<figref idref="DRAWINGS">FIG. 357</figref> shows components of a home refill station
<figref idref="DRAWINGS">FIG. 358</figref> shows a three-ink reservoir unit
<figref idref="DRAWINGS">FIG. 359</figref> shows refill of ink cartridges in a home refill station
<figref idref="DRAWINGS">FIG. 360</figref> shows components of a commercial refill station
<figref idref="DRAWINGS">FIG. 361</figref> shows an ink reservoir unit
<figref idref="DRAWINGS">FIG. 362</figref> shows refill of ink cartridges in a commercial refill station (showing a single refill unit)
<figref idref="DRAWINGS">FIG. 363</figref> shows equivalent signature generation
<figref idref="DRAWINGS">FIG. 364</figref> shows a basic field definition
<figref idref="DRAWINGS">FIG. 365</figref> shows an example of defining field sizes and positions
<figref idref="DRAWINGS">FIG. 366</figref> shows permissions
<figref idref="DRAWINGS">FIG. 367</figref> shows a first example of permissions for a field
<figref idref="DRAWINGS">FIG. 368</figref> shows a second example of permissions for a field
<figref idref="DRAWINGS">FIG. 369</figref> shows field attributes
<figref idref="DRAWINGS">FIG. 370</figref> shows an output signature generation data format for Read
<figref idref="DRAWINGS">FIG. 371</figref> shows an input signature verification data format for Test
<figref idref="DRAWINGS">FIG. 372</figref> shows an output signature generation data format for Translate
<figref idref="DRAWINGS">FIG. 373</figref> shows an input signature verification data format for WriteAuth
<figref idref="DRAWINGS">FIG. 374</figref> shows input signature data format for ReplaceKey
<figref idref="DRAWINGS">FIG. 375</figref> shows a key replacement map
<figref idref="DRAWINGS">FIG. 376</figref> shows a key replacement map after K<sub>1 </sub>is replaced
<figref idref="DRAWINGS">FIG. 377</figref> shows a key replacement process
<figref idref="DRAWINGS">FIG. 378</figref> shows an output signature data format for GetProgramKey
<figref idref="DRAWINGS">FIG. 379</figref> shows transfer and rollback process
<figref idref="DRAWINGS">FIG. 380</figref> shows an upgrade flow
<figref idref="DRAWINGS">FIG. 381</figref> shows authorised ink refill paths in the printing system
<figref idref="DRAWINGS">FIG. 382</figref> shows an input signature verification data format for XferAmount
<figref idref="DRAWINGS">FIG. 383</figref> shows a transfer and rollback process
<figref idref="DRAWINGS">FIG. 384</figref> shows an upgrade flow
<figref idref="DRAWINGS">FIG. 385</figref> shows authorised upgrade paths in the printing system
<figref idref="DRAWINGS">FIG. 386</figref> shows a direct signature validation sequence
<figref idref="DRAWINGS">FIG. 387</figref> shows signature validation using translation
<figref idref="DRAWINGS">FIG. 388</figref> shows setup of preauth field attributes
<figref idref="DRAWINGS">FIG. 389</figref> shows a high level block diagram of QA Chip
<figref idref="DRAWINGS">FIG. 390</figref> shows an analogue unit
<figref idref="DRAWINGS">FIG. 391</figref> shows a serial bus protocol for trimming
<figref idref="DRAWINGS">FIG. 392</figref> shows a block diagram of a trim unit
<figref idref="DRAWINGS">FIG. 393</figref> shows a block diagram of a CPU of the QA chip
<figref idref="DRAWINGS">FIG. 394</figref> shows block diagram of an MIU
<figref idref="DRAWINGS">FIG. 395</figref> shows a block diagram of memory components
<figref idref="DRAWINGS">FIG. 396</figref> shows a first byte sent to an IOU
<figref idref="DRAWINGS">FIG. 397</figref> shows a block diagram of the IOU
<figref idref="DRAWINGS">FIG. 398</figref> shows a relationship between external SDa and SClk and generation of internal signals
<figref idref="DRAWINGS">FIG. 399</figref> shows block diagram of ALU
<figref idref="DRAWINGS">FIG. 400</figref> shows a block diagram of DataSel
<figref idref="DRAWINGS">FIG. 401</figref> shows a block diagram of ROR
<figref idref="DRAWINGS">FIG. 402</figref> shows a block diagram of the ALU's IO block
<figref idref="DRAWINGS">FIG. 403</figref> shows a block diagram of PCU
<figref idref="DRAWINGS">FIG. 404</figref> shows a block diagram of an Address Generator Unit
<figref idref="DRAWINGS">FIG. 405</figref> shows a block diagram for a Counter Unit
<figref idref="DRAWINGS">FIG. 406</figref> shows a block diagram of PMU
<figref idref="DRAWINGS">FIG. 407</figref> shows a state machine for PMU
<figref idref="DRAWINGS">FIG. 408</figref> shows a block diagram of MRU
<figref idref="DRAWINGS">FIG. 409</figref> shows simplified MAU state machine
<figref idref="DRAWINGS">FIG. 410</figref> shows power-on reset behaviour
<figref idref="DRAWINGS">FIG. 411</figref> shows a ring oscillator block diagram
<figref idref="DRAWINGS">FIG. 412</figref> shows a system clock duty cycle
DETAILED DESCRIPTION OF PREFERRED AND OTHER EMBODIMENTS
0479It will be appreciated that the detailed description that follows takes the form of a highly detailed design of the invention, including supporting hardware and software. A high level of detailed disclosure is provided to ensure that one skilled in the art will have ample guidance for implementing the invention.
0480Imperative phrases such as “must”, “requires”, “necessary” and “important” (and similar language) should be read as being indicative of being necessary only for the preferred embodiment actually being described. As such, unless the opposite is clear from the context, imperative wording should not be interpreted as such. Nothing in the detailed description is to be understood as limiting the scope of the invention, which is intended to be defined as widely as is defined in the accompanying claims.
0481Indications of expected rates, frequencies, costs, and other quantitative values are exemplary and estimated only, and are made in good faith. Nothing in this specification should be read as implying that a particular commercial embodiment is or will be capable of a particular performance level in any measurable area.
0482It will be appreciated that the principles, methods and hardware described throughout this document can be applied to other fields. Much of the security-related disclosure, for example, can be applied to many other fields that require secure communications between entities, and certainly has application far beyond the field of printers.
0000System Overview
0483The preferred of the present invention is implemented in a printer using microelectromechanical systems (MEMS) printheads. The printer can receive data from, for example, a personal computer such as an IBM compatible PC or Apple computer. In other embodiments, the printer can receive data directly from, for example, a digital still or video camera. The particular choice of communication link is not important, and can be based, for example, on USB, Firewire, Bluetooth or any other wireless or hardwired communications protocol.
0000Print System Overview
00003 Introduction
0484This document describes the SoPEC (Small office home office Print Engine Controller) ASIC (Application Specific Integrated Circuit) suitable for use in, for example, SoHo printer products. The SoPEC ASIC is intended to be a low cost solution for bi-lithic printhead control, replacing the multichip solutions in larger more professional systems with a single chip. The increased cost competitiveness is achieved by integrating several systems such as a modified PEC1 printing pipeline, CPU control system, peripherals and memory sub-system onto one SoC ASIC, reducing component count and simplifying board design.
0485This section will give a general introduction to Memjet printing systems, introduce the components that make a bi-lithic printhead system, describe possible system architectures and show how several SoPECs can be used to achieve A3 and A4 duplex printing. The section “SoPEC ASIC” describes the SoC SoPEC ASIC, with subsections describing the CPU, DRAM and Print Engine Pipeline subsystems. Each section gives a detailed description of the blocks used and their operation within the overall print system. The final section describes the bi-lithic printhead construction and associated implications to the system due to its makeup.
00004 Nomenclature
00004.1 Bi-lithic Printhead Notation
0486A bi-lithic based printhead is constructed from 2 printhead ICs of varying sizes. The notation M:N is used to express the size relationship of each IC, where M specifies one printhead IC in inches and N specifies the remaining printhead IC in inches.
0487The ‘SoPEC/MoPEC Bilithic Printhead Reference’ document [10] contains a description of the bi-lithic printhead and related terminology.
4.2 DEFINITIONS
0488The following terms are used throughout this specification: <ul id="ul0009" list-style="none"><li id="ul0009-0001" num="0489">Bi-lithic printhead Refers to printhead constructed from 2 printhead ICs</li><li id="ul0009-0002" num="0490">CPU Refers to CPU core, caching system and MMU.</li><li id="ul0009-0003" num="0491">ISI-Bridge chip A device with a high speed interface (such as USB2.0, Ethernet or IEEE1394) and one or more ISI interfaces. The ISI-Bridge would be the ISIMaster for each of the ISI buses it interfaces to.</li><li id="ul0009-0004" num="0492">ISIMaster The ISIMaster is the only device allowed to initiate communication on the Inter Sopec Interface (ISI) bus. The ISIMaster interfaces with the host.</li><li id="ul0009-0005" num="0493">ISISlave Multi-SoPEC systems will contain one or more ISISlave SoPECs connected to the ISI bus. ISISlaves can only respond to communication initiated by the ISIMaster.</li><li id="ul0009-0006" num="0494">LEON Refers to the LEON CPU core.</li><li id="ul0009-0007" num="0495">LineSyncMaster The LineSyncMaster device generates the line synchronisation pulse that all SoPECs in the system must synchronise their line outputs to.</li><li id="ul0009-0008" num="0496">Multi-SoPEC Refers to SoPEC based print system with multiple SoPEC devices</li><li id="ul0009-0009" num="0497">Netpage Refers to page printed with tags (normally in infrared ink).</li><li id="ul0009-0010" num="0498">PEC1 Refers to Print Engine Controller version 1, precursor to SoPEC used to control printheads constructed from multiple angled printhead segments.</li><li id="ul0009-0011" num="0499">Printhead IC Single MEMS IC used to construct bi-lithic printhead</li><li id="ul0009-0012" num="0500">PrintMaster The PrintMaster device is responsible for coordinating all aspects of the print operation. There may only be one PrintMaster in a system.</li><li id="ul0009-0013" num="0501">QA Chip Quality Assurance Chip</li><li id="ul0009-0014" num="0502">Storage SoPEC An ISISlave SoPEC used as a DRAM store and which does not print.</li><li id="ul0009-0015" num="0503">Tag Refers to pattern which encodes information about its position and orientation which allow it to be optically located and its data contents read. <br /> 4.3 Acronym and Abbreviations </li></ul>
0504The following acronyms and abbreviations are used in this specification <ul id="ul0010" list-style="none"><li id="ul0010-0001" num="0505">CFU Contone FIFO Unit</li><li id="ul0010-0002" num="0506">CPU Central Processing Unit</li><li id="ul0010-0003" num="0507">DIU DRAM Interface Unit</li><li id="ul0010-0004" num="0508">DNC Dead Nozzle Compensator</li><li id="ul0010-0005" num="0509">DRAM Dynamic Random Access Memory</li><li id="ul0010-0006" num="0510">DWU DotLine Writer Unit</li><li id="ul0010-0007" num="0511">GPIO General Purpose Input Output</li><li id="ul0010-0008" num="0512">HCU Halftoner Compositor Unit</li><li id="ul0010-0009" num="0513">ICU Interrupt Controller Unit</li><li id="ul0010-0010" num="0514">ISI Inter SoPEC Interface</li><li id="ul0010-0011" num="0515">LDB Lossless Bi-level Decoder</li><li id="ul0010-0012" num="0516">LLU Line Loader Unit</li><li id="ul0010-0013" num="0517">LSS Low Speed Serial interface</li><li id="ul0010-0014" num="0518">MEMS Micro Electro Mechanical System</li><li id="ul0010-0015" num="0519">MMU Memory Management Unit</li><li id="ul0010-0016" num="0520">PCU SoPEC Controller Unit</li><li id="ul0010-0017" num="0521">PHI PrintHead Interface</li><li id="ul0010-0018" num="0522">PSS Power Save Storage Unit</li><li id="ul0010-0019" num="0523">RDU Real-time Debug Unit</li><li id="ul0010-0020" num="0524">ROM Read Only Memory</li><li id="ul0010-0021" num="0525">SCB Serial Communication Block</li><li id="ul0010-0022" num="0526">SFU Spot FIFO Unit</li><li id="ul0010-0023" num="0527">SMG4 Silverbrook Modified Group 4.</li><li id="ul0010-0024" num="0528">SoPEC Small office home office Print Engine</li><li id="ul0010-0025" num="0529">Controller</li><li id="ul0010-0026" num="0530">SRAM Static Random Access Memory</li><li id="ul0010-0027" num="0531">TE Tag Encoder</li><li id="ul0010-0028" num="0532">TFU Tag FIFO Unit</li><li id="ul0010-0029" num="0533">TIM Timers Unit</li><li id="ul0010-0030" num="0534">USB Universal Serial Bus <br /> 4.4 Pseudocode Notation </li></ul>
0535In general the pseudocode examples use C like statements with some exceptions. Symbol and naming convections used for pseudocode. <ul id="ul0011" list-style="none"><li id="ul0011-0001" num="0536">// Comment</li><li id="ul0011-0002" num="0537">=Assignment</li><li id="ul0011-0003" num="0538">==,!=<,> Operator equal, not equal, less than, greater than</li><li id="ul0011-0004" num="0539">+,−,*,/,% Operator addition, subtraction, multiply, divide, modulus</li><li id="ul0011-0005" num="0540">&,|,^,<<,>>,˜ Bitwise AND, bitwise OR, bitwise exclusive OR, left shift, right shift, complement</li><li id="ul0011-0006" num="0541">AND,OR,NOT Logical AND, Logical OR, Logical inversion</li><li id="ul0011-0007" num="0542">[XX:YY] Array/vector specifier</li><li id="ul0011-0008" num="0543">{a, b, c} Concatenation operation</li><li id="ul0011-0009" num="0544">++, −− Increment and decrement <br /> 4.4.1 Register and Signal Naming Conventions </li></ul>
0545In general register naming uses the C style conventions with capitalization to denote word delimiters. Signals use RTL style notation where underscore denote word delimiters. There is a direct translation between both convention. For example the CmdSourceFifo register is equivalent to cmd_source_fifo signal.
00004.5 State Machine Notation
0546State machines should be described using the pseudocode notation outlined above. State machine descriptions use the convention of <u style="single">underline</u> to indicate the cause of a transition from one state to another and plain text (no underline) to indicate the effect of the transition i.e. signal transitions which occur when the new state is entered.
0547A sample state machine is shown in <figref idref="DRAWINGS">FIG. 1</figref>.
00005 Printing Considerations
0548A bi-lithic printhead produces 1600 dpi bi-level dots. On low-diffusion paper, each ejected drop forms a 22.5 μm diameter dot. Dots are easily produced in isolation, allowing dispersed-dot dithering to be exploited to its fullest. Since the bi-lithic printhead is the width of the page and operates with a constant paper velocity, color planes are printed in perfect registration, allowing ideal dot-on-dot printing. Dot-on-dot printing minimizes ‘muddying’ of midtones caused by inter-color bleed. A page layout may contain a mixture of images, graphics and text. Continuous-tone (contone) images and graphics are reproduced using a stochastic dispersed-dot dither. Unlike a clustered-dot (or amplitude-modulated) dither, a dispersed-dot (or frequency-modulated) dither reproduces high spatial frequencies (i.e. image detail) almost to the limits of the dot resolution, while simultaneously reproducing lower spatial frequencies to their full color depth, when spatially integrated by the eye. A stochastic dither matrix is carefully designed to be free of objectionable low-frequency patterns when tiled across the image. As such its size typically exceeds the minimum size required to support a particular number of intensity levels (e.g. 16×16×8 bits for 257 intensity levels).
0549Human contrast sensitivity peaks at a spatial frequency of about 3 cycles per degree of visual field and then falls off logarithmically, decreasing by a factor of 100 beyond about 40 cycles per degree and becoming immeasurable beyond 60 cycles per degree [25][25]. At a normal viewing distance of 12 inches (about 300 mm), this translates roughly to 200–300 cycles per inch (cpi) on the printed page, or 400–600 samples per inch according to Nyquist's theorem.
0550In practice, contone resolution above about 300 ppi is of limited utility outside special applications such as medical imaging. Offset printing of magazines, for example, uses contone resolutions in the range 150 to 300 ppi. Higher resolutions contribute slightly to color error through the dither.
0551Black text and graphics are reproduced directly using bi-level black dots, and are therefore not anti-aliased (i.e. low-pass filtered) before being printed. Text should therefore be supersampled beyond the perceptual limits discussed above, to produce smoother edges when spatially integrated by the eye. Text resolution up to about 1200 dpi continues to contribute to perceived text sharpness (assuming low-diffusion paper, of course).
0552A Netpage printer, for example, may use a contone resolution of 267 ppi (i.e. 1600 dpi/6), and a black text and graphics resolution of 800 dpi. A high end office or departmental printer may use a contone resolution of 320 ppi (1600 dpi/5) and a black text and graphics resolution of 1600 dpi. Both formats are capable of exceeding the quality of commercial (offset) printing and photographic reproduction.
00006 Document Data Flow
00006.1 Considerations
0553Because of the page-width nature of the bi-lithic printhead, each page must be printed at a constant speed to avoid creating visible artifacts. This means that the printing speed can't be varied to match the input data rate. Document rasterization and document printing are therefore decoupled to ensure the printhead has a constant supply of data. A page is never printed until it is fully rasterized. This can be achieved by storing a compressed version of each rasterized page image in memory. This decoupling also allows the RIP(s) to run ahead of the printer when rasterizing simple pages, buying time to rasterize more complex pages.
0554Because contone color images are reproduced by stochastic dithering, but black text and line graphics are reproduced directly using dots, the compressed page image format contains a separate foreground bi-level black layer and background contone color layer. The black layer is composited over the contone layer after the contone layer is dithered (although the contone layer has an optional black component). A final layer of Netpage tags (in infrared or black ink) is optionally added to the page for printout.
0555<figref idref="DRAWINGS">FIG. 2</figref> shows the flow of a document from computer system to printed page.
0556At 267 ppi for example, a A4 page (8.26 inches×11.7 inches) of contone CMYK data has a size of 26.3 MB. At 320 ppi, an A4 page of contone data has a size of 37.8 MB. Using lossy contone compression algorithms such as JPEG [27], contone images compress with a ratio up to 10:1 without noticeable loss of quality, giving compressed page sizes of 2.63 MB at 267 ppi and 3.78 MB at 320 ppi.
0557At 800 dpi, a A4 page of bi-level data has a size of 7.4 MB. At 1600 dpi, a Letter page of bi-level data has a size of 29.5 MB. Coherent data such as text compresses very well. Using lossless bi-level compression algorithms such as SMG4 fax as discussed in Section 8.1.2.3.1, ten-point plain text compresses with a ratio of about 50:1. Lossless bi-level compression across an average page is about 20:1 with 10:1 possible for pages which compress poorly. The requirement for SoPEC is to be able to print text at 10:1 compression. Assuming 10:1 compression gives compressed page sizes of 0.74 MB at 800 dpi, and 2.95 MB at 1600 dpi.
0558Once dithered, a page of CMYK contone image data consists of 116 MB of bi-level data. Using lossless bi-level compression algorithms on this data is pointless precisely because the optimal dither is stochastic—i.e. since it introduces hard-to-compress disorder.
0559Netpage tag data is optionally supplied with the page image. Rather than storing a compressed bi-level data layer for the Netpage tags, the tag data is stored in its raw form. Each tag is supplied up to 120 bits of raw variable data (combined with up to 56 bits of raw fixed data) and covers up to a 6 mm×6 mm area (at 1600 dpi). The absolute maximum number of tags on a A4 page is 15,540 when the tag is only 2 mm×2 mm (each tag is 126 dots×126 dots, for a total coverage of 148 tags×105 tags). 15,540 tags of 128 bits per tag gives a compressed tag page size of 0.24 MB.
0560The multi-layer compressed page image format therefore exploits the relative strengths of lossy JPEG contone image compression, lossless bi-level text compression, and tag encoding. The format is compact enough to be storage-efficient, and simple enough to allow straightforward real-time expansion during printing.
0561Since text and images normally don't overlap, the normal worst-case page image size is image only, while the normal best-case page image size is text only. The addition of worst case Netpage tags adds 0.24 MB to the page image size. The worst-case page image size is text over image plus tags. The average page size assumes a quarter of an average page contains images. Table 1 shows data sizes for compressed Letter page for these different options.
0562<tables id="TABLE-US-00001" num="00001"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 1</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Data sizes for A4 page (8.26 inches × 11.7 inches)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="91pt" align="left" /><colspec colname="1" colwidth="56pt" align="center" /><colspec colname="2" colwidth="70pt" align="center" /><tbody valign="top"><row><entry /><entry>267 ppi contone</entry><entry>320 ppi contone</entry></row><row><entry /><entry>800 dpi bi-level</entry><entry>1600 dpi bi-level</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="56pt" align="center" /><colspec colname="3" colwidth="70pt" align="center" /><tbody valign="top"><row><entry /><entry>Image only (contone),</entry><entry>2.63 MB</entry><entry>3.78 MB</entry></row><row><entry /><entry>10:1 compression</entry></row><row><entry /><entry>Text only (bi-level),</entry><entry>0.74 MB</entry><entry>2.95 MB</entry></row><row><entry /><entry>10:1 compression</entry></row><row><entry /><entry>Netpage tags, 1600 dpi</entry><entry>0.24 MB</entry><entry>0.24 MB</entry></row><row><entry /><entry>Worst case (text +</entry><entry>3.61 MB</entry><entry>6.67 MB</entry></row><row><entry /><entry>image + tags)</entry></row><row><entry /><entry>Average (text +</entry><entry>1.64 MB</entry><entry>4.25 MB</entry></row><row><entry /><entry>25% image + tags)</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 6.2 Document Data Flow
0563The Host PC rasterizes and compresses the incoming document on a page by page basis. The page is restructured into bands with one or more bands used to construct a page. The compressed data is then transferred to the SoPEC device via the USB link. A complete band is stored in SoPEC embedded memory. Once the band transfer is complete the SoPEC device reads the compressed data, expands the band, normalizes contone, bi-level and tag data to 1600 dpi and transfers the resultant calculated dots to the bi-lithic printhead.
0564The document data flow is <ul id="ul0012" list-style="none"><li id="ul0012-0001" num="0000"><ul id="ul0013" list-style="none"><li id="ul0013-0001" num="0565">The RIP software rasterizes each page description and compress the rasterized page image.</li><li id="ul0013-0002" num="0566">The infrared layer of the printed page optionally contains encoded Netpage [5] tags at a programmable density.</li><li id="ul0013-0003" num="0567">The compressed page image is transferred to the SoPEC device via the USB normally on a band by band basis.</li><li id="ul0013-0004" num="0568">The print engine takes the compressed page image and starts the page expansion.</li><li id="ul0013-0005" num="0569">The first stage page expansion consists of 3 operations performed in parallel</li><li id="ul0013-0006" num="0570">expansion of the JPEG-compressed contone layer</li><li id="ul0013-0007" num="0571">expansion of the SMG4 fax compressed bi-level layer</li><li id="ul0013-0008" num="0572">encoding and rendering of the bi-level tag data.</li><li id="ul0013-0009" num="0573">The second stage dithers the contone layer using a programmable dither matrix, producing up to four bi-level layers at full-resolution.</li><li id="ul0013-0010" num="0574">The second stage then composites the bi-level tag data layer, the bi-level SMG4 fax de-compressed layer and up to four bi-level JPEG de-compressed layers into the full-resolution page image.</li><li id="ul0013-0011" num="0575">A fixative layer is also generated as required.</li><li id="ul0013-0012" num="0576">The last stage formats and prints the bi-level data through the bi-lithic printhead via the printhead interface.</li></ul></li></ul>
0577The SoPEC device can print a full resolution page with 6 color planes. Each of the color planes can be generated from compressed data through any channel (either JPEG compressed, bi-level SMG4 fax compressed, tag data generated, or fixative channel created) with a maximum number of 6 data channels from page RIP to bi-lithic printhead color planes.
0578The mapping of data channels to color planes is programmable, this allows for multiple color planes in the printhead to map to the same data channel to provide for redundancy in the printhead to assist dead nozzle compensation.
0579Also a data channel could be used to gate data from another data channel. For example in stencil mode, data from the bilevel data channel at 1600 dpi can be used to filter the contone data channel at 320 dpi, giving the effect of 1600 dpi contone image.
00006.3 Page Considerations Due to SoPEC
0580The SoPEC device typically stores a complete page of document data on chip. The amount of storage available for compressed pages is limited to 2 Mbytes, imposing a fixed maximum on compressed page size. A comparison of the compressed image sizes in Table 2 indicates that SoPEC would not be capable of printing worst case pages unless they are split into bands and printing commences before all the bands for the page have been downloaded. The page sizes in the table are shown for comparison purposes and would be considered reasonable for a professional level printing system. The SoPEC device is aimed at the consumer level and would not be required to print pages of that complexity. Target document types for the SoPEC device are shown Table 2.
0581<tables id="TABLE-US-00002" num="00002"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 2</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Page content targets for SoPEC</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><colspec colname="3" colwidth="42pt" align="center" /><tbody valign="top"><row><entry /><entry /><entry>Size</entry></row><row><entry>Page Content Description</entry><entry>Calculation</entry><entry>(MByte)</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>Best Case picture Image,</entry><entry>8.26 × 11.7 × 267 ×</entry><entry>1.97</entry></row><row><entry>267 ppi with 3 colors,</entry><entry>267 × 3 @ 10:1</entry></row><row><entry>A4 size</entry></row><row><entry>Full page text, 800 dpi</entry><entry>8.26 × 11.7 × 800 ×</entry><entry>0.74</entry></row><row><entry>A4 size</entry><entry>800 @ 10:1</entry></row><row><entry>Mixed Graphics and Text</entry><entry>6 × 4 × 267 × 267 ×</entry><entry>1.55</entry></row><row><entry>Image of 6 inches × 4</entry><entry>3 @ 5:1</entry></row><row><entry>inches @ 267 ppi and</entry><entry>800 × 800 × 73 @ 10:1</entry></row><row><entry>3 colors</entry></row><row><entry>Remaining area text ~73</entry></row><row><entry>inches<sup>2</sup>, 800 dpi</entry></row><row><entry>Best Case Photo, 3 Colors,</entry><entry>6.6 Mpixel @ 10:1</entry><entry>2.00</entry></row><row><entry>6.6 MegaPixel Image</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
0582If a document with more complex pages is required, the page RIP software in the host PC can determine that there is insufficient memory storage in the SoPEC for that document. In such cases the RIP software can take two courses of action. It can increase the compression ratio until the compressed page size will fit in the SoPEC device, at the expense of document quality, or divide the page into bands and allow SoPEC to begin printing a page band before all bands for that page are downloaded. Once SoPEC starts printing a page it cannot stop, if SoPEC consumes compressed data faster than the bands can be downloaded a buffer underrun error could occur causing the print to fail. A buffer underrun occurs if a line synchronisation pulse is received before a line of data has been transferred to the printhead.
0583Other options which can be considered if the page does not fit completely into the compressed page store are to slow the printing or to use multiple SoPECs to print parts of the page. A Storage SoPEC (Section 7.2.5) could be added to the system to provide guaranteed bandwidth data delivery. The print system could also be constructed using an ISI-Bridge chip (Section 7.2.6) to provide guaranteed data delivery.
00007 Memjet Printer Architecture
0584The SoPEC device can be used in several printer configurations and architectures.
0585In the general sense every SoPEC based printer architecture will contain: <ul id="ul0014" list-style="none"><li id="ul0014-0001" num="0000"><ul id="ul0015" list-style="none"><li id="ul0015-0001" num="0586">One or more SoPEC devices.</li><li id="ul0015-0002" num="0587">One or more bi-lithic printheads.</li><li id="ul0015-0003" num="0588">Two or more LSS busses.</li><li id="ul0015-0004" num="0589">Two or more QA chips.</li><li id="ul0015-0005" num="0590">USB 1.1 connection to host or ISI connection to Bridge Chip.</li><li id="ul0015-0006" num="0591">ISI bus connection between SoPECs (when multiple SoPECs are used).</li></ul></li></ul>
0592Some example printer configurations as outlined in Section 7.2. The various system components are outlined briefly in Section 7.1.
00007.1 System Components
00007.1.1 SoPEC Print Engine Controller
0593The SoPEC device contains several system on a chip (SoC) components, as well as the print engine pipeline control application specific logic.
00007.1.1.1 Print Engine Pipeline (PEP) Logic
0594The PEP reads compressed page store data from the embedded memory, optionally decompresses the data and formats it for sending to the printhead. The print engine pipeline functionality includes expanding the page image, dithering the contone layer, compositing the black layer over the contone layer, rendering of Netpage tags, compensation for dead nozzles in the printhead, and sending the resultant image to the bi-lithic printhead.
00007.1.1.2 Embedded CPU
0595SoPEC contains an embedded CPU for general purpose system configuration and management. The CPU performs page and band header processing, motor control and sensor monitoring (via the GPIO) and other system control functions. The CPU can perform buffer management or report buffer status to the host. The CPU can optionally run vendor application specific code for general print control such as paper ready monitoring and LED status update.
00007.1.1.3 Embedded Memory Buffer
0596A 2.5 Mbyte embedded memory buffer is integrated onto the SoPEC device, of which approximately 2 Mbytes are available for compressed page store data. A compressed page is divided into one or more bands, with a number of bands stored in memory. As a band of the page is consumed by the PEP for printing a new band can be downloaded. The new band may be for the current page or the next page.
0597Using banding it is possible to begin printing a page before the complete compressed page is downloaded, but care must be taken to ensure that data is always available for printing or a buffer underrun may occur.
0598An Storage SoPEC acting as a memory buffer (Section 7.2.5) or an ISI-Bridge chip with attached DRAM (Section 7.2.6) could be used to provide guaranteed data delivery.
00007.1.1.4 Embedded USB 1.1 Device
0599The embedded USB 1.1 device accepts compressed page data and control commands from the host PC, and facilitates the data transfer to either embedded memory or to another SoPEC device in multi-SoPEC systems.
00007.1.2 Bi-lithic Printhead
0600The printhead is constructed by abutting 2 printhead ICs together. The printhead ICs can vary in size from 2 inches to 8 inches, so to produce an A4 printhead several combinations are possible. For example two printhead ICs of 7 inches and 3 inches could be used to create a A4 printhead (the notation is 7:3). Similarly 6 and 4 combination (6:4), or 5:5 combination. For an A3 printhead it can be constructed from 8:6 or an 7:7 printhead IC combination. For photographic printing smaller printheads can be constructed.
00007.1.3 LSS Interface Bus
0601Each SoPEC device has 2 LSS system buses for communication with QA devices for system authentication and ink usage accounting. The number of QA devices per bus and their position in the system is unrestricted with the exception that PRINTER_QA and INK_QA devices should be on separate LSS busses.
00007.1.4 QA Devices
0602Each SoPEC system can have several QA devices. Normally each printing SoPEC will have an associated PRINTER_QA. Ink cartridges will contain an INK_QA chip. PRINTER_QA and INK_QA devices should be on separate LSS busses. All QA chips in the system are physically identical with flash memory contents defining PRINTER_QA from INK_QA chip.
00007.1.5 ISI Interface
0603The Inter-SoPEC Interface (ISI) provides a communication channel between SoPECs in a multi-SoPEC system. The ISIMaster can be SoPEC device or an ISI-Bridge chip depending on the printer configuration. Both compressed data and control commands are transferred via the interface.
00007.1.6 ISI-Bridge Chip
0604A device, other than a SoPEC with a USB connection, which provides print data to a number of slave SoPECs. A bridge chip will typically have a high bandwidth connection, such as USB2.0, Ethernet or IEEE1394, to a host and may have an attached external DRAM for compressed page storage. A bridge chip would have one or more ISI interfaces. The use of multiple ISI buses would allow the construction of independent print systems within the one printer. The ISI-Bridge would be the ISIMaster for each of the ISI buses it interfaces to.
00007.2 Possible SoPEC Systems
0605Several possible SoPEC based system architectures exist. The following sections outline some possible architectures. It is possible to have extra SoPEC devices in the system used for DRAM storage. The QA chip configurations shown are indicative of the flexibility of LSS bus architecture, but not limited to those configurations.
00007.2.1 A4 Simplex with 1 SoPEC Device
0606In <figref idref="DRAWINGS">FIG. 3</figref>, a single SoPEC device can be used to control two printhead ICs. The SoPEC receives compressed data through the USB device from the host. The compressed data is processed and transferred to the printhead.
00007.2.2 A4 Duplex with 2 SoPEC Devices
0607In <figref idref="DRAWINGS">FIG. 4</figref>, two SoPEC devices are used to control two bi-lithic printheads, each with two printhead ICs. Each bi-lithic printhead prints to opposite sides of the same page to achieve duplex printing. The SoPEC connected to the USB is the ISIMaster SoPEC, the remaining SoPEC is an ISISlave. The ISIMaster receives all the compressed page data for both SoPECs and re-distributes the compressed data over the Inter-SoPEC Interface (ISI) bus.
0608It may not be possible to print an A4 page every 2 seconds in this configuration since the USB 1.1 connection to the host may not have enough bandwidth. An alternative would be for each SoPEC to have its own USB 1.1 connection. This would allow a faster average print speed.
00007.2.3 A3 Simplex with 2 SoPEC Devices
0609In <figref idref="DRAWINGS">FIG. 5</figref>, two SoPEC devices are used to control one A3 bi-lithic printhead. Each SoPEC controls only one printhead IC (the remaining PHI port typically remains idle). This system uses the SoPEC with the USB connection as the ISIMaster. In this dual SoPEC configuration the compressed page store data is split across 2 SoPECs giving a total of 4 Mbyte page store, this allows the system to use compression rates as in an A4 architecture, but with the increased page size of A3. The ISIMaster receives all the compressed page data for all SoPECs and re-distributes the compressed data over the Inter-SoPEC Interface (ISI) bus.
0610It may not be possible to print an A3 page every 2 seconds in this configuration since the USB 1.1 connection to the host will only have enough bandwidth to supply 2 Mbytes every 2 seconds. Pages which require more than 2 MBytes every 2 seconds will therefore print more slowly. An alternative would be for each SoPEC to have its own USB 1.1 connection. This would allow a faster average print speed.
00007.2.4 A3 Duplex with 4 SoPEC Devices
0611In <figref idref="DRAWINGS">FIG. 6</figref> a 4 SoPEC system is shown. It contains 2 A3 bi-lithic printheads, one for each side of an A3 page. Each printhead contain 2 printhead ICs, each printhead IC is controlled by an independent SoPEC device, with the remaining PHI port typically unused. Again the SoPEC with USB 1.1 connection is the ISIMaster with the other SoPECs as ISISlaves. In total, the system contains 8 Mbytes of compressed page store (2 Mbytes per SoPEC), so the increased page size does not degrade the system print quality, from that of an A4 simplex printer. The ISIMaster receives all the compressed page data for all SoPECs and re-distributes the compressed data over the Inter-SoPEC Interface (ISI) bus.
0612It may not be possible to print an A3 page every 2 seconds in this configuration since the USB 1.1 connection to the host will only have enough bandwidth to supply 2 Mbytes every 2 seconds. Pages which require more than 2 MBytes every 2 seconds will therefore print more slowly. An alternative would be for each SoPEC or set of SoPECs on the same side of the page to have their own USB 1.1 connection (as ISISlaves may also have direct USB connections to the host). This would allow a faster average print speed.
00007.2.5 SoPEC DRAM storage solution: A4 Simplex with 1 printing SoPEC and 1 memory SoPEC
0613Extra SoPECs can be used for DRAM storage e.g. in <figref idref="DRAWINGS">FIG. 7</figref> an A4 simplex printer can be built with a single extra SoPEC used for DRAM storage. The DRAM SoPEC can provide guaranteed bandwidth delivery of data to the printing SoPEC. SoPEC configurations can have multiple extra SoPECs used for DRAM storage.
00007.2.6 ISI-Bridge Chip Solution: A3 Duplex System with 4 SoPEC Devices
0614In <figref idref="DRAWINGS">FIG. 8</figref>, an ISI-Bridge chip provides slave-only ISI connections to SoPEC devices. <figref idref="DRAWINGS">FIG. 8</figref> shows a ISI-Bridge chip with 2 separate ISI ports. The ISI-Bridge chip is the ISIMaster on each of the ISI busses it is connected to. All connected SoPECs are ISISlaves. The ISI-Bridge chip will typically have a high bandwidth connection to a host and may have an attached external DRAM for compressed page storage.
0615An alternative to having a ISI-Bridge chip would be for each SoPEC or each set of SoPECs on the same side of a page to have their own USB 1.1 connection. This would allow a faster average print speed.
00008 Page Format and Printflow
0616When rendering a page, the RIP produces a page header and a number of bands (a non-blank page requires at least one band) for a page. The page header contains high level rendering parameters, and each band contains compressed page data. The size of the band will depend on the memory available to the RIP, the speed of the RIP, and the amount of memory remaining in SoPEC while printing the previous band(s). <figref idref="DRAWINGS">FIG. 9</figref> shows the high level data structure of a number of pages with different numbers of bands in the page.
0617Each compressed band contains a mandatory band header, an optional bi-level plane, optional sets of interleaved contone planes, and an optional tag data plane (for Netpage enabled applications). Since each of these planes is optional<sup>1</sup>, the band header specifies which planes are included with the band. <figref idref="DRAWINGS">FIG. 10</figref> gives a high-level breakdown of the contents of a page band. <sup>1</sup>Although a band must contain at least one plane
0618A single SoPEC has maximum rendering restrictions as follows: <ul id="ul0016" list-style="none"><li id="ul0016-0001" num="0000"><ul id="ul0017" list-style="none"><li id="ul0017-0001" num="0619">1 bi-level plane</li><li id="ul0017-0002" num="0620">1 contone interleaved plane set containing a maximum of 4 contone planes</li><li id="ul0017-0003" num="0621">1 tag data plane</li><li id="ul0017-0004" num="0622">a bi-lithic printhead with a maximum of 2 printhead ICs</li></ul></li></ul>
0623The requirement for single-sided A4 single SoPEC printing is <ul id="ul0018" list-style="none"><li id="ul0018-0001" num="0000"><ul id="ul0019" list-style="none"><li id="ul0019-0001" num="0624">average contone JPEG compression ratio of 10:1, with a local minimum compression ratio of 5:1 for a single line of interleaved JPEG blocks.</li><li id="ul0019-0002" num="0625">average bi-level compression ratio of 10:1, with a local minimum compression ratio of 1:1 for a single line.</li></ul></li></ul>
0626If the page contains rendering parameters that exceed these specifications, then the RIP or the Host PC must split the page into a format that can be handled by a single SoPEC.
0627In the general case, the SoPEC CPU must analyze the page and band headers and generate an appropriate set of register write commands to configure the units in SoPEC for that page. The various bands are passed to the destination SoPEC(s) to locations in DRAM determined by the host.
0628The host keeps a memory map for the DRAM, and ensures that as a band is passed to a SoPEC, it is stored in a suitable free area in DRAM. Each SoPEC is connected to the ISI bus or USB bus via its Serial communication Block (SCB). The SoPEC CPU configures the SCB to allow compressed data bands to pass from the USB or ISI through the SCB to SoPEC DRAM. <figref idref="DRAWINGS">FIG. 11</figref> shows an example data flow for a page destined to be printed by a single SoPEC. Band usage information is generated by the individual SoPECs and passed back to the host.
0629SoPEC has an addressing mechanism that permits circular band memory allocation, thus facilitating easy memory management. However it is not strictly necessary that all bands be stored together. As long as the appropriate registers in SoPEC are set up for each band, and a given band is contiguous<sup>2</sup>, the memory can be allocated in any way. <sup>2</sup>Contiguous allocation also includes wrapping around in SoPEC's band store memory.
00008.1 Print Engine Example Page Format
0630This section describes a possible format of compressed pages expected by the embedded CPU in SoPEC. The format is generated by software in the host PC and interpreted by embedded software in SoPEC. This section indicates the type of information in a page format structure, but implementations need not be limited to this format. The host PC can optionally perform the majority of the header processing.
0631The compressed format and the print engines are designed to allow real-time page expansion during printing, to ensure that printing is never interrupted in the middle of a page due to data underrun.
0632The page format described here is for a single black bi-level layer, a contone layer, and a Netpage tag layer. The black bi-level layer is defined to composite over the contone layer.
0633The black bi-level layer consists of a bitmap containing a 1-bit opacity for each pixel. This black layer matte has a resolution which is an integer or non-integer factor of the printer's dot resolution. The highest supported resolution is 1600 dpi, i.e. the printer's full dot resolution.
0634The contone layer, optionally passed in as YCrCb, consists of a 24-bit CMY or 32-bit CMYK color for each pixel. This contone image has a resolution which is an integer or non-integer factor of the printer's dot resolution. The requirement for a single SoPEC is to support 1 side per 2 seconds A4/Letter printing at a resolution of 267 ppi, i.e. one-sixth the printer's dot resolution.
0635Non-integer scaling can be performed on both the contone and bi-level images. Only integer scaling can be performed on the tag data.
0636The black bi-level layer and the contone layer are both in compressed form for efficient storage in the printer's internal memory.
00008.1.1 Page Structure
0637A single SoPEC is able to print with full edge bleed for Letter and A3 via different stitch part combinations of the bi-lithic printhead. It imposes no margins and so has a printable page area which corresponds to the size of its paper. The target page size is constrained by the printable page area, less the explicit (target) left and top margins specified in the page description. These relationships are illustrated below.
00008.1.2 Compressed Page Format
0638Apart from being implicitly defined in relation to the printable page area, each page description is complete and self-contained. There is no data stored separately from the page description to which the page description refers.<sup>3 </sup>The page description consists of a page header which describes the size and resolution of the page, followed by one or more page bands which describe the actual page content. <sup>3</sup>SoPEC relies on dither matrices and tag structures to have already been set up, but these are not considered to be part of a general page format. It is trivial to extend the page format to allow exact specification of dither matrices and tag structures.
00008.1.2.1 Page Header
0000<ul id="ul0020" list-style="none"><li id="ul0020-0001" num="0000"><ul id="ul0021" list-style="none"><li id="ul0021-0001" num="0639">Table 3 shows an example format of a page header.</li></ul></li></ul>
0640<tables id="TABLE-US-00003" num="00003"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 3</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Page header format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><colspec colname="3" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>field</entry><entry>format</entry><entry>description</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>signature</entry><entry>16-bit</entry><entry>Page header format</entry></row><row><entry /><entry>integer</entry><entry>signature.</entry></row><row><entry>version</entry><entry>16-bit</entry><entry>Page header format</entry></row><row><entry /><entry>integer</entry><entry>version number.</entry></row><row><entry>structure size</entry><entry>16-bit</entry><entry>Size of page header.</entry></row><row><entry /><entry>integer</entry></row><row><entry>band count</entry><entry>16-bit</entry><entry>Number of bands specified</entry></row><row><entry /><entry>integer</entry><entry>for this page.</entry></row><row><entry>target resolution</entry><entry>16-bit</entry><entry>Resolution of target page.</entry></row><row><entry>(dpi)</entry><entry>integer</entry><entry>This is always 1600</entry></row><row><entry /><entry /><entry>for the Memjet printer.</entry></row><row><entry>target page width</entry><entry>16-bit</entry><entry>Width of target page,</entry></row><row><entry /><entry>integer</entry><entry>in dots.</entry></row><row><entry>target page height</entry><entry>32-bit</entry><entry>Height of target page,</entry></row><row><entry /><entry>integer</entry><entry>in dots.</entry></row><row><entry>target left margin</entry><entry>16-bit</entry><entry>Width of target left margin,</entry></row><row><entry>for black and</entry><entry>integer</entry><entry>in dots, for black</entry></row><row><entry>contone</entry><entry /><entry>and contone.</entry></row><row><entry>target top margin</entry><entry>16-bit</entry><entry>Height of target top margin,</entry></row><row><entry>for black and</entry><entry>integer</entry><entry>in dots, for black</entry></row><row><entry>contone</entry><entry /><entry>and contone.</entry></row><row><entry>target right</entry><entry>16-bit</entry><entry>Width of target right margin,</entry></row><row><entry>margin for black</entry><entry>integer</entry><entry>in dots, for black</entry></row><row><entry>and contone</entry><entry /><entry>and contone.</entry></row><row><entry>target bottom</entry><entry>16-bit</entry><entry>Height of target bottom margin,</entry></row><row><entry>margin for black</entry><entry>integer</entry><entry>in dots, for</entry></row><row><entry>and contone</entry><entry /><entry>black and contone.</entry></row><row><entry>target left</entry><entry>16-bit</entry><entry>Width of target left margin,</entry></row><row><entry>margin for tags</entry><entry>integer</entry><entry>in dots, for tags.</entry></row><row><entry>target top</entry><entry>16-bit</entry><entry>Height of target top margin,</entry></row><row><entry>margin for tags</entry><entry>integer</entry><entry>in dots, for tags.</entry></row><row><entry>target right</entry><entry>16-bit</entry><entry>Width of target right margin,</entry></row><row><entry>margin for tags</entry><entry>integer</entry><entry>in dots, for tags.</entry></row><row><entry>target bottom</entry><entry>16-bit</entry><entry>Height of target bottom</entry></row><row><entry>margin for tags</entry><entry>integer</entry><entry>margin, in dots, for</entry></row><row><entry /><entry /><entry>tags.</entry></row><row><entry>generate tags</entry><entry>16-bit</entry><entry>Specifies whether to</entry></row><row><entry /><entry>integer</entry><entry>generate tags for this</entry></row><row><entry /><entry /><entry>page (0 - no, 1 - yes).</entry></row><row><entry>fixed tag data</entry><entry>128-bit</entry><entry>This is only valid if</entry></row><row><entry /><entry>integer</entry><entry>generate tags is set.</entry></row><row><entry>tag vertical</entry><entry>16-bit</entry><entry>Scale factor in vertical</entry></row><row><entry>scale factor</entry><entry>integer</entry><entry>direction from tag data</entry></row><row><entry /><entry /><entry>resolution to target</entry></row><row><entry /><entry /><entry>resolution. Valid range =</entry></row><row><entry /><entry /><entry>1–511. Integer</entry></row><row><entry /><entry /><entry>scaling only</entry></row><row><entry>tag horizontal</entry><entry>16-bit</entry><entry>Scale factor in horizontal</entry></row><row><entry>scale factor</entry><entry>integer</entry><entry>direction from tag</entry></row><row><entry /><entry /><entry>data resolution to target</entry></row><row><entry /><entry /><entry>resolution. Valid</entry></row><row><entry /><entry /><entry>range = 1–511.</entry></row><row><entry /><entry /><entry>Integer scaling only.</entry></row><row><entry>bi-level layer</entry><entry>16-bit</entry><entry>Scale factor in vertical</entry></row><row><entry>vertical scale factor</entry><entry>integer</entry><entry>direction from bi-level</entry></row><row><entry /><entry /><entry>resolution to target</entry></row><row><entry /><entry /><entry>resolution (must be 1 or</entry></row><row><entry /><entry /><entry>greater). May be non-integer.</entry></row><row><entry /><entry /><entry>Expressed as a fraction</entry></row><row><entry /><entry /><entry>with upper 8-bits the</entry></row><row><entry /><entry /><entry>numerator and the lower</entry></row><row><entry /><entry /><entry>8 bits the denominator.</entry></row><row><entry>bi-level layer</entry><entry>16-bit</entry><entry>Scale factor in horizontal</entry></row><row><entry>horizontal</entry><entry>integer</entry><entry>direction from bi-level</entry></row><row><entry>scale factor</entry><entry /><entry>resolution to target</entry></row><row><entry /><entry /><entry>resolution (must be 1</entry></row><row><entry /><entry /><entry>or greater). May be</entry></row><row><entry /><entry /><entry>non-integer. Expressed</entry></row><row><entry /><entry /><entry>as a fraction with upper</entry></row><row><entry /><entry /><entry>8-bits the numerator</entry></row><row><entry /><entry /><entry>and the lower 8 bits the</entry></row><row><entry /><entry /><entry>denominator.</entry></row><row><entry>bi-level layer</entry><entry>16-bit</entry><entry>Width of bi-level layer</entry></row><row><entry>page width</entry><entry>integer</entry><entry>page, in pixels.</entry></row><row><entry>bi-level layer</entry><entry>32-bit</entry><entry>Height of bi-level layer</entry></row><row><entry>page height</entry><entry>integer</entry><entry>page, in pixels.</entry></row><row><entry>contone flags</entry><entry>16 bit</entry><entry>Defines the color conversion</entry></row><row><entry /><entry>integer</entry><entry>that is required</entry></row><row><entry /><entry /><entry>for the JPEG data.</entry></row><row><entry /><entry /><entry>Bits 2–0 specify how</entry></row><row><entry /><entry /><entry>many contone planes there</entry></row><row><entry /><entry /><entry>are (e.g. 3 for CMY and 4</entry></row><row><entry /><entry /><entry>for CMYK).</entry></row><row><entry /><entry /><entry>Bit 3 specifies whether the</entry></row><row><entry /><entry /><entry>first 3 color planes need to</entry></row><row><entry /><entry /><entry>be converted back from YCrCb</entry></row><row><entry /><entry /><entry>to CMY. Only valid if</entry></row><row><entry /><entry /><entry>b2–0 = 3 or 4.</entry></row><row><entry /><entry /><entry>0 - no conversion, leave</entry></row><row><entry /><entry /><entry>JPEG colors alone</entry></row><row><entry /><entry /><entry>1 - color convert.</entry></row><row><entry /><entry /><entry>Bits 7–4 specifies whether</entry></row><row><entry /><entry /><entry>the YCrCb was generated directly</entry></row><row><entry /><entry /><entry>from CMY, or whether it</entry></row><row><entry /><entry /><entry>was converted to RGB first via</entry></row><row><entry /><entry /><entry>the step: R = 255-C,</entry></row><row><entry /><entry /><entry>G = 255-M, B = 255-Y.</entry></row><row><entry /><entry /><entry>Each of the color planes can</entry></row><row><entry /><entry /><entry>be individually inverted.</entry></row><row><entry /><entry /><entry>Bit 4:</entry></row><row><entry /><entry /><entry>0 - do not invert color plane 0</entry></row><row><entry /><entry /><entry>1 - invert color plane 0</entry></row><row><entry /><entry /><entry>Bit 5:</entry></row><row><entry /><entry /><entry>0 - do not invert color plane 1</entry></row><row><entry /><entry /><entry>1 - invert color plane 1</entry></row><row><entry /><entry /><entry>Bit 6:</entry></row><row><entry /><entry /><entry>0 - do not invert color plane 2</entry></row><row><entry /><entry /><entry>1 - invert color plane 2</entry></row><row><entry /><entry /><entry>Bit 7:</entry></row><row><entry /><entry /><entry>0 - do not invert color plane 3</entry></row><row><entry /><entry /><entry>1 - invert color plane 3</entry></row><row><entry /><entry /><entry>Bit 8 specifies whether the</entry></row><row><entry /><entry /><entry>contone data is JPEG compressed</entry></row><row><entry /><entry /><entry>or non-compressed:</entry></row><row><entry /><entry /><entry>0 - JPEG compressed</entry></row><row><entry /><entry /><entry>1 - non-compressed</entry></row><row><entry /><entry /><entry>The remaining bits are</entry></row><row><entry /><entry /><entry>reserved (0).</entry></row><row><entry>contone vertical</entry><entry>16-bit</entry><entry>Scale factor in vertical</entry></row><row><entry>scale factor</entry><entry>integer</entry><entry>direction from contone</entry></row><row><entry /><entry /><entry>channel resolution to target</entry></row><row><entry /><entry /><entry>resolution. Valid range =</entry></row><row><entry /><entry /><entry>1–255. May be non-integer.</entry></row><row><entry /><entry /><entry>Expressed as a fraction with</entry></row><row><entry /><entry /><entry>upper 8-bits the numerator</entry></row><row><entry /><entry /><entry>and the lower 8 bits the</entry></row><row><entry /><entry /><entry>denominator.</entry></row><row><entry>contone</entry><entry>16-bit</entry><entry>Scale factor in horizontal</entry></row><row><entry>horizontal</entry><entry>integer</entry><entry>direction from contone channel</entry></row><row><entry>scale factor</entry><entry /><entry>resolution to target</entry></row><row><entry /><entry /><entry>resolution. Valid range =</entry></row><row><entry /><entry /><entry>1–255. May be non-</entry></row><row><entry /><entry /><entry>integer.</entry></row><row><entry /><entry /><entry>Expressed as a fraction</entry></row><row><entry /><entry /><entry>with upper 8-bits the</entry></row><row><entry /><entry /><entry>numerator and the lower</entry></row><row><entry /><entry /><entry>8 bits the denominator.</entry></row><row><entry>contone page</entry><entry>16-bit</entry><entry>Width of contone page,</entry></row><row><entry>width</entry><entry>integer</entry><entry>in contone pixels.</entry></row><row><entry>contone page</entry><entry>32-bit</entry><entry>Height of contone page,</entry></row><row><entry>height</entry><entry>integer</entry><entry>in contone pixels.</entry></row><row><entry>reserved</entry><entry>up to 128</entry><entry>Reserved and 0 pads out</entry></row><row><entry /><entry>bytes</entry><entry>page header to</entry></row><row><entry /><entry /><entry>multiple of 128 bytes.</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
0641The page header contains a signature and version which allow the CPU to identify the page header format. If the signature and/or version are missing or incompatible with the CPU, then the CPU can reject the page.
0642The contone flags define how many contone layers are present, which typically is used for defining whether the contone layer is CMY or CMYK. Additionally, if the color planes are CMY, they can be optionally stored as YCrCb, and further optionally color space converted from CMY directly or via RGB. Finally the contone data is specified as being either JPEG compressed or non-compressed. The page header defines the resolution and size of the target page. The bi-level and contone layers are clipped to the target page if necessary. This happens whenever the bi-level or contone scale factors are not factors of the target page width or height.
0643The target left, top, right and bottom margins define the positioning of the target page within the printable page area.
0644The tag parameters specify whether or not Netpage tags should be produced for this page and what orientation the tags should be produced at (landscape or portrait mode). The fixed tag data is also provided.
0645The contone, bi-level and tag layer parameters define the page size and the scale factors.
00008.1.2.2 Band Format
0646Table 4 shows the format of the page band header.
0647<tables id="TABLE-US-00004" num="00004"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 4</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Band header format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="49pt" align="left" /><colspec colname="3" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry>field</entry><entry>format</entry><entry>description</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row><row><entry /><entry>signature</entry><entry>16-bit</entry><entry>Page band header</entry></row><row><entry /><entry /><entry>integer</entry><entry>format signature.</entry></row><row><entry /><entry>version</entry><entry>16-bit</entry><entry>Page band header</entry></row><row><entry /><entry /><entry>integer</entry><entry>format version number.</entry></row><row><entry /><entry>structure size</entry><entry>16-bit</entry><entry>Size of page band</entry></row><row><entry /><entry /><entry>integer</entry><entry>header.</entry></row><row><entry /><entry>bi-level layer</entry><entry>16-bit</entry><entry>Height of bi-level</entry></row><row><entry /><entry>band height</entry><entry>integer</entry><entry>layer band, in black</entry></row><row><entry /><entry /><entry /><entry>pixels.</entry></row><row><entry /><entry>bi-level layer</entry><entry>32-bit</entry><entry>Size of bi-level</entry></row><row><entry /><entry>band data size</entry><entry>integer</entry><entry>layer band data,</entry></row><row><entry /><entry /><entry /><entry>in bytes.</entry></row><row><entry /><entry>contone band</entry><entry>16-bit</entry><entry>Height of contone</entry></row><row><entry /><entry>height</entry><entry>integer</entry><entry>band, in contone</entry></row><row><entry /><entry /><entry /><entry>pixels.</entry></row><row><entry /><entry>contone band</entry><entry>32-bit</entry><entry>Size of contone</entry></row><row><entry /><entry>data size</entry><entry>integer</entry><entry>plane band data,</entry></row><row><entry /><entry /><entry /><entry>in bytes.</entry></row><row><entry /><entry>tag band</entry><entry>16-bit</entry><entry>Height of tag band,</entry></row><row><entry /><entry>height</entry><entry>integer</entry><entry>in dots.</entry></row><row><entry /><entry>tag band</entry><entry>32-bit</entry><entry>Size of unencoded tag</entry></row><row><entry /><entry>data size</entry><entry>integer</entry><entry>data band, in bytes.</entry></row><row><entry /><entry /><entry /><entry>Can be 0 which indicates</entry></row><row><entry /><entry /><entry /><entry>that no tag data is provided.</entry></row><row><entry /><entry>reserved</entry><entry>up to 128</entry><entry>Reserved and 0 pads</entry></row><row><entry /><entry /><entry>bytes</entry><entry>out band header to</entry></row><row><entry /><entry /><entry /><entry>multiple of 128 bytes.</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
0648The bi-level layer parameters define the height of the black band, and the size of its compressed band data. The variable-size black data follows the page band header.
0649The contone layer parameters define the height of the contone band, and the size of its compressed page data. The variable-size contone data follows the black data.
0650The tag band data is the set of variable tag data half-lines as required by the tag encoder. The format of the tag data is found in Section 26.5.2. The tag band data follows the contone data.
0651Table 5 shows the format of the variable-size compressed band data which follows the page band header.
0652<tables id="TABLE-US-00005" num="00005"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 5</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Page band data format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="70pt" align="left" /><colspec colname="3" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry>field</entry><entry>format</entry><entry>Description</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row><row><entry /><entry>black data</entry><entry>Modified G4</entry><entry>Compressed bi-level</entry></row><row><entry /><entry /><entry>facsimile bitstream<sup>4</sup></entry><entry>layer.</entry></row><row><entry /><entry>contone data</entry><entry>JPEG bytestream</entry><entry>Compressed contone</entry></row><row><entry /><entry /><entry /><entry>datalayer.</entry></row><row><entry /><entry>tag data map</entry><entry>Tag data array</entry><entry>Tag data format. See</entry></row><row><entry /><entry /><entry /><entry>Section 26.5.2.</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row><row><entry /><entry namest="offset" nameend="3" align="left" id="FOO-00004"><sup>4</sup>See section 8.1.2.3 on page 36 for note regarding the use of this standard</entry></row></tbody></tgroup></table></tables>
0653The start of each variable-size segment of band data should be aligned to a 256-bit DRAM word boundary.
0654The following sections describe the format of the compressed bi-level layers and the compressed contone layer. section 26.5.1 on page 410 describes the format of the tag data structures.
00008.1.2.3 Bi-level Data Compression
0655The (typically 1600 dpi) black bi-level layer is losslessly compressed using Silverbrook Modified Group 4 (SMG4) compression which is a version of Group 4 Facsimile compression [22] without Huffman and with simplified run length encodings. Typically compression ratios exceed 10:1. The encoding are listed in Table 6 and Table 7.
0656<tables id="TABLE-US-00006" num="00006"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 6</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Bi-Level group 4 facsimile style compression encodings</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="63pt" align="center" /><colspec colname="2" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry>Encoding</entry><entry>Description</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="63pt" align="char" char="." /><colspec colname="3" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry>same as Group 4</entry><entry>1000</entry><entry>Pass Command: a0 ←</entry></row><row><entry /><entry>Facsimile</entry><entry /><entry>b2, skip next two edges</entry></row><row><entry /><entry /><entry>1</entry><entry>Vertical(0): a0 ←</entry></row><row><entry /><entry /><entry /><entry>b1, color = !color</entry></row><row><entry /><entry /><entry>110</entry><entry>Vertical(1): a0 ←</entry></row><row><entry /><entry /><entry /><entry>b1 + 1, color = !color</entry></row><row><entry /><entry /><entry>010</entry><entry>Vertical(−1): a0 ←</entry></row><row><entry /><entry /><entry /><entry>b1 − 1, color = !color</entry></row><row><entry /><entry /><entry>110000</entry><entry>Vertical(2): a0 ←</entry></row><row><entry /><entry /><entry /><entry>b1 + 2, color = !color</entry></row><row><entry /><entry /><entry>010000</entry><entry>Vertical(−2): a0 ←</entry></row><row><entry /><entry /><entry /><entry>b1 − 2, color = !color</entry></row><row><entry /><entry>Unique to this</entry><entry>100000</entry><entry>Vertical(3): a0 ←</entry></row><row><entry /><entry>implementation</entry><entry /><entry>b1 + 3, color = !color</entry></row><row><entry /><entry /><entry>000000</entry><entry>Vertical(−3): a0 ←</entry></row><row><entry /><entry /><entry /><entry>b1 − 3, color = !color</entry></row><row><entry /><entry /><entry><RL><RL>100</entry><entry>Horizontal: a0 ←</entry></row><row><entry /><entry /><entry /><entry>a0 + <RL> + <RL></entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
0657SMG4 has a pass through mode to cope with local negative compression. Pass through mode is activated by a special run-length code. Pass through mode continues to either end of line or for a pre-programmed number of bits, whichever is shorter. The special run-length code is always executed as a run-length code, followed by pass through. The pass through escape code is a medium length run-length with a run of less than or equal to 31.
0658<tables id="TABLE-US-00007" num="00007"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 7</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Run length (RL) encodings</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry>Encoding</entry><entry>Description</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><colspec colname="3" colwidth="84pt" align="left" /><tbody valign="top"><row><entry>Unique to this</entry><entry>RRRRR1</entry><entry>Short Black Runlength</entry></row><row><entry>implementation</entry><entry /><entry>(5 bits)</entry></row><row><entry /><entry>RRRRR1</entry><entry>Short White Runlength</entry></row><row><entry /><entry /><entry>(5 bits)</entry></row><row><entry /><entry>RRRRRRRRRR10</entry><entry>Medium Black Runlength</entry></row><row><entry /><entry /><entry>(10 bits)</entry></row><row><entry /><entry>RRRRRRRR10</entry><entry>Medium White Runlength</entry></row><row><entry /><entry /><entry>(8 bits)</entry></row><row><entry /><entry>RRRRRRRRRR10</entry><entry>Medium Black Runlength</entry></row><row><entry /><entry /><entry>with RRRRRRRRRR <=</entry></row><row><entry /><entry /><entry>31, Enter pass through</entry></row><row><entry /><entry>RRRRRRRR10</entry><entry>Medium White Runlength</entry></row><row><entry /><entry /><entry>with RRRRRRRR <=</entry></row><row><entry /><entry /><entry>31, Enter pass through</entry></row><row><entry /><entry>RRRRRRRRRRRRRRR00</entry><entry>Long Black Runlength</entry></row><row><entry /><entry /><entry>(15 bits)</entry></row><row><entry /><entry>RRRRRRRRRRRRRRR00</entry><entry>Long White Runlength</entry></row><row><entry /><entry /><entry>(15 bits)</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
0659Since the compression is a bitstream, the encodings are read right (least significant bit) to left (most significant bit). The run lengths given as RRRR in Table are read in the same way (least significant bit at the right to most significant bit at the left).
0660Each band of bi-level data is optionally self contained. The first line of each band therefore is based on a ‘previous’ blank line or the last line of the previous band.
00008.1.2.3.1 Group 3 and 4 Facsimile Compression
0661The Group 3 Facsimile compression algorithm [22] losslessly compresses bi-level data for transmission over slow and noisy and noisy telephone lines. The bi-level data represents scanned black text and graphics on a while background, and the algorithm is tuned for this class of images (it is explicitly not tuned, for example, for halftoned bi-level images). The 1D Group 3 algorithm runlength-encodes each scanline and then Huffman-encodes the resulting runlengths. Runlengths in the range 0 to 63 are coded with terminating codes. Runlengths in the range 64 to 2623 are coded with make-up codes, each representing a multiple of 64, followed by a terminating code. Runlengths exceeding 2623 are coded with multiple make-up codes followed by a terminating code. The Huffman tables are fixed, but are separately tuned for black and white runs (except for make-up codes above 1728, which are common). When possible, the 2D Group 3 algorithm encodes a scanline as a set of short edge deltas (0, ±1, ±2, ±3) with reference to the previous scanline. The delta symbols are entropy-encoded (so that the zero delta symbol is only one bit long etc.) Edges within a 2D-encoded line which can't be delta-encoded are runlength-encoded, and are identified by a prefix. 1D- and 2D-encoded lines are marked differently. 1D-encoded lines are generated at regular intervals, whether actually required or not, to ensure that the decoder can recover from line noise with minimal image degradation. 2D Group 3 achieves compression ratios of up to 6:1 [32]. The Group 4 Facsimile algorithm [22] losslessly compresses bi-level data for transmission over error-free communications lines (i.e. the lines are truly error-free, or error-correction is done at a lower protocol level). The Group 4 algorithm is based on the 2D Group 3 algorithm, with the essential modification that since transmission is assumed to be error-free, 1D-encoded lines are no longer generated at regular intervals as an aid to error-recovery. Group 4 achieves compression ratios ranging from 20:1 to 60:1 for the CCITT set of test images [32].
0662The design goals and performance of the Group 4 compression algorithm qualify it as a compression algorithm for the bi-level layers. However, its Huffman tables are tuned to a lower scanning resolution (100–400 dpi), and it encodes runlengths exceeding 2623 awkwardly.
00008.1.2.4 Contone Data Compression
0663The contone layer (CMYK) is either a non-compressed bytestream or is compressed to an interleaved JPEG bytestream. The JPEG bytestream is complete and self-contained. It contains all data required for decompression, including quantization and Huffman tables.
0664The contone data is optionally converted to YCrCb before being compressed (there is no specific advantage in color-space converting if not compressing). Additionally, the CMY contone pixels are optionally converted (on an individual basis) to RGB before color conversion using R=255-C, G=255-M, B=255-Y. Optional bitwise inversion of the K plane may also be performed. Note that this CMY to RGB conversion is not intended to be accurate for display purposes, but rather for the purposes of later converting to YCrCb. The inverse transform will be applied before printing.
00008.1.2.4.1 JPEG Compression
0665The JPEG compression algorithm [27] lossily compresses a contone image at a specified quality level. It introduces imperceptible image degradation at compression ratios below 5:1, and negligible image degradation at compression ratios below 10:1 [33].
0666JPEG typically first transforms the image into a color space which separates luminance and chrominance into separate color channels. This allows the chrominance channels to be subsampled without appreciable loss because of the human visual system's relatively greater sensitivity to luminance than chrominance. After this first step, each color channel is compressed separately.
0667The image is divided into 8×8 pixel blocks. Each block is then transformed into the frequency domain via a discrete cosine transform (DCT). This transformation has the effect of concentrating image energy in relatively lower-frequency coefficients, which allows higher-frequency coefficients to be more crudely quantized. This quantization is the principal source of compression in JPEG. Further compression is achieved by ordering coefficients by frequency to maximize the likelihood of adjacent zero coefficients, and then runlength-encoding runs of zeroes. Finally, the runlengths and non-zero frequency coefficients are entropy coded. Decompression is the inverse process of compression.
00008.1.2.4.2 Non-compressed Format
0668If the contone data is non-compressed, it must be in a block-based format bytestream with the same pixel order as would be produced by a JPEG decoder. The bytestream therefore consists of a series of 8×8 block of the original image, starting with the top left 8×8 block, and working horizontally across the page (as it will be printed) until the top rightmost 8×8 block, then the next row of 8×8 blocks (left to right) and so on until the lower row of 8×8 blocks (left to right). Each 8×8 block consists of 64 8-bit pixels for color plane 0 (representing 8 rows of 8 pixels in the order top left to bottom right) followed by 64 8-bit pixels for color plane 1 and so on for up to a maximum of 4 color planes.
0669If the original image is not a multiple of 8 pixels in X or Y, padding must be present (the extra pixel data will be ignored by the setting of margins).
00008.1.2.4.3 Compressed Format
0670If the contone data is compressed the first memory band contains JPEG headers (including tables) plus MCUs (minimum coded units). The ratio of space between the various color planes in the JPEG stream is 1:1:1:1. No subsampling is permitted. Banding can be completely arbitrary i.e there can be multiple JPEG images per band or 1 JPEG image divided over multiple bands. The break between bands is only memory alignment based.
00008.1.2.4.4 Conversion of RGB to YCrCb (in RIP)
0671YCrCb is defined as per CCIR 601-1 [24] except that Y, Cr and Cb are normalized to occupy all 256 levels of an 8-bit binary encoding and take account of the actual hardware implementation of the inverse transform within SoPEC.
0672The exact color conversion computation is as follows: <ul id="ul0022" list-style="none"><li id="ul0022-0001" num="0000"><ul id="ul0023" list-style="none"><li id="ul0023-0001" num="0673">Y*=(9805/32768)R+(19235/32768)G+(3728/32768)B</li><li id="ul0023-0002" num="0674">Cr*=(16375/32768)R−(13716/32768)G−(2659/32768)B+128</li><li id="ul0023-0003" num="0675">Cb*=−(5529/32768)R−(10846/32768)G+(16375/32768)B+128</li></ul></li></ul>
0676Y, Cr and Cb are obtained by rounding to the nearest integer. There is no need for saturation since ranges of Y*, Cr* and Cb* after rounding are [0–255], [1–255] and [1–255] respectively. Note that full accuracy is possible with 24 bits. See [14] for more information.
0000SoPEC ASIC
00009 Overview
0677The Small Office Home Office Print Engine Controller (SoPEC) is a page rendering engine ASIC that takes compressed page images as input, and produces decompressed page images at up to 6 channels of bi-level dot data as output. The bi-level dot data is generated for the Memjet bi-lithic printhead. The dot generation process takes account of printhead construction, dead nozzles, and allows for fixative generation.
0678A single SoPEC can control 2 bi-lithic printheads and up to 6 color channels at 10,000 lines/sec<sup>5</sup>, equating to 30 pages per minute. A single SoPEC can perform full-bleed printing of A3, A4 and Letter pages. The 6 channels of colored ink are the expected maximum in a consumer SOHO, or office Bi-lithic printing environment: <ul id="ul0024" list-style="none"><li id="ul0024-0001" num="0000"><ul id="ul0025" list-style="none"><li id="ul0025-0001" num="0679">CMY, for regular color printing.</li><li id="ul0025-0002" num="0680">K, for black text, line graphics and gray-scale printing.</li><li id="ul0025-0003" num="0681">IR (infrared), for Netpage-enabled [5] applications.</li><li id="ul0025-0004" num="0682">F (fixative), to enable printing at high speed. Because the bi-lithic printer is capable of printing so fast, a fixative may be required to enable the ink to dry before the page touches the page already printed. Otherwise the pages may bleed on each other. In low speed printing environments the fixative may not be required. <sup>5</sup>10,000 lines per second equates to 30 A4/Letter pages per minute at 1600 dpi</li></ul></li></ul>
0683SoPEC is color space agnostic. Although it can accept contone data as CMYX or RGBX, where X is an optional 4th channel, it also can accept contone data in any print color space. Additionally, SoPEC provides a mechanism for arbitrary mapping of input channels to output channels, including combining dots for ink optimization, generation of channels based on any number of other channels etc. However, inputs are typically CMYK for contone input, K for the bi-level input, and the optional Netpage tag dots are typically rendered to an infra-red layer. A fixative channel is typically generated for fast printing applications.
0684SoPEC is resolution agnostic. It merely provides a mapping between input resolutions and output resolutions by means of scale factors. The expected output resolution is 1600 dpi, but SoPEC actually has no knowledge of the physical resolution of the Bi-lithic printhead.
0685SoPEC is page-length agnostic. Successive pages are typically split into bands and downloaded into the page store as each band of information is consumed and becomes free.
0686SoPEC provides an interface for synchronization with other SoPECs. This allows simple multi-SoPEC solutions for simultaneous A3/A4/Letter duplex printing. However, SoPEC is also capable of printing only a portion of a page image. Combining synchronization functionality with partial page rendering allows multiple SoPECs to be readily combined for alternative printing requirements including simultaneous duplex printing and wide format printing.
0687Table 8 lists some of the features and corresponding benefits of SoPEC.
0688<tables id="TABLE-US-00008" num="00008"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 8</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Features and Benefits of SoPEC</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="98pt" align="left" /><colspec colname="2" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>Feature</entry><entry>Benefits</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>Optimised print</entry><entry>30 ppm full page photographic</entry></row><row><entry>architecture in</entry><entry>quality color printing from a</entry></row><row><entry>hardware</entry><entry>desktop PC</entry></row><row><entry>0.13 micron CMOS</entry><entry>High speed</entry></row><row><entry>(>3 million</entry><entry>Low cost</entry></row><row><entry>transistors)</entry><entry>High functionality</entry></row><row><entry>900 Million dots</entry><entry>Extremely fast page generation</entry></row><row><entry>per second</entry></row><row><entry>10,000 lines per</entry><entry>0.5 A4/Letter pages per SoPEC</entry></row><row><entry>second at 1600 dpi</entry><entry>chip per second</entry></row><row><entry>1 chip drives up to</entry><entry>Low cost page-width printers</entry></row><row><entry>133,920 nozzles</entry></row><row><entry>1 chip drives up to 6</entry><entry>99% of SoHo printers can use</entry></row><row><entry>color planes</entry><entry>1 SoPEC device</entry></row><row><entry>Integrated DRAM</entry><entry>No external memory required,</entry></row><row><entry /><entry>leading to low cost systems</entry></row><row><entry>Power saving</entry><entry>SoPEC can enter a power saving</entry></row><row><entry>sleep mode</entry><entry>sleep mode to reduce power</entry></row><row><entry /><entry>dissipation between print jobs</entry></row><row><entry>JPEG expansion</entry><entry>Low bandwidth from PC</entry></row><row><entry /><entry>Low memory requirements in printer</entry></row><row><entry>Lossless bitplane</entry><entry>High resolution text and line</entry></row><row><entry>expansion</entry><entry>art with low bandwidth from PC</entry></row><row><entry /><entry>(e.g. over USB)</entry></row><row><entry>Netpage tag expansion</entry><entry>Generates interactive paper</entry></row><row><entry>Stochastic dispersed</entry><entry>Optically smooth image quality</entry></row><row><entry>dot dither</entry><entry>No moire effects</entry></row><row><entry>Hardware compositor</entry><entry>Pages composited in real-time</entry></row><row><entry>for 6 image planes</entry></row><row><entry>Dead nozzle compensation</entry><entry>Extends printhead life and yield</entry></row><row><entry /><entry>Reduces printhead cost</entry></row><row><entry>Color space agnostic</entry><entry>Compatible with all inksets and</entry></row><row><entry /><entry>image sources including</entry></row><row><entry /><entry>RGB, CMYK, spot, CIE L*a*b*,</entry></row><row><entry /><entry>hexachrome, YCrCbK,</entry></row><row><entry /><entry>sRGB and other</entry></row><row><entry>Color space conversion</entry><entry>Higher quality/lower bandwidth</entry></row><row><entry>Computer interface</entry><entry>USB1.1 interface to host and ISI</entry></row><row><entry /><entry>interface to ISI-Bridge chip</entry></row><row><entry /><entry>thereby allowing connection to</entry></row><row><entry /><entry>IEEE 1394, Bluetooth etc.</entry></row><row><entry>Cascadable in resolution</entry><entry>Printers of any resolution</entry></row><row><entry>Cascadable in color depth</entry><entry>Special color sets e.g.</entry></row><row><entry /><entry>hexachrome can be used</entry></row><row><entry>Cascadable in image size</entry><entry>Printers of any width up to</entry></row><row><entry /><entry>16 inches</entry></row><row><entry>Cascadable in pages</entry><entry>Printers can print both sides</entry></row><row><entry /><entry>simultaneously</entry></row><row><entry>Cascadable in speed</entry><entry>Higher speeds are possible by</entry></row><row><entry /><entry>having each SoPEC print one</entry></row><row><entry /><entry>vertical strip of the page.</entry></row><row><entry>Fixative channel</entry><entry>Extremely fast ink drying</entry></row><row><entry>data generation</entry><entry>without wastage</entry></row><row><entry>Built-in security</entry><entry>Revenue models are protected</entry></row><row><entry>Undercolor removal on</entry><entry>Reduced ink usage</entry></row><row><entry>dot-by-dot basis</entry></row><row><entry>Does not require fonts for</entry><entry>No font substitution or</entry></row><row><entry>high speed operation</entry><entry>missing fonts</entry></row><row><entry>Flexible printhead</entry><entry>Many configurations of</entry></row><row><entry>configuration</entry><entry>printheads are supported</entry></row><row><entry /><entry>by one chip type</entry></row><row><entry>Drives Bi-lithic</entry><entry>No print driver chips required,</entry></row><row><entry>printheads directly</entry><entry>results in lower cost</entry></row><row><entry>Determines dot accurate</entry><entry>Removes need for physical ink</entry></row><row><entry>ink usage</entry><entry>monitoring system in ink</entry></row><row><entry /><entry>cartridges</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 9.1 Printing Rates
0689The required printing rate for SoPEC is 30 sheets per minute with an inter-sheet spacing of 4 cm. To achieve a 30 sheets per minute print rate, this requires: <ul id="ul0026" list-style="none"><li id="ul0026-0001" num="0000"><ul id="ul0027" list-style="none"><li id="ul0027-0001" num="0690">300 mm×63 (dot/mm)/2 sec=105.8 μseconds per line, with no inter-sheet gap.</li><li id="ul0027-0002" num="0691">340 mm×63 (dot/mm)/2 sec=93.3 μseconds per line, with a 4 cm inter-sheet gap.</li></ul></li></ul>
0692A printline for an A4 page consists of 13824 nozzles across the page [2]. At a system clock rate of 160 MHz 13824 dots of data can be generated in 86.4 μseconds. Therefore data can be generated fast enough to meet the printing speed requirement. It is necessary to deliver this print data to the print-heads.
0693Printheads can be made up of 5:5, 6:4, 7:3 and 8:2 inch printhead combinations [2]. Print data is transferred to both print heads in a pair simultaneously. This means the longest time to print a line is determined by the time to transfer print data to the longest print segment. There are 9744 nozzles across a 7 inch printhead. The print data is transferred to the printhead at a rate of 106 MHz (⅔ of the system clock rate) per color plane. This means that it will take 91.9 μs to transfer a single line for a 7:3 printhead configuration. So we can meet the requirement of 30 sheets per minute printing with a 4 cm gap with a 7:3 printhead combination. There are 11160 across an 8 inch printhead. To transfer the data to the printhead at 106 MHz will take 105.3 μs. So an 8:2 printhead combination printing with an inter-sheet gap will print slower than 30 sheets per minute.
00009.2 SoPEC Basic Architecture
0694From the highest point of view the SoPEC device consists of 3 distinct subsystems <ul id="ul0028" list-style="none"><li id="ul0028-0001" num="0000"><ul id="ul0029" list-style="none"><li id="ul0029-0001" num="0695">CPU Subsystem</li><li id="ul0029-0002" num="0696">DRAM Subsystem</li><li id="ul0029-0003" num="0697">Print Engine Pipeline (PEP) Subsystem</li></ul></li></ul>
0698See <figref idref="DRAWINGS">FIG. 13</figref> for a block level diagram of SoPEC.
00009.2.1 CPU Subsystem
0699The CPU subsystem controls and configures all aspects of the other subsystems. It provides general support for interfacing and synchronising the external printer with the internal print engine. It also controls the low speed communication to the QA chips. The CPU subsystem contains various peripherals to aid the CPU, such as GPIO (includes motor control), interrupt controller, LSS Master and general timers. The Serial Communications Block (SCB) on the CPU subsystem provides a full speed USB1.1 interface to the host as well as an Inter SoPEC Interface (ISI) to other SoPEC devices.
00009.2.2 DRAM Subsystem
0700The DRAM subsystem accepts requests from the CPU, Serial Communications Block (SCB) and blocks within the PEP subsystem. The DRAM subsystem (in particular the DIU) arbitrates the various requests and determines which request should win access to the DRAM. The DIU arbitrates based on configured parameters, to allow sufficient access to DRAM for all requesters. The DIU also hides the implementation specifics of the DRAM such as page size, number of banks, refresh rates etc.
00009.2.3 Print Engine Pipeline (PEP) Subsystem
0701The Print Engine Pipeline (PEP) subsystem accepts compressed pages from DRAM and renders them to bi-level dots for a given print line destined for a printhead interface that communicates directly with up to 2 segments of a bi-lithic printhead.
0702The first stage of the page expansion pipeline is the CDU, LBD and TE. The CDU expands the JPEG-compressed contone (typically CMYK) layer, the LBD expands the compressed bi-level layer (typically K), and the TE encodes Netpage tags for later rendering (typically in IR or K ink). The output from the first stage is a set of buffers: the CFU, SFU, and TFU. The CFU and SFU buffers are implemented in DRAM.
0703The second stage is the HCU, which dithers the contone layer, and composites position tags and the bi-level spot0 layer over the resulting bi-level dithered layer. A number of options exist for the way in which compositing occurs. Up to 6 channels of bi-level data are produced from this stage. Note that not all 6 channels may be present on the printhead. For example, the printhead may be CMY only, with K pushed into the CMY channels and IR ignored. Alternatively, the position tags may be printed in K if IR ink is not available (or for testing purposes).
0704The third stage (DNC) compensates for dead nozzles in the printhead by color redundancy and error diffusing dead nozzle data into surrounding dots.
0705The resultant bi-level 6 channel dot-data (typically CMYK-IRF) is buffered and written out to a set of line buffers stored in DRAM via the DWU.
0706Finally, the dot-data is loaded back from DRAM, and passed to the printhead interface via a dot FIFO. The dot FIFO accepts data from the LLU at the system clock rate (pclk), while the PHI removes data from the FIFO and sends it to the printhead at a rate of ⅔ times the system clock rate (see Section 9.1).
00009.3 SoPEC Block Description
0707Looking at <figref idref="DRAWINGS">FIG. 13</figref>, the various units are described here in summary form:
0708<tables id="TABLE-US-00009" num="00009"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="294pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 9</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Units within SoPEC</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><colspec colname="3" colwidth="70pt" align="left" /><colspec colname="4" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>Unit</entry><entry /><entry /></row><row><entry>Subsystem</entry><entry>Acronym</entry><entry>Unit Name</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>DRAM</entry><entry>DIU</entry><entry>DRAM interface unit</entry><entry>Provides the interface for DRAM read and write</entry></row><row><entry /><entry /><entry /><entry>access for the various SoPEC units, CPU and</entry></row><row><entry /><entry /><entry /><entry>the SCB block. The DIU provides arbitration</entry></row><row><entry /><entry /><entry /><entry>between competing units controls DRAM</entry></row><row><entry /><entry /><entry /><entry>access.</entry></row><row><entry /><entry>DRAM</entry><entry>Embedded DRAM</entry><entry>20 Mbits of embedded DRAM,</entry></row><row><entry>CPU</entry><entry>CPU</entry><entry>Central Processing</entry><entry>CPU for system configuration and control</entry></row><row><entry /><entry /><entry>Unit</entry></row><row><entry /><entry>MMU</entry><entry>Memory Management</entry><entry>Limits access to certain memory address areas</entry></row><row><entry /><entry /><entry>Unit</entry><entry>in CPU user mode</entry></row><row><entry /><entry>RDU</entry><entry>Real-time Debug Unit</entry><entry>Facilitates the observation of the contents of</entry></row><row><entry /><entry /><entry /><entry>most of the CPU addressable registers in</entry></row><row><entry /><entry /><entry /><entry>SoPEC in addition to some pseudo-registers in</entry></row><row><entry /><entry /><entry /><entry>realtime.</entry></row><row><entry /><entry>TIM</entry><entry>General Timer</entry><entry>Contains watchdog and general system timers</entry></row><row><entry /><entry>LSS</entry><entry>Low Speed Serial</entry><entry>Low level controller for interfacing with the QA</entry></row><row><entry /><entry /><entry>Interfaces</entry><entry>chips</entry></row><row><entry /><entry>GPIO</entry><entry>General Purpose IOs</entry><entry>General IO controller, with built-in Motor control</entry></row><row><entry /><entry /><entry /><entry>unit, LED pulse units and de-glitch circuitry</entry></row><row><entry /><entry>ROM</entry><entry>Boot ROM</entry><entry>16 KBytes of System Boot ROM code</entry></row><row><entry /><entry>ICU</entry><entry>Interrupt Controller</entry><entry>General Purpose interrupt controller with</entry></row><row><entry /><entry /><entry>Unit</entry><entry>configurable priority, and masking.</entry></row><row><entry /><entry>CPR</entry><entry>Clock, Power and</entry><entry>Central Unit for controlling and generating the</entry></row><row><entry /><entry /><entry>Reset block</entry><entry>system clocks and resets and powerdown</entry></row><row><entry /><entry /><entry /><entry>mechanisms</entry></row><row><entry /><entry>PSS</entry><entry>Power Save Storage</entry><entry>Storage retained while system is powered down</entry></row><row><entry /><entry>USB</entry><entry>Universal Serial Bus</entry><entry>USB device controller for interfacing with the</entry></row><row><entry /><entry /><entry>Device</entry><entry>host USB.</entry></row><row><entry /><entry>ISI</entry><entry>Inter-SoPEC Interface</entry><entry>ISI controller for data and control</entry></row><row><entry /><entry /><entry /><entry>communication with other SoPEC's in a multi-</entry></row><row><entry /><entry /><entry /><entry>SoPEC system</entry></row><row><entry /><entry>SCB</entry><entry>Serial Communication</entry><entry>Contains both the USB and ISI blocks.</entry></row><row><entry /><entry /><entry>Block</entry></row><row><entry>Print Engine</entry><entry>PCU</entry><entry>PEP controller</entry><entry>Provides external CPU with the means to read</entry></row><row><entry>Pipeline</entry><entry /><entry /><entry>and write PEP Unit registers, and read and</entry></row><row><entry>(PEP)</entry><entry /><entry /><entry>write DRAM in single 32-bit chunks.</entry></row><row><entry /><entry>CDU</entry><entry>Contone decoder unit</entry><entry>Expands JPEG compressed contone layer and</entry></row><row><entry /><entry /><entry /><entry>writes decompressed contone to DRAM</entry></row><row><entry /><entry>CFU</entry><entry>Contone FIFO Unit</entry><entry>Provides line buffering between CDU and HCU</entry></row><row><entry /><entry>LBD</entry><entry>Lossless Bi-level</entry><entry>Expands compressed bi-level layer.</entry></row><row><entry /><entry /><entry>Decoder</entry></row><row><entry /><entry>SFU</entry><entry>Spot FIFO Unit</entry><entry>Provides line buffering between LBD and HCU</entry></row><row><entry /><entry>TE</entry><entry>Tag encoder</entry><entry>Encodes tag data into line of tag dots.</entry></row><row><entry /><entry>TFU</entry><entry>Tag FIFO Unit</entry><entry>Provides tag data storage between TE and HCU</entry></row><row><entry /><entry>HCU</entry><entry>Halftoner compositor</entry><entry>Dithers contone layer and composites the bi-</entry></row><row><entry /><entry /><entry>unit</entry><entry>level spot 0 and position tag dots.</entry></row><row><entry /><entry>DNC</entry><entry>Dead Nozzle</entry><entry>Compensates for dead nozzles by color</entry></row><row><entry /><entry /><entry>Compensator</entry><entry>redundancy and error diffusing dead nozzle</entry></row><row><entry /><entry /><entry /><entry>data into surrounding dots.</entry></row><row><entry /><entry>DWU</entry><entry>Dotline Writer Unit</entry><entry>Writes out the 6 channels of dot data for a</entry></row><row><entry /><entry /><entry /><entry>given printline to the line store DRAM</entry></row><row><entry /><entry>LLU</entry><entry>Line Loader Unit</entry><entry>Reads the expanded page image from line</entry></row><row><entry /><entry /><entry /><entry>store, formatting the data appropriately for the</entry></row><row><entry /><entry /><entry /><entry>bi-lithic printhead.</entry></row><row><entry /><entry>PHI</entry><entry>PrintHead Interface</entry><entry>Is responsible for sending dot data to the bi-</entry></row><row><entry /><entry /><entry /><entry>lithic printheads and for providing line</entry></row><row><entry /><entry /><entry /><entry>synchronization between multiple SoPECs.</entry></row><row><entry /><entry /><entry /><entry>Also provides test interface to printhead such</entry></row><row><entry /><entry /><entry /><entry>as temperature monitoring and Dead Nozzle</entry></row><row><entry /><entry /><entry /><entry>Identification.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 9.4 Addressing Scheme in SoPEC
0709SoPEC must address <ul id="ul0030" list-style="none"><li id="ul0030-0001" num="0000"><ul id="ul0031" list-style="none"><li id="ul0031-0001" num="0710">20 Mbit DRAM.</li><li id="ul0031-0002" num="0711">PCU addressed registers in PEP.</li><li id="ul0031-0003" num="0712">CPU-subsystem addressed registers.</li></ul></li></ul>
0713SoPEC has a unified address space with the CPU capable of addressing all CPU-subsystem and PCU-bus accessible registers (in PEP) and all locations in DRAM. The CPU generates byte-aligned addresses for the whole of SoPEC.
071422 bits are sufficient to byte address the whole SoPEC address space.
00009.4.1 DRAM Addressing Scheme
0715The embedded DRAM is composed of 256-bit words. However the CPU-subsystem may need to write individual bytes of DRAM. Therefore it was decided to make the DIU byte addressable. 22 bits are required to byte address 20 Mbits of DRAM.
0716Most blocks read or write 256-bit words of DRAM. Therefore only the top 17 bits i.e. bits <b>21</b> to <b>5</b> are required to address 256-bit word aligned locations.
0717The exceptions are <ul id="ul0032" list-style="none"><li id="ul0032-0001" num="0000"><ul id="ul0033" list-style="none"><li id="ul0033-0001" num="0718">CDU which can write 64-bits so only the top 19 address bits i.e. bits <b>21</b>–<b>3</b> are required.</li><li id="ul0033-0002" num="0719">The CPU-subsystem always generates a 22-bit byte-aligned DIU address but it will send flags to the DIU indicating whether it is an 8, 16 or 32-bit write.</li></ul></li></ul>
0720All DIU accesses must be within the same 256-bit aligned DRAM word.
00009.4.2 PEP Unit DRAM Addressing
0721PEP Unit configuration registers which specify DRAM locations should specify 256-bit aligned DRAM addresses i.e. using address bits <b>21</b>:<b>5</b>. Legacy blocks from PEC1 e.g. the LBD and TE may need to specify 64-bit aligned DRAM addresses if these reused blocks DRAM addressing is difficult to modify. These 64-bit aligned addresses require address bits <b>21</b>:<b>3</b>. However, these 64-bit aligned addresses should be programmed to start at a 256-bit DRAM word boundary.
0722Unlike PEC1, there are no constraints in SoPEC on data organization in DRAM except that all data structures must start on a 256-bit DRAM boundary. If data stored is not a multiple of 256-bits then the last word should be padded.
00009.4.3 CPU Subsystem Bus Addressed Registers
0723The CPU subsystem bus supports 32-bit word aligned read and write accesses with variable access timings. See section 11.4 for more details of the access protocol used on this bus. The CPU subsystem bus does not currently support byte reads and writes but this can be added at a later date if required by imported IP.
00009.4.4 PCU Addressed Registers in PEP
0724The PCU only supports 32-bit register reads and writes for the PEP blocks. As the PEP blocks only occupy a subsection of the overall address map and the PCU is explicitly selected by the MMU when a PEP block is being accessed the PCU does not need to perform a decode of the higher-order address bits. See Table 11 for the PEP subsystem address map.
00009.5 SoPEC Memory Map
00009.5.1 Main Memory Map
0725The system wide memory map is shown in <figref idref="DRAWINGS">FIG. 14</figref> below. The memory map is discussed in detail in Section 11 11 Central Processing Unit (CPU).
00009.5.2 CPU-bus Peripherals Address Map
0726The address mapping for the peripherals attached to the CPU-bus is shown in Table 10 below. The MMU performs the decode of cpu_adr[21:12] to generate the relevant cpu_block_select signal for each block. The addressed blocks decode however many of the lower order bits of cpu_adr[11:2] are required to address all the registers within the block.
0727<tables id="TABLE-US-00010" num="00010"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 10</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>CPU-bus peripherals address map</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="126pt" align="left" /><tbody valign="top"><row><entry /><entry>Block_base</entry><entry>Address</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>ROM_base</entry><entry>0x0000_0000</entry></row><row><entry /><entry>MMU_base</entry><entry>0x0001_0000</entry></row><row><entry /><entry>TIM_base</entry><entry>0x0001_1000</entry></row><row><entry /><entry>LSS_base</entry><entry>0x0001_2000</entry></row><row><entry /><entry>GPIO_base</entry><entry>0x0001_3000</entry></row><row><entry /><entry>SCB_base</entry><entry>0x0001_4000</entry></row><row><entry /><entry>ICU_base</entry><entry>0x0001_5000</entry></row><row><entry /><entry>CPR_base</entry><entry>0x0001_6000</entry></row><row><entry /><entry>DIU_base</entry><entry>0x0001_7000</entry></row><row><entry /><entry>PSS_base</entry><entry>0x0001_8000</entry></row><row><entry /><entry>Reserved</entry><entry>0x0001_9000 to 0x0001_FFFF</entry></row><row><entry /><entry>PCU_base</entry><entry>0x0002_0000 to 0x0002_BFFF</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 9.5.3 PCU Mapped Registers (PEP Blocks) Address Map
0728The PEP blocks are addressed via the PCU. From <figref idref="DRAWINGS">FIG. 14</figref>, the PCU mapped registers are in the range 0x0002<sub>—</sub>0000 to 0x0002_BFFF. From Table 11 it can be seen that there are 12 sub-blocks within the PCU address space. Therefore, only four bits are necessary to address each of the sub-blocks within the PEP part of SoPEC. A further 12 bits may be used to address any configurable register within a PEP block. This gives scope for 1024 configurable registers per sub-block (the PCU mapped registers are all 32-bit addressed registers so the upper 10 bits are required to individually address them). This address will come either from the CPU or from a command stored in DRAM. The bus is assembled as follows: <ul id="ul0034" list-style="none"><li id="ul0034-0001" num="0000"><ul id="ul0035" list-style="none"><li id="ul0035-0001" num="0729">address[15:12]=sub-block address, <ul id="ul0036" list-style="none"><li id="ul0036-0001" num="0730">address[n:2]=register address within sub-block, only the number of bits required to decode the registers within each sub-block are used,</li><li id="ul0036-0002" num="0731">address[1:0]=byte address, unused as PCU mapped registers are all 32-bit addressed registers.</li></ul></li></ul></li></ul>
0732So for the case of the HCU, its addresses range from 0x7000 to 0x7FFF within the PEP subsystem or from 0x0002<sub>—</sub>7000 to 0x0002<sub>—</sub>7FFF in the overall system.
0733<tables id="TABLE-US-00011" num="00011"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 11</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>PEP blocks address map</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="126pt" align="left" /><tbody valign="top"><row><entry /><entry>Block_base</entry><entry>Address</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>PCU_base</entry><entry>0x0002_0000</entry></row><row><entry /><entry>CDU_base</entry><entry>0x0002_1000</entry></row><row><entry /><entry>CFU_base</entry><entry>0x0002_2000</entry></row><row><entry /><entry>LBD_base</entry><entry>0x0002_3000</entry></row><row><entry /><entry>SFU_base</entry><entry>0x0002_4000</entry></row><row><entry /><entry>TE_base</entry><entry>0x0002_5000</entry></row><row><entry /><entry>TFU_base</entry><entry>0x0002_6000</entry></row><row><entry /><entry>HCU_base</entry><entry>0x0002_7000</entry></row><row><entry /><entry>DNC_base</entry><entry>0x0002_8000</entry></row><row><entry /><entry>DWU_base</entry><entry>0x0002_9000</entry></row><row><entry /><entry>LLU_base</entry><entry>0x0002_A000</entry></row><row><entry /><entry>PHI_base</entry><entry>0x0002_B000 to 0x0002_BFFF</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 9.6 Buffer Management in SoPEC
0734As outlined in Section 9.1, SoPEC has a requirement to print 1 side every 2 seconds i.e. 30 sides per minute.
00009.6.1 Page Buffering
0735Approximately 2 Mbytes of DRAM are reserved for compressed page buffering in SoPEC. If a page is compressed to fit within 2 Mbyte then a complete page can be transferred to DRAM before printing. However, the time to transfer 2 Mbyte using USB 1.1 is approximately 2 seconds. The worst case cycle time to print a page then approaches 4 seconds. This reduces the worst-case print speed to 15 pages per minute.
00009.6.2 Band Buffering
0736The SoPEC page-expansion blocks support the notion of page banding. The page can be divided into bands and another band can be sent down to SoPEC while we are printing the current band. Therefore we can start printing once at least one band has been downloaded.
0737The band size granularity should be carefully chosen to allow efficient use of the USB bandwidth and DRAM buffer space. It should be small enough to allow seamless 30 sides per minute printing but not so small as to introduce excessive CPU overhead in orchestrating the data transfer and parsing the band headers. Band-finish interrupts have been provided to notify the CPU of free buffer space. It is likely that the host PC will supervise the band transfer and buffer management instead of the SoPEC CPU.
0738If SoPEC starts printing before the complete page has been transferred to memory there is a risk of a buffer underrun occurring if subsequent bands are not transferred to SoPEC in time e.g. due to insufficient USB bandwidth caused by another USB peripheral consuming USB bandwidth. A buffer underrun occurs if a line synchronisation pulse is received before a line of data has been transferred to the printhead and causes the print job to fail at that line. If there is no risk of buffer underrun then printing can safely start once at least one band has been downloaded.
0739If there is a risk of a buffer underrun occurring due to an interruption of compressed page data transfer, then the safest approach is to only start printing once we have loaded up the data for a complete page. This means that a worst case latency in the region of 2 seconds (with USB1.1) will be incurred before printing the first page. Subsequent pages will take 2 seconds to print giving us the required sustained printing rate of 30 sides per minute.
0740A Storage SoPEC (Section 7.2.5) could be added to the system to provide guaranteed bandwidth data delivery. The print system could also be constructed using an ISI-Bridge chip (Section 7.2.6) to provide guaranteed data delivery.
0741The most efficient page banding strategy is likely to be determined on a per page/print job basis and so SoPEC will support the use of bands of any size.
000010 SoPEC Use Cases
000010.1 Introduction
0742This chapter is intended to give an overview of a representative set of scenarios or use cases which SoPEC can perform. SoPEC is by no means restricted to the particular use cases described and not every SoPEC system is considered here.
0743In this chapter we discuss SoPEC use cases under four headings: <ul id="ul0037" list-style="none"><li id="ul0037-0001" num="0744">1) Normal operation use cases.</li><li id="ul0037-0002" num="0745">2) Security use cases.</li><li id="ul0037-0003" num="0746">3) Miscellaneous use cases.</li><li id="ul0037-0004" num="0747">4) Failure mode use cases.</li></ul>
0748Use cases for both single and multi-SoPEC systems are outlined.
0749Some tasks may be composed of a number of sub-tasks.
0750The realtime requirements for SoPEC software tasks are discussed in “11 Central Processing Unit (CPU)” under Section 11.3 Realtime requirements.
000010.2 Normal Operation in a Single SoPEC System with USB Host Connection
0751SoPEC operation is broken up into a number of sections which are outlined below. Buffer management in a SoPEC system is normally performed by the host.
000010.2.1 Powerup
0752Powerup describes SoPEC initialisation following an external reset or the watchdog timer system reset.
0753A typical powerup sequence is: <ul id="ul0038" list-style="none"><li id="ul0038-0001" num="0754">1) Execute reset sequence for complete SoPEC.</li><li id="ul0038-0002" num="0755">2) CPU boot from ROM.</li><li id="ul0038-0003" num="0756">3) Basic configuration of CPU peripherals, SCB and DIU. DRAM initialisation. USB Wakeup.</li><li id="ul0038-0004" num="0757">4) Download and authentication of program (see Section 10.5.2).</li><li id="ul0038-0005" num="0758">5) Execution of program from DRAM.</li><li id="ul0038-0006" num="0759">6) Retrieve operating parameters from PRINTER_QA and authenticate operating parameters.</li><li id="ul0038-0007" num="0760">7) Download and authenticate any further datasets. <br /> 10.2.2 USB Wakeup </li></ul>
0761The CPU can put different sections of SoPEC into sleep mode by writing to registers in the CPR block (chapter 16). Normally the CPU sub-system and the DRAM will be put in sleep mode but the SCB and power-safe storage (PSS) will still be enabled.
0762Wakeup describes SoPEC recovery from sleep mode with the SCB and power-safe storage (PSS) still enabled. In a single SoPEC system, wakeup can be initiated following a USB reset from the SCB.
0763A typical USB wakeup sequence is: <ul id="ul0039" list-style="none"><li id="ul0039-0001" num="0764">1) Execute reset sequence for sections of SoPEC in sleep mode.</li><li id="ul0039-0002" num="0765">2) CPU boot from ROM, if CPU-subsystem was in sleep mode.</li><li id="ul0039-0003" num="0766">3) Basic configuration of CPU peripherals and DIU, and DRAM initialisation, if required.</li><li id="ul0039-0004" num="0767">4) Download and authentication of program using results in Power-Safe Storage (PSS) (see Section 10.5.2).</li><li id="ul0039-0005" num="0768">5) Execution of program from DRAM.</li><li id="ul0039-0006" num="0769">6) Retrieve operating parameters from PRINTER_QA and authenticate operating parameters.</li><li id="ul0039-0007" num="0770">7) Download and authenticate using results in PSS of any further datasets (programs). <br /> 10.2.3 Print Initialization </li></ul>
0771This sequence is typically performed at the start of a print job following powerup or wakeup: <ul id="ul0040" list-style="none"><li id="ul0040-0001" num="0772">1) Check amount of ink remaining via QA chips.</li><li id="ul0040-0002" num="0773">2) Download static data e.g. dither matrices, dead nozzle tables from host to DRAM.</li><li id="ul0040-0003" num="0774">3) Check printhead temperature, if required, and configure printhead with firing pulse profile etc. accordingly.</li><li id="ul0040-0004" num="0775">4) Initiate printhead pre-heat sequence, if required. <br /> 10.2.4 First Page Download </li></ul>
0776Buffer management in a SoPEC system is normally performed by the host.
0777First page, first band download and processing: <ul id="ul0041" list-style="none"><li id="ul0041-0001" num="0778">1) The host communicates to the SoPEC CPU over the USB to check that DRAM space remaining is sufficient to download the first band.</li><li id="ul0041-0002" num="0779">2) The host downloads the first band (with the page header) to DRAM.</li><li id="ul0041-0003" num="0780">3) When the complete page header has been downloaded the SoPEC CPU processes the page header, calculates PEP register commands and writes directly to PEP registers or to DRAM.</li><li id="ul0041-0004" num="0781">4) If PEP register commands have been written to DRAM, execute PEP commands from DRAM via PCU.</li></ul>
0782Remaining bands download and processing: <ul id="ul0042" list-style="none"><li id="ul0042-0001" num="0783">1) Check DRAM space remaining is sufficient to download the next band.</li><li id="ul0042-0002" num="0784">2) Download the next band with the band header to DRAM.</li><li id="ul0042-0003" num="0785">3) When the complete band header has been downloaded, process the band header according to whichever band-related register updating mechanism is being used. <br /> 10.2.5 Start Printing </li><li id="ul0042-0004" num="0786">1) Wait until at least one band of the first page has been downloaded. One approach is to only start printing once we have loaded up the data for a complete page. If we start printing before the complete page has been transferred to memory we run the risk of a buffer underrun occurring because compressed page data was not transferred to SoPEC in time e.g. due to insufficient USB bandwidth caused by another USB peripheral consuming USB bandwidth.</li><li id="ul0042-0005" num="0787">2) Start all the PEP Units by writing to their Go registers, via PCU commands executed from DRAM or direct CPU writes. A rapid startup order for the PEP units is outlined in Table 12.</li></ul>
0788<tables id="TABLE-US-00012" num="00012"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 12</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Typical PEP Unit startup order for printing a page.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="112pt" align="center" /><colspec colname="2" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>Step#</entry><entry>Unit</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>1</entry><entry>DNC</entry></row><row><entry>2</entry><entry>DWU</entry></row><row><entry>3</entry><entry>HCU</entry></row><row><entry>4</entry><entry>PHI</entry></row><row><entry>5</entry><entry>LLU</entry></row><row><entry>6</entry><entry>CFU, SFU, TFU</entry></row><row><entry>7</entry><entry>CDU</entry></row><row><entry>8</entry><entry>TE, LBD</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><ul id="ul0043" list-style="none"><li id="ul0043-0001" num="0789">3) Print ready interrupt occurs (from PHI).</li><li id="ul0043-0002" num="0790">4) Start motor control, if first page, otherwise feed the next page. This step could occur before the print ready interrupt.</li><li id="ul0043-0003" num="0791">5) Drive LEDs, monitor paper status.</li><li id="ul0043-0004" num="0792">6) Wait for page alignment via page sensor(s) GPIO interrupt.</li><li id="ul0043-0005" num="0793">7) CPU instructs PHI to start producing line syncs and hence commence printing, or wait for an external device to produce line syncs.</li><li id="ul0043-0006" num="0794">8) Continue to download bands and process page and band headers for next page. <br /> 10.2.6 Next Page(s) Download </li></ul>
0795As for first page download, performed during printing of current page.
000010.2.7 Between Bands
0796When the finished band flags are asserted band related registers in the CDU, LBD, TE need to be re-programmed before the subsequent band can be printed. This can be via PCU commands from DRAM. Typically only 3–5 commands per decompression unit need to be executed. These registers can also be reprogrammed directly by the CPU or most likely by updating from shadow registers. The finished band flag interrupts the CPU to tell the CPU that the area of memory associated with the band is now free.
000010.2.8 During Page Print
0797Typically during page printing ink usage is communicated to the QA chips. <ul id="ul0044" list-style="none"><li id="ul0044-0001" num="0798">1) Calculate ink printed (from PHI).</li><li id="ul0044-0002" num="0799">2) Decrement ink remaining (via QA chips).</li><li id="ul0044-0003" num="0800">3) Check amount of ink remaining (via QA chips). This operation may be better performed while the page is being printed rather than at the end of the page. <br /> 10.2.9 Page Finish </li></ul>
0801These operations are typically performed when the page is finished: <ul id="ul0045" list-style="none"><li id="ul0045-0001" num="0802">1) Page finished interrupt occurs from PHI.</li><li id="ul0045-0002" num="0803">2) Shutdown the PEP blocks by de-asserting their Go registers. A typical shutdown order is defined in Table 13. This will set the PEP Unit state-machines to their idle states without resetting their configuration registers.</li><li id="ul0045-0003" num="0804">3) Communicate ink usage to QA chips, if required.</li></ul>
0805<tables id="TABLE-US-00013" num="00013"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 13</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>End of page shutdown order for PEP Units.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="56pt" align="center" /><colspec colname="2" colwidth="161pt" align="left" /><tbody valign="top"><row><entry>Step#</entry><entry>Unit</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>1</entry><entry>PHI (will shutdown by itself in the normal</entry></row><row><entry /><entry>case at the end of a page)</entry></row><row><entry>2</entry><entry>DWU (shutting this down stalls the DNC and</entry></row><row><entry /><entry>therefore the HCU and above)</entry></row><row><entry>3</entry><entry>LLU (should already be halted due to PHI at</entry></row><row><entry /><entry>end of last line of page)</entry></row><row><entry>4</entry><entry>TE (this is the only dot supplier likely to</entry></row><row><entry /><entry>be running, halted by the HCU)</entry></row><row><entry>5</entry><entry>CDU (this is likely to already be halted due</entry></row><row><entry /><entry>to end of contone band)</entry></row><row><entry>6</entry><entry>CFU, SFU, TFU, LBD (order unimportant, and</entry></row><row><entry /><entry>should already be halted due to end of band)</entry></row><row><entry>7</entry><entry>HCU, DNC (order unimportant, should already</entry></row><row><entry /><entry>have halted)</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 10.2.10 Start of Next Page
0806These operations are typically performed before printing the next page: <ul id="ul0046" list-style="none"><li id="ul0046-0001" num="0807">1) Re-program the PEP Units via PCU command processing from DRAM based on page header.</li><li id="ul0046-0002" num="0808">2) Go to Start printing. <br /> 10.2.11 End of Document </li><li id="ul0046-0003" num="0809">1) Stop motor control. <br /> 10.2.12 Sleep Mode </li></ul>
0810The CPU can put different sections of SoPEC into sleep mode by writing to registers in the CPR block described in Section 16. <ul id="ul0047" list-style="none"><li id="ul0047-0001" num="0811">1) Instruct host PC via USB that SoPEC is about to sleep.</li><li id="ul0047-0002" num="0812">2) Store reusable authentication results in Power-Safe Storage (PSS).</li><li id="ul0047-0003" num="0813">3) Put SoPEC into defined sleep mode. <br /> 10.3 Normal Operation in a Multi-SoPEC System—ISIMaster SoPEC </li></ul>
0814In a multi-SoPEC system the host generally manages program and compressed page download to all the SoPECs. Inter-SoPEC communication is over the ISI link which will add a latency. In the case of a multi-SoPEC system with just one USB 1.1 connection, the SoPEC with the USB connection is the ISIMaster. The ISI-bridge chip is the ISIMaster in the case of an ISI-Bridge SoPEC configuration. While it is perfectly possible for an ISISlave to have a direct USB connection to the host we do not treat this scenario explicitly here to avoid possible confusion.
0815In a multi-SoPEC system one of the SoPECs will be the PrintMaster. This SoPEC must manage and control sensors and actuators e.g. motor control. These sensors and actuators could be distributed over all the SoPECs in the system. An ISIMaster SoPEC may also be the PrintMaster SoPEC.
0816In a multi-SoPEC system each printing SoPEC will generally have its own PRINTER_QA chip (or at least access to a PRINTER_QA chip that contains the SoPEC's SoPEC_id_key) to validate operating parameters and ink usage. The results of these operations may be communicated to the PrintMaster SoPEC.
0817In general the ISIMaster may need to be able to: <ul id="ul0048" list-style="none"><li id="ul0048-0001" num="0818">Send messages to the ISISlaves which will cause the ISISlaves to send their status to the ISIMaster.</li><li id="ul0048-0002" num="0819">Instruct the ISISlaves to perform certain operations.</li></ul>
0820As the ISI is an insecure interface commands issued over the ISI are regarded as user mode commands. Supervisor mode code running on the SoPEC CPUs will allow or disallow these commands. The software protocol needs to be constructed with this in mind.
0821The ISIMaster will initiate all communication with the ISISlaves.
0822SoPEC operation is broken up into a number of sections which are outlined below.
000010.3.1 Powerup
0823Powerup describes SoPEC initialisation following an external reset or the watchdog timer system reset. <ul id="ul0049" list-style="none"><li id="ul0049-0001" num="0824">1) Execute reset sequence for complete SoPEC.</li><li id="ul0049-0002" num="0825">2) CPU boot from ROM.</li><li id="ul0049-0003" num="0826">3) Basic configuration of CPU peripherals, SCB and DIU. DRAM initialisation USB Wakeup</li><li id="ul0049-0004" num="0827">4) SoPEC identification by activity on USB end-points 2–4 indicates it is the ISIMaster (unless the SoPEC CPU has explicitly disabled this function).</li><li id="ul0049-0005" num="0828">5) Download and authentication of program (see Section 10.5.3).</li><li id="ul0049-0006" num="0829">6) Execution of program from DRAM.</li><li id="ul0049-0007" num="0830">7) Retrieve operating parameters from PRINTER_QA and authenticate operating parameters.</li><li id="ul0049-0008" num="0831">8) Download and authenticate any further datasets (programs).</li><li id="ul0049-0009" num="0832">9) The initial dataset may be broadcast to all the ISISlaves.</li><li id="ul0049-0010" num="0833">10) ISIMaster master SoPEC then waits for a short time to allow the authentication to take place on the ISISlave SoPECs.</li><li id="ul0049-0011" num="0834">11) Each ISISlave SoPEC is polled for the result of its program code authentication process.</li><li id="ul0049-0012" num="0835">12) If all ISISlaves report successful authentication the OEM code module can be distributed and authenticated. OEM code will most likely reside on one SoPEC. <br /> 10.3.2 USB Wakeup </li></ul>
0836The CPU can put different sections of SoPEC into sleep mode by writing to registers in the CPR block [16]. Normally the CPU sub-system and the DRAM will be put in sleep mode but the SCB and power-safe storage (PSS) will still be enabled.
0837Wakeup describes SoPEC recovery from sleep mode with the SCB and power-safe storage (PSS) still enabled. For an ISIMaster SoPEC connected to the host via USB, wakeup can be initiated following a USB reset from the SCB.
0838A typical USB wakeup sequence is: <ul id="ul0050" list-style="none"><li id="ul0050-0001" num="0839">1) Execute reset sequence for sections of SoPEC in sleep mode.</li><li id="ul0050-0002" num="0840">2) CPU boot from ROM, if CPU-subsystem was in sleep mode.</li><li id="ul0050-0003" num="0841">3) Basic configuration of CPU peripherals and DIU, and DRAM initialisation, if required.</li><li id="ul0050-0004" num="0842">4) SoPEC identification by activity on USB end-points 2–4 indicates it is the ISIMaster (unless the SoPEC CPU has explicitly disabled this function).</li><li id="ul0050-0005" num="0843">5) Download and authentication of program using results in Power-Safe Storage (PSS) (see Section 10.5.3).</li><li id="ul0050-0006" num="0844">6) Execution of program from DRAM.</li><li id="ul0050-0007" num="0845">7) Retrieve operating parameters from PRINTER_QA and authenticate operating parameters.</li><li id="ul0050-0008" num="0846">8) Download and authenticate any further datasets (programs) using results in Power-Safe Storage (PSS) (see Section 10.5.3).</li><li id="ul0050-0009" num="0847">9) Following steps as per Powerup. <br /> 10.3.3 Print Initialization </li></ul>
0848This sequence is typically performed at the start of a print job following powerup or wakeup: <ul id="ul0051" list-style="none"><li id="ul0051-0001" num="0849">1) Check amount of ink remaining via QA chips which may be present on a ISISlave SoPEC.</li><li id="ul0051-0002" num="0850">2) Download static data e.g. dither matrices, dead nozzle tables from host to DRAM.</li><li id="ul0051-0003" num="0851">3) Check printhead temperature, if required, and configure printhead with firing pulse profile etc. accordingly. Instruct ISISlaves to also perform this operation.</li><li id="ul0051-0004" num="0852">4) Initiate printhead pre-heat sequence, if required. Instruct ISISlaves to also perform this operation <br /> 10.3.4 First Page Download </li></ul>
0853Buffer management in a SoPEC system is normally performed by the host. <ul id="ul0052" list-style="none"><li id="ul0052-0001" num="0854">1) The host communicates to the SoPEC CPU over the USB to check that DRAM space remaining is sufficient to download the first band.</li><li id="ul0052-0002" num="0855">2) The host downloads the first band (with the page header) to DRAM.</li><li id="ul0052-0003" num="0856">3) When the complete page header has been downloaded the SoPEC CPU processes the page header, calculates PEP register commands and write directly to PEP registers or to DRAM.</li><li id="ul0052-0004" num="0857">4) If PEP register commands have been written to DRAM, execute PEP commands from DRAM via PCU.</li></ul>
0858Poll ISISlaves for DRAM status and download compressed data to ISISlaves.
0859Remaining first page bands download and processing: <ul id="ul0053" list-style="none"><li id="ul0053-0001" num="0860">1) Check DRAM space remaining is sufficient to download the next band.</li><li id="ul0053-0002" num="0861">2) Download the next band with the band header to DRAM.</li><li id="ul0053-0003" num="0862">3) When the complete band header has been downloaded, process the band header according to whichever band-related register updating mechanism is being used.</li></ul>
0863Poll ISISlaves for DRAM status and download compressed data to ISISlaves.
000010.3.5 Start Printing
0000<ul id="ul0054" list-style="none"><li id="ul0054-0001" num="0864">1) Wait until at least one band of the first page has been downloaded.</li><li id="ul0054-0002" num="0865">2) Start all the PEP Units by writing to their Go registers, via PCU commands executed from DRAM or direct CPU writes, in the suggested order defined in Table.</li><li id="ul0054-0003" num="0866">3) Print ready interrupt occurs (from PHI). Poll ISISlaves until print ready interrupt.</li><li id="ul0054-0004" num="0867">4) Start motor control (which may be on an ISISlave SoPEC), if first page, otherwise feed the next page. This step could occur before the print ready interrupt.</li><li id="ul0054-0005" num="0868">5) Drive LEDS, monitor paper status (which may be on an ISISlave SoPEC).</li><li id="ul0054-0006" num="0869">6) Wait for page alignment via page sensor(s) GPIO interrupt (which may be on an ISISlave SoPEC).</li><li id="ul0054-0007" num="0870">7) If the LineSyncMaster is a SoPEC its CPU instructs PHI to start producing master line syncs. Otherwise wait for an external device to produce line syncs.</li><li id="ul0054-0008" num="0871">8) Continue to download bands and process page and band headers for next page. <br /> 10.3.6 Next Page(s) Download </li></ul>
0872As for first page download, performed during printing of current page.
000010.3.7 Between Bands
0873When the finished band flags are asserted band related registers in the CDU, LBD and TE need to be re-programmed. This can be via PCU commands from DRAM. Typically only 3–5 commands per decompression unit need to be executed. These registers can also be reprogrammed directly by the CPU or by updating from shadow registers. The finished band flag interrupts to the CPU, tell the CPU that the area of memory associated with the band is now free.
000010.3.8 During Page Print
0874Typically during page printing ink usage is communicated to the QA chips. <ul id="ul0055" list-style="none"><li id="ul0055-0001" num="0875">1) Calculate ink printed (from PHI).</li><li id="ul0055-0002" num="0876">2) Decrement ink remaining (via QA chips).</li><li id="ul0055-0003" num="0877">3) Check amount of ink remaining (via QA chips). This operation may be better performed while the page is being printed rather than at the end of the page. <br /> 10.3.9 Page Finish </li></ul>
0878These operations are typically performed when the page is finished: <ul id="ul0056" list-style="none"><li id="ul0056-0001" num="0879">1) Page finished interrupt occurs from PHI. Poll ISISlaves for page finished interrupts.</li><li id="ul0056-0002" num="0880">2) Shutdown the PEP blocks by de-asserting their Go registers in the suggested order in Table. This will set the PEP Unit state-machines to their startup states.</li><li id="ul0056-0003" num="0881">3) Communicate ink usage to QA chips, if required. <br /> 10.3.10 Start of Next Page </li></ul>
0882These operations are typically performed before printing the next page: <ul id="ul0057" list-style="none"><li id="ul0057-0001" num="0883">1) Re-program the PEP Units via PCU command processing from DRAM based on page header.</li><li id="ul0057-0002" num="0884">2) Go to Start printing. <br /> 10.3.11 End of Document </li><li id="ul0057-0003" num="0885">1) Stop motor control. This may be on an ISISlave SoPEC. <br /> 10.3.12 Sleep Mode </li></ul>
0886The CPU can put different sections of SoPEC into sleep mode by writing to registers in the CPR block [16]. This may be as a result of a command from the host or as a result of a timeout. <ul id="ul0058" list-style="none"><li id="ul0058-0001" num="0887">1) Inform host PC of which parts of SoPEC system are about to sleep.</li><li id="ul0058-0002" num="0888">2) Instruct ISISlaves to enter sleep mode.</li><li id="ul0058-0003" num="0889">3) Store reusable cryptographic results in Power-Safe Storage (PSS).</li><li id="ul0058-0004" num="0890">4) Put ISIMaster SoPEC into defined sleep mode. <br /> 10.4 Normal Operation in a Multi-SoPEC System—ISISlave SoPEC </li></ul>
0891This section the outline typical operation of an ISISlave SoPEC in a multi-SoPEC system. The ISIMaster can be another SoPEC or an ISI-Bridge chip. The ISISlave communicates with the host either via the ISIMaster or using a direct connection such as USB. For this use case we consider only an ISISlave that does not have a direct host connection. Buffer management in a SoPEC system is normally performed by the host.
000010.4.1 Powerup
0892Powerup describes SoPEC initialisation following an external reset or the watchdog timer system reset.
0893A typical powerup sequence is: <ul id="ul0059" list-style="none"><li id="ul0059-0001" num="0894">1) Execute reset sequence for complete SoPEC.</li><li id="ul0059-0002" num="0895">2) CPU boot from ROM.</li><li id="ul0059-0003" num="0896">3) Basic configuration of CPU peripherals, SCB and DIU. DRAM initialisation.</li><li id="ul0059-0004" num="0897">4) Download and authentication of program (see Section 10.5.3).</li><li id="ul0059-0005" num="0898">5) Execution of program from DRAM.</li><li id="ul0059-0006" num="0899">6) Retrieve operating parameters from PRINTER_QA and authenticate operating parameters.</li><li id="ul0059-0007" num="0900">7) SoPEC identification by sampling GPIO pins to determine ISIId. Communicate ISIId to ISIMaster.</li><li id="ul0059-0008" num="0901">8) Download and authenticate any further datasets. <br /> 10.4.2 ISI Wakeup </li></ul>
0902The CPU can put different sections of SoPEC into sleep mode by writing to registers in the CPR block [16]. Normally the CPU sub-system and the DRAM will be put in sleep mode but the SCB and power-safe storage (PSS) will still be enabled.
0903Wakeup describes SoPEC recovery from sleep mode with the SCB and power-safe storage (PSS) still enabled. In an ISISlave SoPEC, wakeup can be initiated following an ISI reset from the SCB.
0904A typical ISI wakeup sequence is: <ul id="ul0060" list-style="none"><li id="ul0060-0001" num="0905">1) Execute reset sequence for sections of SoPEC in sleep mode.</li><li id="ul0060-0002" num="0906">2) CPU boot from ROM, if CPU-subsystem was in sleep mode.</li><li id="ul0060-0003" num="0907">3) Basic configuration of CPU peripherals and DIU, and DRAM initialisation, if required.</li><li id="ul0060-0004" num="0908">4) Download and authentication of program using results in Power-Safe Storage (PSS) (see Section 10.5.3).</li><li id="ul0060-0005" num="0909">5) Execution of program from DRAM.</li><li id="ul0060-0006" num="0910">6) Retrieve operating parameters from PRINTER_QA and authenticate operating parameters.</li><li id="ul0060-0007" num="0911">7) SoPEC identification by sampling GPIO pins to determine ISIId. Communicate ISIId to ISIMaster.</li><li id="ul0060-0008" num="0912">8) Download and authenticate any further datasets. <br /> 10.4.3 Print Initialization </li></ul>
0913This sequence is typically performed at the start of a print job following powerup or wakeup: <ul id="ul0061" list-style="none"><li id="ul0061-0001" num="0914">1) Check amount of ink remaining via QA chips.</li><li id="ul0061-0002" num="0915">2) Download static data e.g. dither matrices, dead nozzle tables from ISI to DRAM.</li><li id="ul0061-0003" num="0916">3) Check printhead temperature, if required, and configure printhead with firing pulse profile etc. accordingly.</li><li id="ul0061-0004" num="0917">4) Initiate printhead pre-heat sequence, if required. <br /> 10.4.4 First Page Download </li></ul>
0918Buffer management in a SoPEC system is normally performed by the host via the ISI. <ul id="ul0062" list-style="none"><li id="ul0062-0001" num="0919">1) Check DRAM space remaining is sufficient to download the first band.</li><li id="ul0062-0002" num="0920">2) The host downloads the first band (with the page header) to DRAM via the ISI.</li><li id="ul0062-0003" num="0921">3) When the complete page header has been downloaded, process the page header, calculate PEP register commands and write directly to PEP registers or to DRAM.</li><li id="ul0062-0004" num="0922">4) If PEP register commands have been written to DRAM, execute PEP commands from DRAM via PCU.</li></ul>
0923Remaining first page bands download and processing: <ul id="ul0063" list-style="none"><li id="ul0063-0001" num="0924">1) Check DRAM space remaining is sufficient to download the next band.</li><li id="ul0063-0002" num="0925">2) The host downloads the first band (with the page header) to DRAM via the ISI.</li><li id="ul0063-0003" num="0926">3) When the complete band header has been downloaded, process the band header according to whichever band-related register updating mechanism is being used. <br /> 10.4.5 Start Printing </li><li id="ul0063-0004" num="0927">1) Wait until at least one band of the first page has been downloaded.</li><li id="ul0063-0005" num="0928">2) Start all the PEP Units by writing to their Go registers, via PCU commands executed from DRAM or direct CPU writes, in the order defined in Table</li><li id="ul0063-0006" num="0929">3) Print ready interrupt occurs (from PHI). Communicate to PrintMaster via ISI.</li><li id="ul0063-0007" num="0930">4) Start motor control, if attached to this ISISlave, when requested by PrintMaster, if first page, otherwise feed next page. This step could occur before the print ready interrupt</li><li id="ul0063-0008" num="0931">5) Drive LEDS, monitor paper status, if on this ISISlave SoPEC, when requested by PrintMaster</li><li id="ul0063-0009" num="0932">6) Wait for page alignment via page sensor(s) GPIO interrupt, if on this ISISlave SoPEC, and send to PrintMaster.</li><li id="ul0063-0010" num="0933">7) Wait for line sync and commence printing.</li><li id="ul0063-0011" num="0934">8) Continue to download bands and process page and band headers for next page. <br /> 10.4.6 Next Page(s) Download </li></ul>
0935As for first band download, performed during printing of current page.
000010.4.7 Between Bands
0936When the finished band flags are asserted band related registers in the CDU, LBD and TE need to be re-programmed. This can be via PCU commands from DRAM. Typically only 3–5 commands per decompression unit need to be executed. These registers can also be reprogrammed directly by the CPU or by updating from shadow registers. The finished band flag interrupts to the CPU tell the CPU that the area of memory associated with the band is now free.
000010.4.8 During Page Print
0937Typically during page printing ink usage is communicated to the QA chips. <ul id="ul0064" list-style="none"><li id="ul0064-0001" num="0938">1) Calculate ink printed (from PHI).</li><li id="ul0064-0002" num="0939">2) Decrement ink remaining (via QA chips).</li><li id="ul0064-0003" num="0940">3) Check amount of ink remaining (via QA chips). This operation may be better performed while the page is being printed rather than at the end of the page. <br /> 10.4.9 Page Finish </li></ul>
0941These operations are typically performed when the page is finished: <ul id="ul0065" list-style="none"><li id="ul0065-0001" num="0942">1) Page finished interrupt occurs from PHI. Communicate page finished interrupt to PrintMaster.</li><li id="ul0065-0002" num="0943">2) Shutdown the PEP blocks by de-asserting their Go registers in the suggested order in Table. This will set the PEP Unit state-machines to their startup states.</li><li id="ul0065-0003" num="0944">3) Communicate ink usage to QA chips, if required. <br /> 10.4.10 Start of Next Page </li></ul>
0945These operations are typically performed before printing the next page: <ul id="ul0066" list-style="none"><li id="ul0066-0001" num="0946">1) Re-program the PEP Units via PCU command processing from DRAM based on page header.</li><li id="ul0066-0002" num="0947">2) Go to Start printing. <br /> 10.4.11 End of Document </li></ul>
0948Stop motor control, if attached to this ISISlave, when requested by PrintMaster.
000010.4.12 Powerdown
0949In this mode SoPEC is no longer powered. <ul id="ul0067" list-style="none"><li id="ul0067-0001" num="0950">1) Powerdown ISISlave SoPEC when instructed by ISIMaster. <br /> 10.4.13 Sleep </li></ul>
0951The CPU can put different sections of SoPEC into sleep mode by writing to registers in the CPR block [16]. This may be as a result of a command from the host or ISIMaster or as a result of a timeout. <ul id="ul0068" list-style="none"><li id="ul0068-0001" num="0952">1) Store reusable cryptographic results in Power-Safe Storage (PSS).</li><li id="ul0068-0002" num="0953">2) Put SoPEC into defined sleep mode. <br /> 10.5 Security Use Cases </li></ul>
0954Please see the ‘SoPEC Security Overview’ [9] document for a more complete description of SoPEC security issues. The SoPEC boot operation is described in the ROM chapter of the SoPEC hardware design specification, Section 17.2.
000010.5.1 Communication with the QA Chips
0955Communication between SoPEC and the QA chips (i.e. INK_QA and PRINTER_QA) will take place on at least a per power cycle and per page basis. Communication with the QA chips has three principal purposes: validating the presence of genuine QA chips (i.e the printer is using approved consumables), validation of the amount of ink remaining in the cartridge and authenticating the operating parameters for the printer. After each page has been printed, SoPEC is expected to communicate the number of dots fired per ink plane to the QA chipset. SoPEC may also initiate decoy communications with the QA chips from time to time.
0000Process:
0000<ul id="ul0069" list-style="none"><li id="ul0069-0001" num="0000"><ul id="ul0070" list-style="none"><li id="ul0070-0001" num="0956">When validating ink consumption SoPEC is expected to principally act as a conduit between the PRINTER_QA and INK_QA chips and to take certain actions (basically enable or disable printing and report status to host PC) based on the result. The communication channels are insecure but all traffic is signed to guarantee authenticity. <br /> Known Weaknesses </li><li id="ul0070-0002" num="0957">All communication to the QA chips is over the LSS interfaces using a serial communication protocol. This is open to observation and so the communication protocol could be reverse engineered. In this case both the PRINTER_QA and INK_QA chips could be replaced by impostor devices (e.g. a single FPGA) that successfully emulated the communication protocol. As this would require physical modification of each printer this is considered to be an acceptably low risk. Any messages that are not signed by one of the symmetric keys (such as the SoPEC_id_key) could be reverse engineered. The imposter device must also have access to the appropriate keys to crack the system.</li><li id="ul0070-0003" num="0958">If the secret keys in the QA chips are exposed or cracked then the system, or parts of it, is compromised. <br /> Assumptions: </li></ul></li><li id="ul0069-0002" num="0959">[1] The QA chips are not involved in the authentication of downloaded SoPEC code</li><li id="ul0069-0003" num="0960">[2] The QA chip in the ink cartridge (INK_QA) does not directly affect the operation of the cartridge in any way i.e. it does not inhibit the flow of ink etc.</li><li id="ul0069-0004" num="0961">[3] The INK_QA and PRINTER_QA chips are identical in their virgin state. They only become a INK_QA or PRINTER_QA after their FlashROM has been programmed. <br /> 10.5.2 Authentication of Downloaded Code in a Single SoPEC System <br /> Process: </li><li id="ul0069-0005" num="0962">1) SoPEC identification by activity on USB end-points 2–4 indicates it is the ISIMaster (unless the SoPEC CPU has explicitly disabled this function).</li><li id="ul0069-0006" num="0963">2) The program is downloaded to the embedded DRAM.</li><li id="ul0069-0007" num="0964">3) The CPU calculates a SHA-1 hash digest of the downloaded program.</li><li id="ul0069-0008" num="0965">4) The ResetSrc register in the CPR block is read to determine whether or not a power-on reset occurred.</li><li id="ul0069-0009" num="0966">5) If a power-on reset occurred the signature of the downloaded code (which needs to be in a known location such as the first or last N bytes of the downloaded code) is decrypted using the Silverbrook public boot0key stored in ROM. This decrypted signature is the expected SHA-1 hash of the accompanying program. The encryption algorithm is likely to be a public key algorithm such as RSA. If a power-on reset did not occur then the expected SHA-1 hash is retrieved from the PSS and the compute intensive decryption is not required.</li><li id="ul0069-0010" num="0967">6) The calculated and expected hash values are compared and if they match then the programs authenticity has been verified.</li><li id="ul0069-0011" num="0968">7) If the hash values do not match then the host PC is notified of the failure and the SoPEC will await a new program download.</li><li id="ul0069-0012" num="0969">8) If the hash values match then the CPU starts executing the downloaded program.</li><li id="ul0069-0013" num="0970">9) If, as is very likely, the downloaded program wishes to download subsequent programs (such as OEM code) it is responsible for ensuring the authenticity of everything it downloads. The downloaded program may contain public keys that are used to authenticate subsequent downloads, thus forming a hierarchy of authentication. The SoPEC ROM does not control these authentications—it is solely concerned with verifying that the first program downloaded has come from a trusted source.</li><li id="ul0069-0014" num="0971">10) At some subsequent point OEM code starts executing. The Silverbrook supervisor code acts as an O/S to the OEM user mode code. The OEM code must access most SoPEC functionality via system calls to the Silverbrook code.</li><li id="ul0069-0015" num="0972">11) The OEM code is expected to perform some simple ‘turn on the lights’ tasks after which the host PC is informed that the printer is ready to print and the Start Printing use case comes into play. <br /> Known Weaknesses: <ul id="ul0071" list-style="none"><li id="ul0071-0001" num="0973">If the Silverbrook private boot0key is exposed or cracked then the system is seriously compromised. A ROM mask change would be required to reprogram the boot0key. <br /> 10.5.3 Authentication of Downloaded Code in a Multi-SoPEC System <br /> 10.5.3.1 ISIMaster SoPEC Process: </li></ul></li><li id="ul0069-0016" num="0974">1) SoPEC identification by activity on USB end-points 2–4 indicates it is the ISIMaster.</li><li id="ul0069-0017" num="0975">2) The SCB is configured to broadcast the data received from the host PC.</li><li id="ul0069-0018" num="0976">3) The program is downloaded to the embedded DRAM and broadcasted to all ISISlave SoPECs over the ISI.</li><li id="ul0069-0019" num="0977">4) The CPU calculates a SHA-1 hash digest of the downloaded program.</li><li id="ul0069-0020" num="0978">5) The ResetSrc register in the CPR block is read to determine whether or not a power-on reset occurred.</li><li id="ul0069-0021" num="0979">6) If a power-on reset occurred the signature of the downloaded code (which needs to be in a known location such as the first or last N bytes of the downloaded code) is decrypted using the Silverbrook public boot0key stored in ROM. This decrypted signature is the expected SHA-1 hash of the accompanying program. The encryption algorithm is likely to be a public key algorithm such as RSA. If a power-on reset did not occur then the expected SHA-1 hash is retrieved from the PSS and the compute intensive decryption is not required.</li><li id="ul0069-0022" num="0980">7) The calculated and expected hash values are compared and if they match then the programs authenticity has been verified.</li><li id="ul0069-0023" num="0981">8) If the hash values do not match then the host PC is notified of the failure and the SoPEC will await a new program download.</li><li id="ul0069-0024" num="0982">9) If the hash values match then the CPU starts executing the downloaded program.</li><li id="ul0069-0025" num="0983">10) It is likely that the downloaded program will poll each ISISlave SoPEC for the result of its authentication process and to determine the number of slaves present and their ISIIds.</li><li id="ul0069-0026" num="0984">11) If any ISISlave SoPEC reports a failed authentication then the ISIMaster communicates this to the host PC and the SoPEC will await a new program download.</li><li id="ul0069-0027" num="0985">12) If all ISISlaves report successful authentication then the downloaded program is responsible for the downloading, authentication and distribution of subsequent programs within the multi-SoPEC system.</li><li id="ul0069-0028" num="0986">13) At some subsequent point OEM code starts executing. The Silverbrook supervisor code acts as an O/S to the OEM user mode code. The OEM code must access most SoPEC functionality via system calls to the Silverbrook code.</li><li id="ul0069-0029" num="0987">14) The OEM code is expected to perform some simple ‘turn on the lights’ tasks after which the master SoPEC determines that all SoPECs are ready to print. The host PC is informed that the printer is ready to print and the Start Printing use case comes into play. <br /> 10.5.3.2 ISISlave SoPEC Process: </li><li id="ul0069-0030" num="0988">1) When the CPU comes out of reset the SCB will be in slave mode, and the SCB is already configured to receive data from both the ISI and USB.</li><li id="ul0069-0031" num="0989">2) The program is downloaded (via ISI or USB) to embedded DRAM.</li><li id="ul0069-0032" num="0990">3) The CPU calculates a SHA-1 hash digest of the downloaded program.</li><li id="ul0069-0033" num="0991">4) The ResetSrc register in the CPR block is read to determine whether or not a power-on reset occurred.</li><li id="ul0069-0034" num="0992">5) If a power-on reset occurred the signature of the downloaded code (which needs to be in a known location such as the first or last N bytes of the downloaded code) is decrypted using the Silverbrook public boot0key stored in ROM. This decrypted signature is the expected SHA-1 hash of the accompanying program. The encryption algorithm is likely to be a public key algorithm such as RSA. If a power-on reset did not occur then the expected SHA-1 hash is retrieved from the PSS and the compute intensive decryption is not required.</li><li id="ul0069-0035" num="0993">6) The calculated and expected hash values are compared and if they match then the programs authenticity has been verified.</li><li id="ul0069-0036" num="0994">7) If the hash values do not match, then the ISISlave device will await a new program again</li><li id="ul0069-0037" num="0995">8) If the hash values match then the CPU starts executing the downloaded program.</li><li id="ul0069-0038" num="0996">9) It is likely that the downloaded program will communicate the result of its authentication process to the ISIMaster. The downloaded program is responsible for determining the SoPECs ISIID, receiving and authenticating any subsequent programs.</li><li id="ul0069-0039" num="0997">10) At some subsequent point OEM code starts executing. The Silverbrook supervisor code acts as an O/S to the OEM user mode code. The OEM code must access most SoPEC functionality via system calls to the Silverbrook code.</li><li id="ul0069-0040" num="0998">11) The OEM code is expected to perform some simple ‘turn on the lights’ tasks after which the master SoPEC is informed that this slave is ready to print. The Start Printing use case then comes into play. <br /> Known Weaknesses <ul id="ul0072" list-style="none"><li id="ul0072-0001" num="0999">If the Silverbrook private boot0key is exposed or cracked then the system is seriously compromised.</li><li id="ul0072-0002" num="1000">ISI is an open interface i.e. messages sent over the ISI are in the clear. The communication channels are insecure but all traffic is signed to guarantee authenticity. As all communication over the ISI is controlled by Supervisor code on both the ISIMaster and ISISlave then this also provides some protection against software attacks. <br /> 10.5.4 Authentication and Upgrade of Operating Parameters for a Printer </li></ul></li></ul>
1001The SoPEC IC will be used in a range of printers with different capabilities (e.g. A3/A4 printing, printing speed, resolution etc.). It is expected that some printers will also have a software upgrade capability which would allow a user to purchase a license that enables an upgrade in their printer's capabilities (such as print speed). To facilitate this it must be possible to securely store the operating parameters in the PRINTER_QA chip, to securely communicate these parameters to the SoPEC and to securely reprogram the parameters in the event of an upgrade. Note that each printing SoPEC (as opposed to a SoPEC that is only used for the storage of data) will have its own PRINTER_QA chip (or at least access to a PRINTER_QA that contains the SoPEC's SoPEC_id_key). Therefore both ISIMaster and ISISlave SoPECs will need to authenticate operating parameters.
0000Process:
0000<ul id="ul0073" list-style="none"><li id="ul0073-0001" num="1002">1) Program code is downloaded and authenticated as described in sections 10.5.2 and 10.5.3 above.</li><li id="ul0073-0002" num="1003">2) The program code has a function to create the SoPEC_id_key from the unique SoPEC_id that was programmed when the SoPEC was manufactured.</li><li id="ul0073-0003" num="1004">3) The SoPEC retrieves the signed operating parameters from its PRINTER_QA chip. The PRINTER_QA chip uses the SoPEC_id_key (which is stored as part of the pairing process executed during printhead assembly manufacture & test) to sign the operating parameters which are appended with a random number to thwart replay attacks.</li><li id="ul0073-0004" num="1005">4) The SoPEC checks the signature of the operating parameters using its SoPEC_id_key. If this signature authentication process is successful then the operating parameters are considered valid and the overall boot process continues. If not the error is reported to the host PC.</li><li id="ul0073-0005" num="1006">5) Operating parameters may also be set or upgraded using a second key, the PrintEngineLicense_key, which is stored on the PRINTER_QA and used to authenticate the change in operating parameters. <br /> Known Weaknesses: <ul id="ul0074" list-style="none"><li id="ul0074-0001" num="1007">It may be possible to retrieve the unique SoPEC_id by placing the SoPEC in test mode and scanning it out. It is certainly possible to obtain it by reverse engineering the device. Either way the SoPEC_id (and by extension the SoPEC_id_key) so obtained is valid only for that specific SoPEC and so printers may only be compromised one at a time by parties with the appropriate specialised equipment. Furthermore even if the SoPEC_id is compromised, the other keys in the system, which protect the authentication of consumables and of program code, are unaffected. <br /> 10.6 Miscellaneous Use Cases </li></ul></li></ul>
1008There are many miscellaneous use cases such as the following examples. Software running on the SoPEC CPU or host will decide on what actions to take in these scenarios.
000010.6.1 Disconnect/Re-connect of QA Chips.
0000<ul id="ul0075" list-style="none"><li id="ul0075-0001" num="1009">1) Disconnect of a QA chip between documents or if ink runs out mid-document.</li><li id="ul0075-0002" num="1010">2) Re-connect of a QA chip once authenticated e.g. ink cartridge replacement should allow the system to resume and print the next document <br /> 10.6.2 Page Arrives Before Print Ready Interrupt. </li><li id="ul0075-0003" num="1011">1) Engage clutch to stop paper until print ready interrupt occurs. <br /> 10.6.3 Dead-nozzle Table Upgrade </li></ul>
1012This sequence is typically performed when dead nozzle information needs to be updated by performing a printhead dead nozzle test. <ul id="ul0076" list-style="none"><li id="ul0076-0001" num="1013">1) Run printhead nozzle test sequence</li><li id="ul0076-0002" num="1014">2) Either host or SoPEC CPU converts dead nozzle information into dead nozzle table.</li><li id="ul0076-0003" num="1015">3) Store dead nozzle table on host.</li><li id="ul0076-0004" num="1016">4) Write dead nozzle table to SoPEC DRAM. <br /> 10.7 Failure Mode Use Cases <br /> 10.7.1 System Errors and Security Violations </li></ul>
1017System errors and security violations are reported to the SoPEC CPU and host. Software running on the SoPEC CPU or host will then decide what actions to take.
1018Silverbrook code authentication failure. <ul id="ul0077" list-style="none"><li id="ul0077-0001" num="1019">1) Notify host PC of authentication failure.</li><li id="ul0077-0002" num="1020">2) Abort print run.</li></ul>
1021OEM code authentication failure. <ul id="ul0078" list-style="none"><li id="ul0078-0001" num="1022">1) Notify host PC of authentication failure.</li><li id="ul0078-0002" num="1023">2) Abort print run.</li></ul>
1024Invalid QA chip(s). <ul id="ul0079" list-style="none"><li id="ul0079-0001" num="1025">1) Report to host PC.</li><li id="ul0079-0002" num="1026">2) Abort print run.</li></ul>
1027MMU security violation interrupt. <ul id="ul0080" list-style="none"><li id="ul0080-0001" num="1028">1) This is handled by exception handler.</li><li id="ul0080-0002" num="1029">2) Report to host PC</li><li id="ul0080-0003" num="1030">3) Abort print run.</li></ul>
1031Invalid address interrupt from PCU. <ul id="ul0081" list-style="none"><li id="ul0081-0001" num="1032">1) This is handled by exception handler.</li><li id="ul0081-0002" num="1033">2) Report to host PC.</li><li id="ul0081-0003" num="1034">3) Abort print run.</li></ul>
1035Watchdog timer interrupt. <ul id="ul0082" list-style="none"><li id="ul0082-0001" num="1036">1) This is handled by exception handler.</li><li id="ul0082-0002" num="1037">2) Report to host PC.</li><li id="ul0082-0003" num="1038">3) Abort print run.</li></ul>
1039Host PC does not acknowledge message that SoPEC is about to power down. <ul id="ul0083" list-style="none"><li id="ul0083-0001" num="1040">1) Power down anyway. <br /> 10.7.2 Printing Errors </li></ul>
1041Printing errors are reported to the SoPEC CPU and host. Software running on the host or SoPEC CPU will then decide what actions to take.
1042Insufficient space available in SoPEC compressed band-store to download a band. <ul id="ul0084" list-style="none"><li id="ul0084-0001" num="1043">1) Report to the host PC.</li></ul>
1044Insufficient ink to print. <ul id="ul0085" list-style="none"><li id="ul0085-0001" num="1045">1) Report to host PC.</li></ul>
1046Page not downloaded in time while printing. <ul id="ul0086" list-style="none"><li id="ul0086-0001" num="1047">1) Buffer underrun interrupt will occur.</li><li id="ul0086-0002" num="1048">2) Report to host PC and abort print run.</li></ul>
1049JPEG decoder error interrupt. <ul id="ul0087" list-style="none"><li id="ul0087-0001" num="1050">1) Report to host PC. <br /> CPU Subsystem <br /> 11 Central Processing Unit (CPU) <br /> 11.1 Overview </li></ul>
1051The CPU block consists of the CPU core, MMU, cache and associated logic. The principal tasks for the program running on the CPU to fulfill in the system are:
0000Communications:
0000<ul id="ul0088" list-style="none"><li id="ul0088-0001" num="0000"><ul id="ul0089" list-style="none"><li id="ul0089-0001" num="1052">Control the flow of data from the USB interface to the DRAM and ISI</li><li id="ul0089-0002" num="1053">Communication with the host via USB or ISI</li><li id="ul0089-0003" num="1054">Running the USB device driver <br /> PEP Subsystem Control: </li><li id="ul0089-0004" num="1055">Page and band header processing (may possibly be performed on host PC)</li><li id="ul0089-0005" num="1056">Configure printing options on a per band, per page, per job or per power cycle basis</li><li id="ul0089-0006" num="1057">Initiate page printing operation in the PEP subsystem</li><li id="ul0089-0007" num="1058">Retrieve dead nozzle information from the printhead interface (PHI) and forward to the host PC</li><li id="ul0089-0008" num="1059">Select the appropriate firing pulse profile from a set of predefined profiles based on the printhead characteristics</li><li id="ul0089-0009" num="1060">Retrieve printhead temperature via the PHI <br /> Security: </li><li id="ul0089-0010" num="1061">Authenticate downloaded program code</li><li id="ul0089-0011" num="1062">Authenticate printer operating parameters</li><li id="ul0089-0012" num="1063">Authenticate consumables via the PRINTER_QA and INK_QA chips</li><li id="ul0089-0013" num="1064">Monitor ink usage</li><li id="ul0089-0014" num="1065">Isolation of OEM code from direct access to the system resources <br /> Other: </li><li id="ul0089-0015" num="1066">Drive the printer motors using the GPIO pins</li><li id="ul0089-0016" num="1067">Monitoring the status of the printer (paper jam, tray empty etc.)</li><li id="ul0089-0017" num="1068">Driving front panel LEDs</li><li id="ul0089-0018" num="1069">Perform post-boot initialisation of the SoPEC device</li><li id="ul0089-0019" num="1070">Memory management (likely to be in conjunction with the host PC)</li><li id="ul0089-0020" num="1071">Miscellaneous housekeeping tasks</li></ul></li></ul>
1072To control the Print Engine Pipeline the CPU is required to provide a level of performance at least equivalent to a 16-bit Hitachi H8-3664 microcontroller running at 16 MHz. An as yet undetermined amount of additional CPU performance is needed to perform the other tasks, as well as to provide the potential for such activity as Netpage page assembly and processing, RIPing etc. The extra performance required is dominated by the signature verification task and the SCB (including the USB) management task. An operating system is not required at present. A number of CPU cores have been evaluated and the LEON P1754 is considered to be the most appropriate solution. A diagram of the CPU block is shown in <figref idref="DRAWINGS">FIG. 15</figref> below.
000011.2 Definitions of I/Os
1073<tables id="TABLE-US-00014" num="00014"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="273pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 14</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>CPU Subsystem I/Os</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="154pt" align="left" /><tbody valign="top"><row><entry>Port name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="273pt" align="left" /><tbody valign="top"><row><entry>Clocks and Resets</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="154pt" align="left" /><tbody valign="top"><row><entry>prst_n</entry><entry>1</entry><entry>In</entry><entry>Global reset. Synchronous to pclk, active low.</entry></row><row><entry>Pclk</entry><entry>1</entry><entry>In</entry><entry>Global clock</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="273pt" align="left" /><tbody valign="top"><row><entry>CPU to DIU DRAM interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="154pt" align="left" /><tbody valign="top"><row><entry>cpu_adr[21:2]</entry><entry>20</entry><entry>Out</entry><entry>Address bus for both DRAM and peripheral</entry></row><row><entry /><entry /><entry /><entry>access</entry></row><row><entry>cpu_dataout[31:0]</entry><entry>32</entry><entry>Out</entry><entry>Data out to both DRAM and peripheral devices.</entry></row><row><entry /><entry /><entry /><entry>This should be driven at the same time as the</entry></row><row><entry /><entry /><entry /><entry>cpu_adr and request signals.</entry></row><row><entry>dram_cpu_data[255:0]</entry><entry>256</entry><entry>In</entry><entry>Read data from the DRAM</entry></row><row><entry>cpu_diu_rreq</entry><entry>1</entry><entry>Out</entry><entry>Read request to the DIU DRAM</entry></row><row><entry>diu_cpu_rack</entry><entry>1</entry><entry>In</entry><entry>Acknowledge from DIU that read request has</entry></row><row><entry /><entry /><entry /><entry>been accepted.</entry></row><row><entry>diu_cpu_rvalid</entry><entry>1</entry><entry>In</entry><entry>Signal from DIU telling SoPEC Unit that valid read</entry></row><row><entry /><entry /><entry /><entry>data is on the dram_cpu_data bus</entry></row><row><entry>cpu_diu_wdatavalid</entry><entry>1</entry><entry>Out</entry><entry>Signal from the CPU to the DIU indicating that the</entry></row><row><entry /><entry /><entry /><entry>data currently on the cpu_diu_wdata bus is valid</entry></row><row><entry /><entry /><entry /><entry>and should be committed to the DIU posted write</entry></row><row><entry /><entry /><entry /><entry>buffer</entry></row><row><entry>diu_cpu_write_rdy</entry><entry>1</entry><entry>In</entry><entry>Signal from the DIU indicating that the posted</entry></row><row><entry /><entry /><entry /><entry>write buffer is empty</entry></row><row><entry>cpu_diu_wdadr[21:4]</entry><entry>18</entry><entry>Out</entry><entry>Write address bus to the DIU</entry></row><row><entry>cpu_diu_wdata[127:0]</entry><entry>128</entry><entry>Out</entry><entry>Write data bus to the DIU</entry></row><row><entry>cpu_diu_wmask[15:0]</entry><entry>16</entry><entry>Out</entry><entry>Write mask for the cpu_diu_wdata bus. Each bit</entry></row><row><entry /><entry /><entry /><entry>corresponds to a byte of the 128-bit</entry></row><row><entry /><entry /><entry /><entry>cpu_diu_wdata bus.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="273pt" align="left" /><tbody valign="top"><row><entry>CPU to peripheral blocks</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="154pt" align="left" /><tbody valign="top"><row><entry>cpu_rwn</entry><entry>1</entry><entry>Out</entry><entry>Common read/not-write signal from the CPU</entry></row><row><entry>cpu_acode[1:0]</entry><entry>2</entry><entry>Out</entry><entry>CPU access code signals.</entry></row><row><entry /><entry /><entry /><entry>cpu_acode[0] - Program (0)/Data (1) access</entry></row><row><entry /><entry /><entry /><entry>cpu_acode[1] - User (0)/Supervisor (1) access</entry></row><row><entry>cpu_cpr_sel</entry><entry>1</entry><entry>Out</entry><entry>CPR block select.</entry></row><row><entry>cpr_cpu_rdy</entry><entry>1</entry><entry>In</entry><entry>Ready signal to the CPU. When cpr_cpu_rdy is</entry></row><row><entry /><entry /><entry /><entry>high it indicates the last cycle of the access. For a</entry></row><row><entry /><entry /><entry /><entry>write cycle this means cpu_dataout has been</entry></row><row><entry /><entry /><entry /><entry>registered by the CPR block and for a read cycle</entry></row><row><entry /><entry /><entry /><entry>this means the data on cpr_cpu_data is valid.</entry></row><row><entry>cpr_cpu_berr</entry><entry>1</entry><entry>In</entry><entry>CPR bus error signal to the CPU.</entry></row><row><entry>cpr_cpu_data[31:0]</entry><entry>32</entry><entry>In</entry><entry>Read data bus from the CPR block</entry></row><row><entry>cpu_gpio_sel</entry><entry>1</entry><entry>Out</entry><entry>GPIO block select.</entry></row><row><entry>gpio_cpu_rdy</entry><entry>1</entry><entry>In</entry><entry>GPIO ready signal to the CPU.</entry></row><row><entry>gpio_cpu_berr</entry><entry>1</entry><entry>In</entry><entry>GPIO bus error signal to the CPU.</entry></row><row><entry>gpio_cpu_data[31:0]</entry><entry>32</entry><entry>In</entry><entry>Read data bus from the GPIO block</entry></row><row><entry>cpu_icu_sel</entry><entry>1</entry><entry>Out</entry><entry>ICU block select.</entry></row><row><entry>icu_cpu_rdy</entry><entry>1</entry><entry>In</entry><entry>ICU ready signal to the CPU.</entry></row><row><entry>icu_cpu_berr</entry><entry>1</entry><entry>In</entry><entry>ICU bus error signal to the CPU.</entry></row><row><entry>icu_cpu_data[31:0]</entry><entry>32</entry><entry>In</entry><entry>Read data bus from the ICU block</entry></row><row><entry>cpu_lss_sel</entry><entry>1</entry><entry>Out</entry><entry>LSS block select.</entry></row><row><entry>lss_cpu_rdy</entry><entry>1</entry><entry>In</entry><entry>LSS ready signal to the CPU.</entry></row><row><entry>lss_cpu_berr</entry><entry>1</entry><entry>In</entry><entry>LSS bus error signal to the CPU.</entry></row><row><entry>lss_cpu_data[31:0]</entry><entry>32</entry><entry>In</entry><entry>Read data bus from the LSS block</entry></row><row><entry>cpu_pcu_sel</entry><entry>1</entry><entry>Out</entry><entry>PCU block select.</entry></row><row><entry>pcu_cpu_rdy</entry><entry>1</entry><entry>In</entry><entry>PCU ready signal to the CPU.</entry></row><row><entry>pcu_cpu_berr</entry><entry>1</entry><entry>In</entry><entry>PCU bus error signal to the CPU.</entry></row><row><entry>pcu_cpu_data[31:0]</entry><entry>32</entry><entry>In</entry><entry>Read data bus from the PCU block</entry></row><row><entry>cpu_scb_sel</entry><entry>1</entry><entry>Out</entry><entry>SCB block select.</entry></row><row><entry>scb_cpu_rdy</entry><entry>1</entry><entry>In</entry><entry>SCB ready signal to the CPU.</entry></row><row><entry>scb_cpu_berr</entry><entry>1</entry><entry>In</entry><entry>SCB bus error signal to the CPU.</entry></row><row><entry>scb_cpu_data[31:0]</entry><entry>32</entry><entry>In</entry><entry>Read data bus from the SCB block</entry></row><row><entry>cpu_tim_sel</entry><entry>1</entry><entry>Out</entry><entry>Timers block select.</entry></row><row><entry>tim_cpu_rdy</entry><entry>1</entry><entry>In</entry><entry>Timers block ready signal to the CPU.</entry></row><row><entry>tim_cpu_berr</entry><entry>1</entry><entry>In</entry><entry>Timers bus error signal to the CPU.</entry></row><row><entry>tim_cpu_data[31:0]</entry><entry>32</entry><entry>In</entry><entry>Read data bus from the Timers block</entry></row><row><entry>cpu_rom_sel</entry><entry>1</entry><entry>Out</entry><entry>ROM block select.</entry></row><row><entry>rom_cpu_rdy</entry><entry>1</entry><entry>In</entry><entry>ROM block ready signal to the CPU.</entry></row><row><entry>rom_cpu_berr</entry><entry>1</entry><entry>In</entry><entry>ROM bus error signal to the CPU.</entry></row><row><entry>rom_cpu_data[31:0]</entry><entry>32</entry><entry>In</entry><entry>Read data bus from the ROM block</entry></row><row><entry>cpu_pss_sel</entry><entry>1</entry><entry>Out</entry><entry>PSS block select.</entry></row><row><entry>pss_cpu_rdy</entry><entry>1</entry><entry>In</entry><entry>PSS block ready signal to the CPU.</entry></row><row><entry>pss_cpu_berr</entry><entry>1</entry><entry>In</entry><entry>PSS bus error signal to the CPU.</entry></row><row><entry>pss_cpu_data[31:0]</entry><entry>32</entry><entry>In</entry><entry>Read data bus from the PSS block</entry></row><row><entry>cpu_diu_sel</entry><entry>1</entry><entry>Out</entry><entry>DIU register block select.</entry></row><row><entry>diu_cpu_rdy</entry><entry>1</entry><entry>In</entry><entry>DIU register block ready signal to the CPU.</entry></row><row><entry>diu_cpu_berr</entry><entry>1</entry><entry>In</entry><entry>DIU bus error signal to the CPU.</entry></row><row><entry>diu_cpu_data[31:0]</entry><entry>32</entry><entry>In</entry><entry>Read data bus from the DIU block</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="273pt" align="left" /><tbody valign="top"><row><entry>Interrupt signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="154pt" align="left" /><tbody valign="top"><row><entry>icu_cpu_ilevel[3:0]</entry><entry>3</entry><entry>In</entry><entry>An interrupt is asserted by driving the appropriate</entry></row><row><entry /><entry /><entry /><entry>priority level on icu_cpu_ilevel. These signals</entry></row><row><entry /><entry /><entry /><entry>must remain asserted until the CPU executes an</entry></row><row><entry /><entry /><entry /><entry>interrupt acknowledge cycle.</entry></row><row><entry /><entry>3</entry><entry>Out</entry><entry>Indicates the level of the interrupt the CPU is</entry></row><row><entry /><entry /><entry /><entry>acknowledging when cpu_iack is high</entry></row><row><entry>cpu_iack</entry><entry>1</entry><entry>Out</entry><entry>Interrupt acknowledge signal. The exact timing</entry></row><row><entry /><entry /><entry /><entry>depends on the CPU core implementation</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="273pt" align="left" /><tbody valign="top"><row><entry>Debug signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="154pt" align="left" /><tbody valign="top"><row><entry>diu_cpu_debug_valid</entry><entry>1</entry><entry>In</entry><entry>Signal indicating the data on the diu_cpu_data</entry></row><row><entry /><entry /><entry /><entry>bus is valid debug data.</entry></row><row><entry>tim_cpu_debug_valid</entry><entry>1</entry><entry>In</entry><entry>Signal indicating the data on the tim_cpu_data</entry></row><row><entry /><entry /><entry /><entry>bus is valid debug data.</entry></row><row><entry>scb_cpu_debug_valid</entry><entry>1</entry><entry>In</entry><entry>Signal indicating the data on the scb_cpu_data</entry></row><row><entry /><entry /><entry /><entry>bus is valid debug data.</entry></row><row><entry>pcu_cpu_debug_valid</entry><entry>1</entry><entry>In</entry><entry>Signal indicating the data on the pcu_cpu_data</entry></row><row><entry /><entry /><entry /><entry>bus is valid debug data.</entry></row><row><entry>lss_cpu_debug_valid</entry><entry>1</entry><entry>In</entry><entry>Signal indicating the data on the lss_cpu_data bus</entry></row><row><entry /><entry /><entry /><entry>is valid debug data.</entry></row><row><entry>icu_cpu_debug_valid</entry><entry>1</entry><entry>In</entry><entry>Signal indicating the data on the icu_cpu_data bus</entry></row><row><entry /><entry /><entry /><entry>is valid debug data.</entry></row><row><entry>gpio_cpu_debug_valid</entry><entry>1</entry><entry>In</entry><entry>Signal indicating the data on the gpio_cpu_data</entry></row><row><entry /><entry /><entry /><entry>bus is valid debug data.</entry></row><row><entry>cpr_cpu_debug_valid</entry><entry>1</entry><entry>In</entry><entry>Signal indicating the data on the cpr_cpu_data</entry></row><row><entry /><entry /><entry /><entry>bus is valid debug data.</entry></row><row><entry>debug_data_out</entry><entry>32</entry><entry>Out</entry><entry>Output debug data to be muxed on to the GPIO &</entry></row><row><entry /><entry /><entry /><entry>PHI pins</entry></row><row><entry>debug_data_valid</entry><entry>1</entry><entry>Out</entry><entry>Debug valid signal indicating the validity of the</entry></row><row><entry /><entry /><entry /><entry>data on debug_data_out. This signal is used in all</entry></row><row><entry /><entry /><entry /><entry>debug configurations</entry></row><row><entry>debug_cntrl</entry><entry>33</entry><entry>Out</entry><entry>Control signal for each PHI bound debug data line</entry></row><row><entry /><entry /><entry /><entry>indicating whether or not the debug data should</entry></row><row><entry /><entry /><entry /><entry>be selected by the pin mux</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 11.3 Realtime Requirements
1074The SoPEC realtime requirements have yet to be fully determined but they may be split into three categories: hard, firm and soft
000011.3.1 Hard Realtime Requirements
1075Hard requirements are tasks that must be completed before a certain deadline or failure to do so will result in an error perceptible to the user (printing stops or functions incorrectly). There are three hard realtime tasks: <ul id="ul0090" list-style="none"><li id="ul0090-0001" num="0000"><ul id="ul0091" list-style="none"><li id="ul0091-0001" num="1076">Motor control: The motors which feed the paper through the printer at a constant speed during printing are driven directly by the SoPEC device. Four periodic signals with different phase relationships need to be generated to ensure the paper travels smoothly through the printer. The generation of these signals is handled by the GPIO hardware (see section 13.2 for more details) but the CPU is responsible for enabling these signals (i.e. to start or stop the motors) and coordinating the movement of the paper with the printing operation of the printhead.</li><li id="ul0091-0002" num="1077">Buffer management: Data enters the SoPEC via the SCB at an uneven rate and is consumed by the PEP subsystem at a different rate. The CPU is responsible for managing the DRAM buffers to ensure that neither overrun nor underrun occur. This buffer management is likely to be performed under the direction of the host.</li><li id="ul0091-0003" num="1078">Band processing: In certain cases PEP registers may need to be updated between bands. As the timing requirements are most likely too stringent to be met by direct CPU writes to the PCU a more likely scenario is that a set of shadow registers will programmed in the compressed page units before the current band is finished, copied to band related registers by the finished band signals and the processing of the next band will continue immediately. An alternative solution is that the CPU will construct a DRAM based set of commands (see section 21.8.5 for more details) that can be executed by the PCU. The task for the CPU here is to parse the band headers stored in DRAM and generate a DRAM based set of commands for the next number of bands. The location of the DRAM based set of commands must then be written to the PCU before the current band has been processed by the PEP subsystem. It is also conceivable (but currently considered unlikely) that the host PC could create the DRAM based commands. In this case the CPU will only be required to point the PCU to the correct location in DRAM to execute commands from. <br /> 11.3.2 Firm Requirements </li></ul></li></ul>
1079Firm requirements are tasks that should be completed by a certain time or failure to do so will result in a degradation of performance but not an error. The majority of the CPU tasks for SoPEC fall into this category including all interactions with the QA chips, program authentication, page feeding, configuring PEP registers for a page or job, determining the firing pulse profile, communication of printer status to the host over the USB and the monitoring of ink usage. The authentication of downloaded programs and messages will be the most compute intensive operation the CPU will be required to perform. Initial investigations indicate that the LEON processor, running at 160 MHz, will easily perform three authentications in under a second.
1080<tables id="TABLE-US-00015" num="00015"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 15</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Expected firm requirements</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="119pt" align="left" /><colspec colname="2" colwidth="84pt" align="center" /><tbody valign="top"><row><entry /><entry>Requirement</entry><entry>Duration</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="119pt" align="left" /><colspec colname="2" colwidth="42pt" align="right" /><colspec colname="3" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry>Power-on to start of printing first</entry><entry>~8</entry><entry>secs ??</entry></row><row><entry /><entry>page [USB and slave SoPEC</entry></row><row><entry /><entry>enumeration, 3 or more RSA signature</entry></row><row><entry /><entry>verifications, code and compressed</entry></row><row><entry /><entry>page data download and chip</entry></row><row><entry /><entry>initialisation]</entry></row><row><entry /><entry>Wake-up from sleep mode to start</entry><entry>~2</entry><entry>secs</entry></row><row><entry /><entry>printing [3 or more SHA-1/RSA</entry></row><row><entry /><entry>operations, code and compressed page</entry></row><row><entry /><entry>data download and chip re-</entry></row><row><entry /><entry>initialisation</entry></row><row><entry /><entry>Authenticate ink usage in the printer</entry><entry>~0.5</entry><entry>secs</entry></row><row><entry /><entry>Determining firing pulse profile</entry><entry>~0.1</entry><entry>secs</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="119pt" align="left" /><colspec colname="2" colwidth="84pt" align="center" /><tbody valign="top"><row><entry /><entry>Page feeding, gap between pages</entry><entry>OEM dependent</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="119pt" align="left" /><colspec colname="2" colwidth="42pt" align="right" /><colspec colname="3" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry>Communication of printer status</entry><entry>~10</entry><entry>ms</entry></row><row><entry /><entry>to host PC</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="119pt" align="left" /><colspec colname="2" colwidth="84pt" align="center" /><tbody valign="top"><row><entry /><entry>Configuring PEP registers</entry><entry>??</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 11.3.3 Soft Requirements
1081Soft requirements are tasks that need to be done but there are only light time constraints on when they need to be done. These tasks are performed by the CPU when there are no pending higher priority tasks. As the SoPEC CPU is expected to be lightly loaded these tasks will mostly be executed soon after they are scheduled.
000011.4 Bus Protocols
1082As can be seen from <figref idref="DRAWINGS">FIG. 15</figref> above there are different buses in the CPU block and different protocols are used for each bus. There are three buses in operation:
000011.4.1 AHB Bus
1083The LEON CPU core uses an AMBA2.0 AHB bus to communicate with memory and peripherals (usually via an APB bridge). See the AMBA specification [38], section 5 of the LEON users manual [37] and section 11.6.6.1 of this document for more details.
000011.4.2 CPU to DIU Bus
1084This bus conforms to the DIU bus protocol described in Section 20.14.8. Note that the address bus used for DIU reads (i.e. cpu_adr(21:2)) is also that used for CPU subsystem with bus accesses while the write address bus (cpu_diu_wadr) and the read and write data buses (dram_cpu_data and cpu_diu_wdata) are private buses between the CPU and the DIU. The effective bus width differs between a read (256 bits) and a write (128 bits). As certain CPU instructions may require byte write access this will need to be supported by both the DRAM write buffer (in the AHB bridge) and the DIU. See section 11.6.6.1 for more details.
000011.4.3 CPU Subsystem Bus
1085For access to the on-chip peripherals a simple bus protocol is used. The MMU must first determine which particular block is being addressed (and that the access is a valid one) so that the appropriate block select signal can be generated. During a write access CPU write data is driven out with the address and block select signals in the first cycle of an access. The addressed slave peripheral responds by asserting its ready signal indicating that it has registered the write data and the access can complete. The write data bus is common to all peripherals and is also used for CPU writes to the embedded DRAM. A read access is initiated by driving the address and select signals during the first cycle of an access. The addressed slave responds by placing the read data on its bus and asserting its ready signal to indicate to the CPU that the read data is valid. Each block has a separate point-to-point data bus for read accesses to avoid the need for a tri-stateable bus. All peripheral accesses are 32-bit (Programming note: char or short C types should not be used to access peripheral registers). The use of the ready signal allows the accesses to be of variable length. In most cases accesses will complete in two cycles but three or four (or more) cycles accesses are likely for PEP blocks or IP blocks with a different native bus interface. All PEP blocks are accessed via the PCU which acts as a bridge. The PCU bus uses a similar protocol to the CPU subsystem bus but with the PCU as the bus master.
1086The duration of accesses to the PEP blocks is influenced by whether or not the PCU is executing commands from DRAM. As these commands are essentially register writes the CPU access will need to wait until the PCU bus becomes available when a register access has been completed. This could lead to the CPU being stalled for up to 4 cycles if it attempts to access PEP blocks while the PCU is executing a command. The size and probability of this penalty is sufficiently small to have any significant impact on performance.
1087In order to support user mode (i.e. OEM code) access to certain peripherals the CPU subsystem bus propagates the CPU function code signals (cpu_acode[1:0]). These signals indicate the type of address space (i.e. User/Supervisor and Program/Data) being accessed by the CPU for each access. Each peripheral must determine whether or not the CPU is in the correct mode to be granted access to its registers and in some cases (e.g. Timers and GPIO blocks) different access permissions can apply to different registers within the block. If the CPU is not in the correct mode then the violation is flagged by asserting the block's bus error signal (block_cpu_berr) with the same timing as its ready signal (block_cpu_rdy) which remains deasserted. When this occurs invalid read accesses should return 0 and write accesses should have no effect.
1088<figref idref="DRAWINGS">FIG. 16</figref> shows two examples of the peripheral bus protocol in action. A write to the LSS block from code running in supervisor mode is successfully completed. This is immediately followed by a read from a PEP block via the PCU from code running in user mode. As this type of access is not permitted the access is terminated with a bus error. The bus error exception processing then starts directly after this—no further accesses to the peripheral should be required as the exception handler should be located in the DRAM.
1089Each peripheral acts as a slave on the CPU subsystem bus and its behavior is described by the state machine in section 11.4.3.1
000011.4.3.1 CPU Subsystem Bus Slave State Machine
1090CPU subsystem bus slave operation is described by the state machine in <figref idref="DRAWINGS">FIG. 17</figref>. This state machine will be implemented in each CPU subsystem bus slave. The only new signals mentioned here are the valid_access and reg_available signals. The valid_access is determined by comparing the cpu_acode value with the block or register (in the case of a block that allow user access on a per register basis such as the GPIO block) access permissions and asserting valid_access if the permissions agree with the CPU mode. The reg_available signal is only required in the PCU or in blocks that are not capable of two-cycle access (e.g. blocks containing imported IP with different bus protocols). In these blocks the reg_available signal is an internal signal used to insert wait states (by delaying the assertion of block_cpu_rdy) until the CPU bus slave interface can gain access to the register.
1091When reading from a register that is less than 32 bits wide the CPU subsystems bus slave should return zeroes on the unused upper bits of the block_cpu_data bus.
1092To support debug mode the contents of the register selected for debug observation, debug_reg, are always output on the block_cpu_data bus whenever a read access is not taking place. See section
000011.8 for More Details of Debug Operation.
11.5 LEON CPU
1093The LEON processor is an open-source implementation of the IEEE-1754 standard (SPARC V8) instruction set. LEON is available from and actively supported by Gaisler Research (www.gaisler.com).
1094The following features of the LEON-2 processor will be utilised on SoPEC: <ul id="ul0092" list-style="none"><li id="ul0092-0001" num="0000"><ul id="ul0093" list-style="none"><li id="ul0093-0001" num="1095">IEEE-1754 (SPARC V8) compatible integer unit with 5-stage pipeline</li><li id="ul0093-0002" num="1096">Separate instruction and data cache (Harvard architecture). 1 kbyte direct mapped caches will be used for both.</li><li id="ul0093-0003" num="1097">Full implementation of AMBA-2.0 AHB on-chip bus</li></ul></li></ul>
1098The standard release of LEON incorporates a number of peripherals and support blocks which will not be included on SoPEC. The LEON core as used on SoPEC will consist of: 1) the LEON integer unit, 2) the instruction and data caches (currently 1 kB each), 3) the cache control logic, 4) the AHB interface and 5) possibly the AHB controller (although this functionality may be implemented in the LEON AHB bridge).
1099The version of the LEON database that the SoPEC LEON components will be sourced from is LEON2-1.0.7 although later versions may be used if they offer worthwhile functionality or bug fixes that affect the SoPEC design.
1100The LEON core will be clocked using the system clock, pclk, and reset using the prst_n_section[1] signal. The ICU will assert all the hardware interrupts using the protocol described in section 11.9.
1101The LEON hardware multipliers and floating-point unit are not required. SoPEC will use the recommended 8 register window configuration.
1102Further details of the SPARC V8 instruction set and the LEON processor can be found in [36] and [37] respectively.
000011.5.1 LEON Registers
1103Only two of the registers described in the LEON manual are implemented on SoPEC—the LEON configuration register and the Cache Control Register (CCR). The addresses of these registers are shown in Table 16. The configuration register bit fields are described below and the CCR is described in section 11.7.1.1.
000011.5.1.1 LEON Configuration Register
1104The LEON configuration register allows runtime software to determine the settings of LEONs various configuration options. This is a read-only register whose value for the SoPEC ASIC will be 0x1071<sub>—</sub>8C00. Further descriptions of many of the bitfileds can be found in the LEON manual. The values used for SoPEC are highlighted in bold for clarity.
1105<tables id="TABLE-US-00016" num="00016"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 16</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>LEON Configuration Register</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="35pt" align="center" /><colspec colname="3" colwidth="119pt" align="left" /><tbody valign="top"><row><entry /><entry>Field Name</entry><entry>bit(s)</entry><entry>Description</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row><row><entry /><entry>WriteProtection</entry><entry>1:0</entry><entry>Write protection type.</entry></row><row><entry /><entry /><entry /><entry>00 - none</entry></row><row><entry /><entry /><entry /><entry>01 - standard</entry></row><row><entry /><entry>PCICore</entry><entry>3:2</entry><entry>PCI core type</entry></row><row><entry /><entry /><entry /><entry>00 - none</entry></row><row><entry /><entry /><entry /><entry>01 - InSilicon</entry></row><row><entry /><entry /><entry /><entry>10 - ESA</entry></row><row><entry /><entry /><entry /><entry>11 - Other</entry></row><row><entry /><entry>FPUType</entry><entry>5:4</entry><entry>FPU type.</entry></row><row><entry /><entry /><entry /><entry>00 - none</entry></row><row><entry /><entry /><entry /><entry>01 - Meiko</entry></row><row><entry /><entry>MemStatus</entry><entry>6</entry><entry>0 - No memory status and failing</entry></row><row><entry /><entry /><entry /><entry>address register present</entry></row><row><entry /><entry /><entry /><entry>1 - Memory status and failing</entry></row><row><entry /><entry /><entry /><entry>address register present</entry></row><row><entry /><entry>Watchdog</entry><entry>7</entry><entry>0 - Watchdog timer not present</entry></row><row><entry /><entry /><entry /><entry>(Note this refers to the LEON</entry></row><row><entry /><entry /><entry /><entry>watchdog timer in the LEON timer</entry></row><row><entry /><entry /><entry /><entry>block).</entry></row><row><entry /><entry /><entry /><entry>1 - Watchdog timer present</entry></row><row><entry /><entry>UMUL/SMUL</entry><entry>8</entry><entry>0 - UMUL/SMUL instructions are</entry></row><row><entry /><entry /><entry /><entry>not implemented</entry></row><row><entry /><entry /><entry /><entry>1 - UMUL/SMUL instructions are</entry></row><row><entry /><entry /><entry /><entry>implemented</entry></row><row><entry /><entry>UDIV/SDIV</entry><entry>9</entry><entry>0 - UMUL/SMUL instructions are</entry></row><row><entry /><entry /><entry /><entry>not implemented</entry></row><row><entry /><entry /><entry /><entry>1 - UMUL/SMUL instructions are</entry></row><row><entry /><entry /><entry /><entry>implemented</entry></row><row><entry /><entry>DLSZ</entry><entry>11:10</entry><entry>Data cache line size in 32-bit</entry></row><row><entry /><entry /><entry /><entry>words:</entry></row><row><entry /><entry /><entry /><entry>00 - 1 word</entry></row><row><entry /><entry /><entry /><entry>01 - 2 words</entry></row><row><entry /><entry /><entry /><entry>10 - 4 words</entry></row><row><entry /><entry /><entry /><entry>11 - 8 words</entry></row><row><entry /><entry>DCSZ</entry><entry>14:12</entry><entry>Data cache size in kBbytes =</entry></row><row><entry /><entry /><entry /><entry>2<sup>DCSZ</sup>. SoPEC DCSZ = 0.</entry></row><row><entry /><entry>ILSZ</entry><entry>16:15</entry><entry>Instruction cache line size in</entry></row><row><entry /><entry /><entry /><entry>32-bit words:</entry></row><row><entry /><entry /><entry /><entry>00 - 1 word</entry></row><row><entry /><entry /><entry /><entry>01 - 2 words</entry></row><row><entry /><entry /><entry /><entry>10 - 4 words</entry></row><row><entry /><entry /><entry /><entry>11 - 8 words</entry></row><row><entry /><entry>ICSZ</entry><entry>19:17</entry><entry>Instruction cache size in</entry></row><row><entry /><entry /><entry /><entry>kBbytes = 2<sup>ICSZ</sup>. SoPEC ICSZ = 0.</entry></row><row><entry /><entry>RegWin</entry><entry>24:20</entry><entry>The implemented number of SPARC</entry></row><row><entry /><entry /><entry /><entry>register windows − 1.</entry></row><row><entry /><entry /><entry /><entry>SoPEC value = 7.</entry></row><row><entry /><entry>UMAC/SMAC</entry><entry>25</entry><entry>0 - UMAC/SMAC instructions are</entry></row><row><entry /><entry /><entry /><entry>not implemented</entry></row><row><entry /><entry /><entry /><entry>1 - UMAC/SMAC instructions are</entry></row><row><entry /><entry /><entry /><entry>implemented</entry></row><row><entry /><entry>Watchpoints</entry><entry>28:26</entry><entry>The implemented number of</entry></row><row><entry /><entry /><entry /><entry>hardware watchpoints. SoPEC</entry></row><row><entry /><entry /><entry /><entry>value = 4.</entry></row><row><entry /><entry>SDRAM</entry><entry>29</entry><entry>0 - SDRAM controller not</entry></row><row><entry /><entry /><entry /><entry>present</entry></row><row><entry /><entry /><entry /><entry>1 - SDRAM controller present</entry></row><row><entry /><entry>DSU</entry><entry>30</entry><entry>0 - Debug Support Unit not</entry></row><row><entry /><entry /><entry /><entry>present</entry></row><row><entry /><entry /><entry /><entry>1 - Debug Support Unit present</entry></row><row><entry /><entry>Reserved</entry><entry>31</entry><entry>Reserved. SoPEC value = 0.</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 11.6 Memory Management Unit (MMU)
1106Memory Management Units are typically used to protect certain regions of memory from invalid accesses, to perform address translation for a virtual memory system and to maintain memory page status (swapped-in, swapped-out or unmapped)
1107The SoPEC MMU is a much simpler affair whose function is to ensure that all regions of the SoPEC memory map are adequately protected. The MMU does not support virtual memory and physical addresses are used at all times. The SoPEC MMU supports a full 32-bit address space. The SoPEC memory map is depicted in <figref idref="DRAWINGS">FIG. 18</figref> below.
1108The MMU selects the relevant bus protocol and generates the appropriate control signals depending on the area of memory being accessed. The MMU is responsible for performing the address decode and generation of the appropriate block select signal as well as the selection of the correct block read bus during a read access. The MMU will need to support all of the bus transactions the CPU can produce including interrupt acknowledge cycles, aborted transactions etc. When an MMU error occurs (such as an attempt to access a supervisor mode only region when in user mode) a bus error is generated. While the LEON can recognise different types of bus error (e.g. data store error, instruction access error) it handles them in the same manner as it handles all traps i.e it will transfer control to a trap handler. No extra state information is be stored because of the nature of the trap. The location of the trap handler is contained in the TBR (Trap Base Register). This is the same mechanism as is used to handle interrupts.
000011.6.1 CPU-bus Peripherals Address Map
1109The address mapping for the peripherals attached to the CPU-bus is shown in Table 17 below. The MMU performs the decode of the high order bits to generate the relevant cpu_block_select signal. Apart from the PCU, which decodes the address space for the PEP blocks, each block only needs to decode as many bits of cpu_adr[11:2] as required to address all the registers within the block.
1110<tables id="TABLE-US-00017" num="00017"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 17</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>CPU-bus peripherals address map</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="126pt" align="left" /><tbody valign="top"><row><entry /><entry>Block_base</entry><entry>Address</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>ROM_base</entry><entry>0x0000_0000</entry></row><row><entry /><entry>MMU_base</entry><entry>0x0001_0000</entry></row><row><entry /><entry>TIM_base</entry><entry>0x0001_1000</entry></row><row><entry /><entry>LSS_base</entry><entry>0x0001_2000</entry></row><row><entry /><entry>GPIO_base</entry><entry>0x0001_3000</entry></row><row><entry /><entry>SCB_base</entry><entry>0x0001_4000</entry></row><row><entry /><entry>ICU_base</entry><entry>0x0001_5000</entry></row><row><entry /><entry>CPR_base</entry><entry>0x0001_6000</entry></row><row><entry /><entry>DIU_base</entry><entry>0x0001_7000</entry></row><row><entry /><entry>PSS_base</entry><entry>0x0001_8000</entry></row><row><entry /><entry>Reserved</entry><entry>0x0001_9000 to 0x0001_FFFF</entry></row><row><entry /><entry>PCU_base</entry><entry>0x0002_0000</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 11.6.2 DRAM Region Mapping
1111The embedded DRAM is broken into 8 regions, with each region defined by a lower and upper bound address and with its own access permissions.
1112The association of an area in the DRAM address space with a MMU region is completely under software control. Table 18 below gives one possible region mapping. Regions should be defined according to their access requirements and position in memory. Regions that share the same access requirements and that are contiguous in memory may be combined into a single region. The example below is purely for indicative purposes—real mappings are likely to differ significantly from this. Note that the RegionBottom and RegionTop fields in this example include the DRAM base address offset (0x4000<sub>—</sub>0000) which is not required when programming the RegionNTop and RegionNBottom registers. For more details, see 11.6.5.1 and 11.6.5.2.
1113<tables id="TABLE-US-00018" num="00018"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 18</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Example region mapping</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="35pt" align="center" /><colspec colname="2" colwidth="56pt" align="left" /><colspec colname="3" colwidth="56pt" align="left" /><colspec colname="4" colwidth="70pt" align="left" /><tbody valign="top"><row><entry>Region</entry><entry>RegionBottom</entry><entry>RegionTop</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>0</entry><entry>0x4000_0000</entry><entry>0x4000_0FFF</entry><entry>Silverbrook OS</entry></row><row><entry /><entry /><entry /><entry>(supervisor) data</entry></row><row><entry>1</entry><entry>0x4000_1000</entry><entry>0x4000_BFFF</entry><entry>Silverbrook OS</entry></row><row><entry /><entry /><entry /><entry>(supervisor) code</entry></row><row><entry>2</entry><entry>0x4000_C000</entry><entry>0x4000_C3FF</entry><entry>Silverbrook</entry></row><row><entry /><entry /><entry /><entry>(supervisor/user) data</entry></row><row><entry>3</entry><entry>0x4000_C400</entry><entry>0x4000_CFFF</entry><entry>Silverbrook</entry></row><row><entry /><entry /><entry /><entry>(supervisor/user) code</entry></row><row><entry>4</entry><entry>0x4026_D000</entry><entry>0x4026_D3FF</entry><entry>OEM (user) data</entry></row><row><entry>5</entry><entry>0x4026_D400</entry><entry>0x4026_DFFF</entry><entry>OEM (user) code</entry></row><row><entry>6</entry><entry>0x4027_E000</entry><entry>0x4027_FFFF</entry><entry>Shared Silverbrook/</entry></row><row><entry /><entry /><entry /><entry>OEM space</entry></row><row><entry>7</entry><entry>0x4000_D000</entry><entry>0x4026_CFFF</entry><entry>Compressed page store</entry></row><row><entry /><entry /><entry /><entry>(supervisor data)</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 11.6.3 Non-DRAM Regions
1114As shown in <figref idref="DRAWINGS">FIG. 18</figref> the DRAM occupies only 2.5 MBytes of the total 4 GB SoPEC address space. The non-DRAM regions of SoPEC are handled by the MMU as follows:
1115ROM (1x0000<sub>—</sub>000 to 1x0000_FFFF): The ROM block will control the access types allowed. The cpu_acode[1:0] signals will indicate the CPU mode and access type and the ROM block will assert rom_cpu_berr if an attempted access is forbidden. The protocol is described in more detail in section 11.4.3. The ROM block access permissions are hard wired to allow all read accesses except to the FuseChipID registers which may only be read in supervisor mode.
1116MMU Internal Registers (0x0001<sub>—</sub>0000 to 1x0001<sub>—</sub>0FFF): The MMU is responsible for controlling the accesses to its own internal registers and will only allow data reads and writes (no instruction fetches) from supervisor data space. All other accesses will result in the mmu_cpu_berr signal being asserted in accordance with the CPU native bus protocol.
1117CPU Subsystem Peripheral Registers (1x0001<sub>—</sub>1000 to 1x0001_FFFF): Each peripheral block will control the access types allowed. Every peripheral will allow supervisor data accesses (both read and write) and some blocks (e.g. Timers and GPIO) will also allow user data space accesses as outlined in the relevant chapters of this specification. Neither supervisor nor user instruction fetch accesses are allowed to any block as it is not possible to execute code from peripheral registers. The bus protocol is described in section 11.4.3.
1118PCU Mapped Registers (0x0002<sub>—</sub>0000 to 0x0002_BFFF): All of the PEP blocks registers which are accessed by the CPU via the PCU will inherit the access permissions of the PCU. These access permissions are hard wired to allow supervisor data accesses only and the protocol used is the same as for the CPU peripherals.
1119Unused address space (0x0002_C000 to 0x3FFF_FFFF and 0x4028<sub>—</sub>0000 to 1xFFFF_FFFF): All accesses to the unused portion of the address space will result in the mmu_cpu_berr signal being asserted in accordance with the CPU native bus protocol. These accesses will not propagate outside of the MMU i.e. no external access will be initiated.
000011.6.4 Reset Exception Vector and Reference Zero Traps
1120When a reset occurs the LEON processor starts executing code from address 0x0000<sub>—</sub>0000. A common software bug is zero-referencing or null pointer de-referencing (where the program attempts to access the contents of address 0x0000<sub>—</sub>0000). To assist software debug the MMU will assert a bus error every time the locations 0x0000<sub>—</sub>0000 to 0x0000<sub>—</sub>000F (i.e. the first 4 words of the reset trap) are accessed after the reset trap handler has legitimately been retrieved immediately after reset.
000011.6.5 MMU Configuration Registers
1121The MMU configuration registers include the RDU configuration registers and two LEON registers. Note that all the MMU configuration registers may only be accessed when the CPU is running in supervisor mode.
1122<tables id="TABLE-US-00019" num="00019"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="343pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 19</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>MMU Configuration Registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="70pt" align="left" /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="161pt" align="left" /><tbody valign="top"><row><entry>Address</entry><entry /><entry /><entry /><entry /></row><row><entry>offset from</entry></row><row><entry>MMU_base</entry><entry>Register</entry><entry>#bits</entry><entry>Reset</entry><entry>Description</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="70pt" align="left" /><colspec colname="3" colwidth="21pt" align="char" char="." /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="161pt" align="left" /><tbody valign="top"><row><entry>0x00</entry><entry>Region0Bottom[21:5]</entry><entry>17</entry><entry>0x0_0000</entry><entry>This register contains the physical address that</entry></row><row><entry /><entry /><entry /><entry /><entry>marks the bottom of region 0</entry></row><row><entry>0x04</entry><entry>Region0Top[21:5]</entry><entry>17</entry><entry>0xF_FFFF</entry><entry>This register contains the physical address that</entry></row><row><entry /><entry /><entry /><entry /><entry>marks the top of region 0. Region 0 covers the</entry></row><row><entry /><entry /><entry /><entry /><entry>entire address space after reset whereas all</entry></row><row><entry /><entry /><entry /><entry /><entry>other regions are zero-sized initially.</entry></row><row><entry>0x08</entry><entry>Region1Bottom[21:5]</entry><entry>17</entry><entry>0xF_FFFF</entry><entry>This register contains the physical address that</entry></row><row><entry /><entry /><entry /><entry /><entry>marks the bottom of region 1</entry></row><row><entry>0x0C</entry><entry>Region1Top[21:5]</entry><entry>17</entry><entry>0x0_0000</entry><entry>This register contains the physical address that</entry></row><row><entry /><entry /><entry /><entry /><entry>marks the top of region 1</entry></row><row><entry>0x10</entry><entry>Region2Bottom[21:5]</entry><entry>17</entry><entry>0xF_FFFF</entry><entry>This register contains the physical address that</entry></row><row><entry /><entry /><entry /><entry /><entry>marks the bottom of region 2</entry></row><row><entry>0x14</entry><entry>Region3Top[21:5]</entry><entry>17</entry><entry>0x0_0000</entry><entry>This register contains the physical address that</entry></row><row><entry /><entry /><entry /><entry /><entry>marks the top of region 2</entry></row><row><entry>0x18</entry><entry>Region3Bottom[21:5]</entry><entry>17</entry><entry>0xF_FFFF</entry><entry>This register contains the physical address that</entry></row><row><entry /><entry /><entry /><entry /><entry>marks the bottom of region 3</entry></row><row><entry>0x1C</entry><entry>Region3Top[21:5]</entry><entry>17</entry><entry>0x0_0000</entry><entry>This register contains the physical address that</entry></row><row><entry /><entry /><entry /><entry /><entry>marks the top of region 3</entry></row><row><entry>0x20</entry><entry>Region4Bottom[21:5]</entry><entry>17</entry><entry>0xF_FFFF</entry><entry>This register contains the physical address that</entry></row><row><entry /><entry /><entry /><entry /><entry>marks the bottom of region 4</entry></row><row><entry>0x24</entry><entry>Region4Top[21:5]</entry><entry>17</entry><entry>0x0_0000</entry><entry>This register contains the physical address that</entry></row><row><entry /><entry /><entry /><entry /><entry>marks the top of region 4</entry></row><row><entry>0x28</entry><entry>Region5Bottom[21:5]</entry><entry>17</entry><entry>0xF_FFFF</entry><entry>This register contains the physical address that</entry></row><row><entry /><entry /><entry /><entry /><entry>marks the bottom of region 5</entry></row><row><entry>0x2C</entry><entry>Region5Top[21:5]</entry><entry>17</entry><entry>0x0_0000</entry><entry>This register contains the physical address that</entry></row><row><entry /><entry /><entry /><entry /><entry>marks the top of region 5</entry></row><row><entry>0x30</entry><entry>Region6Bottom[21:5]</entry><entry>17</entry><entry>0xF_FFFF</entry><entry>This register contains the physical address that</entry></row><row><entry /><entry /><entry /><entry /><entry>marks the bottom of region 6</entry></row><row><entry>0x34</entry><entry>Region6Top[21:5]</entry><entry>17</entry><entry>0x0_0000</entry><entry>This register contains the physical address that</entry></row><row><entry /><entry /><entry /><entry /><entry>marks the top of region 6</entry></row><row><entry>0x38</entry><entry>Region7Bottom[21:5]</entry><entry>17</entry><entry>0xF_FFFF</entry><entry>This register contains the physical address that</entry></row><row><entry /><entry /><entry /><entry /><entry>marks the bottom of region 7</entry></row><row><entry>0x3C</entry><entry>Region7Top[21:5]</entry><entry>17</entry><entry>0x0_0000</entry><entry>This register contains the physical address that</entry></row><row><entry /><entry /><entry /><entry /><entry>marks the top of region 7</entry></row><row><entry>0x40</entry><entry>Region0Control</entry><entry>6</entry><entry>0x07</entry><entry>Control register for region 0</entry></row><row><entry>0x44</entry><entry>Region1Control</entry><entry>6</entry><entry>0x07</entry><entry>Control register for region 1</entry></row><row><entry>0x48</entry><entry>Region2Control</entry><entry>6</entry><entry>0x07</entry><entry>Control register for region 2</entry></row><row><entry>0x4C</entry><entry>Region3Control</entry><entry>6</entry><entry>0x07</entry><entry>Control register for region 3</entry></row><row><entry>0x50</entry><entry>Region4Control</entry><entry>6</entry><entry>0x07</entry><entry>Control register for region 4</entry></row><row><entry>0x54</entry><entry>Region5Control</entry><entry>6</entry><entry>0x07</entry><entry>Control register for region 5</entry></row><row><entry>0x58</entry><entry>Region6Control</entry><entry>6</entry><entry>0x07</entry><entry>Control register for region 6</entry></row><row><entry>0x5C</entry><entry>Region7Control</entry><entry>6</entry><entry>0x07</entry><entry>Control register for region 7</entry></row><row><entry>0x60</entry><entry>RegionLock</entry><entry>8</entry><entry>0x00</entry><entry>Writing a 1 to a bit in the RegionLock register</entry></row><row><entry /><entry /><entry /><entry /><entry>locks the value of the corresponding</entry></row><row><entry /><entry /><entry /><entry /><entry>RegionTop, RegionBottom and RegionControl regis-</entry></row><row><entry /><entry /><entry /><entry /><entry>ters. The lock can only be cleared by a reset</entry></row><row><entry /><entry /><entry /><entry /><entry>and any attempt to write to a locked register will</entry></row><row><entry /><entry /><entry /><entry /><entry>result in a bus error.</entry></row><row><entry>0x64</entry><entry>BusTimeout</entry><entry>8</entry><entry>0xFF</entry><entry>This register should be set to the number of</entry></row><row><entry /><entry /><entry /><entry /><entry>pclk cycles to wait after an access has started</entry></row><row><entry /><entry /><entry /><entry /><entry>before aborting the access with a bus error.</entry></row><row><entry /><entry /><entry /><entry /><entry>Writing 0 to this register disables the bus time-</entry></row><row><entry /><entry /><entry /><entry /><entry>out feature.</entry></row><row><entry>0x68</entry><entry>ExceptionSource</entry><entry>6</entry><entry>0x00</entry><entry>This register identifies the source of the last</entry></row><row><entry /><entry /><entry /><entry /><entry>exception. See Section 11.6.5.3 for details.</entry></row><row><entry>0x6C</entry><entry>DebugSelect</entry><entry>7</entry><entry>0x00</entry><entry>Contains address of the register selected for</entry></row><row><entry /><entry /><entry /><entry /><entry>debug observation. It is expected that a number</entry></row><row><entry /><entry /><entry /><entry /><entry>of pseudo-registers will be made available for</entry></row><row><entry /><entry /><entry /><entry /><entry>debug observation and these will be outlined</entry></row><row><entry /><entry /><entry /><entry /><entry>during the implementation phase.</entry></row><row><entry>0x80 to</entry><entry>RDU Registers</entry><entry /><entry /><entry>See Table for details.</entry></row><row><entry>0x108</entry></row><row><entry>0x140</entry><entry>LEON Configuration</entry><entry>32</entry><entry>0x1071_8C00</entry><entry>The LEON configuration register is used by</entry></row><row><entry /><entry>Register</entry><entry /><entry /><entry>software to determine the configuration of this</entry></row><row><entry /><entry /><entry /><entry /><entry>LEON implementation. See section 11.5.1.1 for</entry></row><row><entry /><entry /><entry /><entry /><entry>details. This register is ReadOnly.</entry></row><row><entry>0x144</entry><entry>LEON Cache</entry><entry>32</entry><entry>0x0000_0000</entry><entry>The LEON Cache Control Register is used to</entry></row><row><entry /><entry>Control Register</entry><entry /><entry /><entry>control the operation of the caches. See section</entry></row><row><entry /><entry /><entry /><entry /><entry>11.6 for details.</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 11.6.5.1 RegionTop and RegionBottom Registers
1123The 20 Mbit of embedded DRAM on SoPEC is arranged as 81920 words of 256 bits each. All region boundaries need to align with a 256-bit word. Thus only 17 bits are required for the RegionNTop and RegionNBottom registers. Note that the bottom 5 bits of the RegionNTop and RegionNBottom registers cannot be written to and read as ‘0’ i.e. the RegionNTop and RegionNBottom registers represent byte-aligned DRAM addresses
1124Both the RegionNTop and RegionNBottom registers are inclusive i.e. the addresses in the registers are included in the region. Thus the size of a region is (RegionNTop—RegionNBottom)+1 DRAM words.
1125If DRAM regions overlap (there is no reason for this to be the case but there is nothing to prohibit it either) then only accesses allowed by all overlapping regions are permitted. That is if a DRAM address appears in both Region1 and Region3 (for example) the cpu_acode of an access is checked against the access permissions of both regions. If both regions permit the access then it will proceed but if either or both regions do not permit the access then it will not be allowed. The MMU does not support negatively sized regions i.e. the value of the RegionNTop register should always be greater than or equal to the value of the RegionNBottom register. If RegionNTop is lower in the address map than RegionNTop then the region is considered to be zero-sized and is ignored.
1126When both the RegionNTop and RegionNBottom registers for a region contain the same value the region is then simply one 256-bit word in length and this corresponds to the smallest possible active region.
000011.6.5.2 Region Control Registers
1127Each memory region has a control register associated with it. The RegionNControl register is used to set the access conditions for the memory region bounded by the RegionNTop and RegionNBottom registers. Table 20 describes the function of each bit field in the RegionNControl registers. All bits in a RegionNControl register are both readable and writable by design. However, like all registers in the MMU, the RegionNControl registers can only be accessed by code running in supervisor mode.
1128<tables id="TABLE-US-00020" num="00020"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 20</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Region Control Register</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="42pt" align="center" /><colspec colname="3" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry>Field Name</entry><entry>bit(s)</entry><entry>Description</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row><row><entry /><entry>SupervisorAccess</entry><entry>2:0</entry><entry>Denotes the type of access</entry></row><row><entry /><entry /><entry /><entry>allowed when the CPU is</entry></row><row><entry /><entry /><entry /><entry>running in Supervisor mode.</entry></row><row><entry /><entry /><entry /><entry>For each access type a 1</entry></row><row><entry /><entry /><entry /><entry>indicates the access is per-</entry></row><row><entry /><entry /><entry /><entry>mitted and a 0 indicates the</entry></row><row><entry /><entry /><entry /><entry>access is not permitted.</entry></row><row><entry /><entry /><entry /><entry>bit0 - Data read access</entry></row><row><entry /><entry /><entry /><entry>permission</entry></row><row><entry /><entry /><entry /><entry>bit1 - Data write access</entry></row><row><entry /><entry /><entry /><entry>permission</entry></row><row><entry /><entry /><entry /><entry>bit2 - Instruction fetch</entry></row><row><entry /><entry /><entry /><entry>access permission</entry></row><row><entry /><entry>UserAccess</entry><entry>5:3</entry><entry>Denotes the type of access</entry></row><row><entry /><entry /><entry /><entry>allowed when the CPU is</entry></row><row><entry /><entry /><entry /><entry>running in User mode. For</entry></row><row><entry /><entry /><entry /><entry>each access type a 1 indicates</entry></row><row><entry /><entry /><entry /><entry>the access is permitted and a</entry></row><row><entry /><entry /><entry /><entry>0 indicates the access is not</entry></row><row><entry /><entry /><entry /><entry>permitted.</entry></row><row><entry /><entry /><entry /><entry>bit3 - Data read access</entry></row><row><entry /><entry /><entry /><entry>permission</entry></row><row><entry /><entry /><entry /><entry>bit4 - Data write access</entry></row><row><entry /><entry /><entry /><entry>permission</entry></row><row><entry /><entry /><entry /><entry>bit5 - Instruction fetch</entry></row><row><entry /><entry /><entry /><entry>access permission</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 11.6.5.3 ExceptionSource Register
1129The SPARC V8 architecture allows for a number of types of memory access error to be trapped. These trap types and trap handling in general are described in chapter 7 of the SPARC architecture manual [36]. However on the LEON processor only data_store_error and data_access_exception trap types will result from an external (to LEON) bus error. According to the SPARC architecture manual the processor will automatically move to the next register window (i.e. it decrements the current window pointer) and copies the program counters (PC and nPC) to two local registers in the new window. The supervisor bit in the PSR is also set and the PSR can be saved to another local register by the trap handler (this does not happen automatically in hardware). The ExceptionSource register aids the trap handler by identifying the source of an exception. Each bit in the ExceptionSource register is set when the relevant trap condition and should be cleared by the trap handler by writing a ‘1’ to that bit position.
1130<tables id="TABLE-US-00021" num="00021"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 21</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>ExceptionSource Register</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>Field Name</entry><entry>bit(s)</entry><entry>Description</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>DramAccessExcptn</entry><entry>0</entry><entry>The permissions of an access did</entry></row><row><entry /><entry /><entry>not match those of the DRAM region</entry></row><row><entry /><entry /><entry>it was attempting to access. This</entry></row><row><entry /><entry /><entry>bit will also be set if an attempt</entry></row><row><entry /><entry /><entry>is made to access an undefined</entry></row><row><entry /><entry /><entry>DRAM region (i.e. a location</entry></row><row><entry /><entry /><entry>that is not within the bounds</entry></row><row><entry /><entry /><entry>of any RegionTop/RegionBottom</entry></row><row><entry /><entry /><entry>pair)</entry></row><row><entry>PeriAccessExcptn</entry><entry>1</entry><entry>An access violation occurred when</entry></row><row><entry /><entry /><entry>accessing a CPU subsystem block.</entry></row><row><entry /><entry /><entry>This occurs when the access per-</entry></row><row><entry /><entry /><entry>missions disagree with those set</entry></row><row><entry /><entry /><entry>by the block.</entry></row><row><entry>UnusedAreaExcptn</entry><entry>2</entry><entry>An attempt was made to access an</entry></row><row><entry /><entry /><entry>unused part of the memory map</entry></row><row><entry>LockedWriteExcptn</entry><entry>3</entry><entry>An attempt was made to write to a</entry></row><row><entry /><entry /><entry>regions registers (RegionTop/</entry></row><row><entry /><entry /><entry>Bottom/Control) after they had</entry></row><row><entry /><entry /><entry>been locked.</entry></row><row><entry>ResetHandlerExcptn</entry><entry>4</entry><entry>An attempt was made to access a</entry></row><row><entry /><entry /><entry>ROM location between 0x0000_0000</entry></row><row><entry /><entry /><entry>and 0x0000_000F after the reset</entry></row><row><entry /><entry /><entry>handler was executed. The most</entry></row><row><entry /><entry /><entry>likely cause of such an access</entry></row><row><entry /><entry /><entry>is the use of an uninitialised</entry></row><row><entry /><entry /><entry>pointer or structure.</entry></row><row><entry>TimeoutExcptn</entry><entry>5</entry><entry>A bus timeout condition occurred.</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 11.6.6 MMU Sub-block Partition
1131As can be seen from <figref idref="DRAWINGS">FIG. 19</figref> and <figref idref="DRAWINGS">FIG. 20</figref> the MMU consists of three principal sub-blocks. For clarity the connections between these sub-blocks and other SoPEC blocks and between each of the sub-blocks are shown in two separate diagrams.
000011.6.6.1 LEON AHB Bridge
1132The LEON AHB bridge consists of an AHB bridge to DIU and an AHB to CPU subsystem bus bridge. The AHB bridge will convert between the AHB and the DIU and CPU subsystem bus protocols but the address decoding and enabling of an access happens elsewhere in the MMU. The AHB bridge will always be a slave on the AHB. Note that the AMBA signals from the LEON core are contained within the ahbso and ahbsi records. The LEON records are described in more detail in section 11.7. Glue logic may be required to assist with enabling memory accesses, endianness coherency, interrupts and other miscellaneous signalling.
1133<tables id="TABLE-US-00022" num="00022"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 22</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>LEON AHB bridge I/Os</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="140pt" align="left" /><tbody valign="top"><row><entry>Port name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>Global SoPEC signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="140pt" align="left" /><tbody valign="top"><row><entry>prst_n</entry><entry>1</entry><entry>In</entry><entry>Global reset. Synchronous to pclk, active low.</entry></row><row><entry>pclk</entry><entry>1</entry><entry>In</entry><entry>Global clock</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>LEON core to LEON AHB signals (ahbsi and ahbso records)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="140pt" align="left" /><tbody valign="top"><row><entry>ahbsi.haddr[31:0]</entry><entry>32</entry><entry>In</entry><entry>AHB address bus</entry></row><row><entry>ahbsi.hwdata[31:0]</entry><entry>32</entry><entry>In</entry><entry>AHB write data bus</entry></row><row><entry>ahbso.hrdata[31:0]</entry><entry>32</entry><entry>Out</entry><entry>AHB read data bus</entry></row><row><entry>ahbsi.hsel</entry><entry>1</entry><entry>In</entry><entry>AHB slave select signal</entry></row><row><entry>ahbsi.hwrite</entry><entry>1</entry><entry>In</entry><entry>AHB write signal:</entry></row><row><entry /><entry /><entry /><entry>1 - Write access</entry></row><row><entry /><entry /><entry /><entry>0 - Read access</entry></row><row><entry>ahbsi.htrans</entry><entry>2</entry><entry>In</entry><entry>Indicates the type of the current transfer:</entry></row><row><entry /><entry /><entry /><entry>00 - IDLE</entry></row><row><entry /><entry /><entry /><entry>01 - BUSY</entry></row><row><entry /><entry /><entry /><entry>10 - NONSEQ</entry></row><row><entry /><entry /><entry /><entry>11 - SEQ</entry></row><row><entry>ahbsi.hsize</entry><entry>3</entry><entry>In</entry><entry>Indicates the size of the current transfer:</entry></row><row><entry /><entry /><entry /><entry>000 - Byte transfer</entry></row><row><entry /><entry /><entry /><entry>001 - Halfword transfer</entry></row><row><entry /><entry /><entry /><entry>010 - Word transfer</entry></row><row><entry /><entry /><entry /><entry>011 - 64-bit transfer (unsupported?)</entry></row><row><entry /><entry /><entry /><entry>1xx - Unsupported larger wordsizes</entry></row><row><entry>ahbsi.hburst</entry><entry>3</entry><entry>In</entry><entry>Indicates if the current transfer forms part of a</entry></row><row><entry /><entry /><entry /><entry>burst and the type of burst:</entry></row><row><entry /><entry /><entry /><entry>000 - SINGLE</entry></row><row><entry /><entry /><entry /><entry>001 - INCR</entry></row><row><entry /><entry /><entry /><entry>010 - WRAP4</entry></row><row><entry /><entry /><entry /><entry>011 - INCR4</entry></row><row><entry /><entry /><entry /><entry>100 - WRAP8</entry></row><row><entry /><entry /><entry /><entry>101 - INCR8</entry></row><row><entry /><entry /><entry /><entry>110 - WRAP16</entry></row><row><entry /><entry /><entry /><entry>111 - INCR16</entry></row><row><entry>ahbsi.hprot</entry><entry>4</entry><entry>In</entry><entry>Protection control signals pertaining to the</entry></row><row><entry /><entry /><entry /><entry>current access:</entry></row><row><entry /><entry /><entry /><entry>hprot[0] - Opcode(0)/Data(1) access</entry></row><row><entry /><entry /><entry /><entry>hprot[1] - User(0)/Supervisor access</entry></row><row><entry /><entry /><entry /><entry>hprot[2] - Non-bufferable(0)/Bufferable(1)</entry></row><row><entry /><entry /><entry /><entry>access (unsupported)</entry></row><row><entry /><entry /><entry /><entry>hprot[3] - Non-cacheable(0)/Cacheable</entry></row><row><entry /><entry /><entry /><entry>access</entry></row><row><entry>ahbsi.hmaster</entry><entry>4</entry><entry>In</entry><entry>Indicates the identity of the current bus master.</entry></row><row><entry /><entry /><entry /><entry>This will always be the LEON core.</entry></row><row><entry>ahbsi.hmastlock</entry><entry>1</entry><entry>In</entry><entry>Indicates that the current master is performing</entry></row><row><entry /><entry /><entry /><entry>a locked sequence of transfers.</entry></row><row><entry>ahbso.hready</entry><entry>1</entry><entry>Out</entry><entry>Active high ready signal indicating the access</entry></row><row><entry /><entry /><entry /><entry>has completed</entry></row><row><entry>ahbso.hresp</entry><entry>2</entry><entry>Out</entry><entry>Indicates the status of the transfer:</entry></row><row><entry /><entry /><entry /><entry>00 - OKAY</entry></row><row><entry /><entry /><entry /><entry>01 - ERROR</entry></row><row><entry /><entry /><entry /><entry>10 - RETRY</entry></row><row><entry /><entry /><entry /><entry>11 - SPLIT</entry></row><row><entry>ahbso.hsplit[15:0]</entry><entry>16</entry><entry>Out</entry><entry>This 16-bit split bus is used by a slave to</entry></row><row><entry /><entry /><entry /><entry>indicate to the arbiter which bus masters should</entry></row><row><entry /><entry /><entry /><entry>be allowed attempt a split transaction. This</entry></row><row><entry /><entry /><entry /><entry>feature will be unsupported on the AHB bridge</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>Toplevel/Common LEON AHB bridge signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="140pt" align="left" /><tbody valign="top"><row><entry>cpu_dataout[31:0]</entry><entry>32</entry><entry>Out</entry><entry>Data out bus to both DRAM and peripheral</entry></row><row><entry /><entry /><entry /><entry>devices.</entry></row><row><entry>cpu_rwn</entry><entry>1</entry><entry>Out</entry><entry>Read/NotWrite signal. 1 = Current access is a</entry></row><row><entry /><entry /><entry /><entry>read access, 0 = Current access is a write</entry></row><row><entry /><entry /><entry /><entry>access</entry></row><row><entry>icu_cpu_ilevel[3:0]</entry><entry>4</entry><entry>In</entry><entry>An interrupt is asserted by driving the</entry></row><row><entry /><entry /><entry /><entry>appropriate priority level on icu_cpu_ilevel.</entry></row><row><entry /><entry /><entry /><entry>These signals must remain asserted until the</entry></row><row><entry /><entry /><entry /><entry>CPU executes an interrupt acknowledge cycle.</entry></row><row><entry>cpu_icu_ilevel[3:0]</entry><entry>4</entry><entry>In</entry><entry>Indicates the level of the interrupt the CPU is</entry></row><row><entry /><entry /><entry /><entry>acknowledging when cpu_iack is high</entry></row><row><entry>cpu_iack</entry><entry>1</entry><entry>Out</entry><entry>Interrupt acknowledge signal. The exact timing</entry></row><row><entry /><entry /><entry /><entry>depends on the CPU core implementation</entry></row><row><entry>cpu_start_access</entry><entry>1</entry><entry>Out</entry><entry>Start Access signal indicating the start of a data</entry></row><row><entry /><entry /><entry /><entry>transfer and that the cpu_adr, cpu_dataout,</entry></row><row><entry /><entry /><entry /><entry>cpu_rwn and cpu_acode signals are all valid.</entry></row><row><entry /><entry /><entry /><entry>This signal is only asserted during the first</entry></row><row><entry /><entry /><entry /><entry>cycle of an access.</entry></row><row><entry>cpu_ben[1:0]</entry><entry>2</entry><entry>Out</entry><entry>Byte enable signals.</entry></row><row><entry>dram_cpu_data[255:0]</entry><entry>256</entry><entry>In</entry><entry>Read data from the DRAM.</entry></row><row><entry>diu_cpu_rreq</entry><entry>1</entry><entry>Out</entry><entry>Read request to the DIU.</entry></row><row><entry>diu_cpu_rack</entry><entry>1</entry><entry>In</entry><entry>Acknowledge from DIU that read request has</entry></row><row><entry /><entry /><entry /><entry>been accepted.</entry></row><row><entry>diu_cpu_rvalid</entry><entry>1</entry><entry>In</entry><entry>Signal from DIU indicating that valid read data</entry></row><row><entry /><entry /><entry /><entry>is on the dram_cpu_data bus</entry></row><row><entry>cpu_diu_wdatavalid</entry><entry>1</entry><entry>Out</entry><entry>Signal from the CPU to the DIU indicating that</entry></row><row><entry /><entry /><entry /><entry>the data currently on the cpu_diu_wdata bus is</entry></row><row><entry /><entry /><entry /><entry>valid and should be committed to the DIU</entry></row><row><entry /><entry /><entry /><entry>posted write buffer</entry></row><row><entry>diu_cpu_write_rdy</entry><entry>1</entry><entry>In</entry><entry>Signal from the DIU indicating that the posted</entry></row><row><entry /><entry /><entry /><entry>write buffer is empty</entry></row><row><entry>cpu_diu_wdadr[21:4]</entry><entry>18</entry><entry>Out</entry><entry>Write address bus to the DIU</entry></row><row><entry>cpu_diu_wdata[127:0]</entry><entry>128</entry><entry>Out</entry><entry>Write data bus to the DIU</entry></row><row><entry>cpu_diu_wmask[15:0]</entry><entry>16</entry><entry>Out</entry><entry>Write mask for the cpu_diu_wdata bus. Each</entry></row><row><entry /><entry /><entry /><entry>bit corresponds to a byte of the 128-bit</entry></row><row><entry /><entry /><entry /><entry>cpu_diu_wdata bus.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>LEON AHB bridge to MMU Control Block signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="140pt" align="left" /><tbody valign="top"><row><entry>cpu_mmu_adr</entry><entry>32</entry><entry>Out</entry><entry>CPU Address Bus.</entry></row><row><entry>mmu_cpu_data</entry><entry>32</entry><entry>In</entry><entry>Data bus from the MMU</entry></row><row><entry>mmu_cpu_rdy</entry><entry>1</entry><entry>In</entry><entry>Ready signal from the MMU</entry></row><row><entry>cpu_mmu_acode</entry><entry>2</entry><entry>Out</entry><entry>Access code signals to the MMU</entry></row><row><entry>mmu_cpu_berr</entry><entry>1</entry><entry>In</entry><entry>Bus error signal from the MMU</entry></row><row><entry>dram_access_en</entry><entry>1</entry><entry>In</entry><entry>DRAM access enable signal. A DRAM access</entry></row><row><entry /><entry /><entry /><entry>cannot be initiated unless it has been enabled</entry></row><row><entry /><entry /><entry /><entry>by the MMU control unit.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> Description:
1134The LEON AHB bridge must ensure that all CPU bus transactions are functionally correct and that the timing requirements are met. The AHB bridge also implements a 128-bit DRAM write buffer to improve the efficiency of DRAM writes, particularly for multiple successive writes to DRAM. The AHB bridge is also responsible for ensuring endianness coherency i.e. guaranteeing that the correct data appears in the correct position on the data buses (hrdata, cpu_dataout and cpu_mmu_wdata) for every type of access. This is a requirement because the LEON uses big-endian addressing while the rest of SoPEC is little-endian.
1135The LEON AHB bridge will assert request signals to the DIU if the MMU control block deems the access to be a legal access. The validity (i.e. is the CPU running in the correct mode for the address space being accessed) of an access is determined by the contents of the relevant RegionNControl register. As the SPARC standard requires that all accesses are aligned to their word size (i.e. byte, half-word, word or double-word) and so it is not possible for an access to traverse a 256-bit boundary (as required by the DIU). Invalid DRAM accesses are not propagated to the DIU and will result in an error response (ahbso.hresp=‘01’) on the AHB. The DIU bus protocol is described in more detail in section 20.9. The DIU will return a 256-bit dataword on dram_cpu_data[255:0] for every read access.
1136The CPU subsystem bus protocol is described in section 11.4.3. While the LEON AHB bridge performs the protocol translation between AHB and the CPU subsystem bus the select signals for each block are generated by address decoding in the CPU subsystem bus interface. The CPU subsystem bus interface also selects the correct read data bus, ready and error signals for the block being addressed and passes these to the LEON AHB bridge which puts them on the AHB bus. It is expected that some signals (especially those external to the CPU block) will need to be registered here to meet the timing requirements. Careful thought will be required to ensure that overall CPU access times are not excessively degraded by the use of too many register stages.
000011.6.6.1.1 DRAM Write Buffer
1137The DRAM write buffer improves the efficiency of DRAM writes by aggregating a number of CPU write accesses into a single DIU write access. This is achieved by checking to see if a CPU write is to an address already in the write buffer and if so the write is immediately acknowledged (i.e. the ahbsi.hready signal is asserted without any wait states) and the DRAM write buffer updated accordingly. When the CPU write is to a DRAM address other than that in the write buffer then the current contents of the write buffer are sent to the DIU (where they are placed in the posted write buffer) and the DRAM write buffer is updated with the address and data of the CPU write. The DRAM write buffer consists of a 128-bit data buffer, an 18-bit write address tag and a 16-bit write mask. Each bit of the write mask indicates the validity of the corresponding byte of the write buffer as shown in <figref idref="DRAWINGS">FIG. 21</figref> below.
1138The operation of the DRAM write buffer is summarised by the following set of rules: <ul id="ul0094" list-style="none"><li id="ul0094-0001" num="1139">1) The DRAM write buffer only contains DRAM write data i.e. peripheral writes go directly to the addressed peripheral.</li><li id="ul0094-0002" num="1140">2) CPU writes to locations within the DRAM write buffer or to an empty write buffer (i.e. the write mask bits are all 0) complete with zero wait states regardless of the size of the write (byte/half-word/word/ double-word).</li><li id="ul0094-0003" num="1141">3) The contents of the DRAM write buffer are flushed to DRAM whenever a CPU write to a location outside the write buffer occurs, whenever a CPU read from a location within the write buffer occurs or whenever a write to a peripheral register occurs.</li><li id="ul0094-0004" num="1142">4) A flush resulting from a peripheral write will not cause any extra wait states to be inserted in the peripheral write access.</li><li id="ul0094-0005" num="1143">5) Flushes resulting from a DRAM accesses will cause wait states to be inserted until the DIU posted write buffer is empty. If the DIU posted write buffer is empty at the time the flush is required then no wait states will be inserted for a flush resulting from a CPU write or one wait state will be inserted for a flush resulting from a CPU read (this is to ensure that the DIU sees the write request ahead of the read request). Note that in this case further wait states will also be inserted as a result of the delay in servicing the read request by the DIU. <br /> 11.6.6.1.2 DIU Interface Waveforms </li></ul>
1144<figref idref="DRAWINGS">FIG. 22</figref> below depicts the operation of the AHB bridge over a sample sequence of DRAM transactions consisting of a read into the DCache, a double-word store to an address other than that currently in the DRAM write buffer followed by an ICache line refill. To avoid clutter a number of AHB control signals that are inputs to the MMU have been grouped together as ahbsi.CONTROL and only the ahbso.HREADY is shown of the output AHB control signals.
1145The first transaction is a single word load (‘LD’). The MMU (specifically the MMU control block) uses the first cycle of every access (i.e. the address phase of an AHB transaction) to determine whether or not the access is a legal access. The read request to the DIU is then asserted in the following cycle (assuming the access is a valid one) and is acknowledged by the DIU a cycle later. Note that the time from cpu_diu_rreq being asserted and diu_cpu_rack being asserted is variable as it depends on the DIU configuration and access patterns of DIU requestors. The AHB bridge will insert wait states until it sees the diu_cpu_rvalid signal is high, indicating the data (‘LD1’) on the dram_cpu_data bus is valid. The AHB bridge terminates the read access in the same cycle by asserting the ahbso.HREADY signal (together with an ‘OKAY’ HRESP code). The AHB bridge also selects the appropriate 32 bits (‘RD1’) from the 256-bit DRAM line data (‘LD1’) returned by the DIU corresponding to the word address given by A1.
1146The second transaction is an AHB two-beat incrementing burst issued by the LEON acache block in response to the execution of a double-word store instruction. As LEON is a big endian processor the address issued (‘A2’) during the address phase of the first beat of this transaction is the address of the most significant word of the double-word while the address for the second beat (‘A3’) is that of the least significant word i.e. A3=A2+4. The presence of the DRAM write buffer allows these writes to complete without the insertion of any wait states. This is true even when, as shown here, the DRAM write buffer needs to be flushed into the DIU posted write buffer, provided the DIU posted write buffer is empty. If the DIU posted write buffer is not empty (as would be signified by diu_cpu_write_rdy being low) then wait states would be inserted until it became empty. The cpu_diu_wdata buffer builds up the data to be written to the DIU over a number of transactions (‘BD<b>1</b>’ and ‘BD<b>2</b>’ here) while the cpu_dui_wmask records every byte that has been written to since the last flush—in this case the lowest word and then the second lowest word are written to as a result of the double-word store operation.
1147The final transaction shown here is a DRAM read caused by an ICache miss. Note that the pipelined nature of the AHB bus allows the address phase of this transaction to overlap with the final data phase of the previous transaction. All ICache misses appear as single word loads (‘LD’) on the AHB bus. In this case we can see that the DIU is slower to respond to this read request than to the first read request because it is processing the write access caused by the DRAM write buffer flush. The ICache refill will complete just after the window shown in <figref idref="DRAWINGS">FIG. 22</figref>.
000011.6.6.2 CPU Subsystem Bus Interface
1148The CPU Subsystem Interface block handles all valid accesses to the peripheral blocks that comprise the CPU Subsystem.
1149<tables id="TABLE-US-00023" num="00023"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 23</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>CPU Subsystem Bus Interface I/Os</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="154pt" align="left" /><tbody valign="top"><row><entry>Port name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="left" /><tbody valign="top"><row><entry>Global SoPEC signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="154pt" align="left" /><tbody valign="top"><row><entry>prst_n</entry><entry>1</entry><entry>In</entry><entry>Global reset. Synchronous to pclk, active low.</entry></row><row><entry>pclk</entry><entry>1</entry><entry>In</entry><entry>Global clock</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="left" /><tbody valign="top"><row><entry>Toplevel/Common CPU Subsystem Bus Interface signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="154pt" align="left" /><tbody valign="top"><row><entry>cpu_cpr_sel</entry><entry>1</entry><entry>Out</entry><entry>CPR block select.</entry></row><row><entry>cpu_gpio_sel</entry><entry>1</entry><entry>Out</entry><entry>GPIO block select.</entry></row><row><entry>cpu_icu_sel</entry><entry>1</entry><entry>Out</entry><entry>ICU block select.</entry></row><row><entry>cpu_lss_sel</entry><entry>1</entry><entry>Out</entry><entry>LSS block select.</entry></row><row><entry>cpu_pcu_sel</entry><entry>1</entry><entry>Out</entry><entry>PCU block select.</entry></row><row><entry>cpu_scb_sel</entry><entry>1</entry><entry>Out</entry><entry>SCB block select.</entry></row><row><entry>cpu_tim_sel</entry><entry>1</entry><entry>Out</entry><entry>Timers block select.</entry></row><row><entry>cpu_rom_sel</entry><entry>1</entry><entry>Out</entry><entry>ROM block select.</entry></row><row><entry>cpu_pss_sel</entry><entry>1</entry><entry>Out</entry><entry>PSS block select.</entry></row><row><entry>cpu_diu_sel</entry><entry>1</entry><entry>Out</entry><entry>DIU block select.</entry></row><row><entry>cpr_cpu_data[31:0]</entry><entry>32</entry><entry>In</entry><entry>Read data bus from the CPR block</entry></row><row><entry>gpio_cpu_data[31:0]</entry><entry>32</entry><entry>In</entry><entry>Read data bus from the GPIO block</entry></row><row><entry>icu_cpu_data[31:0]</entry><entry>32</entry><entry>In</entry><entry>Read data bus from the ICU block</entry></row><row><entry>lss_cpu_data[31:0]</entry><entry>32</entry><entry>In</entry><entry>Read data bus from the LSS block</entry></row><row><entry>pcu_cpu_data[31:0]</entry><entry>32</entry><entry>In</entry><entry>Read data bus from the PCU block</entry></row><row><entry>scb_cpu_data[31:0]</entry><entry>32</entry><entry>In</entry><entry>Read data bus from the SCB block</entry></row><row><entry>tim_cpu_data[31:0]</entry><entry>32</entry><entry>In</entry><entry>Read data bus from the Timers block</entry></row><row><entry>rom_cpu_data[31:0]</entry><entry>32</entry><entry>In</entry><entry>Read data bus from the ROM block</entry></row><row><entry>pss_cpu_data[31:0]</entry><entry>32</entry><entry>In</entry><entry>Read data bus from the PSS block</entry></row><row><entry>diu_cpu_data[31:0]</entry><entry>32</entry><entry>In</entry><entry>Read data bus from the DIU block</entry></row><row><entry>cpr_cpu_rdy</entry><entry>1</entry><entry>In</entry><entry>Ready signal to the CPU. When cpr_cpu_rdy is</entry></row><row><entry /><entry /><entry /><entry>high it indicates the last cycle of the access. For a</entry></row><row><entry /><entry /><entry /><entry>write cycle this means cpu_dataout has been</entry></row><row><entry /><entry /><entry /><entry>registered by the CPR block and for a read cycle</entry></row><row><entry /><entry /><entry /><entry>this means the data on cpr_cpu_data is valid.</entry></row><row><entry>gpio_cpu_rdy</entry><entry>1</entry><entry>In</entry><entry>GPIO ready signal to the CPU.</entry></row><row><entry>icu_cpu_rdy</entry><entry>1</entry><entry>In</entry><entry>ICU ready signal to the CPU.</entry></row><row><entry>lss_cpu_rdy</entry><entry>1</entry><entry>In</entry><entry>LSS ready signal to the CPU.</entry></row><row><entry>pcu_cpu_rdy</entry><entry>1</entry><entry>In</entry><entry>PCU ready signal to the CPU.</entry></row><row><entry>scb_cpu_rdy</entry><entry>1</entry><entry>In</entry><entry>SCB ready signal to the CPU.</entry></row><row><entry>tim_cpu_rdy</entry><entry>1</entry><entry>In</entry><entry>Timers block ready signal to the CPU.</entry></row><row><entry>rom_cpu_rdy</entry><entry>1</entry><entry>In</entry><entry>ROM block ready signal to the CPU.</entry></row><row><entry>pss_cpu_rdy</entry><entry>1</entry><entry>In</entry><entry>PSS block ready signal to the CPU.</entry></row><row><entry>diu_cpu_rdy</entry><entry>1</entry><entry>In</entry><entry>DIU register block ready signal to the CPU.</entry></row><row><entry>cpr_cpu_berr</entry><entry>1</entry><entry>In</entry><entry>Bus Error signal from the CPR block</entry></row><row><entry>gpio_cpu_berr</entry><entry>1</entry><entry>In</entry><entry>Bus Error signal from the GPIO block</entry></row><row><entry>icu_cpu_berr</entry><entry>1</entry><entry>In</entry><entry>Bus Error signal from the ICU block</entry></row><row><entry>lss_cpu_berr</entry><entry>1</entry><entry>In</entry><entry>Bus Error signal from the LSS block</entry></row><row><entry>pcu_cpu_berr</entry><entry>1</entry><entry>In</entry><entry>Bus Error signal from the PCU block</entry></row><row><entry>scb_cpu_berr</entry><entry>1</entry><entry>In</entry><entry>Bus Error signal from the SCB block</entry></row><row><entry>tim_cpu_berr</entry><entry>1</entry><entry>In</entry><entry>Bus Error signal from the Timers block</entry></row><row><entry>rom_cpu_berr</entry><entry>1</entry><entry>In</entry><entry>Bus Error signal from the ROM block</entry></row><row><entry>pss_cpu_berr</entry><entry>1</entry><entry>In</entry><entry>Bus Error signal from the PSS block</entry></row><row><entry>diu_cpu_berr</entry><entry>1</entry><entry>In</entry><entry>Bus Error signal from the DIU block</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="left" /><tbody valign="top"><row><entry>CPU Subsystem Bus Interface to MMU Control Block signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="154pt" align="left" /><tbody valign="top"><row><entry>cpu_adr[19:12]</entry><entry>8</entry><entry>In</entry><entry>Toplevel CPU Address bus. Only bits 19–12 are</entry></row><row><entry /><entry /><entry /><entry>required to decode the peripherals address space</entry></row><row><entry>peri_access_en</entry><entry>1</entry><entry>In</entry><entry>Enable Access signal. A peripheral access cannot</entry></row><row><entry /><entry /><entry /><entry>be initiated unless it has been enabled by the MMU</entry></row><row><entry /><entry /><entry /><entry>Control Unit</entry></row><row><entry>peri_mmu_data[31:0]</entry><entry>32</entry><entry>Out</entry><entry>Data bus from the selected peripheral</entry></row><row><entry>peri_mmu_rdy</entry><entry>1</entry><entry>Out</entry><entry>Data Ready signal. Indicates the data on the</entry></row><row><entry /><entry /><entry /><entry>peri_mmu_data bus is valid for a read cycle or that</entry></row><row><entry /><entry /><entry /><entry>the data was successfully written to the peripheral</entry></row><row><entry /><entry /><entry /><entry>for a write cycle.</entry></row><row><entry>peri_mmu_berr</entry><entry>1</entry><entry>Out</entry><entry>Bus Error signal. Indicates a bus error has occurred</entry></row><row><entry /><entry /><entry /><entry>in accessing the selected peripheral</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="left" /><tbody valign="top"><row><entry>CPU Subsystem Bus Interface to LEON AHB bridge signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="154pt" align="left" /><tbody valign="top"><row><entry>cpu_start_access</entry><entry>1</entry><entry>In</entry><entry>Start Access signal from the LEON AHB bridge</entry></row><row><entry /><entry /><entry /><entry>indicating the start of a data transfer and that the</entry></row><row><entry /><entry /><entry /><entry>cpu_adr, cpu_dataout, cpu_rwn and cpu_acode</entry></row><row><entry /><entry /><entry /><entry>signals are all valid. This signal is only asserted</entry></row><row><entry /><entry /><entry /><entry>during the first cycle of an access.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> Description:
1150The CPU Subsystem Bus Interface block performs simple address decoding to select a peripheral and multiplexing of the returned signals from the various peripheral blocks. The base addresses used for the decode operation are defined in Table. Note that access to the MMU configuration registers are handled by the MMU Control Block rather than the CPU Subsystem Bus Interface block. The CPU Subsystem Bus Interface block operation is described by the following pseudocode:
1151<tables id="TABLE-US-00024" num="00024"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>masked_cpu_adr = cpu_adr[17:12]</entry></row><row><entry /><entry>case (masked_cpu_adr)</entry></row><row><entry /><entry>when TIM_base[17:12]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="112pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><tbody valign="top"><row><entry /><entry>cpu_tim_sel = peri_access_en</entry><entry> // The peri_access_en</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>signal will have the</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="112pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><tbody valign="top"><row><entry /><entry>peri_mmu_data = tim_cpu_data</entry><entry>// timing required for</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>block selects</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>peri_mmu_rdy = tim_cpu_rdy</entry></row><row><entry /><entry>peri_mmu_berr = tim_cpu_berr</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry>all_other_selects = 0</entry><entry> // Shorthand to ensure other</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>cpu_block_sel signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="119pt" align="left" /><colspec colname="1" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry>// remain deasserted</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>when LSS_base[17:12]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>cpu_lss_sel = peri_access_en</entry></row><row><entry /><entry>peri_mmu_data = lss_cpu_data</entry></row><row><entry /><entry>peri_mmu_rdy = lss_cpu_rdy</entry></row><row><entry /><entry>peri_mmu_berr = lss_cpu_berr</entry></row><row><entry /><entry>all_other_selects = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>when GPIO_base[17:12]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>cpu_gpio_sel = peri_access_en</entry></row><row><entry /><entry>peri_mmu_data = gpio_cpu_data</entry></row><row><entry /><entry>peri_mmu_rdy = gpio_cpu_rdy</entry></row><row><entry /><entry>peri_mmu_berr = gpio_cpu_berr</entry></row><row><entry /><entry>all_other_selects = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>when SCB_base[17:12]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>cpu_scb_sel = peri_access_en</entry></row><row><entry /><entry>peri_mmu_data = scb_cpu_data</entry></row><row><entry /><entry>peri_mmu_rdy = scb_cpu_rdy</entry></row><row><entry /><entry>peri_mmu_berr = scb_cpu_berr</entry></row><row><entry /><entry>all_other_selects = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>when ICU_base[17:12]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>cpu_icu_sel = peri_access_en</entry></row><row><entry /><entry>peri_mmu_data = icu_cpu_data</entry></row><row><entry /><entry>peri_mmu_rdy = icu_cpu_rdy</entry></row><row><entry /><entry>peri_mmu_berr = icu_cpu_berr</entry></row><row><entry /><entry>all_other_selects = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>when CPR_base[17:12]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>cpu_cpr_sel = peri_access_en</entry></row><row><entry /><entry>peri_mmu_data = cpr_cpu_data</entry></row><row><entry /><entry>peri_mmu_rdy = cpr_cpu_rdy</entry></row><row><entry /><entry>peri_mmu_berr = cpr_cpu_berr</entry></row><row><entry /><entry>all_other_selects = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>when ROM_base[17:12]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>cpu_rom_sel = peri_access_en</entry></row><row><entry /><entry>peri_mmu_data = rom_cpu_data</entry></row><row><entry /><entry>peri_mmu_rdy = rom_cpu_rdy</entry></row><row><entry /><entry>peri_mmu_berr = rom_cpu_berr</entry></row><row><entry /><entry>all_other_selects = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>when PSS_base[17:12]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>cpu_pss_sel = peri_access_en</entry></row><row><entry /><entry>peri_mmu_data = pss_cpu_data</entry></row><row><entry /><entry>peri_mmu_rdy = pss_cpu_rdy</entry></row><row><entry /><entry>peri_mmu_berr = pss_cpu_berr</entry></row><row><entry /><entry>all_other_selects = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>when DIU_base[17:12]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>cpu_diu_sel = peri_access_en</entry></row><row><entry /><entry>peri_mmu_data = diu_cpu_data</entry></row><row><entry /><entry>peri_mmu_rdy = diu_cpu_rdy</entry></row><row><entry /><entry>peri_mmu_berr = diu_cpu_berr</entry></row><row><entry /><entry>all_other_selects = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>when PCU_base[17:12]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>cpu_pcu_sel = peri_access_en</entry></row><row><entry /><entry>peri_mmu_data = pcu_cpu_data</entry></row><row><entry /><entry>peri_mmu_rdy = pcu_cpu_rdy</entry></row><row><entry /><entry>peri_mmu_berr = pcu_cpu_berr</entry></row><row><entry /><entry>all_other_selects = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>when others</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>all_block_selects = 0</entry></row><row><entry /><entry>peri_mmu_data = 0x00000000</entry></row><row><entry /><entry>peri_mmu_rdy = 0</entry></row><row><entry /><entry>peri_mmu_berr = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>end case</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 11.6.6.3 MMU Control Block
1152The MMU Control Block determines whether every CPU access is a valid access. No more than one cycle is to be consumed in determining the validity of an access and all accesses must terminate with the assertion of either mmu_cpu_rdy or mmu_cpu_berr. To safeguard against stalling the CPU a simple bus timeout mechanism will be supported.
1153<tables id="TABLE-US-00025" num="00025"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="273pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 24</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>MMU Control Block I/Os</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="161pt" align="left" /><tbody valign="top"><row><entry>Port name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="273pt" align="left" /><tbody valign="top"><row><entry>Global SoPEC signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="161pt" align="left" /><tbody valign="top"><row><entry>prst_n</entry><entry>1</entry><entry>In</entry><entry>Global reset. Synchronous to pclk, active low.</entry></row><row><entry>pclk</entry><entry>1</entry><entry>In</entry><entry>Global clock</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="273pt" align="left" /><tbody valign="top"><row><entry>Toplevel/Common MMU Control Block signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="161pt" align="left" /><tbody valign="top"><row><entry>cpu_adr[21:2]</entry><entry>22</entry><entry>Out</entry><entry>Address bus for both DRAM and peripheral access.</entry></row><row><entry>cpu_acode[1:0]</entry><entry>2</entry><entry>Out</entry><entry>CPU access code signals (cpu_mmu_acode) retimed</entry></row><row><entry /><entry /><entry /><entry>to meet the CPU Subsystem Bus timing requirements</entry></row><row><entry>dram_access_en</entry><entry>1</entry><entry>Out</entry><entry>DRAM Access Enable signal. Indicates that the</entry></row><row><entry /><entry /><entry /><entry>current CPU access is a valid DRAM access.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="273pt" align="left" /><tbody valign="top"><row><entry>MMU Control Block to LEON AHB bridge signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="161pt" align="left" /><tbody valign="top"><row><entry>cpu_mmu_adr[31:0]</entry><entry>32</entry><entry>In</entry><entry>CPU core address bus.</entry></row><row><entry>cpu_dataout[31:0]</entry><entry>32</entry><entry>In</entry><entry>Toplevel CPU data bus</entry></row><row><entry>mmu_cpu_data[31:0]</entry><entry>32</entry><entry>Out</entry><entry>Data bus to the CPU core. Carries the data for all</entry></row><row><entry /><entry /><entry /><entry>CPU read operations</entry></row><row><entry>cpu_rwn</entry><entry>1</entry><entry>In</entry><entry>Toplevel CPU Read/notWrite signal.</entry></row><row><entry>cpu_mmu_acode[1:0]</entry><entry>2</entry><entry>In</entry><entry>CPU access code signals</entry></row><row><entry>mmu_cpu_rdy</entry><entry>1</entry><entry>Out</entry><entry>Ready signal to the CPU core. Indicates the</entry></row><row><entry /><entry /><entry /><entry>completion of all valid CPU accesses.</entry></row><row><entry>mmu_cpu_berr</entry><entry>1</entry><entry>Out</entry><entry>Bus Error signal to the CPU core. This signal is</entry></row><row><entry /><entry /><entry /><entry>asserted to terminate an invalid access.</entry></row><row><entry>cpu_start_access</entry><entry>1</entry><entry>In</entry><entry>Start Access signal from the LEON AHB bridge</entry></row><row><entry /><entry /><entry /><entry>indicating the start of a data transfer and that the</entry></row><row><entry /><entry /><entry /><entry>cpu_adr, cpu_dataout, cpu_rwn and cpu_acode</entry></row><row><entry /><entry /><entry /><entry>signals are all valid. This signal is only asserted</entry></row><row><entry /><entry /><entry /><entry>during the first cycle of an access.</entry></row><row><entry>cpu_iack</entry><entry>1</entry><entry>In</entry><entry>Interrupt Acknowledge signal from the CPU. This</entry></row><row><entry /><entry /><entry /><entry>signal is only asserted during an interrupt</entry></row><row><entry /><entry /><entry /><entry>acknowledge cycle.</entry></row><row><entry>cpu_ben[1:0]</entry><entry>2</entry><entry>In</entry><entry>Byte enable signals indicating which bytes of the 32-</entry></row><row><entry /><entry /><entry /><entry>bit bus are being accessed.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="273pt" align="left" /><tbody valign="top"><row><entry>MMU Control Block to CPU Subsystem Bus Interface signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="161pt" align="left" /><tbody valign="top"><row><entry>cpu_adr[17:12]</entry><entry>8</entry><entry>Out</entry><entry>Toplevel CPU Address bus. Only bits 17–12 are</entry></row><row><entry /><entry /><entry /><entry>required to decode the peripherals address space</entry></row><row><entry>peri_access_en</entry><entry>1</entry><entry>Out</entry><entry>Enable Access signal. A peripheral access cannot be</entry></row><row><entry /><entry /><entry /><entry>initiated unless it has been enabled by the MMU</entry></row><row><entry /><entry /><entry /><entry>Control Unit</entry></row><row><entry>peri_mmu_data[31:0]</entry><entry>32</entry><entry>In</entry><entry>Data bus from the selected peripheral</entry></row><row><entry>peri_mmu_rdy</entry><entry>1</entry><entry>In</entry><entry>Data Ready signal. Indicates the data on the</entry></row><row><entry /><entry /><entry /><entry>peri_mmu_data bus is valid for a read cycle or that</entry></row><row><entry /><entry /><entry /><entry>the data was successfully written to the peripheral for</entry></row><row><entry /><entry /><entry /><entry>a write cycle.</entry></row><row><entry>peri_mmu_berr</entry><entry>1</entry><entry>In</entry><entry>Bus Error signal. Indicates a bus error has occurred in</entry></row><row><entry /><entry /><entry /><entry>accessing the selected peripheral</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> Description:
1154The MMU Control Block is responsible for the MMU's core functionality, namely determining whether or not an access to any part of the address map is valid. An access is considered valid if it is to a mapped area of the address space and if the CPU is running in the appropriate mode for that address space. Furthermore the MMU control block must correctly handle the special cases that are: an interrupt acknowledge cycle, a reset exception vector fetch, an access that crosses a 256-bit DRAM word boundary and a bus timeout condition. The following pseudocode shows the logic required to implement the MMU Control Block functionality. It does not deal with the timing relationships of the various signals—it is the designer's responsibility to ensure that these relationships are correct and comply with the different bus protocols. For simplicity the pseudocode is split up into numbered sections so that the functionality may be seen more easily.
1155It is important to note that the style used for the pseudocode will differ from the actual coding style used in the RTL implementation. The pseudocode is only intended to capture the required functionality, to clearly show the criteria that need to be tested rather than to describe how the implementation should be performed. In particular the different comparisons of the address used to determine which part of the memory map, which DRAM region (if applicable) and the permission checking should all be performed in parallel (with results ORed together where appropriate) rather than sequentially as the pseudocode implies.
1156PS0 Description: This first segment of code defines a number of constants and variables that are used elsewhere in this description. Most signals have been defined in the I/O descriptions of the MMU sub-blocks that precede this section of the document. The post_reset_state variable is used later (in section PS4) to determine if we should trap a null pointer access.
1157<tables id="TABLE-US-00026" num="00026"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>PS0:</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>const UnusedBottom = 0x002AC000</entry></row><row><entry /><entry>const DRAMTop = 0x4027FFFF</entry></row><row><entry /><entry>const UserDataSpace = b01</entry></row><row><entry /><entry>const UserProgramSpace = b00</entry></row><row><entry /><entry>const SupervisorDataSpace = b11</entry></row><row><entry /><entry>const SupervisorProgramSpace = b10</entry></row><row><entry /><entry>const ResetExceptionCycles = 0x2</entry></row><row><entry /><entry>cpu_adr_peri_masked[5:0] = cpu_mmu_adr[17:12]</entry></row><row><entry /><entry>cpu_adr_dram_masked[16:0] = cpu_mmu_adr & 0x003FFFE0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="119pt" align="left" /><tbody valign="top"><row><entry /><entry>if (prst_n = = 0) then</entry><entry>// Initialise everything</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>cpu_adr = cpu_mmu_adr[21:2]</entry></row><row><entry /><entry>peri_access_en = 0</entry></row><row><entry /><entry>dram_access_en = 0</entry></row><row><entry /><entry>mmu_cpu_data = peri_mmu_data</entry></row><row><entry /><entry>mmu_cpu_rdy = 0</entry></row><row><entry /><entry>mmu_cpu_berr = 0</entry></row><row><entry /><entry>post_reset_state = TRUE</entry></row><row><entry /><entry>access_initiated = FALSE</entry></row><row><entry /><entry>cpu_access_cnt = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// The following is used to determine if we are coming out</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>of reset for the purposes of</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// reset exception vector redirection. There may be a</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>convenient signal in the CPU core</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// that we could use instead of this.</entry></row><row><entry /><entry>if ((cpu_start_access = = 1) AND (cpu_access_cnt <</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>ResetExceptionCycles) AND</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>(clock_tick = = TRUE)) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>cpu_access_cnt = cpu_access_cnt +1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>post_reset_state = FALSE</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
1158PS1 Description: This section is at the top of the hierarchy that determines the validity of an access.
1159The address is tested to see which macro-region (i.e. Unused, CPU Subsystem or DRAM) it falls into or whether the reset exception vector is being accessed.
1160<tables id="TABLE-US-00027" num="00027"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>PS1:</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>if (cpu_mmu_adr >= UnusedBottom) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// The access is to an invalid area of the address</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>space. See section PS2</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif ((cpu_mmu_adr > DRAMTop) AND (cpu_mmu_adr <</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>UnusedBottom)) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>// We are in the CPU Subsystem/PEP Subsystem address</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>space. See section PS3</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>// Only remaining possibility is an access to DRAM address</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>space</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>// First we need to intercept the special case for the</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>reset exception vector</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (cpu_mmu_adr < 0x00000010) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>// The reset exception is being accessed. See section PS4</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif ((cpu_adr_dram_masked >= Region0Bottom) AND</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>(cpu_adr_dram_masked <=</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Region0Top) ) then</entry></row><row><entry /><entry>// We are in Region0. See section PS5</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif ((cpu_adr_dram_masked >= RegionNBottom) AND</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>(cpu_adr_dram_masked <=</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>RegionNTop) ) then // we are in RegionN</entry></row><row><entry /><entry>// Repeat the Region0 (i.e. section PS5) logic for</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>each of Region1 to Region7</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>else // We could end up here if there were gaps in the</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>DRAM regions</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>peri_access_en = 0</entry></row><row><entry /><entry>dram_access_en = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>mmu_cpu_berr = 1</entry><entry>// we have an unknown access error,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>most likely due to hitting</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>mmu_cpu_rdy = 0</entry><entry>// a gap in the DRAM regions</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>// Only thing remaining is to implement a bus timeout</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>function. This is done in PS6</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>end</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
1161PS2 Description: Accesses to the large unused area of the address space are trapped by this section. No bus transactions are initiated and the mmu_cpu_berr signal is asserted.
1162<tables id="TABLE-US-00028" num="00028"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>PS2:</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (cpu_mmu_adr >= UnusedBottom) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>peri_access_en = 0 // The access is to an invalid area</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>of the address space</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>dram_access_en = 0</entry></row><row><entry /><entry>mmu_cpu_berr = 1</entry></row><row><entry /><entry>mmu_cpu_rdy = 0</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
1163PS3 Description: This section deals with accesses to CPU Subsystem peripherals, including the MMU itself. If the MMU registers are being accessed then no external bus transactions are required. Access to the MMU registers is only permitted if the CPU is making a data access from supervisor mode, otherwise a bus error is asserted and the access terminated. For non-MMU accesses then transactions occur over the CPU Subsystem Bus and each peripheral is responsible for determining whether or not the CPU is in the correct mode (based on the cpu_acode signals) to be permitted access to its registers. Note that all of the PEP registers are accessed via the PCU which is on the CPU Subsystem Bus.
1164<tables id="TABLE-US-00029" num="00029"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>PS3:</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="252pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif ((cpu_mmu_adr > DRAMTop) AND (cpu_mmu_adr <</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="left" /><tbody valign="top"><row><entry>UnusedBottom)) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="238pt" align="left" /><tbody valign="top"><row><entry /><entry>// We are in the CPU Subsystem/PEP Subsystem address</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="left" /><tbody valign="top"><row><entry>space</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="238pt" align="left" /><tbody valign="top"><row><entry /><entry>cpu_adr = cpu_mmu_adr[21:2]</entry></row><row><entry /><entry>if (cpu_adr_peri_masked = = MMU_base) then // access is</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="left" /><tbody valign="top"><row><entry>to local registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="224pt" align="left" /><tbody valign="top"><row><entry /><entry>peri_access_en = 0</entry></row><row><entry /><entry>dram_access_en = 0</entry></row><row><entry /><entry>if (cpu_acode = = SupervisorDataSpace) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="210pt" align="left" /><tbody valign="top"><row><entry /><entry>for (i=0; i<26; i++) {</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="196pt" align="left" /><tbody valign="top"><row><entry /><entry>if ((i = = cpu_mmu_adr[6:2]) then // selects the</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="left" /><tbody valign="top"><row><entry>addressed register</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="84pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>if (cpu_rwn = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="98pt" align="left" /><colspec colname="1" colwidth="119pt" align="left" /><colspec colname="2" colwidth="49pt" align="left" /><tbody valign="top"><row><entry /><entry>mmu_cpu_data[16:0] = MMUReg[i]</entry><entry>// MMUReg[i]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="left" /><tbody valign="top"><row><entry>is one of the</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="98pt" align="left" /><colspec colname="1" colwidth="119pt" align="left" /><colspec colname="2" colwidth="49pt" align="left" /><tbody valign="top"><row><entry /><entry>mmu_cpu_rdy = 1</entry><entry>// registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="left" /><tbody valign="top"><row><entry>in Table</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="98pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>mmu_cpu_berr = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="84pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>else // write cycle</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="98pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>MMUReg[i] = cpu_dataout[16:0]</entry></row><row><entry /><entry>mmu_cpu_rdy = 1</entry></row><row><entry /><entry>mmu_cpu_berr = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="196pt" align="left" /><tbody valign="top"><row><entry /><entry>else // there is no register mapped to this</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="left" /><tbody valign="top"><row><entry>address</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="84pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>mmu_cpu_berr = 1 // do we really want a</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="left" /><tbody valign="top"><row><entry>bus_error here as registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="84pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>mmu_cpu_rdy = 0 // are just mirrored in other</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="left" /><tbody valign="top"><row><entry>blocks</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="224pt" align="left" /><tbody valign="top"><row><entry /><entry>else // we have an access violation</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="210pt" align="left" /><tbody valign="top"><row><entry /><entry>mmu_cpu_berr = 1</entry></row><row><entry /><entry>mmu_cpu_rdy = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="238pt" align="left" /><tbody valign="top"><row><entry /><entry>else // access is to something else on the CPU Subsystem</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="left" /><tbody valign="top"><row><entry>Bus</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="224pt" align="left" /><tbody valign="top"><row><entry /><entry>peri_access_en = 1</entry></row><row><entry /><entry>dram_access_en = 0</entry></row><row><entry /><entry>mmu_cpu_data = peri_mmu_data</entry></row><row><entry /><entry>mmu_cpu_rdy = peri_mmu_rdy</entry></row><row><entry /><entry>mmu_cpu_berr = peri_mmu_berr</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
1165PS4 Description: The only correct accesses to the locations beneath 0x00000010 are fetches of the reset trap handling routine and these should be the first accesses after reset. Here we trap all other accesses to these locations regardless of the CPU mode. The most likely cause of such an access will be the use of a null pointer in the program executing on the CPU.
1166<tables id="TABLE-US-00030" num="00030"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>PS4:</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (cpu_mmu_adr < 0x00000010) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>if (post_reset_state = = TRUE)) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>cpu adr = cpu mmu adr[21:2]</entry></row><row><entry /><entry>peri_access_en = 1</entry></row><row><entry /><entry>dram_access_en = 0</entry></row><row><entry /><entry>mmu_cpu_data = peri_mmu_data</entry></row><row><entry /><entry>mmu_cpu_rdy = peri_mmu_rdy</entry></row><row><entry /><entry>mmu_cpu_berr = peri_mmu_berr</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>else // we have a problem (almost certainly a null</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>pointer)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>peri_access_en = 0</entry></row><row><entry /><entry>dram_access_en = 0</entry></row><row><entry /><entry>mmu_cpu_berr = 1</entry></row><row><entry /><entry>mmu_cpu_rdy = 0</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
1167PS5 Description: This large section of pseudocode simply checks whether the access is within the bounds of DRAM Region0 and if so whether or not the access is of a type permitted by the Region0Control register. If the access is permitted then a DRAM access is initiated. If the access is not of a type permitted by the Region0Control register then the access is terminated with a bus error.
1168<tables id="TABLE-US-00031" num="00031"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>PS5:</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="210pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif ((cpu_adr_dram_masked >= Region0Bottom)</entry><entry>AND</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>(cpu_adr_dram_masked <=</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Region0Top) ) then // we are in Region0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>cpu_adr = cpu_mmu_adr[21:2]</entry></row><row><entry /><entry>if (cpu_rwn = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><tbody valign="top"><row><entry /><entry>if ((cpu_acode = = SupervisorProgramSpace</entry><entry>AND</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>Region0Control[2] = = 1))</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><tbody valign="top"><row><entry /><entry>OR (cpu_acode = = UserProgramSpace</entry><entry>AND</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>Region0Control[5] = = 1)) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="77pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>// this is a valid instruction</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>fetch from Region0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="77pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>// The dram_cpu_data bus goes</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>directly to the LEON</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="77pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>// AHB bridge which also handles</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>the hready generation</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>peri_access_en = 0</entry></row><row><entry /><entry>dram_access_en = 1</entry></row><row><entry /><entry>mmu_cpu_berr = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif ((cpu_acode = = SupervisorDataSpace</entry><entry>AND</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>Region0Control[0] = = 1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><tbody valign="top"><row><entry /><entry> OR (cpu_acode = = UserDataSpace</entry><entry>AND</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>Region0Control[3] = = 1)) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="161pt" align="left" /><colspec colname="1" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry> // this is a valid</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>read access from Region0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>peri_access_en = 0</entry></row><row><entry /><entry>dram_access_en = 1</entry></row><row><entry /><entry>mmu_cpu_berr = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="119pt" align="left" /><colspec colname="2" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry><entry> // we have an access</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>violation</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>peri_access_en = 0</entry></row><row><entry /><entry>dram_access_en = 0</entry></row><row><entry /><entry>mmu_cpu_berr = 1</entry></row><row><entry /><entry>mmu_cpu_rdy = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="119pt" align="left" /><colspec colname="2" colwidth="112pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry><entry>// it is a write access</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><tbody valign="top"><row><entry /><entry>if ((cpu_acode = = SupervisorDataSpace</entry><entry>AND</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>Region0Control[1] = = 1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="154pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><tbody valign="top"><row><entry /><entry>OR (cpu_acode = = UserDataSpace</entry><entry>AND</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>Region0Control[4] = = 1)) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="161pt" align="left" /><colspec colname="1" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry>// this is a valid</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>write access to Region0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>peri_access_en = 0</entry></row><row><entry /><entry>dram_access_en = 1</entry></row><row><entry /><entry>mmu_cpu_berr = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="119pt" align="left" /><colspec colname="2" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry><entry> // we have an access</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>violation</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>peri_access_en = 0</entry></row><row><entry /><entry>dram_access_en = 0</entry></row><row><entry /><entry>mmu_cpu_berr = 1</entry></row><row><entry /><entry>mmu_cpu_rdy = 0</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
1169PS6 Description: This final section of pseudocode deals with the special case of a bus timeout. This occurs when an access has been initiated but has not completed before the BusTimeout number of pclk cycles. While access to both DRAM and CPU/PEP Subsystem registers will take a variable number of cycles (due to DRAM traffic, PCU command execution or the different timing required to access registers in imported IP) each access should complete before a timeout occurs. Therefore it should not be possible to stall the CPU by locking either the CPU Subsystem or DIU buses. However given the fatal effect such a stall would have it is considered prudent to implement bus timeout detection.
1170<tables id="TABLE-US-00032" num="00032"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>PS6:</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// Only thing remaining is to implement a bus timeout</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>function.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>if ((cpu_start_access = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>access_initiated = TRUE</entry></row><row><entry /><entry>timeout_countdown = BusTimeout</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>if ((mmu_cpu_rdy = = 1 ) OR (mmu_cpu_berr = =1 )) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>access_initiated = FALSE</entry></row><row><entry /><entry>peri_access_en = 0</entry></row><row><entry /><entry>dram_access_en = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>if ((clock_tick = = TRUE) AND (access_initiated = = TRUE) AND</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>(BusTimeout != 0))</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>if (timeout_countdown > 0) then</entry></row><row><entry /><entry>timeout_countdown − −</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>else // timeout has occurred</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry>peri_access_en = 0</entry><entry>// abort the access</entry></row><row><entry /><entry>dram_access_en = 0</entry></row><row><entry /><entry>mmu_cpu_berr = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>mmu_cpu_rdy = 0</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 11.7 LEON Caches
1171The version of LEON implemented on SoPEC features 1 kB of ICache and 1 kB of DCache. Both caches are direct mapped and feature 8 word lines so their data RAMs are arranged as 32×256-bit and their tag RAMs as 32×30-bit (itag) or 32×32-bit (dtag). Like most of the rest of the LEON code used on SoPEC the cache controllers are taken from the leon2-1.0.7 release. The LEON cache controllers and cache RAMs have been modified to ensure that an entire 256-bit line is refilled at a time to make maximum use out of the memory bandwidth offered by the embedded DRAM organization (DRAM lines are also 256-bit). The data cache controller has also been modified to ensure that user mode code cannot access the DCache contents unless it is authorised to do so. A block diagram of the LEON CPU core as implemented on SoPEC is shown in <figref idref="DRAWINGS">FIG. 23</figref> below.
1172In this diagram dotted lines are used to indicate hierarchy and red items represent signals or wrappers added as part of the SoPEC modifications. LEON makes heavy use of VHDL records and the records used in the CPU core are described in Table 25. Unless otherwise stated the records are defined in the iface.vhd file (part of the LEON release) and this should be consulted for a complete breakdown of the record elements.
1173<tables id="TABLE-US-00033" num="00033"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 25</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Relevant LEON records</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>Record Name</entry><entry>Description</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>rfi</entry><entry>Register File Input record. Contains</entry></row><row><entry /><entry /><entry>address, datain and control signals for</entry></row><row><entry /><entry /><entry>the register file.</entry></row><row><entry /><entry>rfo</entry><entry>Register File Output record. Contains the</entry></row><row><entry /><entry /><entry>data out of the dual read port register</entry></row><row><entry /><entry /><entry>file.</entry></row><row><entry /><entry>ici</entry><entry>Instruction Cache In record. Contains</entry></row><row><entry /><entry /><entry>program counters from different stages</entry></row><row><entry /><entry /><entry>of the pipeline and various control signals</entry></row><row><entry /><entry>ico</entry><entry>Instruction Cache Out record. Contains the</entry></row><row><entry /><entry /><entry>fetched instruction data and various control</entry></row><row><entry /><entry /><entry>signals. This record is also sent to the</entry></row><row><entry /><entry /><entry>DCache (i.e. icol) so that diagnostic</entry></row><row><entry /><entry /><entry>accesses (e.g. lda/sta) can be serviced.</entry></row><row><entry /><entry>dci</entry><entry>Data Cache In record. Contains address</entry></row><row><entry /><entry /><entry>and data buses from different stages</entry></row><row><entry /><entry /><entry>of the pipeline (execute & memory)</entry></row><row><entry /><entry /><entry>and various control signals</entry></row><row><entry /><entry>dco</entry><entry>Data Cache Out record. Contains the data</entry></row><row><entry /><entry /><entry>retrieved from either memory or the</entry></row><row><entry /><entry /><entry>caches and various control signals. This</entry></row><row><entry /><entry /><entry>record is also sent to the ICache (i.e.</entry></row><row><entry /><entry /><entry>dcol) so that diagnostic accesses (e.g.</entry></row><row><entry /><entry /><entry>lda/sta) can be serviced.</entry></row><row><entry /><entry>iui</entry><entry>Integer Unit In record. This record</entry></row><row><entry /><entry /><entry>contains the interrupt request level</entry></row><row><entry /><entry /><entry>and a record for use with LEONs Debug</entry></row><row><entry /><entry /><entry>Support Unit (DSU)</entry></row><row><entry /><entry>iuo</entry><entry>Integer Unit Out record. This record</entry></row><row><entry /><entry /><entry>contains the acknowledged interrupt</entry></row><row><entry /><entry /><entry>request level with control signals and</entry></row><row><entry /><entry /><entry>a record for use with LEONs Debug</entry></row><row><entry /><entry /><entry>Support Unit (DSU)</entry></row><row><entry /><entry>mcii</entry><entry>Memory to Cache Icache In record.</entry></row><row><entry /><entry /><entry>Contains the address of an Icache miss</entry></row><row><entry /><entry /><entry>and various control signals</entry></row><row><entry /><entry>mcio</entry><entry>Memory to Cache Icache Out record.</entry></row><row><entry /><entry /><entry>Contains the returned data from memory</entry></row><row><entry /><entry /><entry>and various control signals</entry></row><row><entry /><entry>mcdi</entry><entry>Memory to Cache Dcache In record.</entry></row><row><entry /><entry /><entry>Contains the address and data of a</entry></row><row><entry /><entry /><entry>Dcache miss or write and various</entry></row><row><entry /><entry /><entry>control signals</entry></row><row><entry /><entry>mcdo</entry><entry>Memory to Cache Dcache Out record.</entry></row><row><entry /><entry /><entry>Contains the returned data from</entry></row><row><entry /><entry /><entry>memory and various control signals</entry></row><row><entry /><entry>ahbi</entry><entry>AHB In record. This is the input</entry></row><row><entry /><entry /><entry>record for an AHB master and contains</entry></row><row><entry /><entry /><entry>the data bus and AHB control signals.</entry></row><row><entry /><entry /><entry>The destination for the signals in this</entry></row><row><entry /><entry /><entry>record is the AHB controller. This</entry></row><row><entry /><entry /><entry>record is defined in the amba.vhd file</entry></row><row><entry /><entry>ahbo</entry><entry>AHB Out record. This is the output record</entry></row><row><entry /><entry /><entry>for an AHB master and contains the address</entry></row><row><entry /><entry /><entry>and data buses and AHB control signals.</entry></row><row><entry /><entry /><entry>The AHB controller drives the signals in</entry></row><row><entry /><entry /><entry>this record. This record is defined in</entry></row><row><entry /><entry /><entry>the amba.vhd file</entry></row><row><entry /><entry>ahbsi</entry><entry>AHB Slave In record. This is the input</entry></row><row><entry /><entry /><entry>record for an AHB slave and contains</entry></row><row><entry /><entry /><entry>the address and data buses and AHB control</entry></row><row><entry /><entry /><entry>signals. It is used by the DCache to</entry></row><row><entry /><entry /><entry>facilitate cache snooping (this feature</entry></row><row><entry /><entry /><entry>is not enabled in SoPEC). This record</entry></row><row><entry /><entry /><entry>is defined in the amba.vhd file</entry></row><row><entry /><entry>crami</entry><entry>Cache RAM In record. This record is</entry></row><row><entry /><entry /><entry>composed of records of records which</entry></row><row><entry /><entry /><entry>contain the address, data and tag</entry></row><row><entry /><entry /><entry>entries with associated control signals</entry></row><row><entry /><entry /><entry>for both the ICache RAM and DCache RAM</entry></row><row><entry /><entry>cramo</entry><entry>Cache RAM Out record. This record is</entry></row><row><entry /><entry /><entry>composed of records of records which</entry></row><row><entry /><entry /><entry>contain the data and tag entries with</entry></row><row><entry /><entry /><entry>associated control signals for both the</entry></row><row><entry /><entry /><entry>ICache RAM and DCache RAM</entry></row><row><entry /><entry>iline_rdy</entry><entry>Control signal from the ICache controller</entry></row><row><entry /><entry /><entry>to the instruction cache memory. This</entry></row><row><entry /><entry /><entry>signal is active (high) when a full 256-</entry></row><row><entry /><entry /><entry>bit line (on dram_cpu_data) is to be</entry></row><row><entry /><entry /><entry>written to cache memory.</entry></row><row><entry /><entry>dline_rdy</entry><entry>Control signal from the DCache controller</entry></row><row><entry /><entry /><entry>to the data cache memory. This signal is</entry></row><row><entry /><entry /><entry>active (high) when a full 256-bit line</entry></row><row><entry /><entry /><entry>(on dram_cpu_data) is to be written to</entry></row><row><entry /><entry /><entry>cache memory.</entry></row><row><entry /><entry>dram_cpu_data</entry><entry>256-bit data bus from the embedded DRAM</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 11.7.1 Cache Controllers
1174The LEON cache module consists of three components: the ICache controller (icache.vhd), the DCache controller (dcache.vhd) and the AHB bridge (acache.vhd) which translates all cache misses into memory requests on the AHB bus.
1175In order to enable full line refill operation a few changes had to be made to the cache controllers. The ICache controller was modified to ensure that whenever a location in the cache was updated (i.e. the cache was enabled and was being refilled from DRAM) all locations on that cache line had their valid bits set to reflect the fact that the full line was updated. The iline_rdy signal is asserted by the ICache controller when this happens and this informs the cache wrappers to update all locations in the idata RAM for that line.
1176A similar change was made to the DCache controller except that the entire line was only updated following a read miss and that existing write through operation was preserved. The DCache controller uses the dline_rdy signal to instruct the cache wrapper to update all locations in the ddata RAM for a line. An additional modification was also made to ensure that a double-word load instruction from a non-cached location would only result in one read access to the DIU i.e. the second read would be serviced by the data cache. Note that if the DCache is turned off then a double-word load instruction will cause two DIU read accesses to occur even though they will both be to the same 256-bit DRAM line.
1177The DCache controller was further modified to ensure that user mode code cannot access cached data to which it does not have permission (as determined by the relevant RegionNControl register settings at the time the cache line was loaded). This required an extra 2 bits of tag information to record the user read and write permissions for each cache line. These user access permissions can be updated in the same manner as the other tag fields (i.e. address and valid bits) namely by line refill, STA instruction or cache flush. The user access permission bits are checked every time user code attempts to access the data cache and if the permissions of the access do not agree with the permissions returned from the tag RAM then a cache miss occurs. As the MMU evaluates the access permissions for every cache miss it will generate the appropriate exception for the forced cache miss caused by the errant user code. In the case of a prohibited read access the trap will be immediate while a prohibited write access will result in a deferred trap. The deferred trap results from the fact that the prohibited write is committed to a write buffer in the DCache controller and program execution continues until the prohibited write is detected by the MMU which may be several cycles later. Because the errant write was treated as a write miss by the DCache controller (as it did not match the stored user access permissions) the cache contents were not updated and so remain coherent with the DRAM contents (which do not get updated because the MMU intercepted the prohibited write). Supervisor mode code is not subject to such checks and so has free access to the contents of the data cache.
1178In addition to AHB bridging, the ACache component also performs arbitration between ICache and DCache misses when simultaneous misses occur (the DCache always wins) and implements the Cache Control Register (CCR). The leon2-1.0.7 release is inconsistent in how it handles cacheability: For instruction fetches the cacheability (i.e. is the access to an area of memory that is cacheable) is determined by the ICache controller while the ACache determines whether or not a data access is cacheable. To further complicate matters the DCache controller does determine if an access resulting from a cache snoop by another AHB master is cacheable (Note that the SoPEC ASIC does not implement cache snooping as it has no need to do so). This inconsistency has been cleaned up in more recent LEON releases but is preserved here to minimise the number of changes to the LEON RTL. The cache controllers were modified to ensure that only DRAM accesses (as defined by the SoPEC memory map) are cached.
1179The only functionality removed as a result of the modifications was support for burst fills of the ICache. When enabled burst fills would refill an ICache line from the location where a miss occurred up to the end of the line. As the entire line is now refilled at once (when executing from DRAM) this functionality is no longer required. Furthermore more substantial modifications to the ICache controller would be needed if we wished to preserve this function without adversely affecting full line refills. The CCR was therefore modified to ensure that the instruction burst fetch bit (bit<b>16</b>) was tied low and could not be written to.
000011.7.1.1 LEON Cache Control Register
1180The CCR controls the operation of both the I and D caches. Note that the bitfields used on the SoPEC implementation of this register are based on the LEON v1.0.7 implementation and some bits have their values tied off. See section 4 of the LEON manual for a description of the LEON cache controllers.
1181<tables id="TABLE-US-00034" num="00034"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 26</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>LEON Cache Control Register</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="49pt" align="center" /><colspec colname="3" colwidth="112pt" align="left" /><tbody valign="top"><row><entry /><entry>Field Name</entry><entry>bit(s)</entry><entry>Description</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row><row><entry /><entry>ICS</entry><entry>1:0</entry><entry>Instruction cache state:</entry></row><row><entry /><entry /><entry /><entry>00 - disabled</entry></row><row><entry /><entry /><entry /><entry>01 - frozen</entry></row><row><entry /><entry /><entry /><entry>10 - disabled</entry></row><row><entry /><entry /><entry /><entry>11 - enabled</entry></row><row><entry /><entry>Reserved</entry><entry>13:6 </entry><entry>Reserved. Reads as 0.</entry></row><row><entry /><entry>DCS</entry><entry>3:2</entry><entry>Data cache state:</entry></row><row><entry /><entry /><entry /><entry>00 - disabled</entry></row><row><entry /><entry /><entry /><entry>01 - frozen</entry></row><row><entry /><entry /><entry /><entry>10 - disabled</entry></row><row><entry /><entry /><entry /><entry>11 - enabled</entry></row><row><entry /><entry>IF</entry><entry>4</entry><entry>ICache freeze on interrupt</entry></row><row><entry /><entry /><entry /><entry>0 - Do not freeze the ICache</entry></row><row><entry /><entry /><entry /><entry>contents on taking an interrupt</entry></row><row><entry /><entry /><entry /><entry>1 - Freeze the ICache contents</entry></row><row><entry /><entry /><entry /><entry>on taking an interrupt</entry></row><row><entry /><entry>DF</entry><entry>5</entry><entry>DCache freeze on interrupt</entry></row><row><entry /><entry /><entry /><entry>0 - Do not freeze the DCache</entry></row><row><entry /><entry /><entry /><entry>contents on taking an interrupt</entry></row><row><entry /><entry /><entry /><entry>1 - Freeze the DCache contents</entry></row><row><entry /><entry /><entry /><entry>on taking an interrupt</entry></row><row><entry /><entry>Reserved</entry><entry>13:6 </entry><entry>Reserved. Reads as 0.</entry></row><row><entry /><entry>DP</entry><entry>14</entry><entry>Data cache flush pending.</entry></row><row><entry /><entry /><entry /><entry>0 - No DCache flush in progress</entry></row><row><entry /><entry /><entry /><entry>1 - DCache flush in progress</entry></row><row><entry /><entry /><entry /><entry>This bit is Readonly.</entry></row><row><entry /><entry>IP</entry><entry>15</entry><entry>Instruction cache flush pending.</entry></row><row><entry /><entry /><entry /><entry>0 - No ICache flush in progress</entry></row><row><entry /><entry /><entry /><entry>1 - ICache flush in progress</entry></row><row><entry /><entry /><entry /><entry>This bit is Readonly.</entry></row><row><entry /><entry>IB</entry><entry>16</entry><entry>Instruction burst fetch enable.</entry></row><row><entry /><entry /><entry /><entry>This bit is tied low on SoPEC</entry></row><row><entry /><entry /><entry /><entry>because it would interfere with</entry></row><row><entry /><entry /><entry /><entry>the operation of the cache</entry></row><row><entry /><entry /><entry /><entry>wrappers. Burst refill</entry></row><row><entry /><entry /><entry /><entry>functionality is automatically</entry></row><row><entry /><entry /><entry /><entry>provided in SoPEC by the cache</entry></row><row><entry /><entry /><entry /><entry>wrappers.</entry></row><row><entry /><entry>Reserved</entry><entry>20:17</entry><entry>Reserved. Reads as 0.</entry></row><row><entry /><entry>FI</entry><entry>21</entry><entry>Flush instruction cache. Writing</entry></row><row><entry /><entry /><entry /><entry>a 1 this bit will flush the</entry></row><row><entry /><entry /><entry /><entry>ICache. Reads as 0.</entry></row><row><entry /><entry>FD</entry><entry>22</entry><entry>Flush data cache. Writing a 1</entry></row><row><entry /><entry /><entry /><entry>this bit will flush the DCache.</entry></row><row><entry /><entry /><entry /><entry>Reads as 0.</entry></row><row><entry /><entry>DS</entry><entry>23</entry><entry>Data cache snoop enable. This</entry></row><row><entry /><entry /><entry /><entry>bit is tied low in SoPEC as</entry></row><row><entry /><entry /><entry /><entry>there is no requirement to</entry></row><row><entry /><entry /><entry /><entry>snoop the data cache.</entry></row><row><entry /><entry>Reserved</entry><entry>31:24</entry><entry>Reserved. Reads as 0.</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 11.7.2 Cache Wrappers
1182The cache RAMs used in the leon2-1.0.7 release needed to be modified to support full line refills and the correct IBM macros also needed to be instantiated. Although they are described as RAMs throughout this document (for consistency), register arrays are actually used to implement the cache RAMs. This is because IBM SRAMs were not available in suitable configurations (offered configurations were too big) to implement either the tag or data cache RAMs. Both instruction and data tag RAMs are implemented using dual port (1 Read & 1 Write) register arrays and the clocked write-through versions of the register arrays were used as they most closely approximate the single port SRAM LEON expects to see.
000011.7.2.1 Cache Tag RAM Wrappers
1183The itag and dtag RAMs differ only in their width—the itag is a 32×30 array while the dtag is a 32×32 array with the extra 2 bits being used to record the user access permissions for each line. When read using a LDA instruction both tags return 32-bit words. The tag fields are described in Table 27 and Table 28 below. Using the IBM naming conventions the register arrays used for the tag RAMs are called RA032X30D2P2W1R1M3 for the itag and RA032X32D2P2W1R1M3 for the dtag. The ibm_syncram wrapper used for the tag RAMs is a simple affair that just maps the wrapper ports on to the appropriate ports of the IBM register array and ensures the output data has the correct timing by registering it. The tag RAMs do not require any special modifications to handle full line refills.
1184<tables id="TABLE-US-00035" num="00035"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 27</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>LEON Instruction Cache Tag</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="42pt" align="center" /><colspec colname="3" colwidth="119pt" align="left" /><tbody valign="top"><row><entry /><entry>Field Name</entry><entry>bit(s)</entry><entry>Description</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row><row><entry /><entry>Valid</entry><entry>7:0</entry><entry>Each valid bit indicates whether or</entry></row><row><entry /><entry /><entry /><entry>not the corresponding word of the</entry></row><row><entry /><entry /><entry /><entry>cache line contains valid data</entry></row><row><entry /><entry>Reserved</entry><entry>9:8</entry><entry>Reserved - these bits do not exist</entry></row><row><entry /><entry /><entry /><entry>in the itag RAM. Reads as 0.</entry></row><row><entry /><entry>Address</entry><entry>31:10</entry><entry>The tag address of the cache line</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
1185<tables id="TABLE-US-00036" num="00036"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 28</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>LEON Data Cache Tag</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="42pt" align="center" /><colspec colname="3" colwidth="119pt" align="left" /><tbody valign="top"><row><entry /><entry>Field Name</entry><entry>bit(s)</entry><entry>Description</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row><row><entry /><entry>Valid</entry><entry>7:0</entry><entry>Each valid bit indicates whether or</entry></row><row><entry /><entry /><entry /><entry>not the corresponding word of the</entry></row><row><entry /><entry /><entry /><entry>cache line contains valid data</entry></row><row><entry /><entry>URP</entry><entry>8</entry><entry>User read permission.</entry></row><row><entry /><entry /><entry /><entry>0 - User mode reads will force a</entry></row><row><entry /><entry /><entry /><entry>refill of this line</entry></row><row><entry /><entry /><entry /><entry>1 - User mode code can read from</entry></row><row><entry /><entry /><entry /><entry>this cache line.</entry></row><row><entry /><entry>UWP</entry><entry>9</entry><entry>User write permission.</entry></row><row><entry /><entry /><entry /><entry>0 - User mode writes will not be</entry></row><row><entry /><entry /><entry /><entry>written to the cache</entry></row><row><entry /><entry /><entry /><entry>1 - User mode code can write to</entry></row><row><entry /><entry /><entry /><entry>this cache line.</entry></row><row><entry /><entry>Address</entry><entry>31:10</entry><entry>The tag address of the cache line</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 11.7.2.2 Cache Data RAM Wrappers
1186The cache data RAM contains the actual cached data and nothing else. Both the instruction and data cache data RAMs are implemented using 8 32×32-bit register arrays and some additional logic to support full line refills. Using the IBM naming conventions the register arrays used for the tag RAMs are called RA032X32D2P2W1R1M3. The ibm_cdram_wrap wrapper used for the tag RAMs is shown in <figref idref="DRAWINGS">FIG. 24</figref> below.
1187To the cache controllers the cache data RAM wrapper looks like a 256×32 single port SRAM (which is what they expect to see) with an input to indicate when a full line refill is taking place (the line_rdy signal). Internally the 8-bit address bus is split into a 5-bit lineaddress, which selects one of the 32 256-bit cache lines, and a 3-bit wordaddress which selects one of the 8 32-bit words on the cache line. Thus each of the 8 32×32 register arrays contains one 32-bit word of each cache line. When a full line is being refilled (indicated by both the line rdy and write signals being high) every register array is written to with the appropriate 32 bits from the linedatain bus which contains the 256-bit line returned by the DIU after a cache miss. When just one word of the cache line is to be written (indicated by the write signal being high while the line_rdy is low) then the wordaddress is used to enable the write signal to the selected register array only—all other write enable signals are kept low. The data cache controller handles byte and half-word write by means of a read-modify-write operation so writes to the cache data RAM are always 32-bit.
1188The wordaddress is also used to select the correct 32-bit word from the cache line to return to the LEON integer unit.
000011.8 Realtime Debug Unit (RDU)
1189The RDU facilitates the observation of the contents of most of the CPU addressable registers in the SoPEC device in addition to some pseudo-registers in realtime. The contents of pseudo-registers, i.e. registers that are collections of otherwise unobservable signals and that do not affect the functionality of a circuit, are defined in each block as required. Many blocks do not have pseudo-registers and some blocks (e.g. ROM, PSS) do not make debug information available to the RDU as it would be of little value in realtime debug.
1190Each block that supports realtime debug observation features a DebugSelect register that controls a local mux to determine which register is output on the block's data bus (i.e. block_cpu_data). One small drawback with reusing the blocks data bus is that the debug data cannot be present on the same bus during a CPU read from the block. An accompanying active high block_cpu_debug_valid signal is used to indicate when the data bus contains valid debug data and when the bus is being used by the CPU. There is no arbitration for the bus as the CPU will always have access when required. A block diagram of the RDU is shown in <figref idref="DRAWINGS">FIG. 25</figref>.
1191<tables id="TABLE-US-00037" num="00037"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 29</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>RDU I/Os</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="28pt" align="center" /><colspec colname="4" colwidth="84pt" align="left" /><tbody valign="top"><row><entry>Port name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="28pt" align="center" /><colspec colname="4" colwidth="84pt" align="left" /><tbody valign="top"><row><entry>diu_cpu_data</entry><entry>32</entry><entry>In</entry><entry>Read data bus from the</entry></row><row><entry /><entry /><entry /><entry>DIU block</entry></row><row><entry>cpr_cpu_data</entry><entry>32</entry><entry>In</entry><entry>Read data bus from the</entry></row><row><entry /><entry /><entry /><entry>CPR block</entry></row><row><entry>gpio_cpu_data</entry><entry>32</entry><entry>In</entry><entry>Read data bus from the</entry></row><row><entry /><entry /><entry /><entry>GPIO block</entry></row><row><entry>icu_cpu_data</entry><entry>32</entry><entry>In</entry><entry>Read data bus from the</entry></row><row><entry /><entry /><entry /><entry>ICU block</entry></row><row><entry>lss_cpu_data</entry><entry>32</entry><entry>In</entry><entry>Read data bus from the</entry></row><row><entry /><entry /><entry /><entry>LSS block</entry></row><row><entry>pcu_cpu_debug_data</entry><entry>32</entry><entry>In</entry><entry>Read data bus from the</entry></row><row><entry /><entry /><entry /><entry>PCU block</entry></row><row><entry>scb_cpu_data</entry><entry>32</entry><entry>In</entry><entry>Read data bus from the</entry></row><row><entry /><entry /><entry /><entry>SCB block</entry></row><row><entry>tim_cpu_data</entry><entry>32</entry><entry>In</entry><entry>Read data bus from the</entry></row><row><entry /><entry /><entry /><entry>TIM block</entry></row><row><entry>diu_cpu_debug_valid</entry><entry>1</entry><entry>In</entry><entry>Signal indicating the</entry></row><row><entry /><entry /><entry /><entry>data on the diu_cpu_data</entry></row><row><entry /><entry /><entry /><entry>bus is valid debug data.</entry></row><row><entry>tim_cpu_debug_valid</entry><entry>1</entry><entry>In</entry><entry>Signal indicating the</entry></row><row><entry /><entry /><entry /><entry>data on the tim_cpu_data</entry></row><row><entry /><entry /><entry /><entry>bus is valid debug data.</entry></row><row><entry>scb_cpu_debug_valid</entry><entry>1</entry><entry>In</entry><entry>Signal indicating the</entry></row><row><entry /><entry /><entry /><entry>data on the scb_cpu_data</entry></row><row><entry /><entry /><entry /><entry>bus is valid debug data.</entry></row><row><entry>pcu_cpu_debug_valid</entry><entry>1</entry><entry>In</entry><entry>Signal indicating the</entry></row><row><entry /><entry /><entry /><entry>data on the pcu_cpu_data</entry></row><row><entry /><entry /><entry /><entry>bus is valid debug data.</entry></row><row><entry>lss_cpu_debug_valid</entry><entry>1</entry><entry>In</entry><entry>Signal indicating the</entry></row><row><entry /><entry /><entry /><entry>data on the lss_cpu_data</entry></row><row><entry /><entry /><entry /><entry>bus is valid debug data.</entry></row><row><entry>icu_cpu_debug_valid</entry><entry>1</entry><entry>In</entry><entry>Signal indicating the</entry></row><row><entry /><entry /><entry /><entry>data on the icu_cpu_data</entry></row><row><entry /><entry /><entry /><entry>bus is valid debug data.</entry></row><row><entry>gpio_cpu_debug_valid</entry><entry>1</entry><entry>In</entry><entry>Signal indicating the</entry></row><row><entry /><entry /><entry /><entry>data on the gpio_cpu_data</entry></row><row><entry /><entry /><entry /><entry>bus is valid debug data.</entry></row><row><entry>cpr_cpu_debug_valid</entry><entry>1</entry><entry>In</entry><entry>Signal indicating the</entry></row><row><entry /><entry /><entry /><entry>data on the cpr_cpu_data</entry></row><row><entry /><entry /><entry /><entry>bus is valid debug data.</entry></row><row><entry>debug_data_out</entry><entry>32</entry><entry>Out</entry><entry>Output debug data to be</entry></row><row><entry /><entry /><entry /><entry>muxed on to the</entry></row><row><entry /><entry /><entry /><entry>PHI/GPIO/other pins</entry></row><row><entry>debug_data_valid</entry><entry>1</entry><entry>Out</entry><entry>Debug valid signal</entry></row><row><entry /><entry /><entry /><entry>indicating the validity</entry></row><row><entry /><entry /><entry /><entry>of the data on</entry></row><row><entry /><entry /><entry /><entry>debug_data_out. This</entry></row><row><entry /><entry /><entry /><entry>signal is used in all</entry></row><row><entry /><entry /><entry /><entry>debug configurations</entry></row><row><entry>debug_cntrl</entry><entry>33</entry><entry>Out</entry><entry>Control signal for</entry></row><row><entry /><entry /><entry /><entry>each debug data line</entry></row><row><entry /><entry /><entry /><entry>indicating whether or</entry></row><row><entry /><entry /><entry /><entry>not the debug data</entry></row><row><entry /><entry /><entry /><entry>should be selected by</entry></row><row><entry /><entry /><entry /><entry>the pin mux</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
1192As there are no spare pins that can be used to output the debug data to an external capture device some of the existing I/Os will have a debug multiplexer placed in front of them to allow them be used as debug pins. Furthermore not every pin that has a debug mux will always be available to carry the debug data as they may be engaged in their primary purpose e.g. as a GPIO pin. The RDU therefore outputs a debug_cntrl signal with each debug data bit to indicate whether the mux associated with each debug pin should select the debug data or the normal data for the pin. The DebugPinSel1 and DebugPinSel2 registers are used to determine which of the 33 potential debug pins are enabled for debug at any particular time.
1193As it may not always be possible to output a full 32-bit debug word every cycle the RDU supports the outputting of an n-bit sub-word every cycle to the enabled debug pins. Each debug test would then need to be re-run a number of times with a different portion of the debug word being output on the n-bit sub-word each time. The data from each run should then be correlated to create a full 32-bit (or whatever size is needed) debug word for every cycle. The debug_data_valid and pclk_out signals will accompany every sub-word to allow the data to be sampled correctly. The pclk_out signal is sourced close to its output pad rather than in the RDU to minimise the skew between the rising edge of the debug data signals (which should be registered close to their output pads) and the rising edge of pclk_out.
1194As multiple debug runs will be needed to obtain a complete set of debug data the n-bit sub-word will need to contain a different bit pattern for each run. For maximum flexibility each debug pin has an associated DebugDataSrc register that allows any of the 32 bits of the debug data word to be output on that particular debug data pin. The debug data pin must be enabled for debug operation by having its corresponding bit in the DebugPinSel registers set for the selected debug data bit to appear on the pin.
1195The size of the sub-word is determined by the number of enabled debug pins which is controlled by the DebugPinSel registers. Note that the debug_data_valid signal is always output. Furthermore debug_cntrl[0] (which is configured by DebugPinSel1) controls the mux for both the debug_data_valid and pclk_out signals as both of these must be enabled for any debug operation. The mapping of debug_data_out[n] signals onto individual pins will take place outside the RDU. This mapping is described in Table 30 below.
1196<tables id="TABLE-US-00038" num="00038"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 30</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>DebugPinSel mapping</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="133pt" align="left" /><tbody valign="top"><row><entry>bit #</entry><entry>Pin</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>DebugPinSel1</entry><entry>phi_frclk. The debug_data_valid signal</entry></row><row><entry /><entry>will appear on this pin when enabled.</entry></row><row><entry /><entry>Enabling this pin also automatically</entry></row><row><entry /><entry>enables the phi_readl pin which will</entry></row><row><entry /><entry>output the pclk_out signal</entry></row><row><entry>DebugPinSel2(0–31)</entry><entry>gpio[0 . . . 31]</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
1197<tables id="TABLE-US-00039" num="00039"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 31</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>RDU Configuration Registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="49pt" align="left" /><colspec colname="3" colwidth="28pt" align="center" /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="77pt" align="left" /><tbody valign="top"><row><entry>Address</entry><entry /><entry /><entry /><entry /></row><row><entry>offset</entry></row><row><entry>from</entry></row><row><entry>MMU<sub>—</sub></entry></row><row><entry>base</entry><entry>Register</entry><entry>#bits</entry><entry>Reset</entry><entry>Description</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="49pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="77pt" align="left" /><tbody valign="top"><row><entry>0x80</entry><entry>DebugSrc</entry><entry>4</entry><entry>0x00</entry><entry>Denotes which block</entry></row><row><entry /><entry /><entry /><entry /><entry>is supplying the debug</entry></row><row><entry /><entry /><entry /><entry /><entry>data. The encoding</entry></row><row><entry /><entry /><entry /><entry /><entry>of this block is given</entry></row><row><entry /><entry /><entry /><entry /><entry>below.</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - MMU</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - TIM</entry></row><row><entry /><entry /><entry /><entry /><entry>2 - LSS</entry></row><row><entry /><entry /><entry /><entry /><entry>3 - GPIO</entry></row><row><entry /><entry /><entry /><entry /><entry>4 - SCB</entry></row><row><entry /><entry /><entry /><entry /><entry>5 - ICU</entry></row><row><entry /><entry /><entry /><entry /><entry>6 - CPR</entry></row><row><entry /><entry /><entry /><entry /><entry>7 - DIU</entry></row><row><entry /><entry /><entry /><entry /><entry>8 - PCU</entry></row><row><entry>0x84</entry><entry>DebugPinSel1</entry><entry>1</entry><entry>0x0</entry><entry>Determines whether</entry></row><row><entry /><entry /><entry /><entry /><entry>the phi_frclk and</entry></row><row><entry /><entry /><entry /><entry /><entry>phi_readl pins are</entry></row><row><entry /><entry /><entry /><entry /><entry>used for debug output.</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - Pin outputs debug</entry></row><row><entry /><entry /><entry /><entry /><entry>data</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - Normal pin function</entry></row><row><entry>0x88</entry><entry>DebugPinSel2</entry><entry>32</entry><entry>0x0000<sub>—</sub></entry><entry>Determines whether a</entry></row><row><entry /><entry /><entry /><entry>0000</entry><entry>pin is used for debug</entry></row><row><entry /><entry /><entry /><entry /><entry>data output.</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - Pin outputs debug</entry></row><row><entry /><entry /><entry /><entry /><entry>data</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - Normal pin function</entry></row><row><entry>0x8C to</entry><entry>DebugDataSrc</entry><entry>32 × 5</entry><entry>0x00</entry><entry>Selects which bit of</entry></row><row><entry>0x108</entry><entry>[31:0]</entry><entry /><entry /><entry>the 32-bit debug data</entry></row><row><entry /><entry /><entry /><entry /><entry>word will be output on</entry></row><row><entry /><entry /><entry /><entry /><entry>debug_data_out[N]</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 11.9 Interrupt Operation
1198The interrupt controller unit (see chapter 14) generates an interrupt request by driving interrupt request lines with the appropriate interrupt level. LEON supports 15 levels of interrupt with level 15 as the highest level (the SPARC architecture manual [36] states that level 15 is non-maskable but we have the freedom to mask this if desired). The CPU will begin processing an interrupt exception when execution of the current instruction has completed and it will only do so if the interrupt level is higher than the current processor priority. If a second interrupt request arrives with the same level as an executing interrupt service routine then the exception will not be processed until the executing routine has completed.
1199When an interrupt trap occurs the LEON hardware will place the program counters (PC and nPC) into two local registers. The interrupt handler routine is expected, as a minimum, to place the PSR register in another local register to ensure that the LEON can correctly return to its pre-interrupt state. The 4-bit interrupt level (irl) is also written to the trap type (tt) field of the TBR (Trap Base Register) by hardware. The TBR then contains the vector of the trap handler routine the processor will then jump. The TBA (Trap Base Address) field of the TBR must have a valid value before any interrupt processing can occur so it should be configured at an early stage.
1200Interrupt pre-emption is supported while ET (Enable Traps) bit of the PSR is set. This bit is cleared during the initial trap processing. In initial simulations the ET bit was observed to be cleared for up to 30 cycles. This causes significant additional interrupt latency in the worst case where a higher priority interrupt arrives just as a lower priority one is taken.
1201The interrupt acknowledge cycles shown in <figref idref="DRAWINGS">FIG. 26</figref> below are derived from simulations of the LEON processor. The SoPEC toplevel interrupt signals used in this diagram map directly to the LEON interrupt signals in the iui and iuo records. An interrupt is asserted by driving its (encoded) level on the icu_cpu_ilevel[3:0] signals (which map to iui.irl[3:0]). The LEON core responds to this, with variable timing, by reflecting the level of the taken interrupt on the cpu_icu_ilevel[3:0] signals (mapped to iuo.irl[3:0]) and asserting the acknowledge signal cpu_iack (iuo.intack). The interrupt controller then removes the interrupt level one cycle after it has seen the level been acknowledged by the core. If there is another pending interrupt (of lower priority) then this should be driven on icu_cpu_ilevel[3:0] and the CPU will take that interrupt (the level 9 interrupt in the example below) once it has finished processing the higher priority interrupt. The cpu_icu_ilevel[3:0] signals always reflect the level of the last taken interrupt, even when the CPU has finished processing all interrupts.
000011.10 Boot Operation
1202See section 17.2 for a description of the SoPEC boot operation.
000011.11 Software Debug
1203Software debug mechanisms are discussed in the “SoPEC Software Debug” document [15].
000012 Serial Communications Block (SCB)
000012.1 Overview
1204The Serial Communications Block (SCB) handles the movement of all data between the SoPEC and the host device (e.g. PC) and between master and slave SoPEC devices. The main components of the SCB are a Full-Speed (FS) USB Device Core, a FS USB Host Core, a Inter-SoPEC Interface (ISI), a DMA manager, the SCB Map and associated control logic. The need for these components and the various types of communication they provide is evident in a multi-SoPEC printer configuration.
000012.1.1 Multi-SoPEC Systems
1205While single SoPEC systems are expected to form the majority of SoPEC systems the SoPEC device must also support its use in multi-SoPEC systems such as that shown in <figref idref="DRAWINGS">FIG. 27</figref>. A SoPEC may be assigned any one of a number of identities in a multi-SoPEC system. A SoPEC may be one or more of a PrintMaster, a LineSyncMaster, an ISIMaster, a StorageSoPEC or an ISISlave SoPEC.
000012.1.1.1 ISIMaster Device
1206The ISIMaster is the only device that controls the common ISI lines (see <figref idref="DRAWINGS">FIG. 30</figref>) and typically interfaces directly with the host. In most systems the ISIMaster will simply be the SoPEC connected to the USB bus. Future systems, however, may employ an ISI-Bridge chip to interface between the host and the ISI bus and in such systems the ISI-Bridge chip will be the ISIMaster. There can only be one ISIMaster on an ISI bus.
1207Systems with multiple SoPECs may have more than one host connection, for example there could be two SoPECs communicating with the external host over their FS USB links (this would of course require two USB cables to be connected), but still only one ISIMaster.
1208While it is not expected to be required, it is possible for a device to hand over its role as the ISIMaster to another device on the ISI i.e. the ISIMaster is not necessarily fixed.
000012.1.1.2 PrintMaster Device
1209The PrintMaster device is responsible for coordinating all aspects of the print operation. This includes starting the print operation in all printing SoPECs and communicating status back to the external host. When the ISIMaster is a SoPEC device it is also likely to be the PrintMaster as well. There may only be one PrintMaster in a system and it is most likely to be a SoPEC device.
000012.1.1.3 LineSyncMaster Device
1210The LineSyncMaster device generates the lsync pulse that all SoPECs in the system must synchronize their line outputs with. Any SoPEC in the system could act as a LineSyncMaster although the PrintMaster is probably the most likely candidate. It is possible that the LineSyncMaster may not be a SoPEC device at all—it could, for example, come from some OEM motor control circuitry. There may only be one LineSyncMaster in a system.
000012.1.1.4 Storage Device
1211For certain printer types it may be realistic to use one SoPEC as a storage device without using its print engine capability—that is to effectively use it as an ISI-attached DRAM. A storage SoPEC would receive data from the ISIMaster (most likely to be an ISI-Bridge chip) and then distribute it to the other SoPECs as required. No other type of data flow (e.g. ISISlave->storage SoPEC->ISISlave) would need to be supported in such a scenario. The SCB supports this functionality at no additional cost because the CPU handles the task of transferring outbound data from the embedded DRAM to the ISI transmit buffer. The CPU in a storage SoPEC will have almost nothing else to do.
000012.1.1.5 ISISlave Device
1212Multi-SoPEC systems will contain one or more ISISlave SoPECs. An ISISlave SoPEC is primarily used to generate dot data for the printhead IC it is driving. An ISISlave will not transmit messages on the ISI without first receiving permission to do so, via a ping packet (see section 12.4.4.6), from the ISIMaster
000012.1.1.6 ISI-Bridge Device
1213SoPEC is targeted at the low-cost small office/home office (SoHo) market. It may also be used in future systems that target different market segments which are likely to have a high speed interface capability. A future device, known as an ISI-Bridge chip, is envisaged which will feature both a high speed interface (such as High-Speed (HS) USB, Ethernet or IEEE1394) and one or more ISI interfaces. The use of multiple ISI buses would allow the construction of independent print systems within the one printer. The ISI-Bridge would be the ISIMaster for each of the ISI buses it interfaces to.
000012.1.1.7 External Host
1214The external host is most likely (but is not required) to be, a PC. Any system that can act as a USB host or that can interface to an ISI-Bridge chip could be the external host. In particular, with the development of USB On-The-Go (USB OTG), it is possible that a number of USB OTG enabled products such as PDAs or digital cameras will be able to directly interface with a SoPEC printer.
000012.1.1.8 External USB Device
1215The external USB device is most likely (but is not required) to be, a digital camera. Any system that can act as a USB device could be connected as an external USB device. This is to facilitate printing in the absence of a PC.
000012.1.2 Types of Communication
000012.1.2.1 Communications with External Host
1216The external host communicates directly with the ISIMaster in order to print pages. When the ISIMaster is a SoPEC, the communications channel is FS USB.
000012.1.2.1.1 External Host to ISIMaster Communication
1217The external host will need to communicate the following information to the ISIMaster device: <ul id="ul0095" list-style="none"><li id="ul0095-0001" num="0000"><ul id="ul0096" list-style="none"><li id="ul0096-0001" num="1218">Communications channel configuration and maintenance information</li><li id="ul0096-0002" num="1219">Most data destined for PrintMaster, ISISlave or storage SoPEC devices. This data is simply relayed by the ISIMaster</li><li id="ul0096-0003" num="1220">Mapping of virtual communications channels, such as USB endpoints, to ISI destination <br /> 12.1.2.1.2 ISIMaster to External Host Communication </li></ul></li></ul>
1221The ISIMaster will need to communicate the following information to the external host: <ul id="ul0097" list-style="none"><li id="ul0097-0001" num="0000"><ul id="ul0098" list-style="none"><li id="ul0098-0001" num="1222">Communications channel configuration and maintenance information</li><li id="ul0098-0002" num="1223">All data originating from the PrintMaster, ISISlave or storage SoPEC devices and destined for the external host. This data is simply relayed by the ISIMaster <br /> 12.1.2.1.3 External Host to PrintMaster Communication </li></ul></li></ul>
1224The external host will need to communicate the following information to the PrintMaster device: <ul id="ul0099" list-style="none"><li id="ul0099-0001" num="0000"><ul id="ul0100" list-style="none"><li id="ul0100-0001" num="1225">Program code for the PrintMaster</li><li id="ul0100-0002" num="1226">Compressed page data for the PrintMaster</li><li id="ul0100-0003" num="1227">Control messages to the PrintMaster</li><li id="ul0100-0004" num="1228">Tables and static data required for printing e.g. dead nozzle tables, dither matrices etc.</li><li id="ul0100-0005" num="1229">Authenticatable messages to upgrade the printer's capabilities <br /> 12.1.2.1.4 PrintMaster to External Host Communication </li></ul></li></ul>
1230The PrintMaster will need to communicate the following information to the external host: <ul id="ul0101" list-style="none"><li id="ul0101-0001" num="0000"><ul id="ul0102" list-style="none"><li id="ul0102-0001" num="1231">Printer status information (i.e. authentication results, paper empty/jammed etc.)</li><li id="ul0102-0002" num="1232">Dead nozzle information</li><li id="ul0102-0003" num="1233">Memory buffer status information</li><li id="ul0102-0004" num="1234">Power management status</li><li id="ul0102-0005" num="1235">Encrypted SoPEC_id for use in the generation of PRINTER_QA keys during factory programming <br /> 12.1.2.1.5 External Host to ISISlave Communication </li></ul></li></ul>
1236All communication between the external host and ISISlave SoPEC devices must be direct (via a dedicated connection between the external host and the ISISlave) or must take place via the ISIMaster. In the case of a SoPEC ISIMaster it is possible to configure each individual USB endpoint to act as a control channel to an ISISlave SoPEC if desired, although the endpoints will be more usually used to transport data. The external host will need to communicate the following information to ISISlave devices over the comms/lSI: <ul id="ul0103" list-style="none"><li id="ul0103-0001" num="0000"><ul id="ul0104" list-style="none"><li id="ul0104-0001" num="1237">Program code for ISISlave SoPEC devices</li><li id="ul0104-0002" num="1238">Compressed page data for ISISlave SoPEC devices</li><li id="ul0104-0003" num="1239">Control messages to the ISISlave SoPEC (where a control channel is supported)</li><li id="ul0104-0004" num="1240">Tables and static data required for printing e.g. dead nozzle tables, dither matrices etc.</li><li id="ul0104-0005" num="1241">Authenticatable messages to upgrade the printer's capabilities <br /> 12.1.2.1.6 ISISlave to External Host Communication </li></ul></li></ul>
1242All communication between the ISISlave SoPEC devices and the external host must take place via the ISIMaster. The ISISlave will need to communicate the following information to the external host over the comms/ISI: <ul id="ul0105" list-style="none"><li id="ul0105-0001" num="0000"><ul id="ul0106" list-style="none"><li id="ul0106-0001" num="1243">Responses to the external host's control messages (where a control channel is supported)</li><li id="ul0106-0002" num="1244">Dead nozzle information from the ISISlave SoPEC.</li><li id="ul0106-0003" num="1245">Encrypted SoPEC_id for use in the generation of PRINTER_QA keys during factory programming <br /> 12.1.2.2 Communication with External USB Device <br /> 12.1.2.2.1 ISIMaster to External USB Device Communication </li><li id="ul0106-0004" num="1246">Communications channel configuration and maintenance information. <br /> 12.1.2.2.2 External USB Device to ISIMaster Communication </li><li id="ul0106-0005" num="1247">Print data from a function on the external USB device. <br /> 12.1.2.3 Communication Over ISI <br /> 12.1.2.3.1 ISIMaster to PrintMaster Communication </li></ul></li></ul>
1248The ISIMaster and PrintMaster will often be the same physical device. When they are different devices then the following information needs to be exchanged over the ISI: <ul id="ul0107" list-style="none"><li id="ul0107-0001" num="0000"><ul id="ul0108" list-style="none"><li id="ul0108-0001" num="1249">All data from the external host destined for the PrintMaster (see section 12.1.2.1.4).</li></ul></li></ul>
1250This data is simply relayed by the ISIMaster
000012.1.2.3.2 PrintMaster to ISIMaster Communication
1251The ISIMaster and PrintMaster will often be the same physical device. When they are different devices then the following information needs to be exchanged over the ISI: <ul id="ul0109" list-style="none"><li id="ul0109-0001" num="0000"><ul id="ul0110" list-style="none"><li id="ul0110-0001" num="1252">All data from the PrintMaster destined for the external host (see section 12.1.2.1.4).</li></ul></li></ul>
1253This data is simply relayed by the ISIMaster
000012.1.2.3.3 ISIMaster to ISISlave Communication
1254The ISIMaster may wish to communicate the following information to the ISISlaves: <ul id="ul0111" list-style="none"><li id="ul0111-0001" num="0000"><ul id="ul0112" list-style="none"><li id="ul0112-0001" num="1255">All data (including program code such as ISIId enumeration) originating from the external host and destined for the ISISlave (see section 12.1.2.1.5). This data is simply relayed by the ISIMaster</li><li id="ul0112-0002" num="1256">wake up from sleep mode <br /> 12.1.2.3.4 ISISlave to ISIMaster Communication </li></ul></li></ul>
1257The ISISlave may wish to communicate the following information to the ISIMaster: <ul id="ul0113" list-style="none"><li id="ul0113-0001" num="0000"><ul id="ul0114" list-style="none"><li id="ul0114-0001" num="1258">All data originating from the ISISlave and destined for the external host (see section 12.1.2.1.6). This data is simply relayed by the ISIMaster <br /> 12.1.2.3.5 PrintMaster to ISISlave Communication </li></ul></li></ul>
1259When the PrintMaster is not the ISIMaster all ISI communication is done in response to ISI ping packets (see 12.4.4.6). When the PrintMaster is the ISIMaster then it will of course communicate directly with the ISISlaves. The PrintMaster SoPEC may wish to communicate the following information to the ISISlaves: <ul id="ul0115" list-style="none"><li id="ul0115-0001" num="0000"><ul id="ul0116" list-style="none"><li id="ul0116-0001" num="1260">Ink status e.g. requests for dotCount data i.e. the number of dots in each color fired by the printheads connected to the ISISlaves</li><li id="ul0116-0002" num="1261">configuration of GPIO ports e.g. for clutch control and lid open detect</li><li id="ul0116-0003" num="1262">power down command telling the ISISlave to enter sleep mode</li><li id="ul0116-0004" num="1263">ink cartridge fail information</li></ul></li></ul>
1264This list is not complete and the time constraints associated with these requirements have yet to be determined.
1265In general the PrintMaster may need to be able to: <ul id="ul0117" list-style="none"><li id="ul0117-0001" num="0000"><ul id="ul0118" list-style="none"><li id="ul0118-0001" num="1266">send messages to an ISISlave which will cause the ISISlave to return the contents of ISISlave registers to the PrintMaster or</li><li id="ul0118-0002" num="1267">to program ISISlave registers with values sent by the PrintMaster</li></ul></li></ul>
1268This should be under the control of software running on the CPU which writes messages to the ISI/SCB interface.
000012.1.2.3.6 ISISlave to PrintMaster Communication
1269ISISlaves may need to communicate the following information to the PrintMaster: <ul id="ul0119" list-style="none"><li id="ul0119-0001" num="0000"><ul id="ul0120" list-style="none"><li id="ul0120-0001" num="1270">ink status e.g. dotCount data i.e. the number of dots in each color fired by the printheads connected to the ISISlaves</li><li id="ul0120-0002" num="1271">band related information e.g. finished band interrupts</li><li id="ul0120-0003" num="1272">page related information i.e. buffer underrun, page finished interrupts</li><li id="ul0120-0004" num="1273">MMU security violation interrupts</li><li id="ul0120-0005" num="1274">GPIO interrupts and status e.g. clutch control and lid open detect</li><li id="ul0120-0006" num="1275">printhead temperature</li><li id="ul0120-0007" num="1276">printhead dead nozzle information from SoPEC printhead nozzle tests</li><li id="ul0120-0008" num="1277">power management status</li></ul></li></ul>
1278This list is not complete and the time constraints associated with these requirements have yet to be determined.
1279As the ISI is an insecure interface commands issued over the ISI should be of limited capability e.g. only limited register writes allowed. The software protocol needs to be constructed with this in mind. In general ISISlaves may need to return register or status messages to the PrintMaster or ISIMaster. They may also need to indicate to the PrintMaster or ISIMaster that a particular interrupt has occurred on the ISISlave. This should be under the control of software running on the CPU which writes messages to the ISI block.
000012.1.2.3.7 ISISlave to ISISlave Communication
1280The amount of information that will need to be communicated between ISISlaves will vary considerably depending on the printer configuration. In some systems ISISlave devices will only need to exchange small amounts of control information with each other while in other systems (such as those employing a storage SoPEC or extra USB connection) large amounts of compressed page data may be moved between ISISlaves. Scenarios where ISISlave to ISISlave communication is required include: (a) when the PrintMaster is not the ISIMaster, (b) QA Chip ink usage protocols, (c) data transmission from data storage SoPECs, (d) when there are multiple external host connections supplying data to the printer.
000012.1.3 SCB Block Diagram
1281The SCB consists of four main sub-blocks, as shown in the basic block diagram of <figref idref="DRAWINGS">FIG. 28</figref>.
000012.1.4 Definitions of I/Os
1282The toplevel I/Os of the SCB are listed in Table 32. A more detailed description of their functionality will be given in the relevant sub-block sections.
1283<tables id="TABLE-US-00040" num="00040"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 32</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>SCB I/O</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>Port name</entry><entry>s</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>Clocks and Resets</entry><entry /><entry /><entry /></row><row><entry>prst_n</entry><entry>1</entry><entry>In</entry><entry>System reset signal. Active low.</entry></row><row><entry>Pclk</entry><entry>1</entry><entry>In</entry><entry>System clock.</entry></row><row><entry>usbclk</entry><entry>1</entry><entry>In</entry><entry>48 MHz clock for the USB device and host</entry></row><row><entry /><entry /><entry /><entry>cores. The cores also require a 12 MHz clock,</entry></row><row><entry /><entry /><entry /><entry>which will be generated locally by dividing the</entry></row><row><entry /><entry /><entry /><entry>48 MHz clock by 4.</entry></row><row><entry>isi_cpr_reset_n</entry><entry>1</entry><entry>Out</entry><entry>Signal from the ISI indicating that ISI activity</entry></row><row><entry /><entry /><entry /><entry>has been detected while in sleep mode and so</entry></row><row><entry /><entry /><entry /><entry>the chip should be reset. Active low.</entry></row><row><entry>usbd_cpr_reset_n</entry><entry>1</entry><entry>Out</entry><entry>Signal from the USB device that a USB reset</entry></row><row><entry /><entry /><entry /><entry>has occurred. Active low.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="left" /><tbody valign="top"><row><entry>USB device IO transceiver signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>usbd_ts</entry><entry>1</entry><entry>Out</entry><entry>USB device IO transceiver (BUSB2_PM) driver</entry></row><row><entry /><entry /><entry /><entry>three-state control. Active high enable.</entry></row><row><entry>usbd_a</entry><entry>1</entry><entry>Out</entry><entry>USB device IO transceiver (BUSB2_PM) driver</entry></row><row><entry /><entry /><entry /><entry>data input.</entry></row><row><entry>usbd_se0</entry><entry>1</entry><entry>Out</entry><entry>USB device IO transceiver (BUSB2_PM)</entry></row><row><entry /><entry /><entry /><entry>single-ended zero input. Active high.</entry></row><row><entry>usbd_zp</entry><entry>1</entry><entry>In</entry><entry>USB device IO transceiver (BUSB2_PM) D+</entry></row><row><entry /><entry /><entry /><entry>receiver output.</entry></row><row><entry>usbd_zm</entry><entry>1</entry><entry>In</entry><entry>USB device IO transceiver (BUSB2_PM) D−</entry></row><row><entry /><entry /><entry /><entry>receiver output.</entry></row><row><entry>usbd_z</entry><entry>1</entry><entry>In</entry><entry>USB device IO transceiver (BUSB2_PM)</entry></row><row><entry /><entry /><entry /><entry>differential receiver output.</entry></row><row><entry>usbd_pull_up_en</entry><entry>1</entry><entry>Out</entry><entry>USB device pull-up resistor enable. Switches</entry></row><row><entry /><entry /><entry /><entry>power to the external pull-up resistor,</entry></row><row><entry /><entry /><entry /><entry>connected to the D+ line that is required for</entry></row><row><entry /><entry /><entry /><entry>device identification to the USB. Active high.</entry></row><row><entry>usbd_vbus_sense</entry><entry>1</entry><entry>In</entry><entry>USB device VBUS power sense. Used to</entry></row><row><entry /><entry /><entry /><entry>detect power on VBUS. NOTE: The IBM Cu11</entry></row><row><entry /><entry /><entry /><entry>PADS are 3.3 V, VBUS is 5 V. An external volt-</entry></row><row><entry /><entry /><entry /><entry>age conversion will be necessary, e.g. resistor</entry></row><row><entry /><entry /><entry /><entry>divider network. Active high.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="left" /><tbody valign="top"><row><entry>USB host IO transceiver signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>usbh_ts</entry><entry>1</entry><entry>Out</entry><entry>USB host IO transceiver (BUSB2_PM) driver</entry></row><row><entry /><entry /><entry /><entry>three-state control. Active high enable</entry></row><row><entry>usbh_a</entry><entry>1</entry><entry>Out</entry><entry>USB host IO transceiver (BUSB2_PM) driver</entry></row><row><entry /><entry /><entry /><entry>data input.</entry></row><row><entry>usbh_se0</entry><entry>1</entry><entry>Out</entry><entry>USB host IO transceiver (BUSB2_PM) single-</entry></row><row><entry /><entry /><entry /><entry>ended zero input. Active high.</entry></row><row><entry>usbh_zp</entry><entry>1</entry><entry>In</entry><entry>USB host IO transceiver (BUSB2_PM) D+</entry></row><row><entry /><entry /><entry /><entry>receiver output.</entry></row><row><entry>usbh_zm</entry><entry>1</entry><entry>In</entry><entry>USB host IO transceiver (BUSB2_PM) D−</entry></row><row><entry /><entry /><entry /><entry>receiver output.</entry></row><row><entry>usbh_z</entry><entry>1</entry><entry>In</entry><entry>USB host IO transceiver (BUSB2_PM)</entry></row><row><entry /><entry /><entry /><entry>differential receiver output.</entry></row><row><entry>usbh_over_current</entry><entry>1</entry><entry>In</entry><entry>USB host port power over current indicator.</entry></row><row><entry /><entry /><entry /><entry>Active high.</entry></row><row><entry>usbh_power_en</entry><entry>1</entry><entry>Out</entry><entry>USB host VBUS power enable. Used for port</entry></row><row><entry /><entry /><entry /><entry>power switching. Active high.</entry></row><row><entry>CPU Interface</entry></row><row><entry>cpu_adr[n:2]</entry><entry>n − 1</entry><entry>In</entry><entry>CPU address bus.</entry></row><row><entry>cpu_dataout[31:0]</entry><entry>32</entry><entry>In</entry><entry>Shared write data bus from the CPU</entry></row><row><entry>scb_cpu_data[31:0]</entry><entry>32</entry><entry>Out</entry><entry>Read data bus to the CPU</entry></row><row><entry>cpu_rwn</entry><entry>1</entry><entry>In</entry><entry>Common read/not-write signal from the CPU</entry></row><row><entry>cpu_acode[1:0]</entry><entry>2</entry><entry>In</entry><entry>CPU Access Code signals. These decode as</entry></row><row><entry /><entry /><entry /><entry>follows:</entry></row><row><entry /><entry /><entry /><entry>00 - User program access</entry></row><row><entry /><entry /><entry /><entry>01 - User data access</entry></row><row><entry /><entry /><entry /><entry>10 - Supervisor program access</entry></row><row><entry /><entry /><entry /><entry>11 - Supervisor data access</entry></row><row><entry>cpu_scb_sel</entry><entry>1</entry><entry>In</entry><entry>Block select from the CPU. When cpu_scb_sel</entry></row><row><entry /><entry /><entry /><entry>is high both cpu_adr and cpu_dataout are valid</entry></row><row><entry>scb_cpu_rdy</entry><entry>1</entry><entry>Out</entry><entry>Ready signal to the CPU. When scb_cpu_rdy is</entry></row><row><entry /><entry /><entry /><entry>high it indicates the last cycle of the access.</entry></row><row><entry /><entry /><entry /><entry>For a write cycle this means cpu_dataout has</entry></row><row><entry /><entry /><entry /><entry>been registered by the SCB and for a read</entry></row><row><entry /><entry /><entry /><entry>cycle this means the data on scb_cpu_data is</entry></row><row><entry /><entry /><entry /><entry>valid.</entry></row><row><entry>scb_cpu_berr</entry><entry>1</entry><entry>Out</entry><entry>Bus error signal to the CPU indicating an</entry></row><row><entry /><entry /><entry /><entry>invalid access.</entry></row><row><entry>scb_cpu_debug_valid</entry><entry>1</entry><entry>Out</entry><entry>Signal indicating that the data currently on</entry></row><row><entry /><entry /><entry /><entry>scb_cpu_data is valid debug data</entry></row><row><entry>Interrupt signals</entry></row><row><entry>dma_icu_irq</entry><entry>1</entry><entry>Out</entry><entry>DMA interrupt signal to the interrupt controller</entry></row><row><entry /><entry /><entry /><entry>block.</entry></row><row><entry>isi_icu_irq</entry><entry>1</entry><entry>Out</entry><entry>ISI interrupt signal to the interrupt controller</entry></row><row><entry /><entry /><entry /><entry>block.</entry></row><row><entry>usb_icu_irq[1:0]</entry><entry>2</entry><entry>Out</entry><entry>USB host and device interrupt signals to the</entry></row><row><entry /><entry /><entry /><entry>ICU.</entry></row><row><entry /><entry /><entry /><entry>Bit 0 - USB Host interrupt</entry></row><row><entry /><entry /><entry /><entry>Bit 1 - USB Device interrupt</entry></row><row><entry>DIU interface</entry></row><row><entry>scb_diu_wadr[21:5]</entry><entry>17</entry><entry>Out</entry><entry>Write address bus to the DIU</entry></row><row><entry>scb_diu_data[63:0]</entry><entry>64</entry><entry>Out</entry><entry>Data bus to the DIU.</entry></row><row><entry>scb_diu_wreq</entry><entry>1</entry><entry>Out</entry><entry>Write request to the DIU</entry></row><row><entry>diu_scb_wack</entry><entry>1</entry><entry>In</entry><entry>Acknowledge from the DIU that the write</entry></row><row><entry /><entry /><entry /><entry>request was accepted.</entry></row><row><entry>scb_diu_wvalid</entry><entry>1</entry><entry>Out</entry><entry>Signal from the SCB to the DIU indicating that</entry></row><row><entry /><entry /><entry /><entry>the data currently on the scb_diu_data[63:0]</entry></row><row><entry /><entry /><entry /><entry>bus is valid</entry></row><row><entry>scb_diu_wmask[7:0]</entry><entry>7</entry><entry>Out</entry><entry>Byte aligned write mask. A “1” in a bit field of</entry></row><row><entry /><entry /><entry /><entry>“scb_diu_wmask[7:0]”</entry></row><row><entry /><entry /><entry /><entry>means that the corresponding byte will be</entry></row><row><entry /><entry /><entry /><entry>written to DRAM.</entry></row><row><entry>scb_diu_rreq</entry><entry>1</entry><entry>Out</entry><entry>Read request to the DIU.</entry></row><row><entry>scb_diu_radr[21:5]</entry><entry>17</entry><entry>Out</entry><entry>Read address bus to the DIU</entry></row><row><entry>diu_scb_rack</entry><entry>1</entry><entry>In</entry><entry>Acknowledge from the DIU that the read</entry></row><row><entry /><entry /><entry /><entry>request was accepted.</entry></row><row><entry>diu_scb_rvalid</entry><entry>1</entry><entry>In</entry><entry>Signal from the DIU to the SCB indicating that</entry></row><row><entry /><entry /><entry /><entry>the data currently on the diu_data [63:0] bus is</entry></row><row><entry /><entry /><entry /><entry>valid</entry></row><row><entry>diu_data[63:0]</entry><entry>64</entry><entry>In</entry><entry>Common DIU data bus.</entry></row><row><entry>GPIO interface</entry></row><row><entry>isi_gpio_dout[3:0]</entry><entry>4</entry><entry>Out</entry><entry>ISI output data to GPIO pins</entry></row><row><entry>isi_gpio_e[3:0]</entry><entry>4</entry><entry>Out</entry><entry>ISI output enable to GPIO pins</entry></row><row><entry>gpio_isi_din[3:0]</entry><entry>4</entry><entry>In</entry><entry>Input data from GPIO pins to ISI</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.1.5 SCB Data Flow
1284A logical view of the SCB is shown in <figref idref="DRAWINGS">FIG. 29</figref>, depicting the transfer of data within the SCB.
000012.2 USBD (USB Device Sub-block)
000012.2.1 Overview
1285The FS USB device controller core and associated SCB logic are referred to as the USB Device (USBD).
1286A SoPEC printer has FS USB device capability to facilitate communication between an external USB host and a SoPEC printer. The USBD is self-powered. It connects to an external USB host via a dedicated USB interface on the SoPEC printer, comprising a USB connector, the necessary discretes for USB signalling and the associated SoPEC ASIC I/Os.
1287The FS USB device core will be third party IP from Synopsys: TymeWare™ USB1.1 Device Controller (UDCVCI). Refer to the UDCVCI User Manual [20] for a description of the core.
1288The device core does not support LS USB operation. Control and bulk transfers are supported by the device. Interrupt transfers are not considered necessary because the required interrupt-type functionality can be achieved by sending query messages over the control channel on a scheduled basis. There is no requirement to support isochronous transfers.
1289The device core is configured to support 6 USB endpoints (EPs): the default control EP (EP0), 4 bulk OUT EPs (EP1, EP2, EP3, EP4) and 1 bulk IN EP (EP5). It should be noted that the direction of each EP is with respect to the USB host, i.e. IN refers to data transferred to the external host and OUT refers to data transferred from the external host. The 4 bulk OUT EPs will be used for the transfer of data from the external host to SoPEC, e.g. compressed page data, program data or control messages. Each bulk OUT EP can be mapped on to any target destination in a multi-SoPEC system, via the SCB Map configuration registers. The bulk IN EP is used for the transfer of data from SoPEC to the external host, e.g. a print image downloaded from a digital camera that requires processing on the external host system. Any feedback data will be returned to the external host on EP0, e.g. status information.
1290The device core does not provide internal buffering for any of its EPs (with the exception of the 8 byte setup data payload for control transfers). All EP buffers are provided in the SCB. Buffers will be grouped according to EP direction and associated packet destination. The SCB Map configuration registers contain a DestISIId and DestISISubId for each OUT EP, defining their EP mapping and therefore their packet destination. Refer to section Section 12.4 ISI (Inter SoPEC Interface Sub-block) for further details on ISIId and ISISubId. Refer to section Section 12.5 CTRL (Control Sub-block) for further details on the mapping of OUT EPs.
000012.2.2 USBD Effective Bandwidth
1291The effective bandwidth between an external USB host and the printer will be influenced by: <ul id="ul0121" list-style="none"><li id="ul0121-0001" num="0000"><ul id="ul0122" list-style="none"><li id="ul0122-0001" num="1292">Amount of activity from other devices that share the USB with the printer.</li><li id="ul0122-0002" num="1293">Throughput of the device controller core.</li><li id="ul0122-0003" num="1294">EP buffering implementation.</li><li id="ul0122-0004" num="1295">Responsiveness of the external host system CPU in handling USB interrupts.</li></ul></li></ul>
1296To maximize bandwidth to the printer it is recommended that no other devices are active on the USB between the printer and the external host. If the printer is connected to a HS USB external host or hub it may limit the bandwidth available to other devices connected to the same hub but it would not significantly affect the bandwidth available to other devices upstream of the hub. The EP buffering should not limit the USB device core throughput, under normal operating conditions. Used in the recommended configuration, under ideal operating conditions, it is expected that an effective bandwidth of 8–9 Mbit/s will be achieved with bulk transfers between the external host and the printer.
000012.2.3 IN EP Packet Buffer
1297The IN EP packet buffer stores packets originating from the LEON CPU that are destined for transmission over the USB to the external USB host. CPU writes to the buffer are 32 bits wide. USB device core reads from the buffer 32 bits wide.
1298128 bytes of local memory are required in total for EP0-IN and EP5-IN buffering. The IN EP buffer is a single, 2-port local memory instance, with a dedicated read port and a dedicated write port. Both ports are 32 bits wide. Each IN EP has a dedicated 64 byte packet location available in the memory array to buffer a single USB packet (maximum USB packet size is 64 bytes). Each individual 64 byte packet location is structured as 16×32 bit words and is read/written in a FIFO manner. When the device core reads a packet entry from the IN EP packet buffer, the buffer must retain the packet until the device core performs a status write, informing the SCB that the packet has been accepted by the external USB host and can be flushed. The CPU can therefore only write a single packet at a time to each IN EP. Any subsequent CPU write request to a buffer location containing a valid packet will be refused, until that packet has been successfully transmitted.
000012.2.4 OUT EP Packet Buffer
1299The OUT EP packet buffer stores packets originating from the external USB host that are destined for transmission over DMAChannel0, DMAChannel1 or the ISI. The SCB control logic is responsible for routing the OUT EP packets from the OUT EP packet buffer to DMA or to the ISITx Buffer, based on the SCB Map configuration register settings. USB core writes to the buffer are 32 bits wide. DMA and ISI associated reads from the buffer are both 64 bits wide.
1300512 bytes of local memory are required in total for EP0-OUT, EP1-OUT, EP2-OUT, EP3-OUT and EP4-OUT buffering. The OUT EP packet buffer is a single, 2-port local memory instance, with a dedicated read port and a dedicated write port. Both ports are 64 bits wide. Byte enables are used for the 32 bit wide USB device core writes to the buffer. Each OUT EP can be mapped to DMAChannel0, DMAChannel1 or the ISI.
1301The OUT EP packet buffer is partitioned accordingly, resulting in three distinct packet FIFOs: <ul id="ul0123" list-style="none"><li id="ul0123-0001" num="0000"><ul id="ul0124" list-style="none"><li id="ul0124-0001" num="1302">USBDDMA0 FIFO, for USB packets destined for DMAChannel0 on the local SoPEC.</li><li id="ul0124-0002" num="1303">USBDDMA1 FIFO, for USB packets destined for DMAChannel1 on the local SoPEC.</li><li id="ul0124-0003" num="1304">USBDISIFIFO, for USB packets destined for transmission over the ISI. <br /> 12.2.4.1 USBDDMAnFIFO </li></ul></li></ul>
1305This description applies to USBDDMA0FIFO and USBDDMA1 FIFO, where ‘n’ represents the respective DMA channel, i.e. n=0 for USBDDMA0FIFO, n=1 for USBDDMA1 FIFO. USBDDMAnFIFO services any EPs mapped to DMAChanneln on the local SoPEC device. This implies that a packet originating from an EP with an associated ISIId that matches the local SoPEC ISIId and an ISISubId=n will be written to USBDDMAnFIFO, if there is space available for that packet.
1306USBDDMAnFIFO has a capacity of 2×64 byte packet entries, and can therefore buffer up to 2 USB packets. It can be considered as a 2 packet entry FIFO. Packets will be read from it in the same order in which they were written, i.e. the first packet written will be the first packet read and the second packet written will be the second packet read. Each individual 64 byte packet location is structured as 8×64 bit words and is read/written in a FIFO manner.
1307The USBDDMAnFIFO has a write granularity of 64 bytes, to allow for the maximum USB packet size. The USBDDMAnFIFO will have a read granularity of 32 bytes to allow for the DMA write access bursts of 4×64 bit words, i.e. the DMA Manager will read 32 byte chunks at a time from the USBDDMAnFIFO 64 byte packet entries, for transfer to the DIU.
1308It is conceivable that a packet which is not a multiple 32 bytes in size may be written to the USBDDMAnFIFO. When this event occurs, the DMA Manager will read the contents of the remaining address locations associated with the 32 byte chunk in the USBDDMAnFIFO, transferring the packet plus whatever data is present in those locations, resulting in a 32 byte packet (a burst of 4×64 bit words) transfer to the DIU.
1309The DMA channels should achieve an effective bandwidth of 160 Mbits/sec (1 bit/cycle) and should never become blocked, under normal operating conditions. As the USB bandwidth is considerably less, a 2 entry packet FIFO for each DMA channel should be sufficient.
12.2.4.2 USBDISIFIFO
1310USBDISIFIFO services any EPs mapped to ISI. This implies that a packet originating from an EP with an associated ISIId that does not match the local SoPEC ISIId will be written to USBDISIFIFO if there is space available for that packet.
1311USBDISIFIFO has a capacity of 4×64 byte packet entries, and can therefore buffer up to 4 USB packets. It can be considered as a 4 packet entry FIFO. Packets will be read from it in the same order in which they were written, i.e. the first packet written will be the first packet read and the second packet written will be the second packet read, etc. Each individual 64 byte packet location is structured as 8×64 bit words and is read/written in a FIFO manner.
1312The ISI long packet format will be used to transfer data across the ISI. Each ISI long packet data payload is 32 bytes. The USBDISIFIFO has a write granularity of 64 bytes, to allow for the maximum USB packet size. The USBDISIFIFO will have a read granularity of 32 bytes to allow for the ISI packet size, i.e. the SCB will read 32 byte chunks at a time from the USBDISIFIFO 64 byte packet entries, for transfer to the ISI.
1313It is conceivable that a packet which is not a multiple 32 bytes in size may be written to the USBDISIFIFO, either intentionally or due to a software error. A maskable interrupt per EP is provided to flag this event. There will be 2 options for dealing with this scenario on a per EP basis: <ul id="ul0125" list-style="none"><li id="ul0125-0001" num="0000"><ul id="ul0126" list-style="none"><li id="ul0126-0001" num="1314">Discard the packet.</li><li id="ul0126-0002" num="1315">Read the contents of the remaining address locations associated with the 32 byte chunk in the USBDISIFIFO, transferring the irregular size packet plus whatever data is present in those locations, resulting in a 32 byte packet transfer to the ISITxBuffer.</li></ul></li></ul>
1316The ISI should achieve an effective bandwidth of 100 Mbits/sec (4 wire configuration). It is possible to encounter a number of retries when transmitting an ISI packet and the LEON CPU will require access to the ISI transmit buffer. However, considering the relatively low bandwidth of the USB, a 4 packet entry FIFO should be sufficient.
000012.2.5 Wake-up from Sleep Mode
1317The SoPEC will be placed in sleep mode after a suspend command is received by the USB device core. The USB device core will continue to be powered and clocked in sleep mode. A USB reset, as opposed to a device resume, will be required to bring SoPEC out of its sleep state as the sleep state is hoped to be logically equivalent to the power down state.
1318The USB reset signal originating from the USB controller will be propagated to the CPR (as usb_cpr_reset_n) if the USBWakeupEnable bit of the WakeupEnable register (see Table) has been set. The USBWakeupEnable bit should therefore be set just prior to entering sleep mode. There is a scenario that would require SoPEC to initiate a USB remote wake-up (i.e. where SoPEC signals resume to the external USB host after being suspended by the external USB host). A digital camera (or other supported external USB device) could be connected to SoPEC via the internal SoPEC USB host controller core interface. There may be a need to transfer data from this external USB device, via SoPEC, to the external USB host system for processing. If the USB connecting the external host system and SoPEC was suspended, then SoPEC would need to initiate a USB remote wake-up.
000012.2.6 Implementation
000012.2.6.1 USBD Sub-block Partition
0000<ul id="ul0127" list-style="none"><li id="ul0127-0001" num="0000"><ul id="ul0128" list-style="none"><li id="ul0128-0001" num="1319">Block diagram</li><li id="ul0128-0002" num="1320">Definition of I/Os <br /> 12.2.6.2 USB Device IP Core <br /> 12.2.6.3 PVCI Target <br /> 12.2.6.4 IN EP Buffer <br /> 12.2.6.5 OUT EP Buffer <br /> 12.3 USBH (USB Host Sub-block) <br /> 12.3.1 Overview </li></ul></li></ul>
1321The SoPEC USB Host Controller (HC) core, associated SCB logic and associated SoPEC ASIC I/Os are referred to as the USB Host (USBH).
1322A SoPEC printer has FS USB host capability, to facilitate communication between an external USB device and a SoPEC printer. The USBH connects to an external USB device via a dedicated USB interface on the SoPEC printer, comprising a USB connector, the necessary discretes for USB signalling and the associated SoPEC ASIC I/Os.
1323The FS USB HC core are third party IP from Synopsys: DesignWare<sup>R </sup>USB1.1 OHCI Host Controller with PVCI (UHOSTC_PVCI). Refer to the UHOSTC_PVCI User Manual [18] for details of the core. Refer to the Open Host Controller Interface (OHCI) Specification Release [19] for details of OHCI operation.
1324The HC core supports Low-Speed (LS) USB devices, although compatible external USB devices are most likely to be FS devices. It is expected that communication between an external USB device and a SoPEC printer will be achieved with control and bulk transfers. However, isochronous and interrupt transfers are also supported by the HC core.
1325There will be 2 communication channels between the Host Controller Driver (HCD) software running on the LEON CPU and the HC core: <ul id="ul0129" list-style="none"><li id="ul0129-0001" num="0000"><ul id="ul0130" list-style="none"><li id="ul0130-0001" num="1326">OHCI operational registers in the HC core. These registers are control, status, list pointers and a pointer to the Host Controller Communications Area (HCCA) in shared memory. A target Peripheral Virtual Component Interface (PCVI) on the HC core will provide LEON with direct read/write access to the operational registers. Refer to the OHCI Specification for details of these registers. <ul id="ul0131" list-style="none"><li id="ul0131-0001" num="1327">HCCA in SoPEC eDRAM. An initiator Peripheral Virtual Component Interface (PCVI) on the HC core will provide the HC with DMA read/write access to an address space in eDRAM. The HCD running on LEON will have read/write access to the same address space. Refer to the OHCI Specification for details of the HCCA.</li></ul></li></ul></li></ul>
1328The target PVCI interface is a 32 bit word aligned interface, with byte enables for write access. All read/write access to the target PVCI interface by the LEON CPU will be 32 bit word aligned. The byte enables will not be used, as all registers will be read and written as 32 bit words.
1329The initiator PVCI interface is a 32 bit word aligned interface with byte enables for write access. All DMA read/write accesses are 256 bit word aligned, in bursts of 4×64 bit words. As there is no guarantee that the read/write requests from the HC core will start at a 256 bit boundary or be 256 bits long, it is necessary to provide 8 byte enables for each of the 64 bit words in a write burst form the HC core to DMA. The signal scb_diu_wmask serves this purpose.
1330Configuration of the HC core will be performed by the HCD.
000012.3.2 Read/Write Buffering
1331The HC core maximum burst size for a read/write access is 4×32 bit words. This implies that the minimum buffering requirements for the HC core will be a 1 entry deep address register and a 4 entry deep data register. It will be necessary to provide data and address mapping functionality to convert the 4×32 bit word HC core read/write bursts into 4×64 bit word DMA read/write bursts. This will meet the minimum buffering requirements.
000012.3.3 USBH Effective Bandwidth
1332The effective bandwidth between an external USB device and a SoPEC printer will be influenced by: <ul id="ul0132" list-style="none"><li id="ul0132-0001" num="0000"><ul id="ul0133" list-style="none"><li id="ul0133-0001" num="1333">Amount of activity from other devices that share the USB with the external USB device.</li><li id="ul0133-0002" num="1334">Throughput of the HC core.</li><li id="ul0133-0003" num="1335">HC read/write buffering implementation.</li><li id="ul0133-0004" num="1336">Responsiveness of the LEON CPU in handling USB interrupts.</li></ul></li></ul>
1337Effective bandwidth between an external USB device and a SoPEC printer is not an issue. The primary application of this connectivity is the download of a print image from a digital camera. Printing speed is not important for this type of print operation. However, to maximize bandwidth to the printer it is recommended that no other devices are active on the USB between the printer and the external USB device. The HC read/write buffering in the SCB should not limit the USB HC core throughput, under normal operating conditions.
1338Used in the recommended configuration, under ideal operating conditions, it is expected that an effective bandwidth of 8–9 Mbit/s will be achieved with bulk transfers between the external USB device and the SoPEC printer.
000012.3.4 Implementation
000012.3.5 USBH Sub-block Partition
0000<ul id="ul0134" list-style="none"><li id="ul0134-0001" num="0000"><ul id="ul0135" list-style="none"><li id="ul0135-0001" num="1339">USBH Block Diagram</li><li id="ul0135-0002" num="1340">Definition of I/Os. <br /> 12.3.5.1 USB Host IP Core <br /> 12.3.5.2 PVCI Target <br /> 12.3.5.3 PVCI Initiator <br /> 12.3.5.4 Read/Write Buffer <br /> 12.4 ISI (Inter SoPEC Interface Sub-block) <br /> 12.4.1 Overview </li></ul></li></ul>
1341The ISI is utilised in all system configurations requiring more than one SoPEC. An example of such a system which requires four SoPECs for duplex A3 printing and an additional SoPEC used as a storage device is shown in <figref idref="DRAWINGS">FIG. 27</figref>.
1342The ISI performs much the same function between an ISISlave SoPEC and the ISIMaster as the USB connection performs between the ISIMaster and the external host. This includes the transfer of all program data, compressed page data and message (i.e. commands or status information) passing between the ISIMaster and the ISISlave SoPECs. The ISIMaster initiates all communication with the ISISlaves.
000012.4.2 ISI Effective Bandwidth
1343The ISI will need to run at a speed that will allow error free transmission on the PCB while minimising the buffering and hardware requirements on SoPEC. While an ISI speed of 10 Mbit/s is adequate to match the effective FS USB bandwidth it would limit the system performance when a high-speed connection (e.g. USB2.0, IEEE1394) is used to attach the printer to the PC. Although they would require the use of an extra ISI-Bridge chip such systems are envisaged for more expensive printers (compared to the low-cost basic SoPEC powered printers that are initially being targeted) in the future.
1344An ISI line speed (i.e. the speed of each individual ISI wire) of 32 Mbit/s is therefore proposed as it will allow ISI data to be over-sampled 5 times (at a pclk frequency of 160 MHz). The total bandwidth of the ISI will depend on the number of pins used to implement the interface. The ISI protocol will work equally well if 2 or 4 pins are used for transmission/reception. The ISINumPins register is used to select between a 2 or 4 wire ISI, giving peak raw bandwidths of 64 Mbit/s and 128 Mbit/s respectively. Using either a 2 or 4 wire ISI solution would allow the movement of data in to and out of a storage SoPEC (as described in 12.1.1.4 above), which is the most bandwidth hungry ISI use, in a timely fashion.
1345The ISINumPins register is used to select between a 2 or 4 wire ISI. A 2 wire ISI is the default setting for ISINumPins and this may be changed to a 4 wire ISI after initial communication has been established between the ISIMaster and all ISISlaves. Software needs to ensure that the switch from 2 to 4 wires is handled in a controlled and coordinated fashion so that nothing is transmitted on the ISI during the switch over period.
1346The maximum effective bandwidth of a two wire ISI, after allowing for protocol overheads and bus turnaround times, is expected to be approx. 50 Mbit/s.
000012.4.3 ISI Device Identification and Enumeration
1347The ISIMasterSel bit of the ISICntrl register (see section Table) determines whether a SoPEC is an ISIMaster (ISIMasterSel=1), or an ISISlave (ISIMasterSel=0).
1348SoPEC defaults to being an ISISlave (ISIMasterSel=0) after a power-on reset—i.e. it will not transmit data on the ISI without first receiving a ping. If a SoPEC's ISIMasterSel bit is changed to 1, then that SoPEC will become the ISIMaster, transmitting data without requiring a ping, and generating pings as appropriately programmed.
1349ISIMasterSel can be set to 1 explicitly by the CPU writing directly to the ISICntrl register. ISIMasterSel can also be automatically set to 1 when activity occurs on any of USB endpoints 2–4 and the AutoMasterEnable bit of the ISICntrl register is also 1 (the default reset condition). Note that if AutoMasterEnable is 0, then activity on USB endpoints 2–4 will not result in ISIMasterSel being set to 1. USB endpoints 2–4 are chosen for the automatic detection since the power-on-reset condition has USB endpoints 0 and 1 pointing to ISIId 0 (which matches the local SoPEC's ISIId after power-on reset). Thus any transmission on USB endpoints 2–4 indicate a desire to transmit on the ISI which would usually indicate ISIMaster status. The automatic setting of ISIMasterSel can be disabled by clearing AutoMasterEnable, thereby allowing the SoPEC to remain an ISISlave while still making use of the USB endpoints 2–4 as external destinations.
1350Thus the setting of a SoPEC being ISIMaster or ISISlave can be completely under software control, or can be completely automatic.
1351The ISIId is established by software downloaded over the ISI (in broadcast mode) which looks at the input levels on a number of GPIO pins to determine the ISIId. For any given printer that uses a multi-SoPEC configuration it is expected that there will always be enough free GPIO pins on the ISISlaves to support this enumeration mechanism.
000012.4.4 ISI Protocol
1352The ISI is a serial interface utilizing a 2/4 wire half-duplex configuration such as the 2-wire system shown in <figref idref="DRAWINGS">FIG. 30</figref> below. An ISIMaster must always be present and a variable number of ISISlaves may also be on the ISI bus. The ISI protocol supports up to 14 addressable slaves, however to simplify electrical issues the ISI drivers need only allow for 5–6 ISI devices on a particular ISI bus. The ISI bus enables broadcasting of data, ISIMaster to ISISlave communication, ISISlave to ISIMaster communication and ISISlave to ISISlave communication. Flow control, error detection and retransmission of errored packets is also supported. ISI transmission is asynchronous and a Start field is present in every transmitted packet to ensure synchronization for the duration of the packet.
1353To maximize the effective ISI bandwidth while minimising pin requirements a half-duplex interleaved transmission scheme is used. <figref idref="DRAWINGS">FIG. 31</figref> below shows how a 16-bit word is transmitted from an ISIMaster to an ISISlave over a 2-wire ISI bus. Since data will be interleaved over the wires and a 4-wire ISI is also supported, all ISI packets should be a multiple of 4 bits.
1354All ISI transactions are initiated by the ISIMaster and every non-broadcast data packet needs to be acknowledged by the addressed recipient. An ISISlave may only transmit when it receives a ping packet (see section 12.4.4.6) addressed to it. To avoid bus contention all ISI devices must wait ISITurnAround bit-times (5 pclk cycles per bit) after detecting the end of a packet before transmitting a packet (assuming they are required to transmit). All non-transmitting ISI devices must tristate their Tx drivers to avoid line contention. The ISI protocol is defined to avoid devices driving out of order (e.g. when an ISISlave is no longer being addressed). As the ISI uses standard I/O pads there is no physical collision detection mechanism.
1355There are three types of ISI packet: a long packet (used for data transmission), a ping packet (used by the ISIMaster to prompt ISISlaves for packets) and a short packet (used to acknowledge receipt of a packet). All ISI packets are delineated by a Start and Stop fields and transmission is atomic i.e. an ISI packet may not be split or halted once transmission has started.
000012.4.4.1 ISI Transactions
1356The different types of ISI transactions are outlined in <figref idref="DRAWINGS">FIG. 32</figref> below. As described later all NAKs are inferred and ACK<sub>S </sub>are not addressed to any particular ISI device.
000012.4.4.2 Start Field Description
1357The Start field serves two purposes: To allow the start of a packet be unambiguously identified and to allow the receiving device synchronise to the data stream. The symbol, or data value, used to identify a Start field must not legitimately occur in the ensuing packet. Bit stuffing is used to guarantee that the Start symbol will be unique in any valid (i.e. error free) packet. The ISI needs to see a valid Start symbol before packet reception can commence i.e. the receive logic constantly looks for a Start symbol in the incoming data and will reject all data until it sees a Start symbol. Furthermore if a Start symbol occurs (incorrectly) during a data packet it will be treated as the start of a new packet. In this case the partially received packet will be discarded.
1358The data value of the Start symbol should guarantee that an adequate number of transitions occur on the physical ISI lines to allow the receiving ISI device to determine the best sampling window for the transmitted data. The Start symbol should also be sufficiently long to ensure that the bit stuffing overhead is low but should still be short enough to reduce its own contribution to the packet overhead. A Start symbol of b01010101 is therefore used as it is an effective compromise between these constraints.
1359Each SoPEC in a multi-SoPEC system will derive its system clock from a unique (i.e. one per SoPEC) crystal. The system clocks of each device will drift relative to each other over any period of time. The system clocks are used for generation and sampling of the ISI data. Therefore the sampling window can drift and could result in incorrect data values being sampled at a later point in time. To overcome this problem the ISI receive circuitry tracks the sampling window against the incoming data to ensure that the data is sampled in the centre of the bit period.
000012.4.4.3 Stop Field Description
1360A 1 bit-time Stop field of b1 per ISI line ensures that all ISI lines return to the high state before the next packet is transmitted. The stop field is driven on to each ISI line simultaneously, i.e. b11 for a 2-wire ISI and b1111 for a 4-wire ISI would be interleaved over the respective ISI lines. Each ISI line is driven high for 1 bit-time. This is necessary because the first bit of the Start field is b0.
000012.4.4.4 Bit Stuffing
1361This involves the insertion of bits into the bitstream at the transmitting SoPEC to avoid certain data patterns. The receiving SoPEC will strip these inserted bits from the bitstream.
1362Bit-stuffing will be performed when the Start symbol appears at a location other than the start field of any packet, i.e. when the bit pattern b0101010 occurs at the transmitter, a 0 will be inserted to escape the Start symbol, resulting in the bit pattern b01010100. Conversely, when the bit pattern b0101010 occurs at the receiver, if the next bit is a ‘0’ it will be stripped, if it is a ‘1’ then a Start symbol is detected.
1363If the frequency variations in the quartz crystal were large enough, it is conceivable that the resultant frequency drift over a large number of consecutive 1s or 0s could cause the receiving SoPEC to loose synchronisation. <sup>6 </sup>The quartz crystal that will be used in SoPEC systems is rated for 32 MHz @ 100 ppm. In a multi-SoPEC system with a 32 MHz+100 ppm crystal and a 32 MHz-100 ppm crystal, it would take approximately 5000 pclk cycles to cause a drift of 1 pclk cycle. This means that we would only need to bit-stuff somewhere before 1000 ISI bits of consecutive 1s or consecutive 0s, to ensure adequate synchronization. As the maximum number of bits transmitted per ISI line in a packet is 145, it should not be necessary to perform bit-stuffing for consecutive 1s or 0s. We may wish to constrain the spec of xtalin and also xtalin for the ISI-Bridge chip to ensure the ISI cannot drift out of sync during packet reception. <sup>6</sup>Current max packet size˜=290 bits=145 bits per ISI line (on a 2 wire ISI)=725 160 MHz cycles. Thus the pclks in the two communicating ISI devices should not drift by more than one cycle in 725 i.e. 1379 ppm. Careful analysis of the crystal, PLL and oscillator specs and the sync detection circuit is needed here to ensure our solution is robust.
1364Note that any violation of bit stuffing will result in the RxFrameErrorSticky status bit being set and the incoming packet will be treated as an errored packet.
000012.4.4.5 ISI Long Packet
1365The format of a long ISI packet is shown in <figref idref="DRAWINGS">FIG. 33</figref> below. Data may only be transferred between ISI devices using a long packet as both the short and ping packets have no payload field. Except in the case of a broadcast packet, the receiving ISI device will always reply to a long packet with an explicit ACK (if no error is detected in the received packet) or will not reply at all (e.g. an error is detected in the received packet), leaving the transmitter to infer a NAK. As with all ISI packets the bitstream of a long packet is transmitted with its lsb (the leftmost bit in <figref idref="DRAWINGS">FIG. 33</figref>) first. Note that the total length (in bits) of an ISI long packet differs slightly between a 2 and 4-wire ISI system due to the different number of bits required for the Start and Stop fields.
1366All long packets begin with the Start field as described earlier. The PktDesc field is described in Table 33.
1367<tables id="TABLE-US-00041" num="00041"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 33</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>PktDesc field description</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="49pt" align="center" /><colspec colname="2" colwidth="168pt" align="left" /><tbody valign="top"><row><entry>Bit</entry><entry>Description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>0:1</entry><entry>00 - Long packet</entry></row><row><entry /><entry>01 - Reserved</entry></row><row><entry /><entry>10 - Ping packet</entry></row><row><entry /><entry>11 - Reserved</entry></row><row><entry>2</entry><entry>Sequence bit value. Only valid for long packets.</entry></row><row><entry /><entry>See section 12.4.4.9 for a description of sequence</entry></row><row><entry /><entry>bit operation</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
1368Any ISI device in the system may transmit a long packet but only the ISIMaster may initiate an ISI transaction using a long packet. An ISISlave may only send a long packet in reply to a ping message from the ISIMaster. A long packet from an ISISlave may be addressed to any ISI device in the system.
1369The Address field is straightforward and complies with the ISI naming convention described in section 12.5.
1370The payload field is exactly what is in the transmit buffer of the transmitting ISI device and gets copied into the receive buffer of the addressed ISI device(s). When present the payload field is always 256 bits.
1371To ensure strong error detection a 16-bit CRC is appended.
000012.4.4.6 ISI Ping Packet
1372The ISI ping packet is used to allow ISISlaves to transmit on the ISI bus. As can be seen from <figref idref="DRAWINGS">FIG. 34</figref> below the ping packet can be viewed as a special case of the long packet. In other words it is a long packet without any payload. Therefore the PktDesc field is the same as a long packet PktDesc, with the exception of the sequence bit, which is not valid for a ping packet. Both the ISISubId and the sequence bit are fixed at 1 for all ping packets. These values were chosen to maximize the hamming distance from an ACK symbol and to minimize the likelihood of bit stuffing. The ISISubId is unused in ping packets because the ISIMaster is addressing the ISI device rather than one of the DMA channels in the device. The ISISlave may address any ISIId.ISISubId in response if it wishes. The ISISlave will respond to a ping packet with either an explicit ACK (if it has nothing to send), an inferred NAK (if it detected an error in the ping packet) or a long packet (containing the data it wishes to send). Note that inferred NAK<sub>S </sub>do not result in the retransmission of a ping packet. This is because the ping packet will be retransmitted on a predetermined schedule (see 12.4.4.11 for more details).
1373An ISISlave should never respond to a ping message to the broadcast ISIId as this must have been sent in error. An ISI ping packet will never be sent in response to any packet and may only originate from an ISIMaster.
000012.4.4.7 ISI Short Packet
1374The ISI short packet is only 17 bits long, including the Start and Stop fields. A value of b11101011 is proposed for the ACK symbol. As a 16-bit CRC is inappropriate for such a short packet it is not used. In fact there is only one valid value for a short ACK packet as the Start, ACK and Stop symbols all have fixed values. Short packets are only used for acknowledgements (i.e. explicit ACKs). The format of a short ISI packet is shown in <figref idref="DRAWINGS">FIG. 35</figref> below. The ACK value is chosen to ensure that no bit stuffing is required in the packet and to minimize its hamming distance from ping and long ISI packets.
000012.4.4.8 Error Detection and Retransmission
1375The 16-bit CRC will provide a high degree of error detection and the probability of transmission errors occurring is very low as the transmission channel (i.e. PCB traces) will have a low inherent bit error rate. The number of undetected errors should therefore be minute.
1376The HDLC standard CRC-16 (i.e. G(x)=x<sup>16</sup>+x<sup>12</sup>+x<sup>5</sup>+1) is to be used for this calculation, which is to be performed serially. It is calculated over the entire packet (excluding the Start and Stop fields). A simple retransmission mechanism frees the CPU from getting involved in error recovery for most errors because the probability of a transmission error occurring more than once in succession is very, very low in normal circumstances.
1377After each non-short ISI packet is transmitted the transmitting device will open a reply window. The size of the reply window will be ISIShortReplyWin bit times when a short packet is expected in reply, i.e. the size of a short packet, allowing for worst case bit stuffing, bus turnarounds and timing differences. The size of the reply window will be ISILongReplyWin bit times when a long packet is expected in reply, i.e. this will be the max size of a long packet, allowing for worst case bit stuffing, bus turnarounds and timing differences. In both cases if an ACK is received the window will close and another packet can be transmitted but if an ACK is not received then the full length of the window must be waited out.
1378As no reply should be sent to a broadcast packet, no reply window should be required however all other long packets open a reply window in anticipation of an ACK. While the desire is to minimize the time between broadcast transmissions the simplest solution should be employed. This would imply the same size reply window as other long packets.
1379When a packet has been received without any errors the receiving ISI device must transmit its acknowledge packet (which may be either a long or short packet) before the reply window closes. When detected errors do occur the receiving ISI device will not send any response. The transmitting ISI device interprets this lack of response as a NAK indicating that errors were detected in the transmitted packet or that the receiving device was unable to receive the packet for some reason (e.g. its buffers are full). If a long packet was transmitted the transmitting ISI device will keep the transmitted packet in its transmit buffer for retransmission. If the transmitting device is the ISIMaster it will retransmit the packet immediately while if the transmitting device is an ISISlave it will retransmit the packet in response to the next ping it receives from the ISIMaster.
1380The transmitting ISI device will continue retransmitting the packet when it receives a NAK until it either receives an ACK or the number of retransmission attempts equals the value of the NumRetries register. If the transmission was unsuccessful then the transmitting device sets the TxErrorSticky bit in its ISIIntStatus register. The receiving device also sets the RxErrorSticky bit in its ISIIntStatus register whenever it detects a CRC error in an incoming packet and is not required to take any further action, as it is up to the transmitting device to detect and rectify the problem. The NumRetries registers in all ISI devices should be set to the same value for consistent operation. Note that successful transmission or reception of ping packets do not affect retransmission operation.
1381Note that a transmit error will cause the ISI to stop transmitting. CPU intervention will be required to resolve the source of the problem and to restart the ISI transmit operation. Receive errors however do not affect receive operation and they are collected to facilitate problem debug and to monitor the quality of the ISI physical channel. Transmit or receive errors should be extremely rare and their occurrence will most likely indicate a serious problem.
1382Note that broadcast packets are never acknowledged to avoid contention on the common ISI lines. If an ISISlave detects an error in a broadcast packet it should use the message passing mechanism described earlier to alert the ISIMaster to the error if it so wishes.
000012.4.4.9 Sequence Bit Operation
1383To ensure that communication between transmitting and receiving ISI devices is correctly ordered a sequence bit is included in every long packet to keep both devices in step with each other. The sequence bit field is a constant for short or ping packets as they are not used for data transmission. In addition to the transmitted sequence bit all ISI devices keep two local sequence bits, one for each ISISubId. Furthermore each ISI device maintains a transmit sequence bit for each ISIId and ISISubId it is in communication with. For packets sourced from the external host (via USB) the transmit sequence bit is contained in the relevant USBEPnDest register while for packets sourced from the CPU the transmit sequence bit is contained in the CPUISITxBuffCntrl register. The sequence bits for received packets are stored in ISISubId0Seq and ISISubId1Seq registers. All ISI devices will initialize their sequence bits to 0 after reset. It is-the responsibility of software to ensure that the sequence bits of the transmitting and receiving ISI devices are correctly initialized each time a new source is selected for any ISIId.ISISubId channel.
1384Sequence bits are ignored by the receiving ISI device for broadcast packets. However the broadcasting ISI device is free to toggle the sequence in the broadcast packets since they will not affect operation. The SCB will do this for all USB source data so that there is no special treatment for the sequence bit of a broadcast packet in the transmitting device. CPU sourced broadcasts will have sequence bits toggled at the discretion of the program code.
1385Each SoPEC may also ignore the sequence bit on either of its ISISubId channels by setting the appropriate bit in the ISISubIdSeqMask register. The sequence bit should be ignored for ISISubId channels that will carry data that can originate from more than one source and is self ordering e.g. control messages.
1386A receiving ISI device will toggle its sequence bit addressed by the ISISubId only when the receiver is able to accept data and receives an error-free data packet addressed to it. The transmitting ISI device will toggle its sequence bit for that ISIId.ISISubId channel only when it receives a valid ACK handshake from the addressed ISI device.
1387<figref idref="DRAWINGS">FIG. 36</figref> shows the transmission of two long packets with the sequence bit in both the transmitting and receiving devices toggling from 0 to 1 and back to 0 again. The toggling operation will continue in this manner in every subsequent transmission until an error condition is encountered.
1388When the receiving ISI device detects an error in the transmitted long packet or is unable to accept the packet (because of full buffers for example) it will not return any packet and it will not toggle its local sequence bit. An example of this is depicted in <figref idref="DRAWINGS">FIG. 37</figref>. The absence of any response prompts the transmitting device to retransmit the original (seq=0) packet. This time the packet is received without any errors (or buffer space may have been freed) so the receiving ISI device toggles its local sequence bit and responds with an ACK. The transmitting device then toggles its local sequence bit to a 1 upon correct receipt of the ACK.
1389However it is also possible for the ACK packet from the receiving ISI device to be corrupted and this scenario is shown in <figref idref="DRAWINGS">FIG. 38</figref>. In this case the receiving device toggles its local sequence bit to 1 when the long packet is received without error and replies with an ACK to the transmitting device. The transmitting device does not receive the ACK correctly and so does not change its local sequence bit. It then retransmits the seq=0 long packet. When the receiving device finds that there is a mismatch between the transmitted sequence bit and the expected (local) sequence bit is discards the long packet and replies with an ACK. When the transmitting ISI device correctly receives the ACK it updates its local sequence bit to a 1, thus restoring synchronization. Note that when the ISISubIdSeqMask bit for the addressed ISISubId is set then the retransmitted packet is not discarded and so a duplicate packet will be received. The data contained in the packet should be self-ordering and so the software handling these packets (most likely control messages) is expected to deal with this eventuality.
000012.4.4.10 Flow Control
1390The ISI also supports flow control by treating it in exactly the same manner as an error in the received packet. Because the SCB enjoys greater guaranteed bandwidth to DRAM than both the ISI and USB can supply flow control should not be required during normal operation. Any blockage on a DMA channel will soon result in the NumRetries value being exceeded and transmission from that SoPEC being halted. If a SoPEC NAK<sub>S </sub>a packet because its RxBuffer is full it will flag an overflow condition. This condition can potentially cause a CPU interrupt, if the corresponding interrupt is enabled. The RxOverflowSticky bit of its ISIIntStatus register reflects this condition. Because flow control is treated in the same manner as an error the transmitting ISI device will not be able to differentiate a flow control condition from an error in the transmitted packet.
000012.4.4.11 Auto-ping Operation
1391While the CPU of the ISIMaster could send a ping packet by writing the appropriate header to the CPUISITxBuffCntrl register it is expected that all ping packets will be generated in the ISI itself. The use of automatically generated ping packets ensures that ISISlaves will be given access to the ISI bus with a programmable minimum guaranteed frequency in addition to whenever it would otherwise be idle. Five registers facilitate the automatic generation of ping messages within the ISI: PingSchedule0, PingSchedule1, PingSchedule2, ISITotalPeriod and ISILocalPeriod. Auto-pinging will be enabled if any bit of any of the PingScheduleN registers is set and disabled if all PingScheduleN registers are 0x0000.
1392Each bit of the 15-bit PingScheduleN register corresponds to an ISIId that is used in the Address field of the ping packet and a 1 in the bit position indicates that a ping packet is to be generated for that ISIId. A 0 in any bit position will ensure that no ping packet is generated for that ISIId. As ISISlaves may differ in their bandwidth requirement (particularly if a storage SoPEC is present) three different PingSchedule registers are used to allow an ISISlave receive up to three times the number of pings as another active ISISlave. When the ISIMaster is not sending long packets (sourced from either the CPU or USB in the case of a SoPEC ISIMaster) ISI ping packets will be transmitted according to the pattern given by the three PingScheduleN registers. The ISI will start with the lsb of PingSchedule0 register and work its way from lsb through msb of each of the PingScheduleN registers. When the msb of PingSchedule2 is reached the ISI returns to the lsb of PingSchedule0 and continues to cycle through each bit position of each PingScheduleN register. The ISI has more than enough time to work out the destination of the next ping packet while a ping or long packet is being transmitted.
1393With the addition of auto-ping operation we now have three potential sources of packets in an ISIMaster SoPEC: USB, CPU and auto-ping. Arbitration between the CPU and USB for access to the ISI is handled outside the ISI. To ensure that local packets get priority whenever possible and that ping packets can have some guaranteed access to the ISI we use two 4-bit counters whose reload value is contained in the ISITotalPeriod and ISILocalPeriod registers. As we saw in section 12.4.4.1 every ISI transaction is initiated by the ISIMaster transmitting either a long packet or a ping packet. The ISITotalPeriod counter is decremented for every ISI transaction (i.e. either long or ping) when its value is non-zero. The ISILocalPeriod counter is decremented for every local packet that is transmitted. Neither counter is decremented by a retransmitted packet. If the ISITotalPeriod counter is zero then ping packets will not change its value from zero. Both the ISITotalPeriod and ISILocalPeriod counters are reloaded by the next local packet transmit request after the ISITotalPeriod counter has reached zero and this local packet has priority over pings.
1394The amount of guaranteed ISI bandwidth allocated to both local and ping packets is determined by the values of the ISITotalPeriod and ISILocalPeriod registers. Local packets will always be given priority when the ISILocalPeriod counter is non-zero. Ping packets will be given priority when the ISILocalPeriod counter is zero and the ISITotalPeriod counter is still non-zero.
1395Note that ping packets are very likely to get more than their guaranteed bandwidth as they will be transmitted whenever the ISI bus would otherwise be idle (i.e. no pending local packets). In particular when the ISITotalPeriod counter is zero it will not be reloaded until another local packet is pending and so ping packets transmitted when the ISITotalPeriod counter is zero will be in addition to the guaranteed bandwidth. Local packets on the other hand will never get more than their guaranteed bandwidth because each local packet transmitted decrements both counters and will cause the counters to be reloaded when the ISITotalPeriod counter is zero. The difference between the values of the ISITotalPeriod and ISILocalPeriod registers determines the number of automatically generated ping packets that are guaranteed to be transmitted every ISITotalPeriod number of ISI transactions. If the ISITotalPeriod and ISILocalPeriod values are the same then the local packets will always get priority and could totally exclude ping packets if the CPU always has packets to send.
1396For example if ISITotalPeriod=0xC; ISILocalPeriod=0x8; PingSchedule0=0x0E; PingSchedule1=0x0C and PingSchedule2=0x08 then four ping messages are guaranteed to be sent in every 12 ISI transactions. Furthermore ISIId3 will receive 3 times the number of ping packets as ISId1 and ISId2 will receive twice as many as ISId1. Thus over a period of 36 contended ISI transactions (allowing for two full rotations through the three PingScheduleN registers) when local packets are always pending 24 local packets will be sent, ISId1 will receive 2 ping packets, ISId2 will receive 4 pings and ISId3 will receive 6 ping packets. If local traffic is less frequent then the ping frequency will automatically adjust upwards to consume all remaining ISI bandwidth.
000012.4.5 Wake-up from Sleep Mode
1397Either the PrintMaster SoPEC or the external host may place any of the ISISlave SoPECs in sleep mode prior to going into sleep mode itself. The ISISlave device should then ensure that its ISIWakeupEnable bit of the WakeupEnable register (see Table 34) is set prior to entering sleep mode. In an ISISlave device the ISI block will continue to receive power and clock during sleep mode so that it may monitor the gpio_isi_din lines for activity. When ISI activity is detected during sleep mode and the ISIWakeupEnable bit is set the ISI asserts the isi_cpr_reset_n signal. This will bring the rest of the chip out of sleep mode by means of a wakeup reset. See chapter <b>16</b> for more details of reset propagation.
000012.4.6 Implementation
1398Although the ISI consists of either 2 or 4 ISI data lines over which a serial data stream is demultiplexed, each ISI line is treated as a separate serial link at the physical layer. This permits a certain amount of skew between the ISI lines that could not be tolerated if the lines were treated as a parallel bus. A lower Bit Error Rate (BER) can be achieved if the serial data recovery is performed separately on each serial link. <figref idref="DRAWINGS">FIG. 39</figref> illustrates the ISI sub block partitioning.
000012.4.6.1 ISI Sub-block Partition
0000<ul id="ul0136" list-style="none"><li id="ul0136-0001" num="0000"><ul id="ul0137" list-style="none"><li id="ul0137-0001" num="1399">Definition of I/Os.</li></ul></li></ul>
1400<tables id="TABLE-US-00042" num="00042"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="308pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 34</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>ISI I/O</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="182pt" align="left" /><tbody valign="top"><row><entry>Port name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="308pt" align="left" /><tbody valign="top"><row><entry>Clock and Reset</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="182pt" align="left" /><tbody valign="top"><row><entry>isi_pclk</entry><entry>1</entry><entry>In</entry><entry>ISI primary clock.</entry></row><row><entry>isi_reset_n</entry><entry>1</entry><entry>In</entry><entry>ISI reset. Active low.</entry></row><row><entry /><entry /><entry /><entry>Asserting isi_reset_n will reset all ISI logic.</entry></row><row><entry /><entry /><entry /><entry>Synchronous to isi_pclk.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="308pt" align="left" /><tbody valign="top"><row><entry>Configuration</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="182pt" align="left" /><tbody valign="top"><row><entry>isi_go</entry><entry>1</entry><entry>In</entry><entry>ISI GO. Active high.</entry></row><row><entry /><entry /><entry /><entry>When GO is de-asserted, all ISI statemachines are</entry></row><row><entry /><entry /><entry /><entry>reset to their idle states, all ISI output signals are de-</entry></row><row><entry /><entry /><entry /><entry>asserted, but all ISI counters retain their values.</entry></row><row><entry /><entry /><entry /><entry>When GO is asserted, all ISI counters are reset and all</entry></row><row><entry /><entry /><entry /><entry>ISI statemachines and output signals will return to their</entry></row><row><entry /><entry /><entry /><entry>normal mode of operation.</entry></row><row><entry>isi_master_select</entry><entry>1</entry><entry>In</entry><entry>ISI master select.</entry></row><row><entry /><entry /><entry /><entry>Determines whether the SoPEC is an ISIMaster or not</entry></row><row><entry /><entry /><entry /><entry>1 = ISIMaster</entry></row><row><entry /><entry /><entry /><entry>0 = ISISlave</entry></row><row><entry>isi_id[3:0]</entry><entry>4</entry><entry>In</entry><entry>ISI ID for this device.</entry></row><row><entry>isi_retries[3:0]</entry><entry>4</entry><entry>In</entry><entry>ISI number of retries.</entry></row><row><entry /><entry /><entry /><entry>Number of times a transmitting ISI device will attempt</entry></row><row><entry /><entry /><entry /><entry>retransmission of a NAK'd packet before aborting the</entry></row><row><entry /><entry /><entry /><entry>transmission and flagging an error. The value of this</entry></row><row><entry /><entry /><entry /><entry>configuration signal should not be changed while there</entry></row><row><entry /><entry /><entry /><entry>are valid packets in the Tx buffer.</entry></row><row><entry>isi_ping_schedule0[14:0]</entry><entry>15</entry><entry>In</entry><entry>ISI auto ping schedule #0.</entry></row><row><entry /><entry /><entry /><entry>Denotes which ISIIds will be receive ping packets. Note</entry></row><row><entry /><entry /><entry /><entry>that bit0 refers to ISIId0, bit1 to ISIId1 . . . bit14 to ISIId14.</entry></row><row><entry /><entry /><entry /><entry>Setting a bit in this schedule will enable auto ping</entry></row><row><entry /><entry /><entry /><entry>generation for the corresponding ISI ID. The ISI will</entry></row><row><entry /><entry /><entry /><entry>start from the bit 0 of isi_ping_schedule0 and cycle</entry></row><row><entry /><entry /><entry /><entry>through to bit 14, generating pings for each bit that is</entry></row><row><entry /><entry /><entry /><entry>set. This operation will be performed in sequence from</entry></row><row><entry /><entry /><entry /><entry>isi_ping_schedule0 through isi_ping_schedule2.</entry></row><row><entry>isi_ping_schedule1[14:0]</entry><entry>15</entry><entry>In</entry><entry>As per isi_ping_schedule0.</entry></row><row><entry>isi_ping_schedule2[14:0]</entry><entry>15</entry><entry>In</entry><entry>As per isi_ping_schedule0.</entry></row><row><entry>isi_total_period[3:0]</entry><entry>4</entry><entry>In</entry><entry>Reload value of the ISI Total Period Counter.</entry></row><row><entry>isi_local_period[3:0]</entry><entry>4</entry><entry>In</entry><entry>Reload value of the ISI Local Period Counter.</entry></row><row><entry>isi_number_pins</entry><entry>1</entry><entry>In</entry><entry>Number of active ISI data pins.</entry></row><row><entry /><entry /><entry /><entry>Used to select how many serial data pins will be used</entry></row><row><entry /><entry /><entry /><entry>to transmit and receive data. Should reflect the number</entry></row><row><entry /><entry /><entry /><entry>of ISI device data pins that are in use.</entry></row><row><entry /><entry /><entry /><entry>1 = isi_data[3:0] active</entry></row><row><entry /><entry /><entry /><entry>0 = isi_data[1:0] active</entry></row><row><entry>isi_turn_around[3:0]</entry><entry>4</entry><entry>In</entry><entry>ISI bus turn around time in ISI clock cycles (32 MHz).</entry></row><row><entry>isi_short_reply_win[4:0]</entry><entry>5</entry><entry>In</entry><entry>ISI long packet reply window in ISI clock cycles</entry></row><row><entry /><entry /><entry /><entry>(32 MHz).</entry></row><row><entry>isi_long_reply_win[8:0]</entry><entry>9</entry><entry>In</entry><entry>ISI long packet reply window in ISI clock cycles</entry></row><row><entry /><entry /><entry /><entry>(32 MHz).</entry></row><row><entry>isi_tx_enable</entry><entry>1</entry><entry>In</entry><entry>ISI transmit enable. Active high.</entry></row><row><entry /><entry /><entry /><entry>Enables ISI transmission of long or ping packets. ACKs</entry></row><row><entry /><entry /><entry /><entry>may still be transmitted when this bit is 0. The value of</entry></row><row><entry /><entry /><entry /><entry>this configuration signal should not be changed while</entry></row><row><entry /><entry /><entry /><entry>there are valid packets in the Tx buffer.</entry></row><row><entry>isi_rx_enable</entry><entry>1</entry><entry>In</entry><entry>ISI receive enable. Active high.</entry></row><row><entry /><entry /><entry /><entry>Enables ISI packet reception. Any activity on the ISI</entry></row><row><entry /><entry /><entry /><entry>bus will be ignored when this signal is de-asserted.</entry></row><row><entry /><entry /><entry /><entry>This signal should only be de-asserted if the ISI block</entry></row><row><entry /><entry /><entry /><entry>is not required for use in the design.</entry></row><row><entry>isi_bit_stuff_rate[3:0]</entry><entry>1</entry><entry>In</entry><entry>ISI bit stuffing limit.</entry></row><row><entry /><entry /><entry /><entry>Allows the bit stuffing counter value to be programmed.</entry></row><row><entry /><entry /><entry /><entry>Is loaded into the 4 upper bits of the 7 bit wide bit</entry></row><row><entry /><entry /><entry /><entry>stuffing counter. The lower bits are always loaded with</entry></row><row><entry /><entry /><entry /><entry>b111, to prevent bit stuffing for less than 7 consecutive</entry></row><row><entry /><entry /><entry /><entry>ones or zeroes. E.g.</entry></row><row><entry /><entry /><entry /><entry>b000: stuff_count = b0000111: bit stuff after 7</entry></row><row><entry /><entry /><entry /><entry>consecutive 0/1</entry></row><row><entry /><entry /><entry /><entry>b111: stuff.count = b1111111: bit stuff after 127</entry></row><row><entry /><entry /><entry /><entry>consecutive 0/1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="308pt" align="left" /><tbody valign="top"><row><entry>Serial Link Signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="182pt" align="left" /><tbody valign="top"><row><entry>isi_ser_data_in[3:0]</entry><entry>4</entry><entry>In</entry><entry>ISI Serial data inputs.</entry></row><row><entry /><entry /><entry /><entry>Each bit corresponds to a separate serial link.</entry></row><row><entry>isi_ser_data_out[3:0]</entry><entry>4</entry><entry>Out</entry><entry>ISI Serial data outputs.</entry></row><row><entry /><entry /><entry /><entry>Each bit corresponds to a separate serial link.</entry></row><row><entry>isi_ser_data_en[3:0]</entry><entry>4</entry><entry>Out</entry><entry>ISI Serial data driver enables. Active high.</entry></row><row><entry /><entry /><entry /><entry>Each bit corresponds to a separate serial link.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="308pt" align="left" /><tbody valign="top"><row><entry>Tx Packet Buffer</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="182pt" align="left" /><tbody valign="top"><row><entry>isi_tx_wr_en</entry><entry>1</entry><entry>In</entry><entry>ISI Tx FIFO write enable. Active high.</entry></row><row><entry /><entry /><entry /><entry>Asserting isi_tx_wr_en will write the 64 bit data on</entry></row><row><entry /><entry /><entry /><entry>isi_tx_wr_data to the FIFO, providing that space is</entry></row><row><entry /><entry /><entry /><entry>available in the FIFO. If isi_tx_wr_en remains asserted</entry></row><row><entry /><entry /><entry /><entry>after the last entry in the current packet is written, the</entry></row><row><entry /><entry /><entry /><entry>write operation will wrap around to the start of the next</entry></row><row><entry /><entry /><entry /><entry>packet, providing that space is available for a second</entry></row><row><entry /><entry /><entry /><entry>packet in the FIFO.</entry></row><row><entry>isi_tx_wr_data[63:0]</entry><entry>64</entry><entry>In</entry><entry>ISI Tx FIFO write data.</entry></row><row><entry>isi_tx_ping</entry><entry>1</entry><entry>In</entry><entry>ISI Tx FIFO ping packet select. Active high.</entry></row><row><entry /><entry /><entry /><entry>Asserting isi_tx_ping will queue a ping packet for</entry></row><row><entry /><entry /><entry /><entry>transmission, as opposed to a long packet. Although</entry></row><row><entry /><entry /><entry /><entry>there is no data payload for a ping packet, a packet</entry></row><row><entry /><entry /><entry /><entry>location in the FIFO is used as a ‘place holder’ for the</entry></row><row><entry /><entry /><entry /><entry>ping packet. Any data written to the associated packet</entry></row><row><entry /><entry /><entry /><entry>location in the FIFO will be discarded when the ping</entry></row><row><entry /><entry /><entry /><entry>packet is transmitted.</entry></row><row><entry>isi_tx_id[3:0]</entry><entry>5</entry><entry>In</entry><entry>ISI Tx FIFO packet ID.</entry></row><row><entry /><entry /><entry /><entry>ISI ID for each packet written to the FIFO. Registered</entry></row><row><entry /><entry /><entry /><entry>when the last entry of the packet is written.</entry></row><row><entry>isi_tx_sub_id</entry><entry>1</entry><entry>In</entry><entry>ISI Tx FIFO packet sub ID.</entry></row><row><entry /><entry /><entry /><entry>ISI sub ID for each packet written to the FIFO.</entry></row><row><entry /><entry /><entry /><entry>Registered when the last entry of the packet is written.</entry></row><row><entry>isi_tx_pkt_count[1:0]</entry><entry>2</entry><entry>Out</entry><entry>ISI Tx FIFO packet count.</entry></row><row><entry /><entry /><entry /><entry>Indicates the number of packets contained in the FIFO.</entry></row><row><entry /><entry /><entry /><entry>The FIFO has a capacity of 2 × 256 bit packets. Range</entry></row><row><entry /><entry /><entry /><entry>is b00−>b10.</entry></row><row><entry>isi_tx_word_count[2:0]</entry><entry>3</entry><entry>Out</entry><entry>ISI Tx FIFO current packet word count.</entry></row><row><entry /><entry /><entry /><entry>Indicates the number of words contained in the current</entry></row><row><entry /><entry /><entry /><entry>Tx packet location of the Tx FIFO. Each packet location</entry></row><row><entry /><entry /><entry /><entry>has a capacity of 4 × 64 bit words. Range is b000−></entry></row><row><entry /><entry /><entry /><entry>b100.</entry></row><row><entry>isi_tx_empty</entry><entry>1</entry><entry>Out</entry><entry>ISI Tx FIFO empty. Active high.</entry></row><row><entry /><entry /><entry /><entry>Indicates that no packets are present in the FIFO.</entry></row><row><entry>isi_tx_full</entry><entry>1</entry><entry>Out</entry><entry>ISI Tx FIFO full. Active high.</entry></row><row><entry /><entry /><entry /><entry>Indicates that 2 packets are present in the FIFO,</entry></row><row><entry /><entry /><entry /><entry>therefore no more packets can be transmitted.</entry></row><row><entry>isi_tx_over_flow</entry><entry>1</entry><entry>Out</entry><entry>ISI Tx FIFO over flow. Active high.</entry></row><row><entry /><entry /><entry /><entry>Indicates that a write operation was performed on a full</entry></row><row><entry /><entry /><entry /><entry>FIFO. The write operation will have no effect on the</entry></row><row><entry /><entry /><entry /><entry>contents of the FIFO or the write pointer.</entry></row><row><entry>isi_tx_error</entry><entry>1</entry><entry>Out</entry><entry>ISI Tx FIFO error. Active high.</entry></row><row><entry /><entry /><entry /><entry>Indicates that an error occurred while transmitting the</entry></row><row><entry /><entry /><entry /><entry>packet currently at the head of the FIFO. This will</entry></row><row><entry /><entry /><entry /><entry>happen if the number of transmission attempts exceeds</entry></row><row><entry /><entry /><entry /><entry>isi_tx_retries.</entry></row><row><entry>isi_tx_desc[2:0]</entry><entry>3</entry><entry>Out</entry><entry>ISI Tx packet descriptor field.</entry></row><row><entry /><entry /><entry /><entry>ISI packet descriptor field for the packet currently at the</entry></row><row><entry /><entry /><entry /><entry>head of the FIFO. See Table for details. Only valid</entry></row><row><entry /><entry /><entry /><entry>when isi_tx_empty = 0, i.e. when there is a valid packet</entry></row><row><entry /><entry /><entry /><entry>in the FIFO.</entry></row><row><entry>isi_tx_addr[4:0]</entry><entry>5</entry><entry>Out</entry><entry>ISI Tx packet address field.</entry></row><row><entry /><entry /><entry /><entry>ISI address field for the packet currently at the head of</entry></row><row><entry /><entry /><entry /><entry>the FIFO. See Table for details. Only valid when</entry></row><row><entry /><entry /><entry /><entry>isi_tx_empty = 0, i.e. when there is a valid packet in the</entry></row><row><entry /><entry /><entry /><entry>FIFO.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="308pt" align="left" /><tbody valign="top"><row><entry>Rx Packet FIFO</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="182pt" align="left" /><tbody valign="top"><row><entry>isi_rx_rd_en</entry><entry>1</entry><entry>In</entry><entry>ISI Rx FIFO read enable. Active high.</entry></row><row><entry /><entry /><entry /><entry>Asserting isi_rx_rd_en will drive isi_rx_rd_data with</entry></row><row><entry /><entry /><entry /><entry>valid data, from the Rx packet at the head of the FIFO,</entry></row><row><entry /><entry /><entry /><entry>providing that data is available in the FIFO. If</entry></row><row><entry /><entry /><entry /><entry>isi_rx_rd_en remains asserted after the last entry is</entry></row><row><entry /><entry /><entry /><entry>read from the current packet, the read operation will</entry></row><row><entry /><entry /><entry /><entry>wrap around to the start of the next packet, providing</entry></row><row><entry /><entry /><entry /><entry>that a second packet is available in the FIFO.</entry></row><row><entry>isi_rx_rd_data[63:0]</entry><entry>64</entry><entry>Out</entry><entry>ISI Rx FIFO read data.</entry></row><row><entry>isi_rx_sub_id</entry><entry>1</entry><entry>Out</entry><entry>ISI Rx packet sub ID.</entry></row><row><entry /><entry /><entry /><entry>Indicates the ISI sub ID associated with the packet at</entry></row><row><entry /><entry /><entry /><entry>the head of the Rx FIFO.</entry></row><row><entry>isi_rx_pkt_count[1:0]</entry><entry>2</entry><entry>Out</entry><entry>ISI Rx FIFO packet count.</entry></row><row><entry /><entry /><entry /><entry>Indicates the number of packets contained in the FIFO.</entry></row><row><entry /><entry /><entry /><entry>The FIFO has a capacity of 2 × 256 bit packets. Range</entry></row><row><entry /><entry /><entry /><entry>is b00−>b10.</entry></row><row><entry>isi_rx_word_count[2:0]</entry><entry>3</entry><entry>Out</entry><entry>ISI Rx FIFO current packet word count.</entry></row><row><entry /><entry /><entry /><entry>Indicates the number of words contained in the Rx</entry></row><row><entry /><entry /><entry /><entry>packet location at the head of the FIFO. Each packet</entry></row><row><entry /><entry /><entry /><entry>location has a capacity of 4 × 64 bit words. Range is</entry></row><row><entry /><entry /><entry /><entry>b000−>b100.</entry></row><row><entry>isi_rx_empty</entry><entry>1</entry><entry>Out</entry><entry>ISI Rx FIFO empty. Active high.</entry></row><row><entry /><entry /><entry /><entry>Indicates that no packets are present in the FIFO.</entry></row><row><entry>isi_rx_full</entry><entry>1</entry><entry>Out</entry><entry>ISI Rx FIFO full. Active high.</entry></row><row><entry /><entry /><entry /><entry>Indicates that 2 packets are present in the FIFO,</entry></row><row><entry /><entry /><entry /><entry>therefore no more packets can be received.</entry></row><row><entry>isi_rx_over_flow</entry><entry>1</entry><entry>Out</entry><entry>ISI Rx FIFO over flow. Active high.</entry></row><row><entry /><entry /><entry /><entry>Indicates that a packet was addressed to the local ISI</entry></row><row><entry /><entry /><entry /><entry>device, but the Rx FIFO was full, resulting in a NAK.</entry></row><row><entry>isi_rx_under_run</entry><entry>1</entry><entry>Out</entry><entry>ISI Rx FIFO under run. Active high.</entry></row><row><entry /><entry /><entry /><entry>Indicates that a read operation was performed on an</entry></row><row><entry /><entry /><entry /><entry>empty FIFO. The invalid read will return the contents of</entry></row><row><entry /><entry /><entry /><entry>the memory location currently addressed by the FIFO</entry></row><row><entry /><entry /><entry /><entry>read pointer and will have no effect on the read pointer.</entry></row><row><entry>isi_rx_frame_error</entry><entry>1</entry><entry>Out</entry><entry>ISI Rx framing error. Active high.</entry></row><row><entry /><entry /><entry /><entry>Asserted by the ISI when a framing error is detected in</entry></row><row><entry /><entry /><entry /><entry>the received packet, which can be caused by an</entry></row><row><entry /><entry /><entry /><entry>incorrect Start or Stop field or by bit stuffing errors. The</entry></row><row><entry /><entry /><entry /><entry>associated packet will be dropped.</entry></row><row><entry>isi_rx_crc_error</entry><entry>1</entry><entry>Out</entry><entry>ISI Rx CRC error. Active high.</entry></row><row><entry /><entry /><entry /><entry>Asserted by the ISI when a CRC error is detected in an</entry></row><row><entry /><entry /><entry /><entry>incoming packet. Other than dropping the errored</entry></row><row><entry /><entry /><entry /><entry>packet ISI reception is unaffected by a CRC Error.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.4.6.2 ISI Serial Interface Engine (isi_sie)
1401There are 4 instantiations of the isi_sie sub block in the ISI, 1 per ISI serial link. The isi_sie is responsible for Rx serial data sampling, Tx serial data output and bit stuffing.
1402Data is sampled based on a phase detection mechanism. The incoming ISI serial data stream is over sampled 5 times per ISI bit period. The phase of the incoming data is determined by detecting transitions in the ISI serial data stream, which indicates the ISI bit boundaries. An ISI bit boundary is defined as the sample phase at which a transition was detected.
1403The basic functional components of the isi_sie are detailed in <figref idref="DRAWINGS">FIG. 40</figref>. These components are simply a grouping of logical functionality and do not necessarily represent hierarchy in the design.
000012.4.6.2.1 SIE Edge Detection and Data I/O
1404The basic structure of the data I/O and edge detection mechanism is detailed in <figref idref="DRAWINGS">FIG. 41</figref>.
1405NOTE: Serial data from the receiver in the pad MUST be synchronized to the isi_pclk domain with a 2 stage shift register external to the ISI, to reduce the risk of metastability. ser_data_out and ser_data_en should be registered externally to the ISI.
1406The Rx/Tx statemachine drives ser_data_en, stuff<sub>—</sub>1_en and stuff<sub>—</sub>0_en. The signals stuff<sub>—</sub>1_en and stuff<sub>—</sub>0_en cause a one or a zero to be driven on ser_data_out when they are asserted, otherwise fifo_rd_data is selected.
000012.4.6.2.2 SIE Rx/Tx Statemachine
1407The Rx/Tx statemachine is responsible for the transmission of ISI Tx data and the sampling of ISI Rx data. Each ISI bit period is 5 isi_pclk cycles in duration.
1408The Tx cycle of the Rx/Tx statemachine is illustrated in <figref idref="DRAWINGS">FIG. 42</figref>. It generates each ISI bit that is transmitted. States tx0->tx4 represent each of the 5 isi_pclk phases that constitute a Tx ISI bit period. ser_data_en controls the tristate enable for the ISI line driver in the bidirectional pad, as shown in <figref idref="DRAWINGS">FIG. 41</figref>. rx_tx_cycle is asserted during both Rx and Tx states to indicate an active Rx or Tx cycle. It is primarily used to enable bit stuffing.
1409NOTE: All statemachine signals are assumed to be ‘0’ unless otherwise stated.
1410The Tx cycle for Tx bit stuffing when the Rx/Tx statemachine inserts a ‘0’ into the bitstream can be seen in <figref idref="DRAWINGS">FIG. 43</figref>.
1411NOTE: All statemachine signals are assumed to be ‘0’ unless otherwise stated
1412The Tx cycle for Tx bit stuffing when the RxTx statemachine inserts a ‘1’ into the bitstream can be seen in <figref idref="DRAWINGS">FIG. 44</figref>.
1413NOTE: All statemachine signals are assumed to be ‘0’ unless otherwise stated
1414The tx* and stuff* states are detailed separately for clarity. They could be easily combined when coding the statemachine, however it would be better for verification and debugging if they were kept separate.
1415The Rx cycle of the ISI Rx/Tx statemachine is detailed in <figref idref="DRAWINGS">FIG. 45</figref>. The Rx cycle of the Rx/Tx Statemachine, samples each ISI bit that is received. States rx0->rx4 represent each of the 5 isi_pclk phases that constitute a Rx ISI bit period.
1416The optimum sample position for an ideal ISI bit period is 2 isi_pclk cycles after the ISI bit boundary sample, which should result in a data sample close to the centre of the ISI bit period. rx_sample is asserted during the rx2 state to indicate a valid ISI data sample on rx_bit, unless the bit should be stripped when flagged by the bit stuffing statemachine, in which case rx_sample is not asserted during rx2 and the bit is not written to the FIFO. When edge is asserted, it resets the Rx cycle to the rx0 state, from any rx state. This is how the isi_sie tracks the phase of the incoming data. The Rx cycle will cycle through states rx0->rx4 until edge is asserted to reset the sample phase, or a tx_req is asserted indicating that the ISI needs to transmit.
1417Due to the 5 times oversampling a maximum phase error of 0.4 of an ISI bit period (2 isi_pclk cycles out of 5) can be tolerated.
1418NOTE: All statemachine signals are assumed to be ‘0’ unless otherwise stated.
1419An example of the Tx data generation mechanism is detailed in <figref idref="DRAWINGS">FIG. 46</figref>. tx_req and fifo_wr_tx are driven by the framer block.
1420An example of the Rx data sampling functional timing is detailed in <figref idref="DRAWINGS">FIG. 47</figref>. The dashed lines on the ser_data_in_ff signal indicate where the Rx/Tx statemachine perceived the bit boundary to be, based on the phase of the last ISI bit boundary. It can be seen that data is sampled during the same phase as the previous bit was, in the absence of a transition.
000012.4.6.2.3 SIE Rx/Tx FIFO
1421The Rx/Tx FIFO is a 7×1 bit synchronous look-ahead FIFO that is shared for Tx and Rx operations. It is required to absorb any Rx/Tx latency caused by bit stripping/stuffing on a per ISI line basis, i.e. some ISI lines may require bit stripping/stuffing during an ISI bit period while the others may not, which would lead to a loss of synchronization between the data of the different ISI lines, if a FIFO were not present in each isi_sie.
1422The basic functional components of the FIFO are detailed in <figref idref="DRAWINGS">FIG. 48</figref>. tx_ready is driven by the Rx/Tx statemachine and selects which signals control the read and write operations. tx_ready=1 during ISI transmission and selects the fifo_*tx control and data signals. tx_ready=0 during ISI reception and selects the fifo_*rx control and data signals. fifo_reset is driven by the Rx/Tx statemachine. It is active high and resets the FIFO and associated logic before/after transmitting a packet to discard any residual data.
1423The size of the FIFO is based on the maximum bit stuffing frequency and the size of the shift register used to segment/re-assemble the multiple serial streams in the ISI framing logic. The maximum bit stuffing frequency is every 7 consecutive ones or zeroes. The shift register used is 32 bits wide. This implies that the maximum number of stuffed bits encountered in the time it takes to fill/empty the shift register if 4. This would suggest that 4×1 bit would be the minimum ideal size of the FIFO. However it is necessary to allow for different skew and phase error between the ISI lines, hence a 7×1 bit FIFO.
1424The FIFO is controlled by the isi_sie during packet reception and is controlled by the isi_frame block during packet transmission. This is illustrated in <figref idref="DRAWINGS">FIG. 49</figref>. The signal tx_ready selects which mode the FIFO control signals operate in. When tx_ready=0, i.e. Rx mode, the isi_sie control signals rx_sample, fifo_rd_rx and ser_data_in_ff are selected. When tx_ready=1, i.e. Tx mode, the sie_frame control signals fifo_wr_tx, fifo_rd_tx and fifo_wr_data_tx are selected.
000012.4.6.3 Bit Stuffing
1425Programmable bit stuffing is implemented in the isi_sie. This is to allow the system to determine the amount of bit stuffing necessary for a specific ISI system devices. It is unlikely that bit stuffing would be required in a system using a 100 ppm rated crystal. However, a programmable bit stuffing implementation is much more versatile and robust.
1426The bit stuffing logic consists of a counter and a statemachine that track the number of consecutive ones or zeroes that are transmitted or received and flags the Rx/Tx statemachine when the bit stuffing limit has been reached. The counter, stuff count, is a 7 bit counter, which decrements when rx_sample is asserted on a Rx cycle or when fifo_rd_tx is asserted on a Tx cycle. The upper 4 bits of stuff_count are loaded with isi_bit_stuff_rate. The lower 3 bits of stuff_count are always loaded with b111, i.e. for isi_bit_stuff_rate=b000, the counter would be loaded with b0000111. This is to prevent bit stuffing for less than 7 consecutive ones or zeroes. This allows the bit stuffing limit to be set in the range 7–>127 consecutive ones or zeroes.
1427NOTE: It is extremely important that a change in the bit stuffing rate, isi_bit_stuff_rate, is carefully coordinated between ISI devices in a system. It is obvious that ISI devices will not be able to communicate reliably with each other with different bit stuffing settings. It is recommended that all ISI devices in a system default to the safest bit stuffing rate (isi_bit_stuff_rate=b000) at reset. The system can then co-ordinate the change to an optimum bit stuffing rate.
1428The ISI bit stuffing statemachine Tx cycle is shown in <figref idref="DRAWINGS">FIG. 50</figref>. The counter is loaded when stuff_count_load is asserted.
1429NOTE: All statemachine signals are assumed to be ‘0’ unless otherwise stated.
1430The ISI bit stuffing statemachine Rx cycle is shown in <figref idref="DRAWINGS">FIG. 51</figref>. It should be noted that the statemachine enters the strip state when stuff_count=0x2. This is because the statemachine can only transition to rx0 or rx1 when rx_sample is asserted as it needs to be synchronized to changes in sampling phase introduced by the Rx/Tx statemachine. Therefore a one or a zero has already been sampled by the time it enters rx0 or rx1. This is not the case for the Tx cycle, as it will always have a stable 5 isi_pclk cycles per bit period and relies purely on the data value when entering tx0 or tx1. The Tx cycle therefore enters stuff1 or stuff0 when stuff_count=0x1.
1431NOTE: All statemachine signals are assumed to be ‘0’ unless otherwise stated.
000012.4.6.4 ISI Framing and CRC Sub-block (isi_frame)
000012.4.6.4.1 CRC Generation/Checking
1432A Cyclic Redundancy Checksum (CRC) is calculated over all fields except the start and stop fields for each long or ping packet transmitted. The receiving ISI device will perform the same calculation on the received packet to verify the integrity of the packet. The procedure used in the CRC generation/checking is the same as the Frame Checking Sequence (FCS) procedure used in HDLC, detailed in ITU-T Recommendation T30[39].
1433For generation/checking of the CRC field, the shift register illustrated in <figref idref="DRAWINGS">FIG. 52</figref> is used to perform the modulo 2 division on the packet contents by the polynomial G(x)=x<sup>16</sup>+x<sup>12</sup>+x<sup>5</sup>+1.
1434To generate the CRC for a transmitted packet, where T(x)=[Packet Descriptor field, Address field, Data Payload field] (a ping packet will not contain a data payload field). <ul id="ul0138" list-style="none"><li id="ul0138-0001" num="0000"><ul id="ul0139" list-style="none"><li id="ul0139-0001" num="1435">Set the shift register to 0xFFFF.</li><li id="ul0139-0002" num="1436">Shift T(x) through the shift register, LSB first. This can occur in parallel with the packet transmission.</li><li id="ul0139-0003" num="1437">Once the each bit of T(x) has been shifted through the register, it will contain the remainder of the modulo 2 division T(x)/G(x).</li><li id="ul0139-0004" num="1438">Perform a ones complement of the register contents, giving the CRC field which is transmitted MSB first, immediately following the last bit of M(x <ul id="ul0140" list-style="none"><li id="ul0140-0001" num="1439">To check the CRC for a received packet, where R(x)=[Packet Descriptor field, Address field, Data Payload field, CRC field] (a ping packet will not contain a data payload field).</li><li id="ul0140-0002" num="1440">Set the shift register to 0xFFFF.</li><li id="ul0140-0003" num="1441">Shift R(x) through the shift register, LSB first. This can occur in parallel with the packet reception.</li><li id="ul0140-0004" num="1442">Once each bit of the packet has been shifted through the register, it will contain the remainder of the modulo 2 division R(x)/G(x).</li><li id="ul0140-0005" num="1443">The remainder should equal b0001110100001111, for a packet without errors. <br /> 12.5 CTRL (Control Sub-block) <br /> 12.5.1 Overview </li></ul></li></ul></li></ul>
1444The CTRL is responsible for high level control of the SCB sub-blocks and coordinating access between them. All control and status registers for the SCB are contained within the CTRL and are accessed via the CPU interface. The other major components of the CTRL are the SCB Map logic and the DMA Manager logic.
000012.5.2 SCB Mapping
1445In order to support maximum flexibility when moving data through a multi-SoPEC system it is possible to map any USB endpoint onto either DMAChannel within any SoPEC in the system. The SCB map, and indeed the SCB itself is based around the concept of an ISIId and an ISISubId. Each SoPEC in the system has a unique ISIId and two ISISubIds, namely ISISubId0 and ISISubId1. We use the convention that ISISubId0 corresponds to DMAChannel0 in each SoPEC and ISISubId1 corresponds to DMAChannel1. The naming convention for the ISIId is shown in Table 35 below and this would correspond to a multi-SoPEC system such as that shown in <figref idref="DRAWINGS">FIG. 27</figref>. We use the term ISIId instead of SoPECId to avoid confusion with the unique ChipID used to create the SoPEC_id and SoPEC_id_key (see chapter 17 and [9] for more details).
1446<tables id="TABLE-US-00043" num="00043"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 35</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>ISIId naming convention</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="42pt" align="center" /><colspec colname="2" colwidth="175pt" align="left" /><tbody valign="top"><row><entry>ISIId</entry><entry>SoPEC to which it refers</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>0–14</entry><entry>Standard device ISIIds (0 is the power-on reset value)</entry></row><row><entry>15</entry><entry>Broadcast ISIId</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
1447The combined ISIId and ISISubId therefore allows the ISI to address DMAChannel0 or DMAChannel1 on any SoPEC device in the system. The ISI, DMA manager and SCB map hardware use the ISIId and ISISubId to handle the different data streams that are active in a multi-SoPEC system as does the software running on the CPU of each SoPEC. In this document we will identify DMAChannels as ISIx.y where x is the ISIId and y is the ISISubId. Thus ISI2.1 refers to DMAChannel1 of ISISlave2. Any data sent to a broadcast channel, i.e. ISI15.0 or ISI15.1, are received by every ISI device in the system including the ISIMaster (which may be an ISI-Bridge). The USB device controller and software stacks however have no understanding of the ISIId and ISISubId but the Silverbrook printer driver software running on the external host does make use of the ISIId and ISISubId. USB is simply used as a data transport—the mapping of USB device endpoints onto ISIId and SubId is communicated from the external host Silverbrook code to the SoPEC Silverbrook code through USB control (or possibly bulk data) messages i.e. the mapping information is simply data payload as far as USB is concerned. The code running on SoPEC is responsible for parsing these messages and configuring the SCB accordingly.
1448The use of just two DMAChannels places some limitations on what can be achieved without software intervention. For every SoPEC in the system there are more potential sources of data than there are sinks. For example an ISISlave could receive both control and data messages from the ISIMaster SoPEC in addition to control and data from the external host, either specifically addressed to that particular ISISlave or over the broadcast ISI channel. However all ISISlaves only have two possible data sinks, i.e. DMAChannel0 and DMAChannel1. Another example is the ISIMaster in a multi-SoPEC system which may receive control messages from each SoPEC in addition to control and data information from the external host (e.g. over USB). In this case all of the control messages are in contention for access to DMAChannel0. We resolve these potential conflicts by adopting the following conventions: <ul id="ul0141" list-style="none"><li id="ul0141-0001" num="1449">1) Control messages may be interleaved in a memory buffer: The memory buffer that the DMAChannel0 points to should be regarded as a central pool of control messages. Every control message must contain fields that identify the size of the message, the source and the destination of the control message. Control messages may therefore be multiplexed over a DMAChannel which allows several control message sources to address the same DMAChannel. Furthermore, if SoPEC-type control messages contain source and destination fields it is possible for the external host to send control messages to individual SoPECs over the ISI15.0 broadcast channel.</li><li id="ul0141-0002" num="1450">2) Data messages should not be interleaved in a memory buffer: As data messages are typically part of a much larger block of data that is being transferred it is not possible to control their contents in the same manner as is possible with the control messages. Furthermore we do not want the CPU to have to perform reassembly of data blocks. Data messages from different sources cannot be interleaved over the same DMAChannel—the SCB map must be reconfigured each time a different data source is given access to the DMAChannel.</li><li id="ul0141-0003" num="1451">3) Every reconfiguration of the SCB map requires the exchange of control messages: SoPEC's SCB map reset state is shown in Table and any subsequent modifications to this map require the exchange of control messages between the SoPEC and the external host. As the external host is expected to control the movement of data in any SoPEC system it is anticipated that all changes to the SCB map will be performed in response to a request from the external host. While the SoPEC could autonomously reconfigure the SCB map (this is entirely up to the software running on the SoPEC) it should not do so without informing the external host in order to avoid data being misrouted.</li></ul>
1452An example of the above conventions in operation is worked through in section 12.5.2.3.
000012.5.2.1 SCB Map Rules
1453The operation of the SCB map is described by these 2 rules: <ul id="ul0142" list-style="none"><li id="ul0142-0001" num="1454">Rule 1: A packet is routed to the DMA manager if it originates from the USB device core and has an ISIId that matches the local SoPEC ISIId.</li><li id="ul0142-0002" num="1455">Rule 2: A packet is routed to the ISI if it originates from the CPU or has an ISIId that does not match the local SoPEC ISIId.</li></ul>
1456If the CPU erroneously addresses a packet to the ISIId contained in the ISIId register (i.e. the ISIId of the local SoPEC) then that packet will be transmitted on the ISI rather than be sent to the DMA manager. While this will usually cause an error on the ISI there is one situation where it could be beneficial, namely for initial dialog in a 2 SoPEC system as both devices come out of reset with an ISIId of 0.
000012.5.2.2 External Host to ISIMaster SoPEC Communication
1457Although the SCB map configuration is independent of ISIMaster status, the following discussion on SCB map configurations assumes the ISIMaster is a SoPEC device rather than an ISI bridge chip, and that only a single USB connection to the external host is present. The information should apply broadly to an ISI-Bridge but we focus here on an ISIMaster SoPEC for clarity.
1458As the ISIMaster SoPEC represents the printer device on the PC USB bus it is required by the USB specification to have a dedicated control endpoint, EP0. At boot time the ISIMaster SoPEC will also require a bulk data endpoint to facilitate the transfer of program code from the external host. The simplest SCB map configuration, i.e. for a single stand-alone SoPEC, is sufficient for external host to ISIMaster SoPEC communication and is shown in Table 36.
1459<tables id="TABLE-US-00044" num="00044"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 36</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Single SoPEC SCB map configuration</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry>Source</entry><entry>Sink</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>EP0</entry><entry>ISI0.0</entry></row><row><entry /><entry>EP1</entry><entry>ISI0.1</entry></row><row><entry /><entry>EP2</entry><entry>nc</entry></row><row><entry /><entry>EP3</entry><entry>nc</entry></row><row><entry /><entry>EP4</entry><entry>nc</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
1460In this configuration all USB control information exchanged between the external host and SoPEC over EP0 (which is the only bidirectional USB endpoint). SoPEC specific control information (printer status, DNC info etc.) is also exchanged over EP0.
1461All packets sent to the external host from SoPEC over EP0 must be written into the DMA mapped EP buffer by the CPU (LEON-PC dataflow in <figref idref="DRAWINGS">FIG. 29</figref>). All packets sent from the external host to SoPEC are placed in DRAM by the DMA Manager, where they can be read by the CPU (PC-DIU dataflow in <figref idref="DRAWINGS">FIG. 29</figref>). This asymmetry is because in a multi-SoPEC environment the CPU will need to examine all incoming control messages (i.e. messages that have arrived over DMAChannel0) to ascertain their source and destination (i.e. they could be from an ISISlave and destined for the external host) and so the additional overhead in having the CPU move the short control messages to the EP0 FIFO is relatively small. Furthermore we wish to avoid making the SCB more complicated than necessary, particularly when there is no significant performance gain to be had as the control traffic will be relatively low bandwidth.
1462The above mechanisms are appropriate for the types of communication outlined in sections 12.1.2.1.1 through 12.1.2.1.4
000012.5.2.3 Broadcast Communication
1463The SCB configuration for broadcast communication is also the default, post power-on reset, configuration for SoPEC and is shown in Table 37.
1464<tables id="TABLE-US-00045" num="00045"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 37</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Default SoPEC SCB map configuration</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry>Source</entry><entry>Sink</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>EP0</entry><entry>ISI0.0</entry></row><row><entry /><entry>EP1</entry><entry>ISI0.1</entry></row><row><entry /><entry>EP2</entry><entry>ISI15.0</entry></row><row><entry /><entry>EP3</entry><entry>ISI15.1</entry></row><row><entry /><entry>EP4</entry><entry>ISI1.1</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
1465USB endpoints EP2 and EP3 are mapped onto ISISubID0 and ISISubId1 of ISIId15 (the broadcast ISIId channel). EP0 is used for control messages as before and EP1 is a bulk data endpoint for the ISIMaster SoPEC. Depending on what is convenient for the boot loader software, EP1 may or may not be used during the initial program download, but EP1 is highly likely to be used for compressed page or other program downloads later. For this reason it is part of the default configuration. In this setup the USB device configuration will take place, as it always must, by exchanging messages over the control channel (EP0).
1466One possible boot mechanism is where the external host sends the bootloader<b>1</b> program code to all SoPECs by broadcasting it over EP3. Each SoPEC in the system then authenticates and executes the bootloader1 program. The ISIMaster SoPEC then polls each ISISlave (over the ISIx.0 channel). Each ISISlave ascertains its ISIId by sampling the particular GPIO pins required by the bootloader1 and reporting its presence and status back to the ISIMaster. The ISIMaster then passes this information back to the external host over EP0. Thus both the external host and the ISIMaster have knowledge of the number of SoPECs, and their ISIIds, in the system. The external host may then reconfigure the SCB map to better optimise the SCB resources for the particular multi-SoPEC system. This could involve simplifying the default configuration to a single SoPEC system or remapping the broadcast channels onto DMAChannels in individual ISISlaves.
0000The following steps are required to reconfigure the SCB map from the configuration depicted in Table to one where EP3 is mapped onto ISI1.0:
0000<ul id="ul0143" list-style="none"><li id="ul0143-0001" num="1467">1) The external host sends a control message(s) to the ISIMaster SoPEC requesting that USB EP3 be remapped to ISI1.0</li><li id="ul0143-0002" num="1468">2) The ISIMaster SoPEC sends a control message to the external host informing it that EP3 has now been mapped to ISI1.0 (and therefore the external host knows that the previous mapping of ISI15.1 is no longer available through EP3).</li><li id="ul0143-0003" num="1469">3) The external host may now send control messages directly to ISISlave1 without requiring any CPU intervention on the ISIMaster SoPEC <br /> 12.5.2.4 External Host to ISISlave SoPEC Communication </li></ul>
1470If the ISIMaster is configured correctly (e.g. when the ISIMaster is a SoPEC, and that SoPEC's SCB map is configured correctly) then data sent from the external host destined for an ISISlave will be transmitted on the ISI with the correct address. The ISI automatically forwards any data addressed to it (including broadcast data) to the DMA channel with the appropriate ISISubId. If the ISISlave has data to send to the external host it must do so by sending a control message to the ISIMaster identifying the external host as the intended recipient. It is then the ISIMaster's responsibility to forward this message to the external host.
1471With this configuration the external host can communicate with the ISISlave via broadcast messages only and this is the mechanism by which the bootloader1 program is downloaded. The ISISlave is unable to communicate with the external host (or the ISIMaster) until the bootloader1 program has successfully executed and the ISISlave has determined what its ISIId is. After the bootloader1 program (and possibly other programs) has executed the SCB map of the ISIMaster may be reconfigured to reflect the most appropriate topology for the particular multi-SoPEC system it is part of.
1472All communication from an ISISlave to external host is either achieved directly (if there is a direct USB connection present for example) or by sending messages via the ISIMaster. The ISISlave can never initiate communication to the external host. If an ISISlave wishes to send a message to the external host via the ISIMaster it must wait until it is pinged by the ISIMaster and then send a the message in a long packet addressed to the ISIMaster. When the ISIMaster receives the message from the ISISlave it first examines it to determine the intended destination and will then copy it into the EP0 FIFO for transmission to the external host. The software running on the ISIMaster is responsible for any arbitration between messages from different sources (including itself) that are all destined for the external host.
1473The above mechanisms are appropriate for the types of communication outlined in sections 12.1.2.1.5 and 12.1.2.1.6.
000012.5.2.5 ISIMaster to ISISlave Communication
1474All ISIMaster to ISISlave communication takes place over the ISI. Immediately after reset this can only be by means of broadcast messages. Once the bootloader1 program has successfully executed on all SoPECs in a multi-SoPEC system the ISIMaster can communicate with each SoPEC on an individual basis.
1475If an ISISlave wishes to send a message to the ISIMaster it may do so in response to a ping packet from the ISIMaster. When the ISIMaster receives the message from the ISISlave it must interpret the message to determine if the message contains information required to be sent to the external host. In the case of the ISIMaster being a SoPEC, software will transfer the appropriate information into the EP0 FIFO for transmission to the external host.
1476The above mechanisms are appropriate for the types of communication outlined in sections 12.1.2.3.3 and 12.1.2.3.4.
000012.5.2.6 ISISlave to ISISlave Communication
1477ISISlave to ISISlave communication is expected to be limited to two special cases: (a) when the PrintMaster is not the ISIMaster and (b) when a storage SoPEC is used. When the PrintMaster is not the ISIMaster then it will need to send control messages (and receive responses to these messages) to other ISISlaves. When a storage SoPEC is present it may need to send data to each SoPEC in the system. All ISISlave to ISISlave communication will take place in response to ping messages from the ISIMaster.
000012.5.2.7 Use of the SCB Map in an ISISlave with a External Host Connection
1478After reset any SoPEC (regardless of ISIMaster/Slave status) with an active USB connection will route packets from EP0,1 to DMA channels 0,1 because the default SCB map is to map EP0 to ISIId0.0 and EP1 to ISIId0.1 and the default ISIId is 0. At some later time the SoPEC learns its true ISIId for the system it is in and re-configures its ISIId and SCB map registers accordingly. Thus if the true ISIId is 3 the external host could reconfigure the SCB map so that EP0 and EP1 (or any other endpoints for that matter) map to ISIId<b>3</b>.<b>0</b> and <b>3</b>.<b>1</b> respectively. The co-ordination of the updating of the ISIId registers and the SCB map is a matter for software to take care of. While the AutoMasterEnable bit of the ISICntrl register is set the external host must not send packets down EP2–4 of the USB connection to the device intended to be an ISISlave. When AutoMasterEnable has been cleared the external host may send data down any endpoint of the USB connection to the ISISlave.
1479The SCB map of an ISISlave can be configured to route packets from any EP to any ISIId.ISISubId oust as an ISIMaster can). As with an ISIMaster these packets will end up in the SCBTxBuffer but while an ISIMaster would just transmit them when it got a local access slot (from ping arbitration) the ISISlave can only transmit them in response to a ping. All this would happen without CPU intervention on the ISISlave (or ISIMaster) and as long as the ping frequency is sufficiently high it would enable maximum use of the bandwidth on both USB buses.
000012.5.3 DMA Manager
1480The DMA manager manages the flow of data between the SCB and the embedded DRAM. Whilst the CPU could be used for the movement of data in SoPEC, a DMA manager is a more efficient solution as it will handle data in a more predictable fashion with less latency and requiring less buffering. Furthermore a DMA manager is required to support the ISI transfer speed and to ensure that the SoPEC could be used with a high speed ISI-Bridge chip in the future.
1481The DMA manager utilizes 2 write channels (DMAChannel0, DMAChannel1) and 1 read/write channel (DMAChannel2) to provide 2 independent modes of access to DRAM via the DIU interface: <ul id="ul0144" list-style="none"><li id="ul0144-0001" num="0000"><ul id="ul0145" list-style="none"><li id="ul0145-0001" num="1482">USBD/ISI type access.</li><li id="ul0145-0002" num="1483">USBH type access.</li></ul></li></ul>
1484DIU read and write access is in bursts of 4×64 bit words. Byte aligned write enables are provided for write access. Data for DIU write accesses will be read directly from the buffers contained in the respective SCB sub-blocks. There is no internal SCB DMA buffer. The DMA manager handles all issues relating to byte/word/longword address alignment, data endianness and transaction scheduling. If a DMA channel is disabled during a DMA access, the access will be completed. Arbitration will be performed between the following DIU access requests: <ul id="ul0146" list-style="none"><li id="ul0146-0001" num="0000"><ul id="ul0147" list-style="none"><li id="ul0147-0001" num="1485">USBD write request.</li><li id="ul0147-0002" num="1486">ISI write request.</li><li id="ul0147-0003" num="1487">USBH write request.</li><li id="ul0147-0004" num="1488">USBH read request.</li></ul></li></ul>
1489DMAChannel0 will have absolute priority over any DMA requesters. In the absence of DMAChannel0 DMA requests, arbitration will be performed in a round robin manner, on a per cycle basis over the other channels.
000012.5.3.1 DMA Effective Bandwidth
1490The DIU bandwidth available to the DMA manager must be set to ensure adequate bandwidth for all data sources, to avoid back pressure on the USB and the ISI. This is achieved by setting the output (i.e. DIU) bandwidth to be greater than the combined input bandwidths (i.e. USBD+USBH+ISI). The required bandwidth is expected to be 160 Mbits/s (1 bit/cycle @ 160 MHz). The guaranteed DIU bandwidth for the SCB is programmable and may need further analysis once there is better knowledge of the data throughput from the USB IP cores.
000012.5.3.2 USBDIISI DMA Access
1491The DMA manager uses the two independent unidirectional write channels for this type of DMA access, one for each ISISubID, to control the movement of data. Both DMAChannel0 and DMAChannel1 only support write operation and can transfer data from any USB device DMA mapped EP buffer and from the ISI receive buffer to separate circular buffers in DRAM, corresponding to each DMA channel.
1492While the DMA manager performs the work of moving data the CPU controls the destination and relative timing of data flows to and from the DRAM. The management of the DRAM data buffers requires the CPU to have accurate and timely visibility of both the DMA and PEP memory usage. In other words when the PEP has completed processing of a page band the CPU needs to be aware of the fact that an area of memory has been freed up to receive incoming data. The management of these buffers may also be performed by the external host.
000012.5.3.2.1 Circular Buffer Operation
1493The DMA manager supports the use of circular buffers for both DMAChannels. Each circular buffer is controlled by 5 registers: DMAnBottomAdr, DMAnTopAdr, DMAnMaxAdr, DMAnCurrWPtr and DMAnIntAdr. The operation of the circular buffers is shown in <figref idref="DRAWINGS">FIG. 53</figref> below.
1494Here we see two snapshots of the status of a circular buffer with (b) occurring sometime after (a) and some CPU writes to the registers occurring in between (a) and (b). These CPU writes are most likely to be as a result of a finished band interrupt (which frees up buffer space) but could also have occurred in a DMA interrupt service routine resulting from DMAnIntAdr being hit. The DMA manager will continue filling the free buffer space depicted in (a), advancing the DMAnCurrWPtr after each write to the DIU. Note that the DMACurrWPtr register always points to the next address the DMA manager will write to. When the DMA manager reaches the address in DMAnIntAdr (i.e. DMACurrWPtr=DMAnIntAdr) it will generate an interrupt if the DMAnIntAdrMask bit in the DMAMask register is set. The purpose of the DMAnintAdr register is to alert the CPU that data (such as a control message or a page or band header) has arrived that it needs to process. The interrupt routine servicing the DMA interrupt will change the DMAnintAdr value to the next location that data of interest to the CPU will have arrived by.
1495In the scenario shown in <figref idref="DRAWINGS">FIG. 53</figref> the CPU has determined (most likely as a result of a finished band interrupt) that the filled buffer space in (a) has been freed up and is therefore available to receive more data. The CPU therefore moves the DMAnMaxAdr to the end of the section that has been freed up and moves the DMAnIntAdr address to an appropriate offset from the DMAnMaxAdr address. The DMA manager continues to fill the free buffer space and when it reaches the address in DMAnTopAdr it wraps around to the address in DMAnBottomAdr and continues from there. DMA transfers will continue indefinitely in this fashion until the DMA manager reaches the address in the DMAnMaxAdr register.
1496The circular buffer is initialized by writing the top and bottom addresses to the DMAnTopAdr and DMAnBottomAdr registers, writing the start address (which does not have to be the same as the DMAnBottomAdr even though it usually will be) to the DMAnCurrWPtr register and appropriate addresses to the DMAnIntAdr and DMAnMaxAdr registers. The DMA operation will not commence until a 1 has been written to the relevant bit of the DMAChanEn register.
1497While it is possible to modify the DMAnTopAdr and DMAnBottomAdr registers after the DMA has started it should be done with caution. The DMAnCurrWPtr register should not be written to while the DMAChannel is in operation. DMA operation may be stalled at any time by clearing the appropriate bit of the DMAChanEn register or by disabling an SCB mapping or ISI receive operation.
000012.5.3.2.2 Non-standard Buffer Operation
1498The DMA manager was designed primarily for use with a circular buffer. However because the DMA pointers are tested for equality (i.e. interrupts generated when DMAnCurrWPtr=DMAIntAdr or DMAnCurrWPtr=DMAMaxAdr) and no bounds checking is performed on their values (i e. neither DMAnIntAdr nor DMAnMaxAdr are checked to see if they lie between DMAnBottomAdr and DMAnTopAdr) a number of non-standard buffer arrangements are possible. These include: <ul id="ul0148" list-style="none"><li id="ul0148-0001" num="0000"><ul id="ul0149" list-style="none"><li id="ul0149-0001" num="1499">Dustbin buffer: If DMAnBottomAdr, DMAnTopAdr and DMAnCurrWPtr all point to the same location and both DMAnIntAdr and DMAnMaxAdr point to anywhere else then all data for that DMA channel will be dumped into the same location without ever generating an interrupt. This is the equivalent to writing to /dev/null on Unix systems.</li><li id="ul0149-0002" num="1500">Linear buffer: If DMAnMaxAdr and DMAnTopAdr have the same value then the DMA manager will simply fill from DMAnBottomAdr to DMAnTopAdr and then stop. DMAnIntAdr should be outside this buffer or have its interrupt disabled. <br /> 12.5.3.3 USBH DMA Access </li></ul></li></ul>
1501The USBH requires DMA access to DRAM in to provide a communication channel between the USB HC and the USB HCD via a shared memory resource. The DMA manager uses two independent channels for this type of DMA access, one for reads and one for writes. The DRAM addresses provided to the DIU interface are generated based on addresses defined in the USB HC core operational registers, in USBH section 12.3.
000012.5.3.4 Cache Coherency
1502As the CPU will be processing some of the data transferred (particularly control messages and page/band headers) into DRAM by the DMA manager, care needs to be taken to ensure that the data it uses is the most recently transferred data. Because the DMA manager will be updating the circular buffers in DRAM without the knowledge of the cache controller logic in the LEON CPU core the contents of the cache can become outdated. This situation can be easily handled by software, for example by flushing the relevant cache lines, and so there is no hardware support to enforce cache coherency.
000012.5.4 ISI Transmit Buffer Arbitration
1503The SCB control logic will arbitrate access to the ISI transmit buffer (ISITxBuffer) interface on the ISI block. There are two sources of ISI Tx packets: <ul id="ul0150" list-style="none"><li id="ul0150-0001" num="0000"><ul id="ul0151" list-style="none"><li id="ul0151-0001" num="1504">CPUISITxBuffer, contained in the SCB control block.</li><li id="ul0151-0002" num="1505">ISI mapped USB EP OUT buffers, contained in the USB device block.</li></ul></li></ul>
1506This arbitration is controlled by the ISITxBuffArb register which contains a high priority bit for both the CPU and the USB. If only one of these bits is set then the corresponding source always has priority. Note that if the CPU is given absolute priority over the USB, then the software filling the ISI transmit buffer needs to ensure that sufficient USB traffic is allowed through. If both bits of the ISITxBufferArb have the same value then arbitration will take place on a round robin basis. The control logic will use the USBEPnDest registers, as it will use the CPUISITxBuffCntrl register, to determine the destination of the packets in these buffers. When the ISITxBuffer has space for a packet, the SCB control logic will immediately seek to refill it. Data will be transferred directly from the CPUISITxBuffer and the ISI mapped USB EP OUT buffers to the ISITxBuffer without any intermediate buffering.
1507As the speed at which the ISITxBuffer can be emptied is at least 5 times greater than it can be filled by USB traffic, the ISI mapped USB EP OUT buffers should not overflow using the above scheme in normal operation. There are a number of scenarios which could lead to the USB EPs being temporarily blocked such as the CPU having priority, retransmissions on the ISI bus, channels being enabled (ChannelEn bit of the USBEPnDest register) with data already in their associated endpoint buffers or short packets being sent on the USB. Care should be taken to ensure that the USB bandwidth is efficiently utilised at all times.
000012.5.5 Implementation
000012.5.5.1 CTRL Sub-block Partition
0000<ul id="ul0152" list-style="none"><li id="ul0152-0001" num="0000"><ul id="ul0153" list-style="none"><li id="ul0153-0001" num="1508">Block Diagram</li><li id="ul0153-0002" num="1509">Definition of I/Os <br /> 12.5.5.2 SCB Configuration Registers </li></ul></li></ul>
1510The SCB register map is listed in Table 38. Registers are grouped according to which SCB sub-block their functionality is associated. All configuration registers reside in the CTRL sub-block. The Reset values in the table indicates the 32 bit hex value that will be returned when the CPU reads the associated address location after reset. All Registers pre-fixed with Hc refer to Host Controller Operational Registers, as defined in the OHCI Spec[19].
1511The SCB will only allow supervisor mode accesses to data space (i.e. cpu_acode[1:0]=b11). All other accesses will result in scb_cpu_berr being asserted.
1512TDB: Is read access necessary for ISI Rx/Tx buffers? Could implement the ISI interface as simple FIFOs as opposed to a memory interface.
1513<tables id="TABLE-US-00046" num="00046"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="329pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 38</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>SCB control block configuration registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="35pt" align="center" /><colspec colname="4" colwidth="42pt" align="left" /><colspec colname="5" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>Address Offset</entry><entry /><entry /><entry /><entry /></row><row><entry>from SCB_base</entry><entry>Register</entry><entry>#Bits</entry><entry>Reset</entry><entry>Description</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="329pt" align="left" /><tbody valign="top"><row><entry>CTRL</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="35pt" align="char" char="." /><colspec colname="4" colwidth="42pt" align="left" /><colspec colname="5" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>0x000</entry><entry>SCBResetN</entry><entry>4</entry><entry>0x0000000F</entry><entry>SCB software reset.</entry></row><row><entry /><entry /><entry /><entry /><entry>Allows individual sub-blocks to be reset</entry></row><row><entry /><entry /><entry /><entry /><entry>separately or together. Once a reset for</entry></row><row><entry /><entry /><entry /><entry /><entry>a block has been initiated, by writing a</entry></row><row><entry /><entry /><entry /><entry /><entry>0 to the relevant register field, it can not</entry></row><row><entry /><entry /><entry /><entry /><entry>be suppressed. Each field will be set</entry></row><row><entry /><entry /><entry /><entry /><entry>after reset. Writing 0x0 to the</entry></row><row><entry /><entry /><entry /><entry /><entry>SCBReset register will have the same</entry></row><row><entry /><entry /><entry /><entry /><entry>effect as CPR generated hardware</entry></row><row><entry /><entry /><entry /><entry /><entry>reset.</entry></row><row><entry>0x004</entry><entry>SCBGo</entry><entry>2</entry><entry>0x00000000</entry><entry>SCB Go.</entry></row><row><entry /><entry /><entry /><entry /><entry>Allows the ISI and CTRL sub-blocks to</entry></row><row><entry /><entry /><entry /><entry /><entry>be selected separately or together.</entry></row><row><entry /><entry /><entry /><entry /><entry>When go is de-asserted for a particular</entry></row><row><entry /><entry /><entry /><entry /><entry>sub-block, its statemachines are reset</entry></row><row><entry /><entry /><entry /><entry /><entry>to their idle states and its interface</entry></row><row><entry /><entry /><entry /><entry /><entry>signals are de-asserted. The sub-block</entry></row><row><entry /><entry /><entry /><entry /><entry>counters and configuration registers</entry></row><row><entry /><entry /><entry /><entry /><entry>retain their values.</entry></row><row><entry /><entry /><entry /><entry /><entry>When go is asserted for a particular</entry></row><row><entry /><entry /><entry /><entry /><entry>sub-block, its counters are reset. The</entry></row><row><entry /><entry /><entry /><entry /><entry>sub-block configuration registers retain</entry></row><row><entry /><entry /><entry /><entry /><entry>their values, i.e. they don't get reset.</entry></row><row><entry /><entry /><entry /><entry /><entry>The sub-block statemachines and</entry></row><row><entry /><entry /><entry /><entry /><entry>interface signals will return to their</entry></row><row><entry /><entry /><entry /><entry /><entry>normal mode of operation.</entry></row><row><entry /><entry /><entry /><entry /><entry>The CTRL field should be de-asserted</entry></row><row><entry /><entry /><entry /><entry /><entry>before disabling the clock from any part</entry></row><row><entry /><entry /><entry /><entry /><entry>of the SCB to avoid erroneous SCB</entry></row><row><entry /><entry /><entry /><entry /><entry>DMA requests when the clock is</entry></row><row><entry /><entry /><entry /><entry /><entry>enabled again.</entry></row><row><entry /><entry /><entry /><entry /><entry>NOTE: This functionality has not been</entry></row><row><entry /><entry /><entry /><entry /><entry>provided for the USBH and USBD sub-</entry></row><row><entry /><entry /><entry /><entry /><entry>blocks because of the USB IP cores</entry></row><row><entry /><entry /><entry /><entry /><entry>that they contain. We do not have</entry></row><row><entry /><entry /><entry /><entry /><entry>direct control over the IP core</entry></row><row><entry /><entry /><entry /><entry /><entry>statemachines and counters, and it</entry></row><row><entry /><entry /><entry /><entry /><entry>would cause unpredictable behaviour if</entry></row><row><entry /><entry /><entry /><entry /><entry>the cores were disabled in this way</entry></row><row><entry /><entry /><entry /><entry /><entry>during operation.</entry></row><row><entry>0x008</entry><entry>SCBWakeupEn</entry><entry>2</entry><entry>0x00000000</entry><entry>USB/ISI WakeUpEnable register</entry></row><row><entry>0x00C</entry><entry>SCBISITxBufferArb</entry><entry>2</entry><entry>0x00000000</entry><entry>ISI transmit buffer access priority</entry></row><row><entry /><entry /><entry /><entry /><entry>register.</entry></row><row><entry>0x010</entry><entry>SCBDebugSel[11:2]</entry><entry>10</entry><entry>0x00000000</entry><entry>SCB Debug select register.</entry></row><row><entry>0x014</entry><entry>USBEP0Dest</entry><entry>7</entry><entry>0x00000020</entry><entry>This register determines which of the</entry></row><row><entry /><entry /><entry /><entry /><entry>data sinks the data arriving in EP0</entry></row><row><entry /><entry /><entry /><entry /><entry>should be routed to.</entry></row><row><entry>0x018</entry><entry>USBEP1Dest</entry><entry>7</entry><entry>0x00000021</entry><entry>Data sink mapping for USB EP1</entry></row><row><entry>0x01C</entry><entry>USBEP2Dest</entry><entry>7</entry><entry>0x0000003E</entry><entry>Data sink mapping for USB EP2</entry></row><row><entry>0x020</entry><entry>USBEP3Dest</entry><entry>7</entry><entry>0x0000003F</entry><entry>Data sink mapping for USB EP3</entry></row><row><entry>0x024</entry><entry>USBEP4Dest</entry><entry>7</entry><entry>0x00000023</entry><entry>Data sink mapping for USB EP4</entry></row><row><entry>0x028</entry><entry>DMA0BottomAdr[21:5]</entry><entry>17</entry><entry /><entry>DMAChannel0 bottom address register.</entry></row><row><entry>0x02C</entry><entry>DMA0TopAdr[21:5]</entry><entry>17</entry><entry /><entry>DMAChannel0 top address register.</entry></row><row><entry>0x030</entry><entry>DMA0CurrWPtr[21:5]</entry><entry>17</entry><entry /><entry>DMAChannel0 current write pointer.</entry></row><row><entry>0x034</entry><entry>DMA0IntAdr[21:5]</entry><entry>17</entry><entry /><entry>DMAChannel0 interrupt address</entry></row><row><entry /><entry /><entry /><entry /><entry>register.</entry></row><row><entry>0x038</entry><entry>DMA0MaxAdr[21:5]</entry><entry>17</entry><entry /><entry>DMAChannel0 max address register.</entry></row><row><entry>0x03C</entry><entry>DMA1BottomAdr[21:5]</entry><entry>17</entry><entry /><entry>As per DMA0BottomAdr.</entry></row><row><entry>0x040</entry><entry>DMA1TopAdr[21:5]</entry><entry>17</entry><entry /><entry>As per DMA0TopAdr.</entry></row><row><entry>0x044</entry><entry>DMA1CurrWPtr[21:5]</entry><entry>17</entry><entry /><entry>As per DMA0CurrWPtr.</entry></row><row><entry>0x048</entry><entry>DMA1IntAdr[21:5]</entry><entry>17</entry><entry /><entry>As per DMA0IntAdr.</entry></row><row><entry>0x04C</entry><entry>DMA1MaxAdr[21:5]</entry><entry>17</entry><entry /><entry>As per DMA0MaxAdr.</entry></row><row><entry>0x050</entry><entry>DMAAccessEn</entry><entry>3</entry><entry>0x00000003</entry><entry>DMA access enable.</entry></row><row><entry>0x054</entry><entry>DMAStatus</entry><entry>4</entry><entry>0x00000000</entry><entry>DMA status register.</entry></row><row><entry>0x058</entry><entry>DMAMask</entry><entry>4</entry><entry>0x00000000</entry><entry>DMA mask register.</entry></row><row><entry>0x05C–0x098</entry><entry>CPUISITxBuff[7:0]</entry><entry>32 × 8</entry><entry>n/a</entry><entry>CPU ISI transmit buffer.</entry></row><row><entry /><entry /><entry /><entry /><entry>32-byte packet buffer, containing the</entry></row><row><entry /><entry /><entry /><entry /><entry>payload of a CPU sourced packet</entry></row><row><entry /><entry /><entry /><entry /><entry>destined for transmission over the ISI.</entry></row><row><entry /><entry /><entry /><entry /><entry>The CPU has full write access to the</entry></row><row><entry /><entry /><entry /><entry /><entry>CPUISITxBuff.</entry></row><row><entry /><entry /><entry /><entry /><entry>NOTE: The CPU does not have read</entry></row><row><entry /><entry /><entry /><entry /><entry>access to CPUISITxBuff. This is</entry></row><row><entry /><entry /><entry /><entry /><entry>because the CPU is the source of the</entry></row><row><entry /><entry /><entry /><entry /><entry>data and to avoid arbitrating read</entry></row><row><entry /><entry /><entry /><entry /><entry>access between the CPU and the</entry></row><row><entry /><entry /><entry /><entry /><entry>CTRL sub-block. Any CPU reads from</entry></row><row><entry /><entry /><entry /><entry /><entry>this address space will return</entry></row><row><entry /><entry /><entry /><entry /><entry>0x00000000.</entry></row><row><entry>0x09C</entry><entry>CPUISITxBuffCtrl</entry><entry>9</entry><entry>0x00000000</entry><entry>CPU ISI transmit buffer control register.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="329pt" align="left" /><tbody valign="top"><row><entry>USBD</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="35pt" align="char" char="." /><colspec colname="4" colwidth="42pt" align="left" /><colspec colname="5" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>0x100</entry><entry>USBDIntStatus</entry><entry>19</entry><entry>0x00000000</entry><entry>USBD Interrupt event status register.</entry></row><row><entry>0x104</entry><entry>USBDISIFIFOStatus</entry><entry>16</entry><entry>0x00000000</entry><entry>USBD ISI mapped OUT EP packet</entry></row><row><entry /><entry /><entry /><entry /><entry>FIFO status register.</entry></row><row><entry>0x108</entry><entry>USBDDMA0FIFOStatus</entry><entry>8</entry><entry>0x00000000</entry><entry>USBD DMAChannel0 mapped OUT EP</entry></row><row><entry /><entry /><entry /><entry /><entry>packet FIFO status register.</entry></row><row><entry>0x10C</entry><entry>USBDDMA1FIFOStatus</entry><entry>8</entry><entry>0x00000000</entry><entry>USBD DMAChannel1 mapped OUT EP</entry></row><row><entry /><entry /><entry /><entry /><entry>packet FIFO status register.</entry></row><row><entry>0x110</entry><entry>USBDResume</entry><entry>1</entry><entry>0x00000000</entry><entry>USBD core resume register.</entry></row><row><entry>0x114</entry><entry>USBDSetup</entry><entry>4</entry><entry>0x00000000</entry><entry>USBD setup/configuration register.</entry></row><row><entry>0x118–0x154</entry><entry>USBDEp0InBuff[15:0]</entry><entry> 32 × 16</entry><entry>n/a</entry><entry>USBD EP0-IN buffer.</entry></row><row><entry /><entry /><entry /><entry /><entry>64-byte packet buffer in the, containing</entry></row><row><entry /><entry /><entry /><entry /><entry>the payload of a USB packet destined</entry></row><row><entry /><entry /><entry /><entry /><entry>for EP0-IN.</entry></row><row><entry /><entry /><entry /><entry /><entry>The CPU has full write access to the</entry></row><row><entry /><entry /><entry /><entry /><entry>USBDEp0InBuff.</entry></row><row><entry /><entry /><entry /><entry /><entry>NOTE: The CPU does not have read</entry></row><row><entry /><entry /><entry /><entry /><entry>access to USBDEp0InBuff. This is</entry></row><row><entry /><entry /><entry /><entry /><entry>because the CPU is the source of the</entry></row><row><entry /><entry /><entry /><entry /><entry>data and to avoid arbitrating read</entry></row><row><entry /><entry /><entry /><entry /><entry>access between the CPU and the USB</entry></row><row><entry /><entry /><entry /><entry /><entry>device core. Any CPU reads from this</entry></row><row><entry /><entry /><entry /><entry /><entry>address space will return 0x00000000.</entry></row><row><entry>0x158</entry><entry>USBDEp0InBuffCtrl</entry><entry>1</entry><entry>0x00000000</entry><entry>USBD EP0-IN buffer control register.</entry></row><row><entry>0x15C–0x198</entry><entry>USBDEp5InBuff[15:0]</entry><entry> 32 × 16</entry><entry>n/a</entry><entry>USBD EP5-IN buffer.</entry></row><row><entry /><entry /><entry /><entry /><entry>As per USBDEp0InBuff.</entry></row><row><entry>0x19C</entry><entry>USBDEp5InBuffCtrl</entry><entry>1</entry><entry>0x00000000</entry><entry>USBD EP5-IN buffer control register.</entry></row><row><entry>0x1A0</entry><entry>USBDMask</entry><entry>19</entry><entry>0x00000000</entry><entry>USBD interrupt mask register.</entry></row><row><entry>0x1A4</entry><entry>USBDDebug</entry><entry>30</entry><entry>0x00000000</entry><entry>USBD debug register.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="329pt" align="left" /><tbody valign="top"><row><entry>USBH</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="35pt" align="char" char="." /><colspec colname="4" colwidth="42pt" align="left" /><colspec colname="5" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>0x200</entry><entry>HcRevision</entry><entry /><entry /><entry>Refer to [19] for #Bits, Reset,</entry></row><row><entry /><entry /><entry /><entry /><entry>Description.</entry></row><row><entry>0x204</entry><entry>HcControl</entry><entry /><entry /><entry>Refer to [19] for #Bits, Reset,</entry></row><row><entry /><entry /><entry /><entry /><entry>Description.</entry></row><row><entry>0x208</entry><entry>HcCommandStatus</entry><entry /><entry /><entry>Refer to [19] for #Bits, Reset,</entry></row><row><entry /><entry /><entry /><entry /><entry>Description.</entry></row><row><entry>0x20C</entry><entry>HcInterruptStatus</entry><entry /><entry /><entry>Refer to [19] for #Bits, Reset,</entry></row><row><entry /><entry /><entry /><entry /><entry>Description.</entry></row><row><entry>0x210</entry><entry>HcInterruptEnable</entry><entry /><entry /><entry>Refer to [19] for #Bits, Reset,</entry></row><row><entry /><entry /><entry /><entry /><entry>Description.</entry></row><row><entry>0x214</entry><entry>HcInterruptDisable</entry><entry /><entry /><entry>Refer to [19] for #Bits, Reset,</entry></row><row><entry /><entry /><entry /><entry /><entry>Description.</entry></row><row><entry>0x218</entry><entry>HcHCCA</entry><entry /><entry /><entry>Refer to [19] for #Bits, Reset,</entry></row><row><entry /><entry /><entry /><entry /><entry>Description.</entry></row><row><entry>0x21C</entry><entry>HcPeriodCurrentED</entry><entry /><entry /><entry>Refer to [19] for #Bits, Reset,</entry></row><row><entry /><entry /><entry /><entry /><entry>Description.</entry></row><row><entry>0x220</entry><entry>HcControlHeadED</entry><entry /><entry /><entry>Refer to [19] for #Bits, Reset,</entry></row><row><entry /><entry /><entry /><entry /><entry>Description.</entry></row><row><entry>0x224</entry><entry>HcControlCurrentED</entry><entry /><entry /><entry>Refer to [19] for #Bits, Reset,</entry></row><row><entry /><entry /><entry /><entry /><entry>Description.</entry></row><row><entry>0x228</entry><entry>HcBulkHeadED</entry><entry /><entry /><entry>Refer to [19] for #Bits, Reset,</entry></row><row><entry /><entry /><entry /><entry /><entry>Description.</entry></row><row><entry>0x22C</entry><entry>HcBulkCurrentED</entry><entry /><entry /><entry>Refer to [19] for #Bits, Reset,</entry></row><row><entry /><entry /><entry /><entry /><entry>Description.</entry></row><row><entry>0x230</entry><entry>HcDoneHead</entry><entry /><entry /><entry>Refer to [19] for #Bits, Reset,</entry></row><row><entry /><entry /><entry /><entry /><entry>Description.</entry></row><row><entry>0x234</entry><entry>HcFmInterval</entry><entry /><entry /><entry>Refer to [19] for #Bits, Reset,</entry></row><row><entry /><entry /><entry /><entry /><entry>Description.</entry></row><row><entry>0x238</entry><entry>HcFmRemaining</entry><entry /><entry /><entry>Refer to [19] for #Bits, Reset,</entry></row><row><entry /><entry /><entry /><entry /><entry>Description.</entry></row><row><entry>0x23C</entry><entry>HcFmNumber</entry><entry /><entry /><entry>Refer to [19] for #Bits, Reset,</entry></row><row><entry /><entry /><entry /><entry /><entry>Description.</entry></row><row><entry>0x240</entry><entry>HcPeriodicStart</entry><entry /><entry /><entry>Refer to [19] for #Bits, Reset,</entry></row><row><entry /><entry /><entry /><entry /><entry>Description.</entry></row><row><entry>0x244</entry><entry>HcLSTheshold</entry><entry /><entry /><entry>Refer to [19] for #Bits, Reset,</entry></row><row><entry /><entry /><entry /><entry /><entry>Description.</entry></row><row><entry>0x248</entry><entry>HcRhDescriptorA</entry><entry /><entry /><entry>Refer to [19] for #Bits, Reset,</entry></row><row><entry /><entry /><entry /><entry /><entry>Description.</entry></row><row><entry>0x24C</entry><entry>HcRhDescriptorB</entry><entry /><entry /><entry>Refer to [19] for #Bits, Reset,</entry></row><row><entry /><entry /><entry /><entry /><entry>Description.</entry></row><row><entry>0x250</entry><entry>HcRhStatus</entry><entry /><entry /><entry>Refer to [19] for #Bits, Reset,</entry></row><row><entry /><entry /><entry /><entry /><entry>Description.</entry></row><row><entry>0x254</entry><entry>HcRhPortStatus[1]</entry><entry /><entry /><entry>Refer to [19] for #Bits, Reset,</entry></row><row><entry /><entry /><entry /><entry /><entry>Description.</entry></row><row><entry>0x258</entry><entry>USBHStatus</entry><entry>3</entry><entry>0x00000000</entry><entry>USBH status register.</entry></row><row><entry>0x25C</entry><entry>USBHMask</entry><entry>2</entry><entry>0x00000000</entry><entry>USBH interrupt mask register.</entry></row><row><entry>0x260</entry><entry>USBHDebug</entry><entry>2</entry><entry>0x00000000</entry><entry>USBH debug register.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="329pt" align="left" /><tbody valign="top"><row><entry>ISI</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="35pt" align="char" char="." /><colspec colname="4" colwidth="42pt" align="left" /><colspec colname="5" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>0x300</entry><entry>ISICntrl</entry><entry>4</entry><entry>0x0000000B</entry><entry>ISI Control register</entry></row><row><entry>0x304</entry><entry>ISIId</entry><entry>4</entry><entry>0x00000000</entry><entry>ISIId for this SoPEC.</entry></row><row><entry>0x308</entry><entry>ISINumRetries</entry><entry>4</entry><entry>0x00000002</entry><entry>Number of ISI retransmissions register.</entry></row><row><entry>0x30C</entry><entry>ISIPingSchedule0</entry><entry>15</entry><entry>0x00000000</entry><entry>ISI Ping schedule 0 register.</entry></row><row><entry>0x310</entry><entry>ISIPingSchedule1</entry><entry>15</entry><entry>0x00000000</entry><entry>ISI Ping schedule 1 register.</entry></row><row><entry>0x314</entry><entry>ISIPingSchedule2</entry><entry>15</entry><entry>0x00000000</entry><entry>ISI Ping schedule 2 register.</entry></row><row><entry>0x318</entry><entry>ISITotalPeriod</entry><entry>4</entry><entry>0x0000000F</entry><entry>Reload value of the ISITotalPeriod</entry></row><row><entry /><entry /><entry /><entry /><entry>counter.</entry></row><row><entry>0x31C</entry><entry>ISILocalPeriod</entry><entry>4</entry><entry>0x0000000F</entry><entry>Reload value of the ISILocalPeriod</entry></row><row><entry /><entry /><entry /><entry /><entry>counter.</entry></row><row><entry>0x320</entry><entry>ISIIntStatus</entry><entry>4</entry><entry>0x00000000</entry><entry>ISI interrupt status register.</entry></row><row><entry>0x324</entry><entry>ISITxBuffStatus</entry><entry>27</entry><entry>0x00000000</entry><entry>ISI Tx buffer status register.</entry></row><row><entry>0x328</entry><entry>ISIRxBuffStatus</entry><entry>27</entry><entry>0x00000000</entry><entry>ISI Rx buffer status register.</entry></row><row><entry>0x32C</entry><entry>ISIMask</entry><entry>4</entry><entry>0x00000000</entry><entry>ISI Interrupt mask register.</entry></row><row><entry>0x330–0x34C</entry><entry>ISITxBuffEntry0[7:0]</entry><entry>32 × 8</entry><entry>n/a</entry><entry>ISI transmit Buff, packet entry #0.</entry></row><row><entry /><entry /><entry /><entry /><entry>32-byte packet entry in the ISITxBuff,</entry></row><row><entry /><entry /><entry /><entry /><entry>containing the payload of an ISI Tx</entry></row><row><entry /><entry /><entry /><entry /><entry>packet.</entry></row><row><entry /><entry /><entry /><entry /><entry>CPU read access to ISITxBuffEntry0 is</entry></row><row><entry /><entry /><entry /><entry /><entry>provided for observability only i.e. CPU</entry></row><row><entry /><entry /><entry /><entry /><entry>reads of the ISITxBuffEntry0 do not</entry></row><row><entry /><entry /><entry /><entry /><entry>alter the state of the buffer. The CPU</entry></row><row><entry /><entry /><entry /><entry /><entry>does not have write access to the</entry></row><row><entry /><entry /><entry /><entry /><entry>ISITxBuffEntry0.</entry></row><row><entry>0x350–0x36C</entry><entry>ISITxBuffEntry1[7:0]</entry><entry>32 × 8</entry><entry>n/a</entry><entry>ISI transmit Buff, packet entry #1.</entry></row><row><entry /><entry /><entry /><entry /><entry>As per ISITxBuffEntry0.</entry></row><row><entry>0x370–0x38C</entry><entry>ISIRxBuffEntry0[7:0]</entry><entry>32 × 8</entry><entry>n/a</entry><entry>ISI receive Buff, packet entry #0.</entry></row><row><entry /><entry /><entry /><entry /><entry>32-byte packet entry in the ISIRxBuff,</entry></row><row><entry /><entry /><entry /><entry /><entry>containing the payload of an ISI Rx</entry></row><row><entry /><entry /><entry /><entry /><entry>packet. Note that the only error-free</entry></row><row><entry /><entry /><entry /><entry /><entry>long packets are placed in the</entry></row><row><entry /><entry /><entry /><entry /><entry>ISIRxBuffEntry0. Both ping and ACKs</entry></row><row><entry /><entry /><entry /><entry /><entry>are consumed in the ISI.</entry></row><row><entry /><entry /><entry /><entry /><entry>CPU access to ISIRxBuffEntry0 is</entry></row><row><entry /><entry /><entry /><entry /><entry>provided for observability only i.e. CPU</entry></row><row><entry /><entry /><entry /><entry /><entry>reads of the ISIRxBuffEntry0 do not</entry></row><row><entry /><entry /><entry /><entry /><entry>alter the state of the buffer.</entry></row><row><entry>0x390–0x3AC</entry><entry>ISIRxBuffEntry1[7:0]</entry><entry>32 × 8</entry><entry>n/a</entry><entry>ISI receive Buff, packet entry #1.</entry></row><row><entry /><entry /><entry /><entry /><entry>As per ISIRxBuffEntry0.</entry></row><row><entry>0x3B0</entry><entry>ISISubId0Seq</entry><entry>1</entry><entry>0x00000000</entry><entry>ISI sub ID 0 sequence bit register.</entry></row><row><entry>0x3B4</entry><entry>ISISubId1Seq</entry><entry>1</entry><entry>0x00000000</entry><entry>ISI sub ID 1 sequence bit register.</entry></row><row><entry>0x3B8</entry><entry>ISISubIdSeqMask</entry><entry>2</entry><entry>0x00000000</entry><entry>ISI sub ID sequence bit mask register.</entry></row><row><entry>0x3BC</entry><entry>ISINumPins</entry><entry>1</entry><entry>0x00000000</entry><entry>ISI number of pins register.</entry></row><row><entry>0x3C0</entry><entry>ISITurnAround</entry><entry>4</entry><entry>0x0000000F</entry><entry>ISI bus turn around register.</entry></row><row><entry>0x3C4</entry><entry>ISITShortReplyWin</entry><entry>5</entry><entry>0x0000001F</entry><entry>ISI short packet reply window.</entry></row><row><entry>0x3C8</entry><entry>ISITLongReplyWin</entry><entry>9</entry><entry>0x000001FF</entry><entry>ISI long packet reply window.</entry></row><row><entry>0x3CC</entry><entry>ISIDebug</entry><entry>4</entry><entry>0x00000000</entry><entry>ISI debug register.</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
1514A detailed description of each register format follows. The CPU has full read access to all registers. Write access to the fields of each register is defined as: <ul id="ul0154" list-style="none"><li id="ul0154-0001" num="0000"><ul id="ul0155" list-style="none"><li id="ul0155-0001" num="1515">Full: The CPU has full write access to the field, i.e. the CPU can write a 1 or a 0 to each bit.</li><li id="ul0155-0002" num="1516">Clear: The CPU can clear the field by writing a 1 to each bit. Writing a 0 to this type of field will have no effect.</li><li id="ul0155-0003" num="1517">None: The CPU has no write access to the field, i.e. a CPU write will have no effect on the field. <br /> 12.5.5.2.1 SCBResetN </li></ul></li></ul>
1518<tables id="TABLE-US-00047" num="00047"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 39</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>SCBResetN register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="42pt" align="center" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>Field Name</entry><entry>Bit(s)</entry><entry>write access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>CTRL</entry><entry>0</entry><entry>Full</entry><entry>scb_ctrl sub-block reset.</entry></row><row><entry /><entry /><entry /><entry>Setting this field will reset the</entry></row><row><entry /><entry /><entry /><entry>SCB control sub-block logic,</entry></row><row><entry /><entry /><entry /><entry>including all configuration registers.</entry></row><row><entry /><entry /><entry /><entry>0 = reset</entry></row><row><entry /><entry /><entry /><entry>1 = default state</entry></row><row><entry>ISI</entry><entry>1</entry><entry>Full</entry><entry>scb_isi sub-block reset.</entry></row><row><entry /><entry /><entry /><entry>Setting this field will reset the</entry></row><row><entry /><entry /><entry /><entry>ISI sub-block logic.</entry></row><row><entry /><entry /><entry /><entry>0 = reset</entry></row><row><entry /><entry /><entry /><entry>1 = default state</entry></row><row><entry>USBH</entry><entry>2</entry><entry>Full</entry><entry>scb_usbh sub-block reset.</entry></row><row><entry /><entry /><entry /><entry>Setting this field will reset the</entry></row><row><entry /><entry /><entry /><entry>USB host controller core</entry></row><row><entry /><entry /><entry /><entry>and associated logic.</entry></row><row><entry /><entry /><entry /><entry>0 = reset</entry></row><row><entry /><entry /><entry /><entry>1 = default state</entry></row><row><entry>USBD</entry><entry>3</entry><entry>Full</entry><entry>scb_usbd sub-block reset.</entry></row><row><entry /><entry /><entry /><entry>Setting this field will reset the</entry></row><row><entry /><entry /><entry /><entry>USB device controller core</entry></row><row><entry /><entry /><entry /><entry>and associated logic.</entry></row><row><entry /><entry /><entry /><entry>0 = reset</entry></row><row><entry /><entry /><entry /><entry>1 = default state</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.2 SCBGo
1519<tables id="TABLE-US-00048" num="00048"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 40</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>SCBGo register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="56pt" align="center" /><colspec colname="4" colwidth="77pt" align="left" /><tbody valign="top"><row><entry /><entry>Field Name</entry><entry>Bit(s)</entry><entry>write access</entry><entry>Description</entry></row><row><entry /><entry namest="offset" nameend="4" align="center" rowsep="1" /></row><row><entry /><entry>CTRL</entry><entry>0</entry><entry>Full</entry><entry>scb_ctrl sub-block go.</entry></row><row><entry /><entry /><entry /><entry /><entry>0 = halted</entry></row><row><entry /><entry /><entry /><entry /><entry>1 = running</entry></row><row><entry /><entry>ISI</entry><entry>1</entry><entry>Full</entry><entry>scb_isi sub-block go.</entry></row><row><entry /><entry /><entry /><entry /><entry>0 = halted</entry></row><row><entry /><entry /><entry /><entry /><entry>1 = running</entry></row><row><entry /><entry namest="offset" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.3 SCBWakeUpEn
1520This register is used to gate the propagation of the USB and ISI reset signals to the CPR block.
1521<tables id="TABLE-US-00049" num="00049"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 41</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>SCBWakeUpEn register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="56pt" align="center" /><colspec colname="4" colwidth="70pt" align="left" /><tbody valign="top"><row><entry>Field Name</entry><entry>Bit(s)</entry><entry>write access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>USBWakeUpEn</entry><entry>0</entry><entry>Full</entry><entry>usb_cpr_reset_n</entry></row><row><entry /><entry /><entry /><entry>propagation enable.</entry></row><row><entry /><entry /><entry /><entry>1 = enable</entry></row><row><entry /><entry /><entry /><entry>0 = disable</entry></row><row><entry>ISIWakeUpEn</entry><entry>1</entry><entry>Full</entry><entry>isi_cpr_reset_n</entry></row><row><entry /><entry /><entry /><entry>propagation enable.</entry></row><row><entry /><entry /><entry /><entry>1 = enable</entry></row><row><entry /><entry /><entry /><entry>0 = disable</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.4 SCBISITxBufferArb
1522This register determines which source has priority at the ISITxBuffer interface on the ISI block. When a bit is set priority is given to the relevant source. When both bits have the same value, arbitration will be performed in a round-robin manner.
1523<tables id="TABLE-US-00050" num="00050"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 42</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>SCBISITxBufferArb register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="56pt" align="center" /><colspec colname="4" colwidth="70pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry /><entry>write</entry><entry /></row><row><entry /><entry>Field Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry /><entry namest="offset" nameend="4" align="center" rowsep="1" /></row><row><entry /><entry>CPUPriority</entry><entry>0</entry><entry>Full</entry><entry>CPU priority</entry></row><row><entry /><entry /><entry /><entry /><entry>1 = high priority</entry></row><row><entry /><entry /><entry /><entry /><entry>0 = low priority</entry></row><row><entry /><entry>USBPriority</entry><entry>1</entry><entry>Full</entry><entry>USB priority</entry></row><row><entry /><entry /><entry /><entry /><entry>1 = high priority</entry></row><row><entry /><entry /><entry /><entry /><entry>0 = low priority</entry></row><row><entry /><entry namest="offset" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.5 SCBDebugSel
1524Contains address of the register selected for debug observation as it would appear on cpu_adr. The contents of the selected register are output in the scb_cpu_data bus while cpu_scb_sel is low and scb_cpu_debug_valid is asserted to indicate the debug data is valid. It is expected that a number of pseudo-registers will be made available for debug observation and these will be outlined with the implementation details.
1525<tables id="TABLE-US-00051" num="00051"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 43</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>SCBDebugSel register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="49pt" align="center" /><colspec colname="4" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry /><entry>write</entry><entry /></row><row><entry /><entry>Field Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry /><entry namest="offset" nameend="4" align="center" rowsep="1" /></row><row><entry /><entry>CPUAdr</entry><entry>11:2</entry><entry>Full</entry><entry>cpu_adr register address.</entry></row><row><entry /><entry namest="offset" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.6 USBEPnDest
1526This register description applies to USBEP0Dest, USBEP1Dest, USBEP2Dest, USBEP3Dest, USBEP4Dest. The SCB has two routing options for each packet received, based on the DestISIId associated with the packets source EP: <ul id="ul0156" list-style="none"><li id="ul0156-0001" num="0000"><ul id="ul0157" list-style="none"><li id="ul0157-0001" num="1527">To the DMA Manager</li><li id="ul0157-0002" num="1528">To the ISI</li></ul></li></ul>
1529The SCB map therefore does not need special fields to identify the DMAChannels on the ISIMaster SoPEC as this is taken care of by the SCB hardware. Thus the USBEP0Dest and USBEP1Dest registers should be programmed with 0x20 and 0x21 (for ISI0.0 and ISI0.1) respectively to ensure data arriving on these endpoints is moved directly to DRAM.
1530<tables id="TABLE-US-00052" num="00052"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 44</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>USBEPnDest register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="28pt" align="center" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Write</entry><entry /></row><row><entry>Field Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>SequenceBit</entry><entry>0</entry><entry>Full</entry><entry>Sequence bit for packets going from</entry></row><row><entry /><entry /><entry /><entry>USBEPn to DestISIId.DestISISubId.</entry></row><row><entry /><entry /><entry /><entry>Every CPU write to this register</entry></row><row><entry /><entry /><entry /><entry>initialises the value of the sequence</entry></row><row><entry /><entry /><entry /><entry>bit and this is subsequently updated</entry></row><row><entry /><entry /><entry /><entry>by the ISI after every successful long</entry></row><row><entry /><entry /><entry /><entry>packet transmission.</entry></row><row><entry>DestISIId</entry><entry>4:1</entry><entry>Full</entry><entry>Destination ISI ID.</entry></row><row><entry /><entry /><entry /><entry>Denotes the ISIId of the target</entry></row><row><entry /><entry /><entry /><entry>SoPEC as per Table</entry></row><row><entry>DestISISubId</entry><entry>5</entry><entry>Full</entry><entry>Destination ISI sub ID.</entry></row><row><entry /><entry /><entry /><entry>Indicates which DMAChannel of the</entry></row><row><entry /><entry /><entry /><entry>target SoPEC the endpoint is</entry></row><row><entry /><entry /><entry /><entry>mapped onto:</entry></row><row><entry /><entry /><entry /><entry>0 = DMAChannel0</entry></row><row><entry /><entry /><entry /><entry>1 = DMAChannel1</entry></row><row><entry>ChannelEn</entry><entry>6</entry><entry>Full</entry><entry>Communication channel enable bit</entry></row><row><entry /><entry /><entry /><entry>for EPn.</entry></row><row><entry /><entry /><entry /><entry>This enables/disables the</entry></row><row><entry /><entry /><entry /><entry>communication channel for EPn.</entry></row><row><entry /><entry /><entry /><entry>When disabled, the SCB will not</entry></row><row><entry /><entry /><entry /><entry>accept USB packets addressed to</entry></row><row><entry /><entry /><entry /><entry>EPn.</entry></row><row><entry /><entry /><entry /><entry>0 = Channel disabled</entry></row><row><entry /><entry /><entry /><entry>1 = Channel enabled</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
1531If the local SoPEC is connected to an external USB host, it is recommended that the EP0 communication channel should always remain enabled and mapped to DMAChannel0 on the local SoPEC, as this is intended as the primary control communication channel between the external USB host and the local SoPEC.
1532A SoPEC ISIMaster should map as many USB endpoints, under the control of the external host, as are required for the multi-SoPEC system it is part of. As already mentioned this mapping may be dynamically reconfigured.
000012.5.5.2.7 DMAnBottomAdr
1533This register description applies to DMA0BottomAdr and DMA1BottomAdr.
1534<tables id="TABLE-US-00053" num="00053"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 45</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>DMAnBottomAdr register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="49pt" align="left" /><colspec colname="4" colwidth="84pt" align="left" /><tbody valign="top"><row><entry>File Name</entry><entry>Bit(s)</entry><entry>Write access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>DMAnBottomAdr</entry><entry>21:5</entry><entry>Full</entry><entry>The 256-bit aligned</entry></row><row><entry /><entry /><entry /><entry>DRAM address of the</entry></row><row><entry /><entry /><entry /><entry>bottom of the circular</entry></row><row><entry /><entry /><entry /><entry>buffer (inclusive)</entry></row><row><entry /><entry /><entry /><entry>serviced by DMAChanneln</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.8 DMAnTopAdr
1535This register description applies to DMA0TopAdr and DMA1 TopAdr.
1536<tables id="TABLE-US-00054" num="00054"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 46</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>DMAnTopAdr register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="42pt" align="center" /><colspec colname="3" colwidth="35pt" align="left" /><colspec colname="4" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Write</entry><entry /></row><row><entry>File Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>DMAnTopAdr</entry><entry>21:5</entry><entry>Full</entry><entry>The 256-bit aligned DRAM</entry></row><row><entry /><entry /><entry /><entry>address of the top of the</entry></row><row><entry /><entry /><entry /><entry>circular buffer (inclusive)</entry></row><row><entry /><entry /><entry /><entry>serviced by DMAChanneln</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.9 DMAnCurrWPtr
1537This register description applies to DMA0CurrWPtr and DMA1CurrWPtr.
1538<tables id="TABLE-US-00055" num="00055"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 47</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>DMAnCurrWptr register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="28pt" align="center" /><colspec colname="3" colwidth="35pt" align="left" /><colspec colname="4" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Write</entry><entry /></row><row><entry>File Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>DMAnCurrWPtr</entry><entry>21:5</entry><entry>Full</entry><entry>The 256-bit aligned DRAM</entry></row><row><entry /><entry /><entry /><entry>address of the next</entry></row><row><entry /><entry /><entry /><entry>location DMAChannel0</entry></row><row><entry /><entry /><entry /><entry>will write to. This</entry></row><row><entry /><entry /><entry /><entry>register is set by the</entry></row><row><entry /><entry /><entry /><entry>CPU at the start of a DMA</entry></row><row><entry /><entry /><entry /><entry>operation and dynamically</entry></row><row><entry /><entry /><entry /><entry>updated by the DMA manager</entry></row><row><entry /><entry /><entry /><entry>during the operation.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.10 DMAIntAdr
1539This register description applies to DMA0IntAdr and DMA1IntAdr.
1540<tables id="TABLE-US-00056" num="00056"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 48</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>DMAnIntAdr register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="42pt" align="center" /><colspec colname="2" colwidth="35pt" align="left" /><colspec colname="3" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Write</entry><entry /></row><row><entry /><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="42pt" align="center" /><colspec colname="3" colwidth="35pt" align="left" /><colspec colname="4" colwidth="91pt" align="left" /><tbody valign="top"><row><entry>DMAnIntAdr</entry><entry>21:5</entry><entry>Full</entry><entry>The 256-bit aligned DRAM</entry></row><row><entry /><entry /><entry /><entry>address of the location</entry></row><row><entry /><entry /><entry /><entry>that will trigger an</entry></row><row><entry /><entry /><entry /><entry>interrupt when reached by</entry></row><row><entry /><entry /><entry /><entry>DMAChanneln buffer.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.11 DMAnMaxAdr
1541This register description applies to DMA0MaxAdr and DMA1MaxAdr.
1542<tables id="TABLE-US-00057" num="00057"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 49</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>DMAnMaxAdr register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="42pt" align="center" /><colspec colname="3" colwidth="35pt" align="left" /><colspec colname="4" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Write</entry><entry /></row><row><entry>Field Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>DMAnMaxAdr</entry><entry>21:5</entry><entry>Full</entry><entry>The 256-bit aligned DRAM</entry></row><row><entry /><entry /><entry /><entry>address of the last free</entry></row><row><entry /><entry /><entry /><entry>location that in the</entry></row><row><entry /><entry /><entry /><entry>DMAChanneln circular</entry></row><row><entry /><entry /><entry /><entry>buffer. DMAChannel0</entry></row><row><entry /><entry /><entry /><entry>transfers will stop when</entry></row><row><entry /><entry /><entry /><entry>it reaches this address.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.12 DMAAccessEn
1543This register enables DMA access for the various requesters, on a per channel basis.
1544<tables id="TABLE-US-00058" num="00058"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 50</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>DMAAccessEn register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="28pt" align="center" /><colspec colname="3" colwidth="35pt" align="left" /><colspec colname="4" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Write</entry><entry /></row><row><entry>Field Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>DMAChannel0En</entry><entry>0</entry><entry>Full</entry><entry>DMA Channel #0 access</entry></row><row><entry /><entry /><entry /><entry>enable. This uni-directional</entry></row><row><entry /><entry /><entry /><entry>write channel is used</entry></row><row><entry /><entry /><entry /><entry>by the USBD and the ISI.</entry></row><row><entry /><entry /><entry /><entry>1 = enable</entry></row><row><entry /><entry /><entry /><entry>0 = disable</entry></row><row><entry>DMAChannel1En</entry><entry>1</entry><entry>Full</entry><entry>As per USBDISI0En.</entry></row><row><entry>DMAChannel2En</entry><entry>2</entry><entry>Full</entry><entry>DMA Channel #2 access</entry></row><row><entry /><entry /><entry /><entry>enable. This bi-directional</entry></row><row><entry /><entry /><entry /><entry>read/write channel is</entry></row><row><entry /><entry /><entry /><entry>used by the USBH.</entry></row><row><entry /><entry /><entry /><entry>1 = enable</entry></row><row><entry /><entry /><entry /><entry>0 = disable</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.13 DMAStatus
1545The status bits are not sticky bits i.e. they reflect the ‘live’ status of the channel. DMAChannelNntAdrHit and DMAChannelNMaxAdrHit status bits may only be cleared by writing to the relevant DMAnintAdr or DMAnMaxAdr register.
1546<tables id="TABLE-US-00059" num="00059"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 51</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>DMAStatus register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Write</entry><entry /></row><row><entry>Field Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>DMAChannel0IntAdrHit</entry><entry>0</entry><entry>None</entry><entry>DMA channel #0</entry></row><row><entry /><entry /><entry /><entry>interrupt address hit.</entry></row><row><entry /><entry /><entry /><entry>1 = DMAChannel0</entry></row><row><entry /><entry /><entry /><entry>has reached the</entry></row><row><entry /><entry /><entry /><entry>address contained</entry></row><row><entry /><entry /><entry /><entry>in the DMA0IntAdr</entry></row><row><entry /><entry /><entry /><entry>register.</entry></row><row><entry /><entry /><entry /><entry>0 = default state</entry></row><row><entry>DMAChannel0MaxAdrHit</entry><entry>1</entry><entry>None</entry><entry>DMA channel #0 max</entry></row><row><entry /><entry /><entry /><entry>address hit.</entry></row><row><entry /><entry /><entry /><entry>1 = DMAChannel0</entry></row><row><entry /><entry /><entry /><entry>has reached the</entry></row><row><entry /><entry /><entry /><entry>address contained</entry></row><row><entry /><entry /><entry /><entry>in the DMA0MaxAdr</entry></row><row><entry /><entry /><entry /><entry>register.</entry></row><row><entry /><entry /><entry /><entry>0 = default state</entry></row><row><entry>DMAChannel1IntAdrHit</entry><entry>3</entry><entry>None</entry><entry>As per</entry></row><row><entry /><entry /><entry /><entry>DMAChannel0IntAdrHit.</entry></row><row><entry>DMAChannel1MaxAdrHit</entry><entry>4</entry><entry>None</entry><entry>As per</entry></row><row><entry /><entry /><entry /><entry>DMAChannel0MaxAdrHit.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.14 DMAMask Register
1547All bits of the DMAMask are both readable and writable by the CPU. The DMA manager cannot alter the value of this register. All interrupts are generated in an edge sensitive manner i.e. the DMA manager will generate a dma_icu_irq pulse each time a status bit goes high and its corresponding mask bit is enabled.
1548<tables id="TABLE-US-00060" num="00060"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 52</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>DMAMask register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="105pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="35pt" align="left" /><colspec colname="4" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Write</entry><entry /></row><row><entry>Field Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>DMAChannel0IntAdrHitIntEn</entry><entry>0</entry><entry>Full</entry><entry>DMAChannel0IntAdrHit</entry></row><row><entry /><entry /><entry /><entry>status interrupt</entry></row><row><entry /><entry /><entry /><entry>enable.</entry></row><row><entry /><entry /><entry /><entry>1 = enable</entry></row><row><entry /><entry /><entry /><entry>0 = disable</entry></row><row><entry>DMAChannel0MaxAdrHitIntEn</entry><entry>1</entry><entry>Full</entry><entry>DMAChannel0MaxAdrHit</entry></row><row><entry /><entry /><entry /><entry>status interrupt</entry></row><row><entry /><entry /><entry /><entry>enable.</entry></row><row><entry /><entry /><entry /><entry>1 = enable</entry></row><row><entry /><entry /><entry /><entry>0 = disable</entry></row><row><entry>DMAChannel1IntAdrHitIntEn</entry><entry>2</entry><entry>Full</entry><entry>As per</entry></row><row><entry /><entry /><entry /><entry>DMAChannel0IntAdrHitIntEn</entry></row><row><entry>DMAChannel1MaxAdrHitIntEn</entry><entry>3</entry><entry>Full</entry><entry>As per</entry></row><row><entry /><entry /><entry /><entry>DMAChannel0MaxAdrHitIntEn</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.15 CPUISITxBuffCtrl Register
1549<tables id="TABLE-US-00061" num="00061"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 53</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>CPUISITxBuffCtrl register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="119pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Write</entry><entry /></row><row><entry>Field Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>PktValid</entry><entry>0</entry><entry>full</entry><entry>This field should be set by the CPU to</entry></row><row><entry /><entry /><entry /><entry>indicate the validity of the</entry></row><row><entry /><entry /><entry /><entry>CPUISITxBuff contents. This field will</entry></row><row><entry /><entry /><entry /><entry>be cleared by the SCB once the</entry></row><row><entry /><entry /><entry /><entry>contents of the CPUISITxBuff has been</entry></row><row><entry /><entry /><entry /><entry>copied to the ISITxBuff.</entry></row><row><entry /><entry /><entry /><entry>NOTE: The CPU should not clear this</entry></row><row><entry /><entry /><entry /><entry>field under normal operation. If the</entry></row><row><entry /><entry /><entry /><entry>CPU clears this field during a packet</entry></row><row><entry /><entry /><entry /><entry>transfer to the ISITxBuff, the transfer</entry></row><row><entry /><entry /><entry /><entry>will be aborted - this is not</entry></row><row><entry /><entry /><entry /><entry>recommended.</entry></row><row><entry /><entry /><entry /><entry>1 = valid packet.</entry></row><row><entry /><entry /><entry /><entry>0 = default state.</entry></row><row><entry>PktDesc</entry><entry>3:1</entry><entry>full</entry><entry>PktDesc field, as per Table , of the</entry></row><row><entry /><entry /><entry /><entry>packet contained in the CPUISITxBuff.</entry></row><row><entry /><entry /><entry /><entry>The CPU is responsible for maintaining</entry></row><row><entry /><entry /><entry /><entry>the correct sequence bit value for each</entry></row><row><entry /><entry /><entry /><entry>ISIId.ISISubId channel it communicates</entry></row><row><entry /><entry /><entry /><entry>with. Only valid when CPU-</entry></row><row><entry /><entry /><entry /><entry>ISITxBuffCtrl.PktValid = 1.</entry></row><row><entry>DestISIId</entry><entry>7:4</entry><entry>full</entry><entry>Denotes the ISIId of the target SoPEC</entry></row><row><entry /><entry /><entry /><entry>as per Table .</entry></row><row><entry>DestISISubId</entry><entry>8</entry><entry>full</entry><entry>Indicates which DMAChannel of the</entry></row><row><entry /><entry /><entry /><entry>target SoPEC the packet in the</entry></row><row><entry /><entry /><entry /><entry>CPUISITxBuff is destined for.</entry></row><row><entry /><entry /><entry /><entry>1 = DMAChannel1</entry></row><row><entry /><entry /><entry /><entry>0 = DMAChannel0</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.16 USBDIntStatus
1550The USBDIntStatus register contains status bits that are related to conditions that can cause an interrupt to the CPU, if the corresponding interrupt enable bits are set in the USBDMask register. The field name extension Sticky implies that the status condition will remain registered until cleared by a CPU write of 1 to each bit of the field.
1551NOTE: There is no Ep0IrregPktSticky field because the default control EP will frequently receive packets that are not multiples of 32 bytes during normal operation.
1552<tables id="TABLE-US-00062" num="00062"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="280pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 54</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>USBDIntStatus register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Write</entry><entry /></row><row><entry>Field Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="140pt" align="left" /><tbody valign="top"><row><entry>CoreSuspendSticky</entry><entry>0</entry><entry>Clear</entry><entry>Device core USB suspend flag. Sticky.</entry></row><row><entry /><entry /><entry /><entry>1 = USB suspend state. Set when device core</entry></row><row><entry /><entry /><entry /><entry>udcvci_suspend signal transitions from 1 −> 0.</entry></row><row><entry /><entry /><entry /><entry>0 = default value.</entry></row><row><entry>CoreUSBResetSticky</entry><entry>1</entry><entry>Clear</entry><entry>Device core USB reset flag. Sticky.</entry></row><row><entry /><entry /><entry /><entry>1 = USB reset. Set when device core</entry></row><row><entry /><entry /><entry /><entry>udcvci_reset signal transitions from 1 −> 0.</entry></row><row><entry /><entry /><entry /><entry>0 = default value.</entry></row><row><entry>CoreUSBSOFSticky</entry><entry>2</entry><entry>Clear</entry><entry>Device core USB Start Of Frame (SOF) flag.</entry></row><row><entry /><entry /><entry /><entry>Sticky.</entry></row><row><entry /><entry /><entry /><entry>1 = USB SOF. Set when device core</entry></row><row><entry /><entry /><entry /><entry>udcvci_sof signal transitions from 1 −> 0</entry></row><row><entry /><entry /><entry /><entry>0 = default value.</entry></row><row><entry>CPUISITxBuffEmptySticky</entry><entry>3</entry><entry>Clear</entry><entry>CPU ISI transmit buffer empty flag. Sticky.</entry></row><row><entry /><entry /><entry /><entry>1 = empty.</entry></row><row><entry /><entry /><entry /><entry>0 = default value.</entry></row><row><entry>CPUEp0InBuffEmptySticky</entry><entry>4</entry><entry>Clear</entry><entry>CPU EP0 IN buffer empty flag. Sticky.</entry></row><row><entry /><entry /><entry /><entry>1 = empty.</entry></row><row><entry /><entry /><entry /><entry>0 = default value.</entry></row><row><entry>CPUEp5InBuffEmptySticky</entry><entry>5</entry><entry>Clear</entry><entry>CPU EP5 IN buffer empty flag. Sticky.</entry></row><row><entry /><entry /><entry /><entry>1 = empty.</entry></row><row><entry /><entry /><entry /><entry>0 = default value.</entry></row><row><entry>Ep0InNAKSticky</entry><entry>6</entry><entry>clear</entry><entry>EP0-IN NAK flag. Sticky</entry></row><row><entry /><entry /><entry /><entry>This flag is set if the USB device core issues</entry></row><row><entry /><entry /><entry /><entry>a read request for EP0-IN and there is not a</entry></row><row><entry /><entry /><entry /><entry>valid packet present in the EP0-IN buffer. The</entry></row><row><entry /><entry /><entry /><entry>core will therefore send a NAK response to</entry></row><row><entry /><entry /><entry /><entry>the IN token that was received from external</entry></row><row><entry /><entry /><entry /><entry>USB host. This is an indicator of any back-</entry></row><row><entry /><entry /><entry /><entry>pressure on the USB caused by EP0-IN.</entry></row><row><entry /><entry /><entry /><entry>1 = NAK sent.</entry></row><row><entry /><entry /><entry /><entry>0 = default value</entry></row><row><entry>Ep5InNAKSticky</entry><entry>7</entry><entry>Clear</entry><entry>Us per Ep0InNAK.</entry></row><row><entry>Ep0OutNAKSticky</entry><entry>8</entry><entry>Clear</entry><entry>EP0-OUT NAK flag. Sticky</entry></row><row><entry /><entry /><entry /><entry>This flag is set if the USB device core issues</entry></row><row><entry /><entry /><entry /><entry>a write request for EP0-OUT and there is no</entry></row><row><entry /><entry /><entry /><entry>space in the OUT EP buffer for a the packet.</entry></row><row><entry /><entry /><entry /><entry>The core will therefore send a NAK response</entry></row><row><entry /><entry /><entry /><entry>to the OUT token that was received from</entry></row><row><entry /><entry /><entry /><entry>external USB host. This is an indicator of any</entry></row><row><entry /><entry /><entry /><entry>back-pressure on the USB caused by EP0-</entry></row><row><entry /><entry /><entry /><entry>OUT.</entry></row><row><entry /><entry /><entry /><entry>1 = NAK sent.</entry></row><row><entry /><entry /><entry /><entry>0 = default value</entry></row><row><entry>Ep1OutNAKSticky</entry><entry>9</entry><entry>Clear</entry><entry>As per EP0OutNAK.</entry></row><row><entry>Ep2OutNAKSticky</entry><entry>10</entry><entry>Clear</entry><entry>As per EP0OutNAK.</entry></row><row><entry>Ep3OutNAKSticky</entry><entry>11</entry><entry>Clear</entry><entry>As per EP0OutNAK.</entry></row><row><entry>Ep4OutNAKSticky</entry><entry>12</entry><entry>Clear</entry><entry>As per EP0OutNAK.</entry></row><row><entry>Ep1IrregPktSticky</entry><entry>13</entry><entry>Clear</entry><entry>EP1-OUT irregular sized packet flag. Sticky.</entry></row><row><entry /><entry /><entry /><entry>Indicates a packet that is not a multiple of</entry></row><row><entry /><entry /><entry /><entry>32 bytes in size was received by EP1-OUT.</entry></row><row><entry /><entry /><entry /><entry>1 = irregular sized packet received.</entry></row><row><entry /><entry /><entry /><entry>0 = default value.</entry></row><row><entry>Ep2IrregPktSticky</entry><entry>14</entry><entry>Clear</entry><entry>As per Ep1IrregPktSticky.</entry></row><row><entry>Ep3IrregPktSticky</entry><entry>15</entry><entry>Clear</entry><entry>As per Ep1IrregPktSticky.</entry></row><row><entry>Ep4IrregPktSticky</entry><entry>16</entry><entry>Clear</entry><entry>As per Ep1IrregPktSticky.</entry></row><row><entry>OutBuffOverFlowSticky</entry><entry>17</entry><entry>Clear</entry><entry>OUT EP buffer overflow flag. Sticky.</entry></row><row><entry /><entry /><entry /><entry>This flag is set if the USB device core</entry></row><row><entry /><entry /><entry /><entry>attempted to write a packet of more than 64</entry></row><row><entry /><entry /><entry /><entry>bytes to the OUT EP buffer. This is a fatal</entry></row><row><entry /><entry /><entry /><entry>error, suggesting a problem in the USB device</entry></row><row><entry /><entry /><entry /><entry>IP core. The SCB will take no further action.</entry></row><row><entry /><entry /><entry /><entry>1 = overflow condition detected.</entry></row><row><entry /><entry /><entry /><entry>0 = default value.</entry></row><row><entry>InBuffUnderRunSticky</entry><entry>18</entry><entry>clear</entry><entry>IN EP buffer underrun flag. Sticky.</entry></row><row><entry /><entry /><entry /><entry>This flag is set if the USB device core</entry></row><row><entry /><entry /><entry /><entry>attempted to read more data than was</entry></row><row><entry /><entry /><entry /><entry>present from the IN EP buffer. This is a fatal</entry></row><row><entry /><entry /><entry /><entry>error, suggesting a problem in the USB device</entry></row><row><entry /><entry /><entry /><entry>IP core. The SCB will take no further action.</entry></row><row><entry /><entry /><entry /><entry>1 = underrun condition detected.</entry></row><row><entry /><entry /><entry /><entry>0 = default value.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.17 USBDISIFIFOStatus
1553This register contains the status of the ISI mapped OUT EP packet FIFO. This is a secondary status register and will not cause any interrupts to the CPU.
1554<tables id="TABLE-US-00063" num="00063"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 55</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>USBDISIFIFOStatus register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="35pt" align="left" /><colspec colname="4" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Write</entry><entry /></row><row><entry>Field Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="35pt" align="left" /><colspec colname="4" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>Entry0Valid</entry><entry>0</entry><entry>none</entry><entry>FIFO entry #0 valid field.</entry></row><row><entry /><entry /><entry /><entry>This flag will be set by the USBD</entry></row><row><entry /><entry /><entry /><entry>when the USB device core</entry></row><row><entry /><entry /><entry /><entry>indicates the validity of packet</entry></row><row><entry /><entry /><entry /><entry>entry #0 in the FIFO.</entry></row><row><entry /><entry /><entry /><entry>1 = valid USB packet in ISI</entry></row><row><entry /><entry /><entry /><entry>OUT EP buffer 0.</entry></row><row><entry /><entry /><entry /><entry>0 = default value.</entry></row><row><entry>Entry0Source</entry><entry>3:1</entry><entry>none</entry><entry>FIFO entry #0 source field.</entry></row><row><entry /><entry /><entry /><entry>Contains the EP associated with</entry></row><row><entry /><entry /><entry /><entry>packet entry #0 in the FIFO.</entry></row><row><entry /><entry /><entry /><entry>Binary Coded Decimal.</entry></row><row><entry /><entry /><entry /><entry>Only valid when</entry></row><row><entry /><entry /><entry /><entry>ISIBuff0PktValid = 1.</entry></row><row><entry>Entry1Valid</entry><entry>4</entry><entry>none</entry><entry>As per Entry0Valid.</entry></row><row><entry>Entry1Source</entry><entry>7:5</entry><entry>none</entry><entry>As per Entry0Source.</entry></row><row><entry>Entry2Valid</entry><entry>8</entry><entry>none</entry><entry>As per Entry0Valid.</entry></row><row><entry>Entry2Source</entry><entry>11:9 </entry><entry>none</entry><entry>As per Entry0Source.</entry></row><row><entry>Entry3Valid</entry><entry>12</entry><entry>none</entry><entry>As per Entry0Valid.</entry></row><row><entry>Entry3Source</entry><entry>15:13</entry><entry>none</entry><entry>As per Entry0Source.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.18 USBDDMAOFIFOStatus
1555This register description applies to USBDDMAOFIFOStatus and USBDDMA1FIFOStatus.
1556This register contains the status of the DMAChannelN mapped OUT EP packet FIFO. This is a secondary status register and will not cause any interrupts to the CPU.
1557<tables id="TABLE-US-00064" num="00064"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 56</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>USBDDMANFIFOStatus register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="21pt" align="left" /><colspec colname="3" colwidth="35pt" align="left" /><colspec colname="4" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Write</entry><entry /></row><row><entry>Field Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>Entry0Valid</entry><entry>0</entry><entry>none</entry><entry>FIFO entry #0 valid field.</entry></row><row><entry /><entry /><entry /><entry>This flag will be set by the USBD</entry></row><row><entry /><entry /><entry /><entry>when the USB device core</entry></row><row><entry /><entry /><entry /><entry>indicates the validity of packet</entry></row><row><entry /><entry /><entry /><entry>entry #0 in the FIFO.</entry></row><row><entry /><entry /><entry /><entry>1 = valid USB packet in ISI OUT</entry></row><row><entry /><entry /><entry /><entry>EP buffer 0.</entry></row><row><entry /><entry /><entry /><entry>0 = default value.</entry></row><row><entry>Entry0Source</entry><entry>3:1</entry><entry>none</entry><entry>FIFO entry #0 source field.</entry></row><row><entry /><entry /><entry /><entry>Contains the EP associated with</entry></row><row><entry /><entry /><entry /><entry>packet entry #0 in the FIFO.</entry></row><row><entry /><entry /><entry /><entry>Binary Coded Decimal.</entry></row><row><entry /><entry /><entry /><entry>Only valid when Entry0Valid = 1.</entry></row><row><entry>Entry1Valid</entry><entry>4</entry><entry>none</entry><entry>As per Entry0Valid.</entry></row><row><entry>Entry1Source</entry><entry>7:5</entry><entry>none</entry><entry>As per Entry0Source.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.19 USBDResume
1558This register causes the USB device core to initiate resume signalling to the external USB host.
1559Only applicable when the device core is in the suspend state.
1560<tables id="TABLE-US-00065" num="00065"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 57</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>USBDResume register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="42pt" align="center" /><colspec colname="3" colwidth="35pt" align="left" /><colspec colname="4" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Write</entry><entry /></row><row><entry>Field Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>USBDResume</entry><entry>0</entry><entry>full</entry><entry>USBD core resume register.</entry></row><row><entry /><entry /><entry /><entry>The USBD will clear this</entry></row><row><entry /><entry /><entry /><entry>register upon resume</entry></row><row><entry /><entry /><entry /><entry>notification from the device</entry></row><row><entry /><entry /><entry /><entry>core.</entry></row><row><entry /><entry /><entry /><entry>1 = generate</entry></row><row><entry /><entry /><entry /><entry>resume signalling.</entry></row><row><entry /><entry /><entry /><entry>0 = default value.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.20 USBDSetup
1561This register controls the general setup/configuration of the USBD.
1562<tables id="TABLE-US-00066" num="00066"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 58</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>USBDSetup register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="28pt" align="center" /><colspec colname="3" colwidth="35pt" align="left" /><colspec colname="4" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>write</entry><entry /></row><row><entry>Field Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>Ep1IrregPktCntrl</entry><entry>0</entry><entry>full</entry><entry>EP 1 OUT irregular sized</entry></row><row><entry /><entry /><entry /><entry>packet control. An Irregular</entry></row><row><entry /><entry /><entry /><entry>sized packet is defined</entry></row><row><entry /><entry /><entry /><entry>as a packet that is not a</entry></row><row><entry /><entry /><entry /><entry>multiple of 32 bytes.</entry></row><row><entry /><entry /><entry /><entry>1 = discard irregular</entry></row><row><entry /><entry /><entry /><entry>sized packets.</entry></row><row><entry /><entry /><entry /><entry>0 = read 32 bytes from</entry></row><row><entry /><entry /><entry /><entry>buffer, regardless of packets</entry></row><row><entry /><entry /><entry /><entry>size.</entry></row><row><entry>Ep2IrregPktCntrl</entry><entry>1</entry><entry>full</entry><entry>As per Ep1IrregPktDiscard</entry></row><row><entry>Ep3IrregPktCntrl</entry><entry>2</entry><entry>full</entry><entry>As per Ep1IrregPktDiscard</entry></row><row><entry>Ep4IrregPktCntrl</entry><entry>3</entry><entry>full</entry><entry>As per Ep1IrregPktDiscard</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.21 USBDEpNInBuffCtrl Register
1563This register description applies to USBDEp0InBuffCtrl and USBDEp5InBuffCtrl.
1564<tables id="TABLE-US-00067" num="00067"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 59</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>USBDEpNInBuffCtrl register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="21pt" align="left" /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="119pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Write</entry><entry /></row><row><entry>Field Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>PktValid</entry><entry>0</entry><entry>full</entry><entry>Setting this register validates</entry></row><row><entry /><entry /><entry /><entry>the contents of USBDEpNInBuff. This</entry></row><row><entry /><entry /><entry /><entry>field will be cleared by the SCB</entry></row><row><entry /><entry /><entry /><entry>once the packet has been</entry></row><row><entry /><entry /><entry /><entry>successfully transmitted to the</entry></row><row><entry /><entry /><entry /><entry>external USB host.</entry></row><row><entry /><entry /><entry /><entry>NOTE: The CPU should not clear this</entry></row><row><entry /><entry /><entry /><entry>field under normal operation. If the</entry></row><row><entry /><entry /><entry /><entry>CPU clears this field during a packet</entry></row><row><entry /><entry /><entry /><entry>transfer to the USB, the transfer will</entry></row><row><entry /><entry /><entry /><entry>be aborted - this is not recommended.</entry></row><row><entry /><entry /><entry /><entry>1 = valid packet.</entry></row><row><entry /><entry /><entry /><entry>0 = default state.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.22 USBDMask
1565This register serves as an interrupt mask for all USBD status conditions that can cause a CPU interrupt. Setting a field enables interrupt generation for the associated status event. Clearing a field disables interrupt generation for the associated status event. All interrupts will be generated in an edge sensitive manner, i.e. when the associated status register transitions from 0->1.
1566<tables id="TABLE-US-00068" num="00068"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="301pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 60</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>USBDMask register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="98pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="28pt" align="center" /><colspec colname="4" colwidth="154pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Write</entry><entry /></row><row><entry>Field Name</entry><entry>Bit(s)</entry><entry>Access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="98pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="28pt" align="center" /><colspec colname="4" colwidth="154pt" align="left" /><tbody valign="top"><row><entry>CoreSuspendStickyEn</entry><entry>0</entry><entry>full</entry><entry>CoreSuspendSticky status interrupt enable.</entry></row><row><entry>CoreUSBResetStickyEn</entry><entry>1</entry><entry>full</entry><entry>CoreUSBResetSticky status interrupt enable.</entry></row><row><entry>CoreUSBSOFStickyEn</entry><entry>2</entry><entry>full</entry><entry>CoreUSBSOFSticky status interrupt enable.</entry></row><row><entry>CPUISITxBuffEmptyStickyEn</entry><entry>3</entry><entry>full</entry><entry>CPUISITxBuffEmptySticky status interrupt enable.</entry></row><row><entry>CPUEp0InBuffEmptyStickyEn</entry><entry>4</entry><entry>full</entry><entry>CPUEp0InBuffEmptySticky status interrupt enable.</entry></row><row><entry>CPUEp5InBuffEmptyStickyEn</entry><entry>5</entry><entry>full</entry><entry>CPUEp5InBuffEmptySticky status interrupt enable.</entry></row><row><entry>Ep0InNAKStickyEn</entry><entry>6</entry><entry>full</entry><entry>Ep0InNAKSticky status interrupt enable.</entry></row><row><entry>Ep5InNAKStickyEn</entry><entry>7</entry><entry>full</entry><entry>Ep5InNAKSticky status interrupt enable.</entry></row><row><entry>Ep0OutNAKStickyEn</entry><entry>8</entry><entry>full</entry><entry>Ep0OutNAKSticky status interrupt enable.</entry></row><row><entry>Ep1OutNAKStickyEn</entry><entry>9</entry><entry>full</entry><entry>Ep1OutNAKSticky status interrupt enable.</entry></row><row><entry>Ep2OutNAKStickyEn</entry><entry>10</entry><entry>full</entry><entry>Ep2OutNAKSticky status interrupt enable.</entry></row><row><entry>Ep3OutNAKStickyEn</entry><entry>11</entry><entry>full</entry><entry>Ep3OutNAKSticky status interrupt enable.</entry></row><row><entry>Ep4OutNAKStickyEn</entry><entry>12</entry><entry>full</entry><entry>Ep4OutNAKSticky status interrupt enable.</entry></row><row><entry>Ep1IrregPktStickyEn</entry><entry>13</entry><entry>full</entry><entry>Ep1IrregPktSticky status interrupt enable.</entry></row><row><entry>Ep2IrregPktStickyEn</entry><entry>14</entry><entry>full</entry><entry>Ep2IrregPktSticky status interrupt enable.</entry></row><row><entry>Ep3IrregPktStickyEn</entry><entry>15</entry><entry>full</entry><entry>Ep3IrregPktSticky status interrupt enable.</entry></row><row><entry>Ep4IrregPktStickyEn</entry><entry>16</entry><entry>full</entry><entry>Ep4IrregPktSticky status interrupt enable.</entry></row><row><entry>OutBuffOverFlowStickyEn</entry><entry>17</entry><entry>full</entry><entry>OutBuffOverFlowSticky status interrupt enable.</entry></row><row><entry>InBuffUnderRunStickyEn</entry><entry>18</entry><entry>full</entry><entry>InBuffUnderRunSticky status interrupt enable.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.23 USBDDebug
1567This register is intended for debug purposes only. Contains non-sticky versions of all interrupt capable status bits, which are referred to as dynamic in the table.
1568<tables id="TABLE-US-00069" num="00069"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 61</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>USBDDebug register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="left" /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>write</entry><entry /></row><row><entry>Field Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>CoreTimeStamp</entry><entry>10:0</entry><entry>none</entry><entry>USB device core frame</entry></row><row><entry /><entry /><entry /><entry>number.</entry></row><row><entry>CoreSuspend</entry><entry>11</entry><entry>none</entry><entry>Dynamic version of</entry></row><row><entry /><entry /><entry /><entry>CoreSuspendSticky.</entry></row><row><entry>CoreUSBReset</entry><entry>12</entry><entry>none</entry><entry>Dynamic version of</entry></row><row><entry /><entry /><entry /><entry>CoreUSBResetSticky.</entry></row><row><entry>CoreUSBSOF</entry><entry>13</entry><entry>none</entry><entry>Dynamic version of</entry></row><row><entry /><entry /><entry /><entry>CoreUSBSOFSticky.</entry></row><row><entry>CPUISITxBuffEmpty</entry><entry>14</entry><entry>none</entry><entry>Dynamic version of</entry></row><row><entry /><entry /><entry /><entry>CPUISITxBuffEmptySticky.</entry></row><row><entry>CPUEp0InBuffEmpty</entry><entry>15</entry><entry>none</entry><entry>Dynamic version of</entry></row><row><entry /><entry /><entry /><entry>CPUEp0InBuffEmptySticky.</entry></row><row><entry>CPUEp5InBuffEmpty</entry><entry>16</entry><entry>none</entry><entry>Dynamic version of</entry></row><row><entry /><entry /><entry /><entry>CPUEp5InBuffEmptySticky.</entry></row><row><entry>Ep0InNAK</entry><entry>17</entry><entry>none</entry><entry>Dynamic version of</entry></row><row><entry /><entry /><entry /><entry>Ep0InNAKSticky.</entry></row><row><entry>Ep5InNAK</entry><entry>18</entry><entry>none</entry><entry>Dynamic version of</entry></row><row><entry /><entry /><entry /><entry>Ep5InNAKSticky.</entry></row><row><entry>Ep0OutNAK</entry><entry>19</entry><entry>none</entry><entry>Dynamic version of</entry></row><row><entry /><entry /><entry /><entry>Ep0OutNAKSticky.</entry></row><row><entry>Ep1OutNAK</entry><entry>20</entry><entry>none</entry><entry>Dynamic version of</entry></row><row><entry /><entry /><entry /><entry>Ep1OutNAKSticky.</entry></row><row><entry>Ep2OutNAK</entry><entry>21</entry><entry>none</entry><entry>Dynamic version of</entry></row><row><entry /><entry /><entry /><entry>Ep2OutNAKSticky.</entry></row><row><entry>Ep3OutNAK</entry><entry>22</entry><entry>none</entry><entry>Dynamic version of</entry></row><row><entry /><entry /><entry /><entry>Ep3OutNAKSticky.</entry></row><row><entry>Ep4OutNAK</entry><entry>23</entry><entry>none</entry><entry>Dynamic version of</entry></row><row><entry /><entry /><entry /><entry>Ep4OutNAKSticky.</entry></row><row><entry>Ep1IrregPkt</entry><entry>24</entry><entry>none</entry><entry>Dynamic version of</entry></row><row><entry /><entry /><entry /><entry>Ep1IrregPktSticky.</entry></row><row><entry>Ep2IrregPkt</entry><entry>25</entry><entry>none</entry><entry>Dynamic version of</entry></row><row><entry /><entry /><entry /><entry>Ep2IrregPktSticky.</entry></row><row><entry>Ep3IrregPkt</entry><entry>26</entry><entry>none</entry><entry>Dynamic version of</entry></row><row><entry /><entry /><entry /><entry>Ep3IrregPktSticky.</entry></row><row><entry>Ep4IrregPkt</entry><entry>27</entry><entry>none</entry><entry>Dynamic version of</entry></row><row><entry /><entry /><entry /><entry>Ep4IrregPktSticky.</entry></row><row><entry>OutBuffOverFlow</entry><entry>28</entry><entry>none</entry><entry>Dynamic version of</entry></row><row><entry /><entry /><entry /><entry>OutBuffOverFlowSticky.</entry></row><row><entry>InBuffUnderRun</entry><entry>29</entry><entry>none</entry><entry>Dynamic version of</entry></row><row><entry /><entry /><entry /><entry>InBuffUnderRunSticky.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.24 USBHStatus
1569This register contains all status bits associated with the USBH. The field name extension Sticky implies that the status condition will remain registered until cleared by a CPU write.
1570<tables id="TABLE-US-00070" num="00070"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 62</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>USBHStatus register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="119pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Write</entry><entry /></row><row><entry>Field Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>CoreIRQSticky</entry><entry>0</entry><entry>clear</entry><entry>HC core IRQ interrupt flag.</entry></row><row><entry /><entry /><entry /><entry>Sticky Set when HC core</entry></row><row><entry /><entry /><entry /><entry>UHOSTC_IrqN output signal</entry></row><row><entry /><entry /><entry /><entry>transitions from 0 −> 1.</entry></row><row><entry /><entry /><entry /><entry>Refer to OHCI spec for details</entry></row><row><entry /><entry /><entry /><entry>on HC interrupt processing.</entry></row><row><entry /><entry /><entry /><entry>1 = IRQ interrupt from core.</entry></row><row><entry /><entry /><entry /><entry>0 = default value.</entry></row><row><entry>CoreSMISticky</entry><entry>1</entry><entry>clear</entry><entry>HC core SMI interrupt flag.</entry></row><row><entry /><entry /><entry /><entry>Sticky Set when HC core</entry></row><row><entry /><entry /><entry /><entry>UHOSTC_SmiN output signal transi-</entry></row><row><entry /><entry /><entry /><entry>tions from 0 −> 1. Refer to OHCI</entry></row><row><entry /><entry /><entry /><entry>spec for details on HC</entry></row><row><entry /><entry /><entry /><entry>interrupt processing.</entry></row><row><entry /><entry /><entry /><entry>1 = SMI interrupt from HC.</entry></row><row><entry /><entry /><entry /><entry>0 = default value.</entry></row><row><entry>CoreBuffAcc</entry><entry>2</entry><entry>none</entry><entry>HC core buffer access flag.</entry></row><row><entry /><entry /><entry /><entry>HC core UHOSTC_BufAcc output</entry></row><row><entry /><entry /><entry /><entry>signal. Indicates whether the</entry></row><row><entry /><entry /><entry /><entry>HC is accessing a descriptor</entry></row><row><entry /><entry /><entry /><entry>or a buffer in shared system</entry></row><row><entry /><entry /><entry /><entry>memory.</entry></row><row><entry /><entry /><entry /><entry>1 = buffer access</entry></row><row><entry /><entry /><entry /><entry>0 = descriptor access.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.25 USBHMask
1571This register serves as an interrupt mask for all USBH status conditions that can cause a CPU interrupt. All interrupts will be generated in an edge sensitive manner, i.e. when the associated status register transitions from 0->1.
1572<tables id="TABLE-US-00071" num="00071"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 63</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>USBHMask register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="28pt" align="center" /><colspec colname="3" colwidth="35pt" align="left" /><colspec colname="4" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Write</entry><entry /></row><row><entry>Field Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>CoreIRQIntEn</entry><entry>0</entry><entry>full</entry><entry>CoreIRQSticky status interrupt</entry></row><row><entry /><entry /><entry /><entry>enable.</entry></row><row><entry /><entry /><entry /><entry>1 = enable.</entry></row><row><entry /><entry /><entry /><entry>0 = disable.</entry></row><row><entry>CoreSMIIntEn</entry><entry>1</entry><entry>full</entry><entry>CoreSMISticky status interrupt</entry></row><row><entry /><entry /><entry /><entry>enable.</entry></row><row><entry /><entry /><entry /><entry>1 = enable.</entry></row><row><entry /><entry /><entry /><entry>0 = disable.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.26 USBHDebug
1573This register is intended for debug purposes only. Contains non-sticky versions of all interrupt capable status bits, which are referred to as dynamic in the table.
1574<tables id="TABLE-US-00072" num="00072"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 64</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>USBHDebug register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="35pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>write</entry><entry /></row><row><entry>Field Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>CoreIRQ</entry><entry>0</entry><entry>none</entry><entry>Dynamic version of CoreIRQSticky.</entry></row><row><entry>CoreSMI</entry><entry>1</entry><entry>None</entry><entry>Dynamic version of CoreSMISticky.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.27 ISICntrl
1575This register controls the general setup/configuration of the ISI.
1576Note that the reset value of this register allows the SoPEC to automatically become an ISIMaster (AutoMasterEnable=1) if any USB packets are received on endpoints 2–4. On becoming an ISIMaster the ISIMasterSel bit is set and any USB or CPU packets destined for other ISI devices are transmitted. The CPU can override this capability at any time by clearing the AutoMasterEnable bit.
1577<tables id="TABLE-US-00073" num="00073"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 65</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>ISICntrl register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="left" /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Write</entry><entry /></row><row><entry>Field Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>TxEnable</entry><entry>0</entry><entry>Full</entry><entry>ISI transmit enable.</entry></row><row><entry /><entry /><entry /><entry>Enables ISI transmission of</entry></row><row><entry /><entry /><entry /><entry>long or ping packets. ACKs may</entry></row><row><entry /><entry /><entry /><entry>still be transmitted when this</entry></row><row><entry /><entry /><entry /><entry>bit is 0.</entry></row><row><entry /><entry /><entry /><entry>This is cleared by transmit</entry></row><row><entry /><entry /><entry /><entry>errors and needs to be restarted</entry></row><row><entry /><entry /><entry /><entry>by the CPU.</entry></row><row><entry /><entry /><entry /><entry>1 = Transmission enabled</entry></row><row><entry /><entry /><entry /><entry>0 = Transmission disabled</entry></row><row><entry>RxEnable</entry><entry>1</entry><entry>Full</entry><entry>ISI receive enable.</entry></row><row><entry /><entry /><entry /><entry>Enables ISI reception. This is</entry></row><row><entry /><entry /><entry /><entry>can only be cleared by the CPU</entry></row><row><entry /><entry /><entry /><entry>and it is only anticipated that</entry></row><row><entry /><entry /><entry /><entry>reception will be disabled when</entry></row><row><entry /><entry /><entry /><entry>the ISI in not in use and the</entry></row><row><entry /><entry /><entry /><entry>ISI pins are being used by the</entry></row><row><entry /><entry /><entry /><entry>GPIO for another purpose.</entry></row><row><entry /><entry /><entry /><entry>1 = Reception enabled</entry></row><row><entry /><entry /><entry /><entry>0 = Reception disabled</entry></row><row><entry>ISIMasterSel</entry><entry>2</entry><entry>Full</entry><entry>ISI master select.</entry></row><row><entry /><entry /><entry /><entry>Determines whether the SoPEC is</entry></row><row><entry /><entry /><entry /><entry>an ISIMaster or not</entry></row><row><entry /><entry /><entry /><entry>1 = ISIMaster</entry></row><row><entry /><entry /><entry /><entry>0 = ISISlave</entry></row><row><entry>AutoMasterEnable</entry><entry>3</entry><entry>Full</entry><entry>ISI auto master enable.</entry></row><row><entry /><entry /><entry /><entry>Enables the device to automatically</entry></row><row><entry /><entry /><entry /><entry>become the ISIMaster if activity</entry></row><row><entry /><entry /><entry /><entry>is detected on USB endpoints2–4.</entry></row><row><entry /><entry /><entry /><entry>1 = auto-master operation enabled</entry></row><row><entry /><entry /><entry /><entry>0 = auto-master operation disabled</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.28 ISIId
1578<tables id="TABLE-US-00074" num="00074"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 66</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>ISIId register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="35pt" align="left" /><colspec colname="2" colwidth="28pt" align="left" /><colspec colname="3" colwidth="35pt" align="left" /><colspec colname="4" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>Field</entry><entry /><entry>Write</entry><entry /></row><row><entry>Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>ISIId</entry><entry>3:0</entry><entry>Full</entry><entry>ISIId for this SoPEC.</entry></row><row><entry /><entry /><entry /><entry>SoPEC resets to being an ISISlave</entry></row><row><entry /><entry /><entry /><entry>with ISIId0. 0xF (the broadcast</entry></row><row><entry /><entry /><entry /><entry>ISIId) is an illegal value and</entry></row><row><entry /><entry /><entry /><entry>should not be written to this register.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.29 ISINumRetries
1579<tables id="TABLE-US-00075" num="00075"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 67</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>ISINumRetries register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="28pt" align="center" /><colspec colname="3" colwidth="35pt" align="left" /><colspec colname="4" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Write</entry><entry /></row><row><entry>Field Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>ISINumRetries</entry><entry>3:0</entry><entry>Full</entry><entry>Number of ISI retransmissions</entry></row><row><entry /><entry /><entry /><entry>to attempt in response to an</entry></row><row><entry /><entry /><entry /><entry>inferred NAK before aborting</entry></row><row><entry /><entry /><entry /><entry>a long packet transmission</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.30 ISIPingScheduleN
1580This register description applies to ISIPingSchedule0, ISIPingSchedule1 and ISIPingSchedule2.
1581<tables id="TABLE-US-00076" num="00076"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 68</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>ISIPingScheduleN register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="left" /><colspec colname="3" colwidth="35pt" align="left" /><colspec colname="4" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Write</entry><entry /></row><row><entry>Field Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>ISIPingSchedule</entry><entry>14:0</entry><entry>Full</entry><entry>Denotes which ISIIds will be</entry></row><row><entry /><entry /><entry /><entry>receive ping packets. Note that</entry></row><row><entry /><entry /><entry /><entry>bit0 refers to ISIId0, bit1 to</entry></row><row><entry /><entry /><entry /><entry>ISIId1 . . . bit14 to ISIId14.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.31 ISITotalPeriod
1582<tables id="TABLE-US-00077" num="00077"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 69</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>ISITotalPeriod register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="28pt" align="left" /><colspec colname="3" colwidth="42pt" align="left" /><colspec colname="4" colwidth="77pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry /><entry>Write</entry><entry /></row><row><entry /><entry>Field Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry /><entry namest="offset" nameend="4" align="center" rowsep="1" /></row><row><entry /><entry>ISITotalPeriod</entry><entry>3:0</entry><entry>Full</entry><entry>Reload value of the</entry></row><row><entry /><entry /><entry /><entry /><entry>ISITotalPeriod counter</entry></row><row><entry /><entry namest="offset" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.32 ISILocalPeriod
1583<tables id="TABLE-US-00078" num="00078"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 70</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>ISILocalPeriod register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="35pt" align="center" /><colspec colname="3" colwidth="42pt" align="left" /><colspec colname="4" colwidth="77pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry /><entry>Write</entry><entry /></row><row><entry /><entry>Field Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry /><entry namest="offset" nameend="4" align="center" rowsep="1" /></row><row><entry /><entry>ISILocalPeriod</entry><entry>3:0</entry><entry>Full</entry><entry>Reload value of the</entry></row><row><entry /><entry /><entry /><entry /><entry>ISILocalPeriod counter</entry></row><row><entry /><entry namest="offset" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.33 ISIIntStatus
1584The ISIIntStatus register contains status bits that are related to conditions that can cause an interrupt to the CPU, if the corresponding interrupt enable bits are set in the ISIMask register.
1585<tables id="TABLE-US-00079" num="00079"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 71</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>ISIIntStatus register</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Write</entry><entry /></row><row><entry>Field Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>TxErrorSticky</entry><entry>0</entry><entry>None</entry><entry>ISI transmit error flag.</entry></row><row><entry /><entry /><entry /><entry>Sticky.</entry></row><row><entry /><entry /><entry /><entry>Receiving ISI device would</entry></row><row><entry /><entry /><entry /><entry>not accept the transmitted</entry></row><row><entry /><entry /><entry /><entry>packet. Only set after</entry></row><row><entry /><entry /><entry /><entry>NumRetries unsuccessful</entry></row><row><entry /><entry /><entry /><entry>retransmissions, (excluding</entry></row><row><entry /><entry /><entry /><entry>ping packets).</entry></row><row><entry /><entry /><entry /><entry>This bit is cleared by the</entry></row><row><entry /><entry /><entry /><entry>ISI after transmission has</entry></row><row><entry /><entry /><entry /><entry>been re-enabled by the CPU</entry></row><row><entry /><entry /><entry /><entry>setting the TxEnable bit of</entry></row><row><entry /><entry /><entry /><entry>the ISICntrl register.</entry></row><row><entry /><entry /><entry /><entry>1 = transmit error.</entry></row><row><entry /><entry /><entry /><entry>0 = default state.</entry></row><row><entry>RxFrameErrorSticky</entry><entry>1</entry><entry>Clear</entry><entry>ISI receive framing error</entry></row><row><entry /><entry /><entry /><entry>flag. Sticky.</entry></row><row><entry /><entry /><entry /><entry>This bit is set by the ISI</entry></row><row><entry /><entry /><entry /><entry>when a framing error detect-</entry></row><row><entry /><entry /><entry /><entry>ed in the received packet,</entry></row><row><entry /><entry /><entry /><entry>which can be caused by an</entry></row><row><entry /><entry /><entry /><entry>incorrect Start or Stop</entry></row><row><entry /><entry /><entry /><entry>field or by bit stuffing</entry></row><row><entry /><entry /><entry /><entry>errors.</entry></row><row><entry /><entry /><entry /><entry>1 = framing error detected.</entry></row><row><entry /><entry /><entry /><entry>0 = default state.</entry></row><row><entry>RxCRCErrorSticky</entry><entry>2</entry><entry>Clear</entry><entry>ISI receive CRC error flag.</entry></row><row><entry /><entry /><entry /><entry>This bit is set by the ISI</entry></row><row><entry /><entry /><entry /><entry>when a CRC error is detected</entry></row><row><entry /><entry /><entry /><entry>in an incoming packet. Other</entry></row><row><entry /><entry /><entry /><entry>than dropping the errored</entry></row><row><entry /><entry /><entry /><entry>packet ISI reception is un-</entry></row><row><entry /><entry /><entry /><entry>affected by a CRC Error.</entry></row><row><entry /><entry /><entry /><entry>1 = CRC error</entry></row><row><entry /><entry /><entry /><entry>0 = default state.</entry></row><row><entry>RxBuffOverFlowSticky</entry><entry>3</entry><entry>Clear</entry><entry>ISI receive buffer over</entry></row><row><entry /><entry /><entry /><entry>flow flag. Sticky.</entry></row><row><entry /><entry /><entry /><entry>An overflow has occurred</entry></row><row><entry /><entry /><entry /><entry>in the ISI receive</entry></row><row><entry /><entry /><entry /><entry>buffer and a packet had</entry></row><row><entry /><entry /><entry /><entry>to be dropped.</entry></row><row><entry /><entry /><entry /><entry>1 = over flow</entry></row><row><entry /><entry /><entry /><entry>condition detected.</entry></row><row><entry /><entry /><entry /><entry>0 = default state.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.34 ISITxBuffStatus
1586The ISITxBuffStatus register contains status bits that are related to the ISI Tx buffer. This is a secondary status register and will not cause any interrupts to the CPU.
1587<tables id="TABLE-US-00080" num="00080"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 72</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>ISITxBuffStatus register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Write</entry><entry /></row><row><entry>Field Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>Entry0PktValid</entry><entry>0</entry><entry>None</entry><entry>ISI Tx buffer entry #0</entry></row><row><entry /><entry /><entry /><entry>packet valid flag.</entry></row><row><entry /><entry /><entry /><entry>This flag will be set by</entry></row><row><entry /><entry /><entry /><entry>the ISI when a valid ISI</entry></row><row><entry /><entry /><entry /><entry>packet is written to</entry></row><row><entry /><entry /><entry /><entry>entry #0 in the ISITxBuff</entry></row><row><entry /><entry /><entry /><entry>for transmission over the</entry></row><row><entry /><entry /><entry /><entry>ISI bus. A Tx packet is</entry></row><row><entry /><entry /><entry /><entry>considered valid when it is</entry></row><row><entry /><entry /><entry /><entry>32 bytes in size and the ISI</entry></row><row><entry /><entry /><entry /><entry>has written the packet header</entry></row><row><entry /><entry /><entry /><entry>information to Entry0PktDesc,</entry></row><row><entry /><entry /><entry /><entry>Entry0DestISIId and</entry></row><row><entry /><entry /><entry /><entry>Entry0DestISISubId.</entry></row><row><entry /><entry /><entry /><entry>1 = packet valid.</entry></row><row><entry /><entry /><entry /><entry>0 = default value.</entry></row><row><entry>Entry0PktDesc</entry><entry>3:1</entry><entry>None</entry><entry>ISI Tx buffer entry #0 packet</entry></row><row><entry /><entry /><entry /><entry>descriptor.</entry></row><row><entry /><entry /><entry /><entry>PktDesc field as per Table for</entry></row><row><entry /><entry /><entry /><entry>the packet entry #0 in the</entry></row><row><entry /><entry /><entry /><entry>ISITxBuff. Only valid when</entry></row><row><entry /><entry /><entry /><entry>Entry0PktValid = 1.</entry></row><row><entry>Entry0DestISIId</entry><entry>7:4</entry><entry>None</entry><entry>ISI Tx buffer entry #0</entry></row><row><entry /><entry /><entry /><entry>destination ISI ID.</entry></row><row><entry /><entry /><entry /><entry>Denotes the ISIId of the</entry></row><row><entry /><entry /><entry /><entry>target SoPEC as per Table .</entry></row><row><entry /><entry /><entry /><entry>Only valid when</entry></row><row><entry /><entry /><entry /><entry>Entry0PktValid = 1.</entry></row><row><entry>Entry0DestISISubId</entry><entry>8</entry><entry>None</entry><entry>ISI Tx buffer entry #0</entry></row><row><entry /><entry /><entry /><entry>destination ISI sub ID.</entry></row><row><entry /><entry /><entry /><entry>Indicates which DMAChannel on</entry></row><row><entry /><entry /><entry /><entry>the target SoPEC that packet</entry></row><row><entry /><entry /><entry /><entry>entry #0 in the ISITxBuff is</entry></row><row><entry /><entry /><entry /><entry>destined for. Only valid when</entry></row><row><entry /><entry /><entry /><entry>Entry0PktValid = 1.</entry></row><row><entry /><entry /><entry /><entry>1 = DMAChannel1</entry></row><row><entry /><entry /><entry /><entry>0 = DMAChannel0</entry></row><row><entry>Entry1PktValid</entry><entry>9</entry><entry>None</entry><entry>As per Entry0PktValid.</entry></row><row><entry>Entry1PktDesc</entry><entry>12:10</entry><entry>None</entry><entry>As per Entry0PktDesc.</entry></row><row><entry>Entry1DestISIId</entry><entry>16:13</entry><entry>None</entry><entry>As per Entry0DestISIId.</entry></row><row><entry>Entry1DestISISubId</entry><entry>17</entry><entry>None</entry><entry>As per Entry0DestISISubId.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.35 ISIRxBuffStatus
1588The ISIRxBuffStatus register contains status bits that are related to the ISI Rx buffer. This is a secondary status register and will not cause any interrupts to the CPU.
1589<tables id="TABLE-US-00081" num="00081"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 73</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>ISIRxBuffStatus register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="35pt" align="left" /><colspec colname="4" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Write</entry><entry /></row><row><entry>Field Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="35pt" align="left" /><colspec colname="4" colwidth="91pt" align="left" /><tbody valign="top"><row><entry>Entry0PktValid</entry><entry>0</entry><entry>None</entry><entry>ISI Rx buffer entry #0</entry></row><row><entry /><entry /><entry /><entry>packet valid flag.</entry></row><row><entry /><entry /><entry /><entry>This flag will be set by the</entry></row><row><entry /><entry /><entry /><entry>ISI when a valid ISI packet</entry></row><row><entry /><entry /><entry /><entry>is received and written to</entry></row><row><entry /><entry /><entry /><entry>entry #0 of the ISIRxBuff.</entry></row><row><entry /><entry /><entry /><entry>A Rx packet is considered</entry></row><row><entry /><entry /><entry /><entry>valid when it is 32 bytes</entry></row><row><entry /><entry /><entry /><entry>in size and no framing or</entry></row><row><entry /><entry /><entry /><entry>CRC errors were detected.</entry></row><row><entry /><entry /><entry /><entry>1 = valid packet</entry></row><row><entry /><entry /><entry /><entry>0 = default value</entry></row><row><entry>Entry0PktDesc</entry><entry>3:1</entry><entry>None</entry><entry>ISI Rx buffer entry #0</entry></row><row><entry /><entry /><entry /><entry>packet descriptor.</entry></row><row><entry /><entry /><entry /><entry>PktDesc field as per Table</entry></row><row><entry /><entry /><entry /><entry>for packet entry #0 of</entry></row><row><entry /><entry /><entry /><entry>the ISIRxBuff. Only valid</entry></row><row><entry /><entry /><entry /><entry>when Entry0PktValid = 1.</entry></row><row><entry>Entry0DestISIId</entry><entry>7:4</entry><entry>None</entry><entry>ISI Rx buffer 0 destination</entry></row><row><entry /><entry /><entry /><entry>ISI ID.</entry></row><row><entry /><entry /><entry /><entry>Denotes the ISIId of the</entry></row><row><entry /><entry /><entry /><entry>target SoPEC as per Table .</entry></row><row><entry /><entry /><entry /><entry>This should always corre-</entry></row><row><entry /><entry /><entry /><entry>spond to the local SoPEC</entry></row><row><entry /><entry /><entry /><entry>ISIId. Only valid when</entry></row><row><entry /><entry /><entry /><entry>Entry0PktValid = 1.</entry></row><row><entry>Entry0DestISISubId</entry><entry>8</entry><entry>None</entry><entry>ISI Rx buffer 0 destination</entry></row><row><entry /><entry /><entry /><entry>ISI sub ID.</entry></row><row><entry /><entry /><entry /><entry>Indicates which DMAChannel</entry></row><row><entry /><entry /><entry /><entry>on the target SoPEC that</entry></row><row><entry /><entry /><entry /><entry>entry #0 of the ISIRxBuff</entry></row><row><entry /><entry /><entry /><entry>is destined for. Only valid</entry></row><row><entry /><entry /><entry /><entry>when Entry0PktValid = 1.</entry></row><row><entry /><entry /><entry /><entry>1 = DMAChannel1</entry></row><row><entry /><entry /><entry /><entry>0 = DMAChannel0</entry></row><row><entry>Entry1PktValid</entry><entry>9</entry><entry>None</entry><entry>As per Entry0PktValid.</entry></row><row><entry>Entry1PktDesc</entry><entry>12:10</entry><entry>None</entry><entry>As per Entry0PktDesc.</entry></row><row><entry>Entry1DestISIId</entry><entry>16:13</entry><entry>None</entry><entry>As per Entry0DestISIId.</entry></row><row><entry>Entry1DestISISubId</entry><entry>17</entry><entry>None</entry><entry>As per Entry0DestISISubId.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.36 ISIMask Register
1590An interrupt will be generated in an edge sensitive manner i.e. the ISI will generate an isi_icu_irq pulse each time a status bit goes high and the corresponding bit of the ISIMask register is enabled.
1591<tables id="TABLE-US-00082" num="00082"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 74</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>ISIMask register</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Write</entry><entry /></row><row><entry>Field Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>TxErrorIntEn</entry><entry>0</entry><entry>Full</entry><entry>TxErrorSticky status</entry></row><row><entry /><entry /><entry /><entry>interrupt enable.</entry></row><row><entry /><entry /><entry /><entry>1 = enable.</entry></row><row><entry /><entry /><entry /><entry>0 = disable.</entry></row><row><entry>RxFrameErrorIntEn</entry><entry>1</entry><entry>Full</entry><entry>RxFrameErrorSticky status</entry></row><row><entry /><entry /><entry /><entry>interrupt enable.</entry></row><row><entry /><entry /><entry /><entry>1 = enable.</entry></row><row><entry /><entry /><entry /><entry>0 = disable.</entry></row><row><entry>RxCRCErrorIntEn</entry><entry>2</entry><entry>Full</entry><entry>RxCRCErrorSticky status</entry></row><row><entry /><entry /><entry /><entry>interrupt enable.</entry></row><row><entry /><entry /><entry /><entry>1 = enable.</entry></row><row><entry /><entry /><entry /><entry>0 = disable.</entry></row><row><entry>RxBuffOverFlowIntEn</entry><entry>3</entry><entry>Full</entry><entry>RxBuffOverFlowSticky status</entry></row><row><entry /><entry /><entry /><entry>interrupt enable.</entry></row><row><entry /><entry /><entry /><entry>1 = enable.</entry></row><row><entry /><entry /><entry /><entry>0 = disable.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.37 ISISubIdNSeq
1592This register description applies to ISISubId0Seq and ISISubId0Seq.
1593<tables id="TABLE-US-00083" num="00083"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 75</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>ISISubIdNSeq register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="28pt" align="center" /><colspec colname="3" colwidth="35pt" align="left" /><colspec colname="4" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Write</entry><entry /></row><row><entry>Field Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>ISISubIdNSeq</entry><entry>0</entry><entry>Full</entry><entry>ISI sub ID channel N</entry></row><row><entry /><entry /><entry /><entry>sequence bit. This bit may be</entry></row><row><entry /><entry /><entry /><entry>initialised by the CPU but is</entry></row><row><entry /><entry /><entry /><entry>updated by the ISI each</entry></row><row><entry /><entry /><entry /><entry>time an error-free long</entry></row><row><entry /><entry /><entry /><entry>packet is recieved.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.38 ISISubIdSeqMask
1594<tables id="TABLE-US-00084" num="00084"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 76</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>ISISubIdSeqMask register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="35pt" align="left" /><colspec colname="4" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Write</entry><entry /></row><row><entry>Field Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>ISISubIdSeq0Mask</entry><entry>0</entry><entry>Full</entry><entry>ISI sub ID channel 0 sequence</entry></row><row><entry /><entry /><entry /><entry>bit mask.</entry></row><row><entry /><entry /><entry /><entry>Setting this bit ensures that</entry></row><row><entry /><entry /><entry /><entry>the sequence bit will be</entry></row><row><entry /><entry /><entry /><entry>ignored for incoming packets</entry></row><row><entry /><entry /><entry /><entry>for the ISISubId.</entry></row><row><entry /><entry /><entry /><entry>1 = ignore sequence bit.</entry></row><row><entry /><entry /><entry /><entry>0 = default state.</entry></row><row><entry>ISISubIdSeq1Mask</entry><entry>1</entry><entry>Full</entry><entry>As per ISISubIdSeq0Mask.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.39 ISINumPins
1595<tables id="TABLE-US-00085" num="00085"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 77</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>ISINumPins register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="28pt" align="center" /><colspec colname="3" colwidth="35pt" align="left" /><colspec colname="4" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Write</entry><entry /></row><row><entry>Field Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>ISINumPins</entry><entry>0</entry><entry>Full</entry><entry>Select number of active ISI pins.</entry></row><row><entry /><entry /><entry /><entry>1 = 4 pins</entry></row><row><entry /><entry /><entry /><entry>0 = 2 pins</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.40 ISITurnAround
1596The ISI bus turnaround time will reset to its maximum value of 0xF to provide a safer starting mode for the ISI bus. This value should be set to a value that is suitable for the physical implementation of the ISI bus, i.e. the lowest turn around time that the physical implementation will allow without significant degradation of signal integrity.
1597<tables id="TABLE-US-00086" num="00086"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 78</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>ISITurnAround register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="42pt" align="center" /><colspec colname="3" colwidth="35pt" align="left" /><colspec colname="4" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Write</entry><entry /></row><row><entry>Field Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>ISITurnAround</entry><entry>3:0</entry><entry>Full</entry><entry>ISI bus turn around time in</entry></row><row><entry /><entry /><entry /><entry>ISI clock cycles (32 MHz).</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.41 ISIShortReplyWin
1598The ISI short packet reply window time will reset to its maximum value of 0x1F to provide a safer starting mode for the ISI bus. This value should be set to a value that will allow for expected frequency of bit stuffing and receiver response timing.
1599<tables id="TABLE-US-00087" num="00087"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 79</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>ISIShortReplyWin register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="35pt" align="left" /><colspec colname="4" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Write</entry><entry /></row><row><entry>Field Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>ISIShortReplyWin</entry><entry>4:0</entry><entry>Full</entry><entry>ISI long packet reply window</entry></row><row><entry /><entry /><entry /><entry>in ISI clock cycles (32 MHz).</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.42 ISILongReplyWin
1600The ISI long packet reply window time will reset to its maximum value of 0x1FF to provide a safer starting mode for the ISI bus. This value should be set to a value that will allow for expected frequency of bit stuffing and receiver response timing.
1601<tables id="TABLE-US-00088" num="00088"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 80</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>ISILongReplyWin register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="35pt" align="left" /><colspec colname="4" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Write</entry><entry /></row><row><entry>Field Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>ISILongReplyWin</entry><entry>8:0</entry><entry>Full</entry><entry>ISI long packet reply window</entry></row><row><entry /><entry /><entry /><entry>in ISI clock cycles (32 MHz).</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.2.43 ISIDebug
1602This register is intended for debug purposes only. Contains non-sticky versions of all interrupt capable status bits, which are referred to as dynamic in the table.
1603<tables id="TABLE-US-00089" num="00089"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 81</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>ISIDebug register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="42pt" align="center" /><colspec colname="3" colwidth="35pt" align="left" /><colspec colname="4" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Write</entry><entry /></row><row><entry>Field Name</entry><entry>Bit(s)</entry><entry>access</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>TxError</entry><entry>0</entry><entry>None</entry><entry>Dynamic version of</entry></row><row><entry /><entry /><entry /><entry>TxErrorSticky.</entry></row><row><entry>RxFrameError</entry><entry>1</entry><entry>None</entry><entry>Dynamic version of</entry></row><row><entry /><entry /><entry /><entry>RxFrameErrorSticky.</entry></row><row><entry>RxCRCError</entry><entry>2</entry><entry>None</entry><entry>Dynamic version of</entry></row><row><entry /><entry /><entry /><entry>RxCRCErrorSticky.</entry></row><row><entry>RxBuffOverFlow</entry><entry>3</entry><entry>None</entry><entry>Dynamic version of</entry></row><row><entry /><entry /><entry /><entry>RxBuffOverFlowSticky.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.5.5.3 CPU Bus Interface <br /> 12.5.5.4 Control Core Logic <br /> 12.5.5.5 DIU Bus Interface <br /> 12.6 DMA Regs
1604All of the circular buffer registers are 256-bit word aligned as required by the DIU. The DMAnBottomAdr and DMAnTopAdr registers are inclusive i.e. the addresses contained in those registers form part of the circular buffer. The DMAnCurrWPtr always points to the next location the DMA manager will write to so interrupts are generated whenever the DMA manager reaches the address in either the DMAnIntAdr or DMAnMaxAdr registers rather than when it actually writes to these locations. It therefore can not write to the location in the DMAnMaxAdr register.
0000SCB Map Regs
1605The SCB map is configured by mapping a USB endpoint on to a data sink. This is performed on a endpoint basis i.e. each endpoint has a configuration register to allow its data sink be selected. Mapping an endpoint on to a data sink does not initiate any data flow—each endpoint/data sink needs to be enabled by writing to the appropriate configuration registers for the USBD, ISI and DMA manager.
000013. General Purpose IO (GPIO)
000013.1 Overview
1606The General Purpose IO block (GPIO) is responsible for control and interfacing of GPIO pins to the rest of the SoPEC system. It provides easily programmable control logic to simplify control of GPIO functions. In all there are 32 GPIO pins of which any pin can assume any output or input function. Possible output functions are <ul id="ul0158" list-style="none"><li id="ul0158-0001" num="0000"><ul id="ul0159" list-style="none"><li id="ul0159-0001" num="1607">4 Stepper Motor control Outputs</li><li id="ul0159-0002" num="1608">12 Brushless DC Motor Control Output (total of 2 different controllers each with 6 outputs)</li><li id="ul0159-0003" num="1609">4 General purpose high drive pulsed outputs capable of driving LEDs.</li><li id="ul0159-0004" num="1610">4 Open drain IOs used for LSS interfaces</li><li id="ul0159-0005" num="1611">4 Normal drive low impedance IOs used for the ISI interface in Multi-SoPEC mode</li></ul></li></ul>
1612Each of the pins can be configured in either input or output mode, each pin is independently controlled. A programmable de-glitching circuit exists for a fixed number of input pins. Each input is a schmidt trigger to increase noise immunity should the input be used without the de-glitch circuit. The mapping of the above functions and their alternate use in a slave SoPEC to GPIO pins is shown in Table 82 below.
1613<tables id="TABLE-US-00090" num="00090"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 82</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>GPIO pin type</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="70pt" align="left" /><tbody valign="top"><row><entry /><entry>GPIO pin(s)</entry><entry>Pin IO Type</entry><entry>Default Function</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row><row><entry /><entry>gpio[3:0]</entry><entry>Normal drive, low</entry><entry>Pins 1 and 0</entry></row><row><entry /><entry /><entry>impedance IO (35</entry><entry>in ISI Mode,</entry></row><row><entry /><entry /><entry>Ohm), Integrated</entry><entry>pins 2 and 3</entry></row><row><entry /><entry /><entry>pull-up resistor</entry><entry>in input mode</entry></row><row><entry /><entry>gpio[7:4]</entry><entry>High drive, normal</entry><entry>Input Mode</entry></row><row><entry /><entry /><entry>impedance IO (65</entry></row><row><entry /><entry /><entry>Ohm), intended for</entry></row><row><entry /><entry /><entry>LED drivers</entry></row><row><entry /><entry>gpio[31:8]</entry><entry>Normal drive,</entry><entry>Input Mode</entry></row><row><entry /><entry /><entry>normal impedance</entry></row><row><entry /><entry /><entry>IO (65 Ohm), no</entry></row><row><entry /><entry /><entry>pull-up</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 13.2 Stepper Motor Control
1614The motor control pins can be directly controlled by the CPU or the motor control logic can be used to generate the phase pulses for the stepper motors. The controller consists of two central counters from which the control pins are derived. The central counters have several registers (see Table) used to configure the cycle period, the phase, the duty cycle, and counter granularity.
1615There are two motor master counters (0 and 1) with identical features. The period of the master counters are defined by the MotorMasterClkPeriod[1:0] and MotorMasterClkSrc registers i.e. both master counters are derived from the same MotorMasterClkSrc. The MotorMasterClkSrc defines the timing pulses used by the master counters to determine the timing period. The MotorMasterClkSrc can select clock sources of 1 μs, 100 μs, 10 ms and pclk timing pulses.
1616The MotorMasterClkPeriod[1:0] registers are set to the number of timing pulses required before the timing period re-starts. Each master counter is set to the relevant MotorMasterClkPeriod value and counts down a unit each time a timing pulse is received.
1617The master counters reset to MotorMasterClkPeriod value and count down. Once the value hits zero a new value is reloaded from the MotorMasterClkPeriod[1:0] registers. This ensures that no master clock glitch is generated when changing the clock period.
1618Each of the IO pins for the motor controller are derived from the master counters. Each pin has independent configuration registers. The MotorMasterClkSelect[3:0] registers define which of the two master counters to use as the source for each motor control pin. The master counter value is compared with the configured MotorCtrlLow and MotorCtrlHigh registers (bit fields of the MotorCtrlConfig register). If the count is equal to MotorCtrlHigh value the motor control is set to 1, if the count is equal to MotorCtrlLow value the motor control pin is set to 0.
1619This allows the phase and duty cycle of the motor control pins to be varied at pclk granularity. The motor control generators keep a working copy of the MotorCtrlLow, MotorCtrlHigh values and update the configured value to the working copy when it is safe to do so. This allows the phase or duty cycle of a motor control pin to be safely adjusted by the CPU without causing a glitch on the output pin.
1620Note that when reprogramming the MotorCtrlLow, MotorCtrlHigh registers to reorder the sequence of the transition points (e.g changing from low point less than high point to low point greater than high point and vice versa) care must still taken to avoid introducing glitching on the output pin.
000013.3 LED Control
1621LED lifetime and brightness can be improved and power consumption reduced by driving the LEDs with a pulsed rather than a DC signal. The source clock for each of the LED pins is a 7.8 kHz (128 μs period) clock generated from the 1 μs clock pulse from the Timers block. The LEDDutySelect registers are used to create a signal with the desired waveform. Unpulsed operation of the LED pins can be achieved by using CPU IO direct control, or setting LEDDutySelect to 0. By default the LED pins are controlled by the LED control logic.
000013.4 LSS Interface via GPIO
1622In some SoPEC system configurations one or more of the LSS interfaces may not be used. Unused LSS interface pins can be reused as general IO pins by configuring the IOModeSelect registers. When a mode select register for a particular GPIO pin is set to 23,22,21,20 the GPIO pin is connected to LSS control IOs 3 to 0 respectively.
000013.5 ISI Interface via GPIO
1623In Multi-SoPEC mode the SCB block (in particular the ISI sub-block) requires direct access to and from the GPIO pins. Control of the ISI interface pins is determined by the IOModeSelect registers. When a mode select register for a particular GPIO pin is set to 27,26,25,24 the GPIO pin connected to the ISI control bits <b>3</b> to <b>0</b> respectively. By default the GPIO pins <b>1</b> to <b>0</b> are directly controlled by the ISI block.
1624In single SoPEC systems the pins can be re-used by the GPIO.
000013.6 CPU GPIO Control
1625The CPU can assume direct control of any (or all) of the IO pins individually. On a per pin basis the CPU can turn on direct access to the pin by configuring the IOModeSelect register to CPU direct mode. Once set the IO pin assumes the direction specified by the CpuIODirection register. When in output mode the value in register CpuIOOut will be directly reflected to the output driver. When in input mode the status of the input pin can be read by reading CpuIOIn register. When writing to the CpuIOOut register the value being written is XORed with the current value in CpuIOOut. The CPU can also read the status of the 10 selected de-glitched inputs by reading the CpuIOInDeGlitch register.
000013.7 Programmable De-glitching Logic
1626Each IO pin can be filtered through a de-glitching logic circuit, the pin that the de-glitching logic is connected to is configured by the InputPinSelect registers. There are IO de-glitching circuits, so a maximum of IO input pin can be de-glitched at anytime.
1627The de-glitch circuit can be configured to sample the IO pin for a predetermined time before concluding that a pin is in a particular state. The exact sampling length is configurable, but each de-glitch circuit must use one of two possible configured values (selected by DeGlitchSelect). The sampling length is the same for both high and low states. The DeGlitchCount is programmed to the number of system time units that a state must be valid for before the state is passed on. The time units are selected by DeGlitchClkSel and can be one of 1 μs, 100 μs, 10 ms and pclk pulses.
1628For example if DeGlitchCount is set to 10 and DeGlitchClkSel set to 3, then the selected input pin must consistently retain its value for 10 system clock cycles (pclk) before the input state will be propagated from CpuIOIn to CpuIOInDeglitch.
000013.8 Interrupt Generation
1629Any of the selected input pins (selected by InputPinSelect) can generate an interrupt from the raw or deglitched version of the input pin. There are IO possible interrupt sources from the GPIO to the interrupt controller, one interrupt per input pin. The InterruptSrcSelect register determines whether the raw input or the deglitched version is used as the interrupt source.
1630The interrupt type, masking and priority can be programmed in the interrupt controller.
000013.9 Frequency Analyser
1631The frequency analyser measures the duration between successive positive edges on a selected input pin (selected by InputPinSelect) and reports the last period measured (FreqAnaLastPeriod) and a running average period (FreqAnaAverage).
1632The running average is updated each time a new positive edge is detected and is calculated by FreqAnaAverage=(FreqAnaAverage/8)*7+FreqAnaLastPeriod/8.
1633The analyser can be used with any selected input pin (or its deglitched form), but only one input at a time can be selected. The input is selected by the FreqAnaPinSelect (range of 0 to 9) and its deglitched form can be selected by FreqAnaPinFormSelect.
000013.10 Brushless DC (BLDC) Motor Controllers
1634The GPIO contains 2 brushless DC (BLDC) motor controllers. Each controller consists of 3 hall inputs, a direction input, and six possible outputs. The outputs are derived from the input state and a pulse width modulated (PWM) input from the Stepper Motor controller, and is given by the truth table in Table 83.
1635<tables id="TABLE-US-00091" num="00091"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 83</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Truth Table for BLDC Motor Controllers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="10"><colspec colname="1" colwidth="42pt" align="center" /><colspec colname="2" colwidth="14pt" align="center" /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="14pt" align="center" /><colspec colname="5" colwidth="28pt" align="center" /><colspec colname="6" colwidth="14pt" align="center" /><colspec colname="7" colwidth="28pt" align="center" /><colspec colname="8" colwidth="14pt" align="center" /><colspec colname="9" colwidth="28pt" align="center" /><colspec colname="10" colwidth="14pt" align="center" /><tbody valign="top"><row><entry>direction</entry><entry>hc</entry><entry>hb</entry><entry>ha</entry><entry>q6</entry><entry>q5</entry><entry>q4</entry><entry>q3</entry><entry>q2</entry><entry>q1</entry></row><row><entry namest="1" nameend="10" align="center" rowsep="1" /></row><row><entry>0</entry><entry>0</entry><entry>0</entry><entry>1</entry><entry>0</entry><entry>0</entry><entry>0</entry><entry>1</entry><entry>PWM</entry><entry>0</entry></row><row><entry>0</entry><entry>0</entry><entry>1</entry><entry>1</entry><entry>PWM</entry><entry>0</entry><entry>0</entry><entry>1</entry><entry>0</entry><entry>0</entry></row><row><entry>0</entry><entry>0</entry><entry>1</entry><entry>0</entry><entry>PWM</entry><entry>0</entry><entry>0</entry><entry>0</entry><entry>0</entry><entry>1</entry></row><row><entry>0</entry><entry>1</entry><entry>1</entry><entry>0</entry><entry>0</entry><entry>0</entry><entry>PWM</entry><entry>0</entry><entry>0</entry><entry>1</entry></row><row><entry>0</entry><entry>1</entry><entry>0</entry><entry>0</entry><entry>0</entry><entry>1</entry><entry>PWM</entry><entry>0</entry><entry>0</entry><entry>0</entry></row><row><entry>0</entry><entry>1</entry><entry>0</entry><entry>1</entry><entry>0</entry><entry>1</entry><entry>0</entry><entry>0</entry><entry>PWM</entry><entry>0</entry></row><row><entry>0</entry><entry>0</entry><entry>0</entry><entry>0</entry><entry>0</entry><entry>0</entry><entry>0</entry><entry>0</entry><entry>0</entry><entry>0</entry></row><row><entry>0</entry><entry>1</entry><entry>1</entry><entry>1</entry><entry>0</entry><entry>0</entry><entry>0</entry><entry>0</entry><entry>0</entry><entry>0</entry></row><row><entry>1</entry><entry>0</entry><entry>0</entry><entry>1</entry><entry>0</entry><entry>0</entry><entry>PWM</entry><entry>0</entry><entry>0</entry><entry>1</entry></row><row><entry>1</entry><entry>0</entry><entry>1</entry><entry>1</entry><entry>PWM</entry><entry>0</entry><entry>0</entry><entry>0</entry><entry>0</entry><entry>1</entry></row><row><entry>1</entry><entry>0</entry><entry>1</entry><entry>0</entry><entry>PWM</entry><entry>0</entry><entry>0</entry><entry>1</entry><entry>0</entry><entry>0</entry></row><row><entry>1</entry><entry>1</entry><entry>1</entry><entry>0</entry><entry>0</entry><entry>0</entry><entry>0</entry><entry>1</entry><entry>PWM</entry><entry>0</entry></row><row><entry>1</entry><entry>1</entry><entry>0</entry><entry>0</entry><entry>0</entry><entry>1</entry><entry>0</entry><entry>0</entry><entry>PWM</entry><entry>0</entry></row><row><entry>1</entry><entry>1</entry><entry>0</entry><entry>1</entry><entry>0</entry><entry>1</entry><entry>PWM</entry><entry>0</entry><entry>0</entry><entry>0</entry></row><row><entry>1</entry><entry>0</entry><entry>0</entry><entry>0</entry><entry>0</entry><entry>0</entry><entry>0</entry><entry>0</entry><entry>0</entry><entry>0</entry></row><row><entry>1</entry><entry>1</entry><entry>1</entry><entry>1</entry><entry>0</entry><entry>0</entry><entry>0</entry><entry>0</entry><entry>0</entry><entry>0</entry></row><row><entry namest="1" nameend="10" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
1636All inputs to a BLDC controller must be de-glitched. Each controller has its inputs hardwired to de-glitch circuits. Controller <b>1</b> hall inputs are de-glitched by circuits <b>2</b> to <b>0</b>, and its direction input is de-glitched by circuit <b>3</b>. Controller <b>2</b> inputs are de-glitched by circuits <b>6</b> to <b>4</b> for hall inputs and <b>7</b> for direction input.
1637Each controller also requires a PWM input. The stepper motor controller outputs are reused, output <b>0</b> is connected to BLDC controller <b>1</b>, and output <b>1</b> to BLDC controller <b>2</b>.
1638The controllers have two modes of operation, internal and external direction control (configured by BLDCMode). If a controller is in external direction mode the direction input is taken from a de-glitched circuit, if it is in internal direction mode the direction input is configured by the BLDCDirection register.
1639The BLDC controller outputs are connected to the GPIO output pins by configuring the IOModeSelect register for each pin. e.g Setting the mode register to 8 will connect q1 Controller 1 to drive the pin.
000013.11 Implementation
000013.11.1 Definitions of I/O
1640<tables id="TABLE-US-00092" num="00092"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="287pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 84</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>I/O definition</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="161pt" align="left" /><tbody valign="top"><row><entry>Port name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="287pt" align="left" /><tbody valign="top"><row><entry>Clocks and Resets</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="161pt" align="left" /><tbody valign="top"><row><entry>Pclk</entry><entry>1</entry><entry>In</entry><entry>System Clock</entry></row><row><entry>prst_n</entry><entry>1</entry><entry>In</entry><entry>System reset, synchronous active low</entry></row><row><entry>tim_pulse[2:0]</entry><entry>3</entry><entry>In</entry><entry>Timers block generated timing pulses.</entry></row><row><entry /><entry /><entry /><entry>0 - 1 μs pulse</entry></row><row><entry /><entry /><entry /><entry>1 - 100 μs pulse</entry></row><row><entry /><entry /><entry /><entry>2 - 10 ms pulse</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="287pt" align="left" /><tbody valign="top"><row><entry>CPU Interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="161pt" align="left" /><tbody valign="top"><row><entry>cpu_adr[8:2]</entry><entry>8</entry><entry>In</entry><entry>CPU address bus. Only 7 bits are required</entry></row><row><entry /><entry /><entry /><entry>to decode the address space for this block</entry></row><row><entry>cpu_dataout[31:0]</entry><entry>32</entry><entry>In</entry><entry>Shared write data bus from the CPU</entry></row><row><entry>gpio_cpu_data[31:0]</entry><entry>32</entry><entry>Out</entry><entry>Read data bus to the CPU</entry></row><row><entry>cpu_rwn</entry><entry>1</entry><entry>In</entry><entry>Common read/not-write signal from the CPU</entry></row><row><entry>cpu_gpio_sel</entry><entry>1</entry><entry>In</entry><entry>Block select from the CPU. When cpu_gpio_sel is</entry></row><row><entry /><entry /><entry /><entry>high both cpu_adr and cpu_dataout are valid</entry></row><row><entry>gpio_cpu_rdy</entry><entry>1</entry><entry>Out</entry><entry>Ready signal to the CPU. When gpio_cpu_rdy is</entry></row><row><entry /><entry /><entry /><entry>high it indicates the last cycle of the access. For a</entry></row><row><entry /><entry /><entry /><entry>write cycle this means cpu_dataout has been</entry></row><row><entry /><entry /><entry /><entry>registered by the GPIO block and for a read cycle</entry></row><row><entry /><entry /><entry /><entry>this means the data on gpio_cpu_data is valid.</entry></row><row><entry>gpio_cpu_berr</entry><entry>1</entry><entry>Out</entry><entry>Bus error signal to the CPU indicating an invalid</entry></row><row><entry /><entry /><entry /><entry>access.</entry></row><row><entry>gpio_cpu_debug_valid</entry><entry>1</entry><entry>Out</entry><entry>Debug Data valid on gpio_cpu_data bus. Active high</entry></row><row><entry>cpu_acode[1:0]</entry><entry>2</entry><entry>In</entry><entry>CPU Access Code signals. These decode as follows:</entry></row><row><entry /><entry /><entry /><entry>00 - User program access</entry></row><row><entry /><entry /><entry /><entry>01 - User data access</entry></row><row><entry /><entry /><entry /><entry>10 - Supervisor program access</entry></row><row><entry /><entry /><entry /><entry>11 - Supervisor data access</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="287pt" align="left" /><tbody valign="top"><row><entry>IO Pins</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="161pt" align="left" /><tbody valign="top"><row><entry>gpio_o[31:0]</entry><entry>32</entry><entry>Out</entry><entry>General purpose IO output to IO driver</entry></row><row><entry>gpio_i[31:0]</entry><entry>32</entry><entry>In</entry><entry>General purpose IO input from IO receiver</entry></row><row><entry>gpio_e[31:0]</entry><entry>32</entry><entry>Out</entry><entry>General purpose IO output control. Active high</entry></row><row><entry /><entry /><entry /><entry>driving</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="287pt" align="left" /><tbody valign="top"><row><entry>GPIO to LSS</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="161pt" align="left" /><tbody valign="top"><row><entry>lss_gpio_dout[1:0]</entry><entry>2</entry><entry>In</entry><entry>LSS bus data output</entry></row><row><entry /><entry /><entry /><entry>Bit 0 - LSS bus 0</entry></row><row><entry /><entry /><entry /><entry>Bit 1 - LSS bus 1</entry></row><row><entry>gpio_lss_din[1:0]</entry><entry>2</entry><entry>Out</entry><entry>LSS bus data input</entry></row><row><entry /><entry /><entry /><entry>Bit 0 - LSS bus 0</entry></row><row><entry /><entry /><entry /><entry>Bit 1 - LSS bus 1</entry></row><row><entry>lss_gpio_e[1:0]</entry><entry>2</entry><entry>In</entry><entry>LSS bus data output enable, active high</entry></row><row><entry /><entry /><entry /><entry>Bit 0 - LSS bus 0</entry></row><row><entry /><entry /><entry /><entry>Bit 1 - LSS bus 1</entry></row><row><entry>lss_gpio_clk[1:0]</entry><entry>2</entry><entry>In</entry><entry>LSS bus clock output</entry></row><row><entry /><entry /><entry /><entry>Bit 0 - LSS bus 0</entry></row><row><entry /><entry /><entry /><entry>Bit 1 - LSS bus 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="287pt" align="left" /><tbody valign="top"><row><entry>GPIO to ISI</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="161pt" align="left" /><tbody valign="top"><row><entry>gpio_isi_din3[1:0]</entry><entry>2</entry><entry>Out</entry><entry>Input data from IO receivers to ISI.</entry></row><row><entry>isi_gpio_dout[1:0]</entry><entry>2</entry><entry>In</entry><entry>Data output from ISI to IO drivers</entry></row><row><entry>isi_gpio_e[1:0]</entry><entry>2</entry><entry>In</entry><entry>GPIO ISI pins output enable (active high) from ISI</entry></row><row><entry /><entry /><entry /><entry>interface</entry></row><row><entry>usbh_gpio_power_en</entry><entry>1</entry><entry>In</entry><entry>Port Power enable from the USB host core, active</entry></row><row><entry /><entry /><entry /><entry>high</entry></row><row><entry>gpio_usbh_over_current</entry><entry>1</entry><entry>Out</entry><entry>Over current detect to the USB host core, active</entry></row><row><entry /><entry /><entry /><entry>high</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="287pt" align="left" /><tbody valign="top"><row><entry>Miscellaneous</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="161pt" align="left" /><tbody valign="top"><row><entry>gpio_icu_irq[9:0]</entry><entry>10</entry><entry>Out</entry><entry>GPIO pin interrupts</entry></row><row><entry>gpio_cpr_wakeup</entry><entry>1</entry><entry>Out</entry><entry>SoPEC wakeup to the CPR block active high.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="287pt" align="left" /><tbody valign="top"><row><entry>Debug</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="161pt" align="left" /><tbody valign="top"><row><entry>debug_data_out[31:0]</entry><entry>32</entry><entry>In</entry><entry>Output debug data to be muxed on to the GPIO pins</entry></row><row><entry>debug_cntrl[31:0]</entry><entry>32</entry><entry>In</entry><entry>Control signal for each GPIO bound debug data line</entry></row><row><entry /><entry /><entry /><entry>indicating whether or not the debug data should be</entry></row><row><entry /><entry /><entry /><entry>selected by the pin mux</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 13.11.2 Configuration Registers
1641The configuration registers in the GPIO are programmed via the CPU interface. Refer to section 11.4.3 on page 69 for a description of the protocol and timing diagrams for reading and writing registers in the GPIO. Note that since addresses in SoPEC are byte aligned and the CPU only supports 32-bit register reads and writes, the lower 2 bits of the CPU address bus are not required to decode the address space for the GPIO. When reading a register that is less than 32 bits wide zeros should be returned on the upper unused bit(s) of gpio_cpu_data. Table 85 lists the configuration registers in the GPIO block
1642<tables id="TABLE-US-00093" num="00093"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="378pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 85</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>GPIO Register Definition</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="28pt" align="center" /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="161pt" align="center" /><tbody valign="top"><row><entry>Address</entry><entry /><entry /><entry /><entry /></row><row><entry>GPIO_base+</entry><entry>Register</entry><entry>#bits</entry><entry>Reset</entry><entry>Description</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="28pt" align="center" /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="161pt" align="left" /><tbody valign="top"><row><entry>0x000–0x07C</entry><entry>IOModeSelect[31:0]</entry><entry>32 × 5</entry><entry>See</entry><entry>Specifies the mode of operation for each</entry></row><row><entry /><entry /><entry /><entry>Table for</entry><entry>GPIO pin. One 5 bit bus per pin.</entry></row><row><entry /><entry /><entry /><entry>default values</entry><entry>Possible assignment values and correspond</entry></row><row><entry /><entry /><entry /><entry /><entry>controller outputs are as follows</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="49pt" align="left" /><colspec colname="6" colwidth="112pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry /><entry /><entry>Value -</entry><entry>Controlled by</entry></row><row><entry /><entry /><entry /><entry /><entry>3 to 0 -</entry><entry>Output, LED controller 4 to 1</entry></row><row><entry /><entry /><entry /><entry /><entry>7 to 4 -</entry><entry>Output Stepper Motor control 4–1</entry></row><row><entry /><entry /><entry /><entry /><entry>13 to 8 -</entry><entry>Output BLDC 1 Motor control 6–1</entry></row><row><entry /><entry /><entry /><entry /><entry>19 to 14 -</entry><entry>Output BLDC 2 Motor control 6–1</entry></row><row><entry /><entry /><entry /><entry /><entry>23 to 20 -</entry><entry>LSS control 4–1</entry></row><row><entry /><entry /><entry /><entry /><entry>27 to 24 -</entry><entry>ISI control 4–1</entry></row><row><entry /><entry /><entry /><entry /><entry>28 -</entry><entry>CPU Direct Control</entry></row><row><entry /><entry /><entry /><entry /><entry>29 -</entry><entry>USB power enable output</entry></row><row><entry /><entry /><entry /><entry /><entry>30 -</entry><entry>Input Mode</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="28pt" align="center" /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="161pt" align="left" /><tbody valign="top"><row><entry>0x080–0xA4</entry><entry>InputPinSelect[9:0]</entry><entry>10 × 5</entry><entry>0x00</entry><entry>Specifies which pins should be selected as</entry></row><row><entry /><entry /><entry /><entry /><entry>inputs. Used to select the pin source to the</entry></row><row><entry /><entry /><entry /><entry /><entry>DeGlitch Circuits.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="378pt" align="left" /><tbody valign="top"><row><entry>CPU IO Control</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="161pt" align="left" /><tbody valign="top"><row><entry>0x0B0</entry><entry>CpuIOUserModeMask</entry><entry>32</entry><entry>0x0000_0000</entry><entry>User Mode Access Mask to CPU GPIO</entry></row><row><entry /><entry /><entry /><entry /><entry>control register. When 1 user access is</entry></row><row><entry /><entry /><entry /><entry /><entry>enabled. One bit per gpio pin. Enables</entry></row><row><entry /><entry /><entry /><entry /><entry>access to CpuIODirection, CpuIOOut and</entry></row><row><entry /><entry /><entry /><entry /><entry>CpuIOIn in user mode.</entry></row><row><entry>0x0B4</entry><entry>CpuIOSuperModeMask</entry><entry>32</entry><entry>0xFFFF_FFFF</entry><entry>Supervisor Mode Access Mask to CPU</entry></row><row><entry /><entry /><entry /><entry /><entry>GPIO control register. When 1 supervisor</entry></row><row><entry /><entry /><entry /><entry /><entry>access is enabled. One bit per gpio pin.</entry></row><row><entry /><entry /><entry /><entry /><entry>Enables access to CpuIODirection,</entry></row><row><entry /><entry /><entry /><entry /><entry>CpuIOOut and CpuIOIn in supervisor mode.</entry></row><row><entry>0x0B8</entry><entry>CpuIODirection</entry><entry>32</entry><entry>0x0000_0000</entry><entry>Indicates the direction of each IO pin, when</entry></row><row><entry /><entry /><entry /><entry /><entry>controlled by the CPU</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - Indicates Input Mode</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - Indicates Output Mode</entry></row><row><entry>0x0BC</entry><entry>CpuIOOut</entry><entry>32</entry><entry>0x0000_0000</entry><entry>Value used to drive output pin in CPU direct</entry></row><row><entry /><entry /><entry /><entry /><entry>mode.</entry></row><row><entry /><entry /><entry /><entry /><entry>bits31:0 - Value to drive on output GPIO</entry></row><row><entry /><entry /><entry /><entry /><entry>pins</entry></row><row><entry /><entry /><entry /><entry /><entry>When written to the register assumes the</entry></row><row><entry /><entry /><entry /><entry /><entry>new value XORed with the current value.</entry></row><row><entry>0x0C0</entry><entry>CpuIOIn</entry><entry>32</entry><entry>External</entry><entry>Value received on each input pin regardless</entry></row><row><entry /><entry /><entry /><entry>pin value</entry><entry>of mode. Read Only register.</entry></row><row><entry>0x0C4</entry><entry>CpuDeGlitchUserModeMask</entry><entry>10</entry><entry>0x000</entry><entry>User Mode Access Mask to</entry></row><row><entry /><entry /><entry /><entry /><entry>CpuIOInDeglitch control register. When 1</entry></row><row><entry /><entry /><entry /><entry /><entry>user access is enabled, otherwise bit reads</entry></row><row><entry /><entry /><entry /><entry /><entry>as zero.</entry></row><row><entry>0x0C8</entry><entry>CpuIOInDeglitch</entry><entry>10</entry><entry>0x000</entry><entry>Deglitched version of selected input pins.</entry></row><row><entry /><entry /><entry /><entry /><entry>The input pins are selected by the</entry></row><row><entry /><entry /><entry /><entry /><entry>InputPinSelect register.</entry></row><row><entry /><entry /><entry /><entry /><entry>Note that after reset this register will reflect</entry></row><row><entry /><entry /><entry /><entry /><entry>the external pin values 256 pclk cycles after</entry></row><row><entry /><entry /><entry /><entry /><entry>they have stabilized. Read Only register.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="378pt" align="left" /><tbody valign="top"><row><entry>Deglitch control</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="28pt" align="center" /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="161pt" align="left" /><tbody valign="top"><row><entry>0x0D0–0x0D4</entry><entry>DeGlitchCount[1:0]</entry><entry>2 × 8</entry><entry>0xFF</entry><entry>Deglitch circuit sample count in</entry></row><row><entry /><entry /><entry /><entry /><entry>DeGlitchClkSrc selected units.</entry></row><row><entry>0x0D8–0x0DC</entry><entry>DeGlitchClkSrc[1:0]</entry><entry>2 × 2</entry><entry>0x3</entry><entry>Specifies the unit use of the GPIO deglitch</entry></row><row><entry /><entry /><entry /><entry /><entry>circuits:</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - 1 μs pulse</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - 100 μs pulse</entry></row><row><entry /><entry /><entry /><entry /><entry>2 - 10 ms pulse</entry></row><row><entry /><entry /><entry /><entry /><entry>3 - pclk</entry></row><row><entry>0x0E0</entry><entry>DeGlitchSelect</entry><entry>10</entry><entry>0x000</entry><entry>Specifies which deglitch count</entry></row><row><entry /><entry /><entry /><entry /><entry>(DeGlitchCount) and unit select</entry></row><row><entry /><entry /><entry /><entry /><entry>(DeGlitchClkSrc) should be used with each</entry></row><row><entry /><entry /><entry /><entry /><entry>de-glitch circuit</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - Specifies DeGlitchCount[0] and</entry></row><row><entry /><entry /><entry /><entry /><entry>DeGlitchClkSrc[0]</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - Specifies DeGlitchCount[1] and</entry></row><row><entry /><entry /><entry /><entry /><entry>DeGlitchClkSrc[1]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="378pt" align="left" /><tbody valign="top"><row><entry>Motor Control</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="161pt" align="left" /><tbody valign="top"><row><entry>0x0E4</entry><entry>MotorCtrlUserModeEnable</entry><entry>1</entry><entry>0x0</entry><entry>User Mode Access enable to Motor control</entry></row><row><entry /><entry /><entry /><entry /><entry>configuration registers. When 1 user access</entry></row><row><entry /><entry /><entry /><entry /><entry>is enabled.</entry></row><row><entry /><entry /><entry /><entry /><entry>Enables user access to</entry></row><row><entry /><entry /><entry /><entry /><entry>MotorMasterClkPeriod, MotorMasterClkSrc,</entry></row><row><entry /><entry /><entry /><entry /><entry>MotorDutySelect, MotorPhaseSelect,</entry></row><row><entry /><entry /><entry /><entry /><entry>MotorMasterClockEnable, MotorMasterClkSelect,</entry></row><row><entry /><entry /><entry /><entry /><entry>BLDCMode and BLDCDirection registers</entry></row><row><entry>0x0E8–0x0EC</entry><entry>MotorMasterClkPeriod[1:0]</entry><entry>2 × 16</entry><entry>0x0000</entry><entry>Specifies the motor controller master clock</entry></row><row><entry /><entry /><entry /><entry /><entry>periods in MotorMasterClkSrc selected units</entry></row><row><entry>0x0F0</entry><entry>MotorMasterClkSrc</entry><entry>2</entry><entry>0x0</entry><entry>Specifies the unit use by the motor controller</entry></row><row><entry /><entry /><entry /><entry /><entry>master clock generator:</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - 1 μs pulse</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - 100 μs pulse</entry></row><row><entry /><entry /><entry /><entry /><entry>2 - 10 ms pulse</entry></row><row><entry /><entry /><entry /><entry /><entry>3 - pclk</entry></row><row><entry>0x0F4–0x100</entry><entry>MotorCtrlConfig[3:0]</entry><entry>4 × 32</entry><entry>0x0000_0000</entry><entry>Specifies the transition points in the clock</entry></row><row><entry /><entry /><entry /><entry /><entry>period for each motor control pin. One</entry></row><row><entry /><entry /><entry /><entry /><entry>register per pin</entry></row><row><entry /><entry /><entry /><entry /><entry>bits 15:0 - MotorCtrlLow, high to low</entry></row><row><entry /><entry /><entry /><entry /><entry>transition point</entry></row><row><entry /><entry /><entry /><entry /><entry>bits 31:16 - MotorCtrlHigh, low to high</entry></row><row><entry /><entry /><entry /><entry /><entry>transition point</entry></row><row><entry>0x104</entry><entry>MotorMasterClkSelect</entry><entry>4</entry><entry>0x0</entry><entry>Specifies which motor master clock should</entry></row><row><entry /><entry /><entry /><entry /><entry>be used as a pin generator source</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - Clock derived from MotorMasterClockPeriod[0]</entry></row><row><entry /><entry /><entry /><entry /><entry>1 -Clock derived from MotorMasterClockPeriod[1]</entry></row><row><entry>0x108</entry><entry>MotorMasterClockEnable</entry><entry>2</entry><entry>0x0</entry><entry>Enable the motor master clock counter.</entry></row><row><entry /><entry /><entry /><entry /><entry>When 1 count is enabled</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 0 - Enable motor master clock 0</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 1 - Enable motor master clock 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="378pt" align="left" /><tbody valign="top"><row><entry>BLDC Motor Controllers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="161pt" align="left" /><tbody valign="top"><row><entry>0x10C</entry><entry>BLDCMode</entry><entry>2</entry><entry>0x0</entry><entry>Specifies the Mode of operation of the BLDC</entry></row><row><entry /><entry /><entry /><entry /><entry>Controller. One bit per Controller.</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - External direction control</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - Internal direction control</entry></row><row><entry>0x110</entry><entry>BLDCDirection</entry><entry>2</entry><entry>0x0</entry><entry>Specifies the direction input of the BLDC</entry></row><row><entry /><entry /><entry /><entry /><entry>controller. Only used when BLDC controller</entry></row><row><entry /><entry /><entry /><entry /><entry>is an internal direction control mode. One bit</entry></row><row><entry /><entry /><entry /><entry /><entry>per controller.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="378pt" align="left" /><tbody valign="top"><row><entry>LED control</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="161pt" align="left" /><tbody valign="top"><row><entry>0x114</entry><entry>LEDCtrlUserModeEnable</entry><entry>4</entry><entry>0x0</entry><entry>User Mode Access enable to LED control</entry></row><row><entry /><entry /><entry /><entry /><entry>configuration registers. When 1 user access</entry></row><row><entry /><entry /><entry /><entry /><entry>is enabled. One bit per LEDDutySelect select register.</entry></row><row><entry>0x118–0x124</entry><entry>LEDDutySelect3:0]</entry><entry>4 × 3</entry><entry>0x0</entry><entry>Specifies the duty cycle for each LED</entry></row><row><entry /><entry /><entry /><entry /><entry>control output. See FIG. 54 for encoding</entry></row><row><entry /><entry /><entry /><entry /><entry>details. The LEDDutySelect[3:0] registers</entry></row><row><entry /><entry /><entry /><entry /><entry>determine the duty cycle of the LED</entry></row><row><entry /><entry /><entry /><entry /><entry>controller outputs .</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="378pt" align="left" /><tbody valign="top"><row><entry>Frequency Analyser</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="161pt" align="left" /><tbody valign="top"><row><entry>0x130</entry><entry>FreqAnaUserModeEnable</entry><entry>1</entry><entry>0x0</entry><entry>User Mode Access enable to Frequency</entry></row><row><entry /><entry /><entry /><entry /><entry>analyser configuration registers. When 1</entry></row><row><entry /><entry /><entry /><entry /><entry>user access is enabled. Controls access to</entry></row><row><entry /><entry /><entry /><entry /><entry>FreqAnaPinFormSelect,</entry></row><row><entry /><entry /><entry /><entry /><entry>FreqAnaLastPeriod, FreqAnaAverage and</entry></row><row><entry /><entry /><entry /><entry /><entry>FreqAnaCountInc.</entry></row><row><entry>0x134</entry><entry>FreqAnaPinSelect</entry><entry>4</entry><entry>0x00</entry><entry>Selects which selected input should be used</entry></row><row><entry /><entry /><entry /><entry /><entry>for the frequency analyses.</entry></row><row><entry>0x138</entry><entry>FreqAnaPinFormSelect</entry><entry>1</entry><entry>0x0</entry><entry>Selects if the frequency analyser should use</entry></row><row><entry /><entry /><entry /><entry /><entry>the raw input or the deglitched form.</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - Deglitched form of input pin</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - Raw form of input pin</entry></row><row><entry>0x13C</entry><entry>FreqAnaLastPeriod</entry><entry>16</entry><entry>0x0000</entry><entry>Frequency Analyser last period of selected</entry></row><row><entry /><entry /><entry /><entry /><entry>input pin.</entry></row><row><entry>0x140</entry><entry>FreqAnaAverage</entry><entry>16</entry><entry>0x0000</entry><entry>Frequency Analyser average period of</entry></row><row><entry /><entry /><entry /><entry /><entry>selected input pin.</entry></row><row><entry>0x144</entry><entry>FreqAnaCountInc</entry><entry>20</entry><entry>0x0000 0</entry><entry>Frequency Analyser counter increment</entry></row><row><entry /><entry /><entry /><entry /><entry>amount. For each clock cycle no edge is</entry></row><row><entry /><entry /><entry /><entry /><entry>detected on the selected input pin the</entry></row><row><entry /><entry /><entry /><entry /><entry>accumulator is incremented by this amount.</entry></row><row><entry>0x148</entry><entry>FreqAnaCount</entry><entry>32</entry><entry>0x0000_0000</entry><entry>Frequency Analyser running counter</entry></row><row><entry /><entry /><entry /><entry /><entry>(Working register)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="378pt" align="left" /><tbody valign="top"><row><entry>Miscellaneous</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="161pt" align="left" /><tbody valign="top"><row><entry>0x150</entry><entry>InterruptSrcSelect</entry><entry>10</entry><entry>0x3FF</entry><entry>Interrupt source select. 1 bit per selected</entry></row><row><entry /><entry /><entry /><entry /><entry>input. Determines whether the interrupt</entry></row><row><entry /><entry /><entry /><entry /><entry>source is direct form the selected input pin</entry></row><row><entry /><entry /><entry /><entry /><entry>or the deglitched version. Input pins are</entry></row><row><entry /><entry /><entry /><entry /><entry>selected by the DeGlitchPinSelect register.</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - Selected input direct</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - Deglitched selected input</entry></row><row><entry>0x154</entry><entry>DebugSelect[8:2]</entry><entry>7</entry><entry>0x00</entry><entry>Debug address select. Indicates the address</entry></row><row><entry /><entry /><entry /><entry /><entry>of the register to report on the</entry></row><row><entry /><entry /><entry /><entry /><entry>gpio_cpu_data bus when it is not otherwise</entry></row><row><entry /><entry /><entry /><entry /><entry>being used.</entry></row><row><entry>0x158–0x15C</entry><entry>MotorMasterCount[1:0]</entry><entry>2 × 16</entry><entry>0x0000</entry><entry>Motor master clock counter values.</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 0 - Master clock count 0</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 1 - Master clock count 1</entry></row><row><entry /><entry /><entry /><entry /><entry>Read Only registers</entry></row><row><entry>0x160</entry><entry>WakeUpInputMask</entry><entry>10</entry><entry>0x000</entry><entry>Indicates which deglitched inputs should be</entry></row><row><entry /><entry /><entry /><entry /><entry>considered to generate the CPR wakeup.</entry></row><row><entry /><entry /><entry /><entry /><entry>Active high</entry></row><row><entry>0x164</entry><entry>WakeUpLevel</entry><entry>1</entry><entry>0</entry><entry>Defines the level to detect on the masked</entry></row><row><entry /><entry /><entry /><entry /><entry>GPIO inputs to generate a wakeup to the</entry></row><row><entry /><entry /><entry /><entry /><entry>CPR</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - Level 0</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - Level 1</entry></row><row><entry>0x168</entry><entry>USBOverCurrentPinSelect</entry><entry>4</entry><entry>0x00</entry><entry>Selects which deglitched input should be</entry></row><row><entry /><entry /><entry /><entry /><entry>used for the USB over current detect.</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 13.11.2.1 Supervisor and User Mode Access
1643The configuration registers block examines the CPU access type (cpu_acode signal) and determines if the access is allowed to that particular register, based on configured user access registers. If an access is not allowed the GPIO will issue a bus error by asserting the gpio_cpu_berr signal.
1644All supervisor and user program mode accesses will result in a bus error.
1645Access to the CpuIODirection, CpuIOOut and CpuIOIn is filtered by the CpuIOUserModeMask and CpuIOSuperModeMask registers. Each bit masks access to the corresponding bits in the CpuIO* registers for each mode, with CpuIOUserModeMask filtering user data mode access and CpuIOSuperModeMask filtering supervisor data mode access.
1646The addition of the CpuIOSuperModeMask register helps prevent potential conflicts between user and supervisor code read modify write operations. For example a conflict could exist if the user code is interrupted during a read modify write operation by a supervisor ISR which also modifies the CpuIO* registers.
1647An attempt to write to a disabled bit in user or supervisor mode will be ignored, and an attempt to read a disabled bit returns zero. If there are no user mode enabled bits then access is not allowed in user mode and a bus error will result. Similarly for supervisor mode.
1648When writing to the CpuIOOut register, the value being written is XORed with the current value in the CpuIOOut register, and the result is reflected on the GPIO pins.
1649The pseudocode for determining access to the CpuIOOut register is shown below. Similar code could be shown for the CpuIODirection and CpuIOIn registers. Note that when writing to CpuIODirection data is deposited directly and not XORed with the existing data (as in the CpuIOOut case).
1650<tables id="TABLE-US-00094" num="00094"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>if (cpu_acode = = SUPERVISOR_DATA_MODE) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// supervisor mode</entry></row><row><entry /><entry>if (CpuIOSuperModeMask[31:0] = = 0 ) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>// access is denied, and bus error</entry></row><row><entry /><entry>gpio_cpu_berr = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (cpu_rwn = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>// read mode (no filtering needed)</entry></row><row><entry /><entry>gpio_cpu_data[31:0] = CpuIOOut[31:0]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>// write mode, filtered by mask</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="21pt" align="left" /><tbody valign="top"><row><entry /><entry>mask[31:0]</entry><entry>= (cpu_dataout[31:0]</entry><entry>&</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>CpuIOSuperModeMask[31:0])</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><colspec colname="2" colwidth="21pt" align="left" /><tbody valign="top"><row><entry /><entry>CpuIOOut[31:0] = (cpu_dataout[31:0] {circumflex over ( )} mask[31:0]</entry><entry>)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>//bitwise XOR operator</entry></row><row><entry>elsif (cpu_acode = = USER_DATA_MODE) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// user datamode</entry></row><row><entry /><entry>if (CpuIOUserModeMask[31:0] = = 0 ) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>// access is denied, and bus error</entry></row><row><entry /><entry>gpio_cpu_berr = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (cpu_rwn = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>// read mode, filtered by mask</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="21pt" align="left" /><tbody valign="top"><row><entry /><entry>gpio_cpu_data</entry><entry>= ( CpuIOOut[31:0]</entry><entry>&</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>CpuIOUserModeMask[31:0])</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>// write mode, filtered by mask</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="21pt" align="left" /><tbody valign="top"><row><entry /><entry>mask[31:0]</entry><entry>= (cpu_dataout[31:0]</entry><entry>&</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>CpuIOUserModeMask[31:0])</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><colspec colname="2" colwidth="21pt" align="left" /><tbody valign="top"><row><entry /><entry>CpuIOOut[31:0] = (cpu_dataout[31:0] {circumflex over ( )} mask[31:0]</entry><entry>)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>//bitwise XOR operator</entry></row><row><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// access is denied, bus error</entry></row><row><entry /><entry>gpio_cpu_berr = 1</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
1651Table 86 details the access modes allowed for registers in the GPIO block. In supervisor mode all registers are accessible. In user mode forbidden accesses will result in a bus error (gpio_cpu_berr asserted).
1652<tables id="TABLE-US-00095" num="00095"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 86</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>GPIO supervisor and user access modes</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>Register Address</entry><entry>Registers</entry><entry>Access Permitted</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>0x000–0x07C</entry><entry>IOModeSelect[31:0]</entry><entry>Supervisor data mode only</entry></row><row><entry>0x080–0x94</entry><entry>InputPinSelect[9:0]</entry><entry>Supervisor data mode only</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="left" /><tbody valign="top"><row><entry>CPU IO Control</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>0x0B0</entry><entry>CpuIOUserModeMask</entry><entry>Supervisor data mode only</entry></row><row><entry>0x0B4</entry><entry>CpuIOSuperModeMask</entry><entry>Supervisor data mode only</entry></row><row><entry>0x0B8</entry><entry>CpuIODirection</entry><entry>CpuIOUserModeMask and</entry></row><row><entry /><entry /><entry>CpuIOSuperModeMask filtered</entry></row><row><entry>0x0BC</entry><entry>CpuIOOut</entry><entry>CpuIOUserModeMask and</entry></row><row><entry /><entry /><entry>CpuIOSuperModeMask filtered</entry></row><row><entry>0x0C0</entry><entry>CpuIOIn</entry><entry>CpuIOUserModeMask and</entry></row><row><entry /><entry /><entry>CpuIOSuperModeMask filtered</entry></row><row><entry>0x0C4</entry><entry>CpuDeGlitchUserModeMask</entry><entry>Supervisor data mode only</entry></row><row><entry>0x0C8</entry><entry>CpuIOInDeglitch</entry><entry>CpuDeGlitchUserModeMask filtered.</entry></row><row><entry /><entry /><entry>Unrestricted Supervisor data mode</entry></row><row><entry /><entry /><entry>access</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="left" /><tbody valign="top"><row><entry>Deglitch control</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>0x0D0–0x0D4</entry><entry>DeGlitchCount[1:0]</entry><entry>Supervisor data mode only</entry></row><row><entry>0x0D8–0x0DC</entry><entry>DeGlitchClkSrc[1:0]</entry><entry>Supervisor data mode only</entry></row><row><entry>0x0E0</entry><entry>DeGlitchSelect</entry><entry>Supervisor data mode only</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="left" /><tbody valign="top"><row><entry>Motor Control</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>0x0E4</entry><entry>MotorCtrlUserModeEnable</entry><entry>Supervisor data mode only</entry></row><row><entry>0x0E8–0x0EC</entry><entry>MotorMasterClkPeriod[1:0]</entry><entry>MotorCtrlUserModeEnable enabled.</entry></row><row><entry>0x0F0</entry><entry>MotorMasterClkSrc</entry><entry>MotorCtrlUserModeEnable enabled.</entry></row><row><entry>0x0F4–0x100</entry><entry>MotorCtrlConfig[3:0]</entry><entry>MotorCtrlUserModeEnable enabled</entry></row><row><entry>0x104</entry><entry>MotorMasterClkSelect</entry><entry>MotorCtrlUserModeEnable enabled</entry></row><row><entry>0x108</entry><entry>MotorMasterClockEnable</entry><entry>MotorCtrlUserModeEnable enabled</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="left" /><tbody valign="top"><row><entry>BLDC Motor Controllers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>0x10C</entry><entry>BLDCMode</entry><entry>MotorCtrlUserModeEnable Enabled</entry></row><row><entry>0x110</entry><entry>BLDCDirection</entry><entry>MotorCtrlUserModeEnable Enabled</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="left" /><tbody valign="top"><row><entry>LED control</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>0x114</entry><entry>LEDCtrlUserModeEnable</entry><entry>Supervisor data mode only</entry></row><row><entry>0x118–0x124</entry><entry>LEDDutySelect[3:0]</entry><entry>LEDCtrlUserModeEnable[3:0] enabled</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="left" /><tbody valign="top"><row><entry>Frequency Analyser</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>0x130</entry><entry>FreqAnaUserModeEnable</entry><entry>Supervisor data mode only</entry></row><row><entry>0x134</entry><entry>FreqAnaPinSelect</entry><entry>FreqAnaUserModeEnable enabled</entry></row><row><entry>0x138</entry><entry>FreqAnaPinFormSelect</entry><entry>FreqAnaUserModeEnable enabled</entry></row><row><entry>0x13C</entry><entry>FreqAnaLastPeriod</entry><entry>FreqAnaUserModeEnable enabled</entry></row><row><entry>0x140</entry><entry>FreqAnaAverage</entry><entry>FreqAnaUserModeEnable enabled</entry></row><row><entry>0x144</entry><entry>FreqAnaCountInc</entry><entry>FreqAnaUserModeEnable enabled</entry></row><row><entry>0x148</entry><entry>FreqAnaCount</entry><entry>FreqAnaUserModeEnable enabled</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="left" /><tbody valign="top"><row><entry>Miscellaneous</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>0x150</entry><entry>InterruptSrcSelect</entry><entry>Supervisor data mode only</entry></row><row><entry>0x154</entry><entry>DebugSelect[8:2]</entry><entry>Supervisor data mode only</entry></row><row><entry>0x158–0x15C</entry><entry>MotorMasterCount[1:0]</entry><entry>Supervisor data mode only</entry></row><row><entry>0x160</entry><entry>WakeUpInputMask</entry><entry>Supervisor data mode only</entry></row><row><entry>0x164</entry><entry>WakeUpLevel</entry><entry>Supervisor data mode only</entry></row><row><entry>0x168</entry><entry>USBOverCurrentPinSelect</entry><entry>Supervisor data mode only</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 13.11.3 GPIO Partition <br /> 13.11.4 IO Control
1653The IO control block connects the IO pin drivers to internal signalling based on configured setup registers and debug control signals.
1654<tables id="TABLE-US-00096" num="00096"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>// Output Control</entry></row><row><entry>for (i=0; i<32 ; i++) {</entry></row><row><entry>if (debug_cntrl[i] = = 1) then // debug mode</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>gpio_e[i] = 1;gpio_o[i] =debug_data_out[i]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>else // normal mode</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>case io_mode_select[i] is</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry>0 : gpio_e[i] =1 ;gpio_o[i] =led_ctrl[0]</entry><entry> // LED</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>output 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry>1 : gpio_e[i] =1 ;gpio_o[i] =led_ctrl[1]</entry><entry> // LED</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>output 2</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry>2 : gpio_e[i] =1 ;gpio_o[i] =led_ctrl[2]</entry><entry> // LED</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>output 3</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry>3 : gpio_e[i] =1 ;gpio_o[i] =led_ctrl[3]</entry><entry> // LED</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>output 4</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry>4 : gpio_e[i] =1 ;gpio_o[i] =motor_ctrl[0]</entry><entry>// Stepper</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Motor Control 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry>5 : gpio_e[i] =1 ;gpio_o[i] =motor_ctrl[1]</entry><entry>// Stepper</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Motor Control 2</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry>6 : gpio_e[i] =1 ;gpio_o[i] =motor_ctrl[2]</entry><entry>// Stepper</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Motor Control 3</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry>7 : gpio_e[i] =1 ;gpio_o[i] =motor_Ctrl[3]</entry><entry>// stepper</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Motor Control 4</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry>8 : gpio_e[i] =1 ;gpio_o[i] =bldc_ctrl[0][0]</entry><entry> // BLDC</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Motor Control 1,output 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry>9 : gpio_e[i] =1 ;gpio_o[i] =bldc_ctrl[0][1]</entry><entry> // BLDC</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Motor Control 1,output 2</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry>10: gpio_e[i] =1 gpio_o[i] =bldc_ctrl[0][2]</entry><entry> // BLDC</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Motor Control 1,output 3</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry>11: gpio_e[i] =1 ;gpio_o[i] =bldc_ctrl[0][3]</entry><entry> // BLDC</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Motor Control 1,output 4</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry>12: gpio_e[i] =1 ;gpio_o[i] =bldc_ctrl[0][4]</entry><entry> // BLDC</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Motor Control 1,output 5</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry>13: gpio_e[i] =1 ;gpio_o[i] =bldc_ctrl[0][5]</entry><entry> // BLDC</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Motor Control 1,output 6</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry>14: gpio_e[i] =1 ;gpio_o[i] =bldc_ctrl[1][0]</entry><entry> // BLDC</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Motor Control 2,output 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry>15: gpio_e[i] =1 ;gpio_o[i] =bldc_ctrl[1][1]</entry><entry> // BLDC</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Motor Control 2,output 2</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry>16: gpio_e[i] =1 ;gpio_o[i] =bldc_ctrl[1][2]</entry><entry> // BLDC</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Motor Control 2,output 3</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry>17: gpio_e[i] =1 ;gpio_o[i] =bldc_ctrl[1][3]</entry><entry> // BLDC</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Motor Control 2,output 4</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry>18: gpio_e[i] =1 ;gpio_o[i] =bldc_ctrl[1][4]</entry><entry> // BLDC</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Motor Control 2,output 5</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry>19: gpio_e[i] =1 ;gpio_o[i] =bldc_ctrl[1][5]</entry><entry> // BLDC</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Motor Control 2,output 6</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry>20: gpio_e[i] =1 ;gpio_o[i] =lss_gpio_clk[0]</entry><entry>// LSS Clk</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry>21: gpio_e[i] =1 ;gpio_o[i] =lss_gpio_clk[1]</entry><entry>// LSS Clk</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="119pt" align="left" /><colspec colname="3" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry>22:</entry><entry>gpio_e[i] =lss_gpio_e[0]</entry><entry>;gpio_o[i]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>=lss_gpio_dout[0]; // LSS Data 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>gpio_lss_din[0] = gpio_i[i]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="119pt" align="left" /><colspec colname="3" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry>23:</entry><entry>gpio_e[i] =lss_gpio_e[1]</entry><entry>;gpio_o[i]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>=lss_gpio_dout[1]; // LSS Data 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>gpio_lss_din[1] = gpio_i[i]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="119pt" align="left" /><colspec colname="3" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry>24:</entry><entry>gpio_e[i] =isi_gpio_e[0]</entry><entry>;gpio_o[i]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>=isi_gpio_dout[0]; // ISI Control 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>gpio_isi_din[0] = gpio_i[i]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="119pt" align="left" /><colspec colname="3" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry>25:</entry><entry>gpio_e[i] =isi_gpio_e[1]</entry><entry>;gpio_o[i]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>=isi_gpio_dout[1]; // ISI Control 2</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>gpio_isi_din[1] = gpio_i[i]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="119pt" align="left" /><colspec colname="3" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry>26:</entry><entry>gpio_e[i] =isi_gpio_e[2]</entry><entry>;gpio_o[i]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>=isi_gpio_dout[2]; // ISI Control 3</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>gpio_isi_din[2] = gpio_i[i]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="119pt" align="left" /><colspec colname="3" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry>27:</entry><entry>gpio_e[i] =isi_gpio_e[3]</entry><entry>;gpio_o[i]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>=isi_gpio_dout[3]; // ISI Control 4</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>gpio_isi_din[3] = gpio_i[i]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>28: gpio_e[i] =cpu_io_dir[i] ;gpio_o[i] =cpu_io_out[i];</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>// CPU Direct</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>29:</entry><entry>gpio e[i] =1 ;gpio o[i] =usbh gpio power en</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>// USB host power enable</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="49pt" align="left" /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="35pt" align="left" /><tbody valign="top"><row><entry /><entry>30:</entry><entry>gpio e[i]</entry><entry>=0</entry><entry>;gpio o[i]</entry><entry>=0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>// Input only mode</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>end case</entry></row><row><entry /><entry>// all gpio are always readable by the CPU</entry></row><row><entry /><entry>cpu_io_in[i] = gpio_i[i];</entry></row><row><entry /><entry>}</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
1655The input selection pseudocode, for determining which pin connects to which de-glitch circuit.
1656<tables id="TABLE-US-00097" num="00097"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="196pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>for( i=0 ;i < 10 ; i++) {</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry>pin_num</entry><entry>= input_pin_select[i]</entry></row><row><entry /><entry>deglitch_input[i]</entry><entry>= gpio_i[pin_num]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>}</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><ul id="ul0160" list-style="none"><li id="ul0160-0001" num="0000"><ul id="ul0161" list-style="none"><li id="ul0161-0001" num="1657">The gpio_usbh_over_current output to the USB core is driven by a selected deglitched input (configured by the USBOverCurrentPinSelect register).</li><li id="ul0161-0002" num="1658">index=USBOverCurrentPinSelect</li><li id="ul0161-0003" num="1659">gpio_usbh_over_vurrent=cpu_io_in_deglitch[index] <br /> 13.11.5 Wakeup Generator </li></ul></li></ul>
1660The wakeup generator compares the deglitched inputs with the configured mask (WakeUpInputMask) and level (WakeUpLevel), and determines whether to generate a wakeup to the CPR block.
1661<tables id="TABLE-US-00098" num="00098"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>for (i =0;i<10; i++) {</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="112pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><tbody valign="top"><row><entry /><entry>if (wakeup_level = 0) then</entry><entry>// level 0 active</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>wakeup = wakeup OR wakeup_input_mask[i]</entry></row><row><entry /><entry>AND NOT</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>cpu_io_in_deglitch[i]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="112pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry><entry>// level 1 active</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>wakeup = wakeup OR wakeup_input_mask[i]</entry></row><row><entry /><entry>AND</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>cpu_io_in_deglitch[i]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>}</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// assign the output</entry></row><row><entry /><entry>gpio_cpr_wakeup = wakeup</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 13.11.6 LED Pulse Generator
1662The pulse generator logic consists of a 7-bit counter that is incremented on a 1 μs pulse from the timers block (tim_pulse[0]). The LED control signal is generated by comparing the count value with the configured duty cycle for the LED (led_duty_sel).
1663The logic is given by:
1664<tables id="TABLE-US-00099" num="00099"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>for (i=0 i<4 ;i++) { // for each LED pin</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>// period divided into 8 segments</entry></row><row><entry /><entry>period_div8 = cnt[6:4];</entry></row><row><entry /><entry>if (period_div8 < led_duty_sel[i]) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="63pt" align="left" /><colspec colname="1" colwidth="154pt" align="left" /><tbody valign="top"><row><entry /><entry>led_ctrl[i] = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="63pt" align="left" /><colspec colname="1" colwidth="154pt" align="left" /><tbody valign="top"><row><entry /><entry>led_ctrl[i] = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>}</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>// update the counter every 1us pulse</entry></row><row><entry /><entry>if (tim_pulse[0] = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>cnt ++</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 13.11.7 Stepper Motor Control
1665The motor controller consists of 2 counters, and 4 phase generator logic blocks, one per motor control pin. The counters decrement each time a timing pulse (cnt_en) is received. The counters start at the configured clock period value (motor_mas_clk_period) and decrement to zero. If the counters are enabled (via motor_mas_clk_enable), the counters will automatically restart at the configured clock period value, otherwise they will wait until the counters are re-enabled. <ul id="ul0162" list-style="none"><li id="ul0162-0001" num="0000"><ul id="ul0163" list-style="none"><li id="ul0163-0001" num="1666">The timing pulse period is one of pclk, 1 μs, 100 μs, 1 ms depending on the motor_mas_clk_sel signal. The counters are used to derive the phase and duty cycle of each motor control pin.</li></ul></li></ul>
1667<tables id="TABLE-US-00100" num="00100"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>// decrement logic</entry></row><row><entry>if (cnt_en = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>if ((mas_cnt = = 0) AND (motor_mas_clk_enable = = 1)) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>mas_cnt = motor_mas_clk_period[15:0]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif ((mas_cnt = = 0) AND (motor_mas_clk_enable = = 0)) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>mas_cnt = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>mas_cnt − −</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>else // hold the value</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>mas_cnt = mas_cnt</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
1668The phase generator block generates the motor control logic based on the selected clock generator (motor_mas_clk_sel) the motor control high transition point (curr_motor_ctrl_high) and the motor control low transition point (curr_motor_ctrl_low).
1669The phase generator maintains current copies of the motor_ctrl_config configuration value (motor_ctrl_config[31:16] becomes curr_motor_ctrl_high and motor_ctrl_config[15:0] becomes curr_motor_ctrl_low). It updates these values to the current register values when it is safe to do so without causing a glitch on the output motor pin.
1670Note that when reprogramming the motor_ctrl_config register to reorder the sequence of the transition points (e.g changing from low point less than high point to low point greater than high point and vice versa) care must taken to avoid introducing glitching on the output pin.
1671There are 4 instances one per motor control pin.
1672The logic is given by:
1673<tables id="TABLE-US-00101" num="00101"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>// select the input counter to use</entry></row><row><entry /><entry>if (motor_mas_clk_sel = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>count = mas_cnt[1]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>count = mas_cnt[0]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// Generate the phase and duty cycle</entry></row><row><entry /><entry>if (count = = curr_motor_ctrl_low) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>motor_ctrl = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (count = = curr_motor_ctrl_high) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>motor_ctrl = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>motor_ctrl = motor_ctrl // remain the same</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// update the current registers at period boundary</entry></row><row><entry /><entry>if (count = = 0) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><colspec colname="2" colwidth="28pt" align="left" /><tbody valign="top"><row><entry /><entry>curr_motor_ctrl_high = motor_ctrl_config[31:16]</entry><entry>//</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>update to new high value</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><colspec colname="2" colwidth="28pt" align="left" /><tbody valign="top"><row><entry /><entry>curr_motor_ctrl_low = motor_ctrl_config[15:0]</entry><entry>//</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>update to new high value</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 13.11.8 Input Deglitch
1674The input deglitch logic rejects input states of duration less than the configured number of time units (deglitch_cnt), input states of greater duration are reflected on the output cpu_io_in_deglitch. The time units used (either pclk, 1 μs, 100 μs, 1 ms) by the deglitch circuit is selected by the deglitch_clk_src bus.
1675There are 2 possible sets of deglitch_cnt and deglitch_clk_src that can be used to deglitch the input pins. The values used are selected by the deglitch_sel signal.
1676There are 10 deglitch circuits in the GPIO. Any GPIO pin can be connected to a deglitch circuit. Pins are selected for deglitching by the InputPinSelect registers.
1677Each selected input can be used to generate an interrupt. The interrupt can be generated from the raw input signal (deglitch_input) or a deglitched version of the input (cpu_io_in_deglitch). The interrupt source is selected by the interrupt_src_select signal.
1678The counter logic is given by
1679<tables id="TABLE-US-00102" num="00102"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="196pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>if (deglitch_input != deglitch_input_delay) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry>cnt</entry><entry>= deglitch_cnt</entry></row><row><entry /><entry>output_en</entry><entry>= 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="196pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (cnt = = 0 ) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry>cnt</entry><entry>= cnt</entry></row><row><entry /><entry>output_en</entry><entry>= 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="196pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (cnt_en = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>cnt − −</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry>output_en</entry><entry>= 0</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 13.11.9 Frequency Analyser
1680The frequency analyser block monitors a selected deglitched input (cpu_io_in_deglitch) or a direct selected input (deglitch_input) and detects positive edges. The selected input is configured by FreqAnaPinSelect and FreqAnaPinFormSel registers. Between successive positive edges detected on the input it increments a counter (FreqAnaCount) by a programmed amount (FreqAnaCountInc) on each clock cycle. When a positive edge is detected the FreqAnaLastPeriod register is updated with the top 16 bits of the counter and the counter is reset. The frequency analyser also maintains a running average of the FreqAnaLastPeriod register. Each time a positive edge is detected on the input the FreqAnaAverage register is updated with the new calculated FreqAnaLastPeriod. The average is calculated as ⅞ the current value plus ⅛ of the new value. The FreqAnaLastPeriod, FreqAnaCount and FreqAnaAverage registers can be written to by the CPU.
1681The pseudocode is given by
1682<tables id="TABLE-US-00103" num="00103"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>if ((pin = = 1) AND pin_delay = =0)) then // positive edge</entry></row><row><entry>detected</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>freq_ana_lastperiod[15:0] = freq_ana_count[31:16]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="112pt" align="left" /><tbody valign="top"><row><entry /><entry>freq_ana_average[15:0]</entry><entry>= freq_ana_average[15:0] −</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>freq_ana_average [15:3]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="168pt" align="left" /><colspec colname="1" colwidth="49pt" align="left" /><tbody valign="top"><row><entry /><entry>+</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>freq_ana_lastperiod[15:3]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="119pt" align="left" /><tbody valign="top"><row><entry /><entry>freq_ana_count[15:0]</entry><entry>= 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="98pt" align="left" /><colspec colname="2" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry>freq_ana_count[31:0]</entry><entry>= freq_ana_count[31:0] +</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>freq_ana_count_inc[19:0]</entry></row><row><entry>// implement the configuration register write</entry></row><row><entry>if (wr_last_en = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>freq_ana_lastperiod = wr_data</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>elsif (wr_average_en = = 1 ) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>freq_ana_average = wr_data</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>elsif (wr_freq_count_en = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>freq_ana_count = wr_data</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 13.11.10 BLDC Motor Controller
1683The BLDC controller logic is identical for both instances, only the input connections are different. The logic implements the truth table shown in Table. The six q outputs are combinationally based on the direction, ha, hb, hc and pwm inputs. The direction input has 2 possible sources selected by the mode, the pseudocode is as follows
1684<tables id="TABLE-US-00104" num="00104"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="196pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>// determine if in internal or external direction mode</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="105pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry>if (mode = = 1) then</entry><entry>// internal mode</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>direction = int_direction</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="105pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry><entry>// external mode</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>direction = ext_direction</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 14 Interrupt Controller Unit (ICU)
1685The interrupt controller accepts up to N input interrupt sources, determines their priority, arbitrates based on the highest priority and generates an interrupt request to the CPU. The ICU complies with the interrupt acknowledge protocol of the CPU. Once the CPU accepts an interrupt (i.e. processing of its service routine begins) the interrupt controller will assert the next arbitrated interrupt if one is pending.
1686Each interrupt source has a fixed vector number N, and an associated configuration register, IntReg[N]. The format of the IntReg[N] register is shown in Table 87 below.
1687<tables id="TABLE-US-00105" num="00105"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 87</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>IntReg[N] register format</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="35pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="161pt" align="left" /><tbody valign="top"><row><entry>Field</entry><entry>bit(s)</entry><entry>Description</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>Priority</entry><entry>3:0</entry><entry>Interrupt priority</entry></row><row><entry>Type</entry><entry>5:4</entry><entry>Determines the triggering conditions for the interrupt</entry></row><row><entry /><entry /><entry>00 - Positive edge</entry></row><row><entry /><entry /><entry>10 - Negative edge</entry></row><row><entry /><entry /><entry>01 - Positive level</entry></row><row><entry /><entry /><entry>11 - Negative level</entry></row><row><entry>Mask</entry><entry>6</entry><entry>Mask bit.</entry></row><row><entry /><entry /><entry>1 - Interrupts from this source are enabled,</entry></row><row><entry /><entry /><entry>0 - Interrupts from this source are disabled.</entry></row><row><entry /><entry /><entry>Note that there may be additional masks in operation at</entry></row><row><entry /><entry /><entry>the source of the interrupt.</entry></row><row><entry>Reserved</entry><entry>31:7</entry><entry>Reserved. Write as 0.</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
1688Once an interrupt is received the interrupt controller determines the priority and maps the programmed priority to the appropriate CPU priority levels, and then issues an interrupt to the CPU. The programmed interrupt priority maps directly to the LEON CPU interrupt levels. Level 0 is no interrupt. Level 15 is the highest interrupt level.
000014.1 Interrupt Preemption
1689With standard LEON pre-emption an interrupt can only be pre-empted by an interrupt with a higher priority level. If an interrupt with the same priority level (1 to 14) as the interrupt being serviced becomes pending then it is not acknowledged until the current service routine has completed. Note that the level 15 interrupt is a special case, in that the LEON processor will continue to take level 15 interrupts (i.e re-enter the ISR) as long as level 15 is asserted on the icu_cpu_ilevel. Level 0 is also a special case, in that LEON consider level 0 interrupts as no interrupt, and will not issue an acknowledge when level 0 is presented on the icu_cpu_ilevel bus.
1690Thus when pre-emption is required, interrupts should be programmed to different levels as interrupt priorities of the same level have no guaranteed servicing order. Should several interrupt sources be programmed with the same priority level, the lowest value interrupt source will be serviced first and so on in increasing order.
1691The interrupt is directly acknowledged by the CPU and the ICU automatically clears the pending bit of the lowest value pending interrupt source mapped to the acknowledged interrupt level.
1692All interrupt controller registers are only accessible in supervisor data mode. If the user code wishes to mask an interrupt it must request this from the supervisor and the supervisor software will resolve user access levels.
000014.2 Interrupt Sources
1693The mapping of interrupt sources to interrupt vectors (and therefore IntReg[N] registers) is shown in Table 88 below. Please refer to the appropriate section of this specification for more details of the interrupt sources.
1694<tables id="TABLE-US-00106" num="00106"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 88</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Interrupt sources vector table</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="63pt" align="center" /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>Vector</entry><entry>Source</entry><entry>Description</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="63pt" align="char" char="." /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>0</entry><entry>Timers</entry><entry>WatchDog Timer Update request</entry></row><row><entry>1</entry><entry>Timers</entry><entry>Generic Timer 1 interrupt</entry></row><row><entry>2</entry><entry>Timers</entry><entry>Generic Timer 2 interrupt</entry></row><row><entry>3</entry><entry>PCU</entry><entry>PEP Sub-system Interrupt- TE</entry></row><row><entry /><entry /><entry>finished band</entry></row><row><entry>4</entry><entry>PCU</entry><entry>PEP Sub-system Interrupt- LBD</entry></row><row><entry /><entry /><entry>finished band</entry></row><row><entry>5</entry><entry>PCU</entry><entry>PEP Sub-system Interrupt- CDU</entry></row><row><entry /><entry /><entry>finished band</entry></row><row><entry>6</entry><entry>PCU</entry><entry>PEP Sub-system Interrupt- CDU</entry></row><row><entry /><entry /><entry>error</entry></row><row><entry>7</entry><entry>PCU</entry><entry>PEP Sub-system Interrupt- PCU</entry></row><row><entry /><entry /><entry>finished band</entry></row><row><entry>8</entry><entry>PCU</entry><entry>PEP Sub-system Interrupt- PCU</entry></row><row><entry /><entry /><entry>Invalid address interrupt</entry></row><row><entry>9</entry><entry>PHI</entry><entry>PEP Sub-system Interrupt- PHI</entry></row><row><entry /><entry /><entry>Line Sync Interrupt</entry></row><row><entry>10</entry><entry>PHI</entry><entry>PEP Sub-system Interrupt- PHI</entry></row><row><entry /><entry /><entry>Buffer underrun</entry></row><row><entry>11</entry><entry>PHI</entry><entry>PEP Sub-system Interrupt- PHI</entry></row><row><entry /><entry /><entry>Page finished</entry></row><row><entry>12</entry><entry>PHI</entry><entry>PEP Sub-system Interrupt- PHI</entry></row><row><entry /><entry /><entry>Print ready</entry></row><row><entry>13</entry><entry>SCB</entry><entry>USB Host interrupt</entry></row><row><entry>14</entry><entry>SCB</entry><entry>USB Device interrupt</entry></row><row><entry>15</entry><entry>SCB</entry><entry>ISI interrupt</entry></row><row><entry>16</entry><entry>SCB</entry><entry>DMA interrupt</entry></row><row><entry>17</entry><entry>LSS</entry><entry>LSS interrupt, LSS interface</entry></row><row><entry /><entry /><entry>0 interrupt request</entry></row><row><entry>18</entry><entry>LSS</entry><entry>LSS interrupt, LSS interface</entry></row><row><entry /><entry /><entry>1 interrupt request</entry></row><row><entry>19–28</entry><entry>GPIO</entry><entry>GPIO general purpose interrupts</entry></row><row><entry>29</entry><entry>Timers</entry><entry>Generic Timer 3 interrupt</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 14.3 Implentation <br /> 14.3.1 Definitions of I/O
1695<tables id="TABLE-US-00107" num="00107"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="273pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 89</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Interrupt Controller Unit I/O definition</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>Port name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="273pt" align="left" /><tbody valign="top"><row><entry>Clocks and Resets</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>Pclk</entry><entry>1</entry><entry>In</entry><entry>System Clock</entry></row><row><entry>prst_n</entry><entry>1</entry><entry>In</entry><entry>System reset, synchronous active low</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="273pt" align="left" /><tbody valign="top"><row><entry>CPU interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>cpu_adr[7:2]</entry><entry>6</entry><entry>In</entry><entry>CPU address bus. Only 6 bits are required to</entry></row><row><entry /><entry /><entry /><entry>decode the address space for the ICU block</entry></row><row><entry>cpu_dataout[31:0]</entry><entry>32</entry><entry>In</entry><entry>Shared write data bus from the CPU</entry></row><row><entry>icu_cpu_data[31:0]</entry><entry>32</entry><entry>Out</entry><entry>Read data bus to the CPU</entry></row><row><entry>cpu_rwn</entry><entry>1</entry><entry>In</entry><entry>Common read/not-write signal from the CPU</entry></row><row><entry>cpu_icu_sel</entry><entry>1</entry><entry>In</entry><entry>Block select from the CPU. When cpu_icu_sel is</entry></row><row><entry /><entry /><entry /><entry>high both cpu_adr and cpu_dataout are valid</entry></row><row><entry>icu_cpu_rdy</entry><entry>1</entry><entry>Out</entry><entry>Ready signal to the CPU. When icu_cpu_rdy is</entry></row><row><entry /><entry /><entry /><entry>high it indicates the last cycle of the access. For</entry></row><row><entry /><entry /><entry /><entry>a write cycle this means cpu_dataout has been</entry></row><row><entry /><entry /><entry /><entry>registered by the ICU block and for a read cycle</entry></row><row><entry /><entry /><entry /><entry>this means the data on icu_cpu_data is valid.</entry></row><row><entry>icu_cpu_ilevel[3:0]</entry><entry>4</entry><entry>Out</entry><entry>Indicates the priority level of the current active</entry></row><row><entry /><entry /><entry /><entry>interrupt.</entry></row><row><entry>cpu_iack</entry><entry>1</entry><entry>In</entry><entry>Interrupt request acknowledge from the LEON</entry></row><row><entry /><entry /><entry /><entry>core.</entry></row><row><entry>cpu_icu_ilevel[3:0]</entry><entry>4</entry><entry>In</entry><entry>Interrupt acknowledged level from the LEON</entry></row><row><entry /><entry /><entry /><entry>core</entry></row><row><entry>icu_cpu_berr</entry><entry>1</entry><entry>Out</entry><entry>Bus error signal to the CPU indicating an invalid</entry></row><row><entry /><entry /><entry /><entry>access.</entry></row><row><entry>cpu_acode[1:0]</entry><entry>2</entry><entry>In</entry><entry>CPU Access Code signals. These decode as</entry></row><row><entry /><entry /><entry /><entry>follows:</entry></row><row><entry /><entry /><entry /><entry>00 - User program access</entry></row><row><entry /><entry /><entry /><entry>01 - User data access</entry></row><row><entry /><entry /><entry /><entry>10 - Supervisor program access</entry></row><row><entry /><entry /><entry /><entry>11 - Supervisor data access</entry></row><row><entry>icu_cpu_debug_valid</entry><entry>1</entry><entry>Out</entry><entry>Debug Data valid on icu_cpu_data bus. Active</entry></row><row><entry /><entry /><entry /><entry>high</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="273pt" align="left" /><tbody valign="top"><row><entry>Interrupts</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>tim_icu_wd_irq</entry><entry>1</entry><entry>In</entry><entry>Watchdog timer interrupt signal from the Timers</entry></row><row><entry /><entry /><entry /><entry>block</entry></row><row><entry>tim_icu_irq[2:0]</entry><entry>3</entry><entry>In</entry><entry>Generic timer interrupt signals from the Timers</entry></row><row><entry /><entry /><entry /><entry>block</entry></row><row><entry>gpio_icu_irq[9:0]</entry><entry>10</entry><entry>In</entry><entry>GPIO pin interrupts</entry></row><row><entry>usb_icu_irq[1:0]</entry><entry>2</entry><entry>In</entry><entry>USB host and device interrupts from the SCB</entry></row><row><entry /><entry /><entry /><entry>Bit 0 - USB Host interrupt</entry></row><row><entry /><entry /><entry /><entry>Bit 1 - USB Device interrupt</entry></row><row><entry>isi_icu_irq</entry><entry>1</entry><entry>In</entry><entry>ISI interrupt from the SCB</entry></row><row><entry>dma_icu_irq</entry><entry>1</entry><entry>In</entry><entry>DMA interrupt from the SCB</entry></row><row><entry>lss_icu_irq[1:0]</entry><entry>2</entry><entry>In</entry><entry>LSS interface interrupt request</entry></row><row><entry>cdu_finishedband</entry><entry>1</entry><entry>In</entry><entry>Finished band interrupt request from the CDU</entry></row><row><entry>cdu_icu_jpegerror</entry><entry>1</entry><entry>In</entry><entry>JPEG error interrupt from the CDU</entry></row><row><entry>lbd_finishedband</entry><entry>1</entry><entry>In</entry><entry>Finished band interrupt request from the LBD</entry></row><row><entry>te_finishedband</entry><entry>1</entry><entry>In</entry><entry>Finished band interrupt request from the TE</entry></row><row><entry>pcu_finishedband</entry><entry>1</entry><entry>In</entry><entry>Finished band interrupt request from the PCU</entry></row><row><entry>pcu_icu_address_invalid</entry><entry>1</entry><entry>In</entry><entry>Invalid address interrupt request from the PCU</entry></row><row><entry>phi_icu_underrun</entry><entry>1</entry><entry>In</entry><entry>Buffer underrun interrupt request from the PHI</entry></row><row><entry>phi_icu_page_finish</entry><entry>1</entry><entry>In</entry><entry>Page finished interrupt request from the PHI</entry></row><row><entry>phi_icu_print_rdy</entry><entry>1</entry><entry>In</entry><entry>Print ready interrupt request from the PHI</entry></row><row><entry>phi_icu_linesync_int</entry><entry>1</entry><entry>In</entry><entry>Line sync interrupt request from the PHI</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 14.3.2 Configuration Registers
1696The configuration registers in the ICU are programmed via the CPU interface. Refer to section 11.4 on page 69 for a description of the protocol and timing diagrams for reading and writing registers in the ICU. Note that since addresses in SoPEC are byte aligned and the CPU only supports 32-bit register reads and writes, the lower 2 bits of the CPU address bus are not required to decode the address space for the ICU. When reading a register that is less than 32 bits wide zeros should be returned on the upper unused bit(s) of icu_pcu_data. Table 90 lists the configuration registers in the ICU block.
1697The ICU block will only allow supervisor data mode accesses (i.e. cpu_acode[1:0]=SUPERVISOR_DATA). All other accesses will result in icu_cpu_berr being asserted.
1698<tables id="TABLE-US-00108" num="00108"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="322pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 90</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>ICU Register Map</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="56pt" align="left" /><colspec colname="3" colwidth="28pt" align="center" /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>Address</entry><entry /><entry /><entry /><entry /></row><row><entry>ICU_base+</entry><entry>Register</entry><entry>#bits</entry><entry>Reset</entry><entry>Description</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row><row><entry>0x00–0x74</entry><entry>IntReg[29:0]</entry><entry>30 × 7</entry><entry>0x00</entry><entry>Interrupt vector configuration register</entry></row><row><entry>0x88</entry><entry>IntClear</entry><entry>30</entry><entry>0x0000_0000</entry><entry>Interrupt pending clear register. If written with a</entry></row><row><entry /><entry /><entry /><entry /><entry>one it clears corresponding interrupt</entry></row><row><entry /><entry /><entry /><entry /><entry>Bits[30:0] - Interrupts sources 30 to 0</entry></row><row><entry /><entry /><entry /><entry /><entry>(Reads as zero)</entry></row><row><entry>0x90</entry><entry>IntPending</entry><entry>30</entry><entry>0x0000_0000</entry><entry>Interrupt pending register. (Read Only)</entry></row><row><entry /><entry /><entry /><entry /><entry>Bits[30:0]- Interrupts sources 30 to 0</entry></row><row><entry>0xA0</entry><entry>IntSource</entry><entry>5</entry><entry>0x1F</entry><entry>Indicates the interrupt source of the last acknowl-</entry></row><row><entry /><entry /><entry /><entry /><entry>edged interrupt. The NoInterrupt value is defined</entry></row><row><entry /><entry /><entry /><entry /><entry>as all bits set to one.</entry></row><row><entry /><entry /><entry /><entry /><entry>(Read Only)</entry></row><row><entry>0xC0</entry><entry>DebugSelect[7:2]</entry><entry>6</entry><entry>0x00</entry><entry>Debug address select. Indicates the address of</entry></row><row><entry /><entry /><entry /><entry /><entry>the register to report on the icu_cpu_data bus</entry></row><row><entry /><entry /><entry /><entry /><entry>when it is not otherwise being used.</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 14.3.3 ICU Partition <br /> 14.3.4 Interrupt Detect
1699The ICU contains multiple instances of the interrupt detect block, one per interrupt source. The interrupt detect block examines the interrupt source signal, and determines whether it should generate request pending (int_pend) based on the configured interrupt type and the interrupt source conditions. If the interrupt is not masked the interrupt will be reflected to the interrupt arbiter via the int_active signal. Once an interrupt is pending it remains pending until the interrupt is accepted by the CPU or it is level sensitive and gets removed. Masking a pending interrupt has the effect of removing the interrupt from arbitration but the interrupt will still remain pending.
1700When the CPU accepts the interrupt (using the normal ISR mechanism), the interrupt controller automatically generates an interrupt clear for that interrupt source (cpu_int_clear). Alternatively if the interrupt is masked, the CPU can determine pending interrupts by polling the IntPending registers. Any active pending interrupts can be cleared by the CPU without using an ISR via the IntClear registers.
1701Should an interrupt clear signal (either from the interrupt clear unit or the CPU) and a new interrupt condition happen at the same time, the interrupt will remain pending. In the particular case of a level sensitive interrupt, if the level remains the interrupt will stay active regardless of the clear signal.
1702The logic is shown below:
1703<tables id="TABLE-US-00109" num="00109"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="147pt" align="left" /><thead><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>mask</entry><entry>= int_config[6]</entry></row><row><entry>type</entry><entry>= int_config[5:4]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="70pt" align="left" /><tbody valign="top"><row><entry>int_pend</entry><entry> = last_int_pend</entry><entry>// the last pending</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>interrupt</entry></row><row><entry>// update the pending FF</entry></row><row><entry>// test for interrupt condition</entry></row><row><entry>if (type = = NEG_LEVEL) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>int_pend = NOT(int_src)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>elsif (type = = POS_LEVEL)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>int_pend = int_src</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>elsif ((type = = POS_EDGE ) AND (int_src = = 1)</entry></row><row><entry>AND</entry></row><row><entry>(last_int_src = = 0))</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>int_pend = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>elsif ((type = = NEG_EDGE ) AND (int_src = = 0)</entry></row><row><entry>AND</entry></row><row><entry>(last_int_src = = 1) )</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>int_pend = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>elsif ((int_clear = = 1 )OR (cpu_int_clear= =1)) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>int_pend = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>int_pend = last_int_pend // stay the same as before</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>// mask the pending bit</entry></row><row><entry>if (mask = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>int_active</entry><entry>= int_pend</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>int_active = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>// assign the registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>last_int_src</entry><entry>= int_src</entry></row><row><entry>last_int_pend</entry><entry>= int_pend</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 14.3.5 Interrupt Arbiter
1704The interrupt arbiter logic arbitrates a winning interrupt request from multiple pending requests based on configured priority. It generates the interrupt to the CPU by setting icu_cpu_ilevel to a non-zero value. The priority of the interrupt is reflected in the value assigned to icu_cpu_ilevel, the higher the value the higher the priority, 15 being the highest, and 0 considered no interrupt.
1705<tables id="TABLE-US-00110" num="00110"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>// arbitrate with the current winner</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="154pt" align="left" /><tbody valign="top"><row><entry /><entry>int_ilevel</entry><entry>= 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>for (i=0;i<30;i++) {</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>if ( int_active[i] = = 1) then {</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>if (int_config[i][3:0] > win_int_ilevel[3:0] ) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>win_int_ilevel[3:0] = int_config[i][3:0]</entry></row><row><entry /><entry>}</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>}</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>}</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// assign the CPU interrupt level</entry></row><row><entry /><entry>int_ilevel = win_int_ilevel[3:0]</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 14.3.6 Interrupt Clear Unit
1706The interrupt clear unit is responsible for accepting an interrupt acknowledge from the CPU, determining which interrupt source generated the interrupt, clearing the pending bit for that source and updating the IntSource register.
1707When an interrupt acknowledge is received from the CPU, the interrupt clear unit searches through each interrupt source looking for interrupt sources that match the acknowledged interrupt level (cpu_icu_ilevel) and determines the winning interrupt (lower interrupt source numbers have higher priority). When found the interrupt source pending bit is cleared and the IntSource register is updated with the interrupt source number.
1708The LEON interrupt acknowledge mechanism automatically disables all other interrupts temporarily until it has correctly saved state and jumped to the ISR routine. It is the responsibility of the ISR to re-enable the interrupts. To prevent the IntSource register indicating the incorrect source for an interrupt level, the ISR must read and store the IntSource value before re-enabling the interrupts via the Enable Traps (ET) field in the Processor State Register (PSR) of the LEON.
1709See section 11.9 on page 104 for a complete description of the interrupt handling procedure. After reset the state machine remains in Idle state until an interrupt acknowledge is received from the CPU (indicated by cpu_iack). When the acknowledge is received the state machine transitions to the Compare state, resetting the source counter (cnt) to the number of interrupt sources.
1710While in the Compare state the state machine cycles through each possible interrupt source in decrementing order. For each active interrupt source the programmed priority (int_priority[cnt][3:0]) is compared with the acknowledged interrupt level from the CPU (cpu_icu_ilevel), if they match then the interrupt is considered the new winner. This implies the last interrupt source checked has the highest priority, e.g interrupt source zero has the highest priority and the first source checked has the lowest priority. After all interrupt sources are checked the state machine transitions to the IntClear state, and updates the int_source register on the transition.
1711Should there be no active interrupts for the acknowledged level (e.g. a level sensitive interrupt was removed), the IntSource register will be set to NoInterrupt. NoInterrupt is defined as the highest possible value that IntSource can be set to (in this case 0x1F), and the state machine will return to Idle.
1712The exact number of compares performed per clock cycle is dependent the number of interrupts, and logic area to logic speed trade-off, and is left to the implementer to determine. A comparison of all interrupt sources must complete within 8 clock cycles (determined by the CPU acknowledge hardware).
1713When in the IntClear state the state machine has determined the interrupt source to clear (indicated by the int_source register). It resets the pending bit for that interrupt source, transitions back to the Idle state and waits for the next acknowledge from the CPU.
1714The minimum time between successive interrupt acknowledges from the CPU is 8 cycles.
000015 Timers Block (TIM)
1715The Timers block contains general purpose timers, a watchdog timer and timing pulse generator for use in other sections of SoPEC.
000015.1 Watchdog Timer
1716The watchdog timer is a 32 bit counter value which counts down each time a timing pulse is received. The period of the timing pulse is selected by the WatchDogUnitSel register. The value at any time can be read from the WatchDogTimer register and the counter can be reset by writing a non-zero value to the register. When the counter transitions from 1 to 0, a system wide reset will be triggered as if the reset came from a hardware pin.
1717The watchdog timer can be polled by the CPU and reset each time it gets close to 1, or alternatively a threshold (WatchDogIntThres) can be set to trigger an interrupt for the watchdog timer to be serviced by the CPU. If the WatchDogIntThres is set to N, then the interrupt will be triggered on the N to N−1 transition of the WatchDogTimer. This interrupt can be effectively masked by setting the threshold to zero. The watchdog timer can be disabled, without causing a reset, by writing zero to the WatchDogTimer register.
000015.2 Timing Pulse Generator
1718The timing block contains a timing pulse generator clocked by the system clock, used to generate timing pulses of programmable periods. The period is programmed by accessing the TimerStartValue registers. Each pulse is of one system clock duration and is active high, with the pulse period accurate to the system clock frequency. The periods after reset are set to 1 us, 100 us and 100 ms.
1719The timing pulse generator also contains a 64-bit free running counter that can be read or reset by accessing the FreeRunCount registers. The free running counter can be used to determine elapsed time between events at system clock accuracy or could be used as an input source in low-security random number generator.
000015.3 Generic Timers
1720SoPEC contains 3 programmable generic timing counters, for use by the CPU to time the system. The timers are programmed to a particular value and count down each time a timing pulse is received. When a particular timer decrements from 1 to 0, an interrupt is generated. The counter can be programmed to automatically restart the count, or wait until re-programmed by the CPU. At any time the status of the counter can be read from GenCntValue, or can be reset by writing to GenCntValue register. The auto-restart is activated by setting the GenCntAuto register, when activated the counter restarts at GenCntStartValue. A counter can be stopped or started at any time, without affecting the contents of the GenCntValue register, by writing a 1 or 0 to the relevent GenCntEnable register.
000015.4 Implementation
000015.4.1 Definitions of I/O
1721<tables id="TABLE-US-00111" num="00111"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="287pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 91</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Timers block I/O definition</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="168pt" align="left" /><tbody valign="top"><row><entry>Port name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="287pt" align="left" /><tbody valign="top"><row><entry>Clocks and Resets</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="168pt" align="left" /><tbody valign="top"><row><entry>Pclk</entry><entry>1</entry><entry>In</entry><entry>System Clock</entry></row><row><entry>prst_n</entry><entry>1</entry><entry>In</entry><entry>System reset, synchronous active low</entry></row><row><entry>tim_pulse[2:0]</entry><entry>3</entry><entry>Out</entry><entry>Timers block generated timing pulses, each one pclk</entry></row><row><entry /><entry /><entry /><entry>wide</entry></row><row><entry /><entry /><entry /><entry>0 - Nominal 1 μs pulse</entry></row><row><entry /><entry /><entry /><entry>1 - Nominal 100 μs pulse</entry></row><row><entry /><entry /><entry /><entry>2 - Nominal 10 ms pulse</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="287pt" align="left" /><tbody valign="top"><row><entry>CPU interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="168pt" align="left" /><tbody valign="top"><row><entry>cpu_adr[6:2]</entry><entry>5</entry><entry>In</entry><entry>CPU address bus. Only 5 bits are required to decode</entry></row><row><entry /><entry /><entry /><entry>the address space for the ICU block</entry></row><row><entry>cpu_dataout[31:0]</entry><entry>32</entry><entry>In</entry><entry>Shared write data bus from the CPU</entry></row><row><entry>tim_cpu_data[31:0]</entry><entry>32</entry><entry>Out</entry><entry>Read data bus to the CPU</entry></row><row><entry>cpu_rwn</entry><entry>1</entry><entry>In</entry><entry>Common read/not-write signal from the CPU</entry></row><row><entry>cpu_tim_sel</entry><entry>1</entry><entry>In</entry><entry>Block select from the CPU. When cpu_tim_sel is high</entry></row><row><entry /><entry /><entry /><entry>both cpu_adr and cpu_dataout are valid</entry></row><row><entry>tim_cpu_rdy</entry><entry>1</entry><entry>Out</entry><entry>Ready signal to the CPU. When tim_cpu_rdy is high</entry></row><row><entry /><entry /><entry /><entry>it indicates the last cycle of the access. For a write</entry></row><row><entry /><entry /><entry /><entry>cycle this means cpu_dataout has been registered by</entry></row><row><entry /><entry /><entry /><entry>the TIM block and for a read cycle this means the</entry></row><row><entry /><entry /><entry /><entry>data on tim_cpu_data is valid.</entry></row><row><entry>tim_cpu_berr</entry><entry>1</entry><entry>Out</entry><entry>Bus error signal to the CPU indicating an invalid</entry></row><row><entry /><entry /><entry /><entry>access.</entry></row><row><entry>cpu_acode[1:0]</entry><entry>2</entry><entry>In</entry><entry>CPU Access Code signals. These decode as follows:</entry></row><row><entry /><entry /><entry /><entry>00 - User program access</entry></row><row><entry /><entry /><entry /><entry>01 - User data access</entry></row><row><entry /><entry /><entry /><entry>10 - Supervisor program access</entry></row><row><entry /><entry /><entry /><entry>11 - Supervisor data access</entry></row><row><entry>tim_cpu_debug_valid</entry><entry>1</entry><entry>Out</entry><entry>Debug Data valid on tim_cpu_data bus. Active high</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="287pt" align="left" /><tbody valign="top"><row><entry>Miscellaneous</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="168pt" align="left" /><tbody valign="top"><row><entry>tim_icu_wd_irq</entry><entry>1</entry><entry>Out</entry><entry>Watchdog timer interrupt signal to the ICU block</entry></row><row><entry>tim_icu_irq[2:0]</entry><entry>3</entry><entry>Out</entry><entry>Generic timer interrupt signals to the ICU block</entry></row><row><entry>tim_cpr_reset_n</entry><entry>1</entry><entry>Out</entry><entry>Watch dog timer system reset.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 15.4.2 Timers Sub-block Partition <br /> 15.4.3 Watchdog Timer
1722The watchdog timer counts down from pre-programmed value, and generates a system wide reset when equal to one. When the counter passes a pre-programmed threshold (wdog_tim_thres) value an interrupt is generated (tim_icu_wd_irq) requesting the CPU to update the counter. Setting the counter to zero disables the watchdog reset. In supervisor mode the watchdog counter can be written to or read from at any time, in user mode access is denied. Any accesses in user mode will generate a bus error.
1723The counter logic is given by
1724<tables id="TABLE-US-00112" num="00112"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>if (wdog_wen = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="119pt" align="left" /><colspec colname="2" colwidth="70pt" align="left" /><tbody valign="top"><row><entry /><entry>wdog_tim_cnt = write_data</entry><entry>// load new data</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif ( wdog_tim_cnt = = 0) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="119pt" align="left" /><colspec colname="2" colwidth="70pt" align="left" /><tbody valign="top"><row><entry /><entry>wdog_tim_cnt = wdog_tim_cnt</entry><entry>// count disabled</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif ( cnt_en = = 1 ) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>wdog_tim_cnt− −</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>wdog_tim_cnt = wdog_tim_cnt</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
1725The timer decode logic is
1726<tables id="TABLE-US-00113" num="00113"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>if (( wdog_tim_cnt == wdog_tim_thres) AND (wdog_tim_cnt != 0</entry></row><row><entry>)AND (cnt_en == 1)) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>tim_icu_wd_irq = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>tim_icu_wd_irq = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>// reset generator logic</entry></row><row><entry>if (wdog_tim_cnt == 1) AND (cnt_en == 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>tim_cpr_reset_n = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>tim_cpr_reset_n = 1</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 15.4.4 Generic Timers
1727The generic timers block consists of 3 identical counters. A timer is set to a pre-configured value (GenCntStartValue) and counts down once per selected timing pulse (gen_unit_sel). The timer can be enabled or disabled at any time (gen_tim_en), when disabled the counter is stopped but not cleared. The timer can be set to automatically restart (gen_tim_auto) after it generates an interrupt. In supervisor mode a timer can be written to or read from at any time, in user mode access is determined by the GenCntUserModeEnable register settings.
1728The counter logic is given by
1729<tables id="TABLE-US-00114" num="00114"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>if (gen_wen = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>gen_tim_cnt = write_data</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (( cnt_en = = 1 )AND (gen_tim_en = = 1 )) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>if ( gen_tim_cnt = = 1) OR ( gen_tim_cnt = = 0) then //</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>counter may need re-starting</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>if (gen_tim_auto = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>gen_tim_cnt = gen_tim_cnt_st_value</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="112pt" align="left" /><colspec colname="2" colwidth="49pt" align="left" /><tbody valign="top"><row><entry /><entry>gen_tim_cnt = 0</entry><entry>// hold</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>count at zero</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>gen_tim_cnt− −</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>gen_tim_cnt = gen_tim_cnt</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
1730The decode logic is
1731<tables id="TABLE-US-00115" num="00115"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>if (gen_tim_cnt == 1)AND ( cnt_en == 1 )AND (gen_tim_en == 1</entry></row><row><entry>) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>tim_icu_irq = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>tim_icu_irq = 0</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 15.4.5 Timing Pulse Generator
1732The timing pulse generator contains a general free running 64-bit timer and 3 timing pulse generators producing timing pulses of one cycle duration with a programmable period. The period is programmed by changed the TimerStartValue registers, but have a nominal starting period of 1 μs, 100 μs and 1 ms. In supervisor mode the free running timer register can be written to or read from at any time, in user mode access is denied. The status of each of the timers can be read by accessing the PulseTimerStatus registers in supervisor mode. Any accesses in user mode will result in a bus error.
000015.4.5.1 Free Run Timer
1733The increment logic block increments the timer count on each clock cycle. The counter wraps around to zero and continues incrementing if overflow occurs. When the timing register (FreeRunCount) is written to, the configuration registers block will set the free_run_wen high for a clock cycle and the value on write_data will become the new count value. If free_run_wen[1] is 1 the higher 32 bits of the counter will be written to, otherwise if free_run_wen[0] the lower 32 bits are written to. It is the responsibility of software to handle these writes in a sensible manner.
1734The increment logic is given by
1735<tables id="TABLE-US-00116" num="00116"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>if (free_run_wen[1] = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>free_run_cnt[63:32] = write_data</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (free_run_wen[0] = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>free_run_cnt[31:0] = write_data</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>free_run_cnt ++</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 15.4.5.2 Pulse Timers
1736The pulse timer logic generates timing pulses of 1 clock cycle length and programmable period. Nominally they generate pulse periods of 1 μs, 100 μs and 1 ms. The logic for timer 0 is given by:
1737<tables id="TABLE-US-00117" num="00117"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>// Nominal 1us generator</entry></row><row><entry /><entry>if (pulse_0_cnt = = 0 ) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>pulse_0_cnt = timer_start_value[0]</entry></row><row><entry /><entry>tim_pulse[0] = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>pulse_0_cnt − −</entry></row><row><entry /><entry>tim_pulse[0] = 0</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
1738The logic for timer 1 is given by:
1739<tables id="TABLE-US-00118" num="00118"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="196pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>// 100us generator</entry></row><row><entry /><entry>if ((pulse_1_cnt = = 0) AND (tim_pulse[0] = = 1)) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>pulse_1_cnt = timer_start_value[1]</entry></row><row><entry /><entry>tim_pulse[1] = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="196pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (tim_pulse[0] = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>pulse_1_cnt − −</entry></row><row><entry /><entry>tim_pulse[1] = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="196pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>pulse_1_cnt = pulse_1_cnt</entry></row><row><entry /><entry>tim_pulse[1] = 0</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
1740The logic for the timer 2 is given by:
1741<tables id="TABLE-US-00119" num="00119"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="196pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>// 10ms generator</entry></row><row><entry /><entry>if ((pulse_2_cnt = = 0 ) AND (tim_pulse[1] = = 1)) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>pulse_2_cnt = timer_start_value[2]</entry></row><row><entry /><entry>tim_pulse[2] = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="196pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (tim_pulse[1] = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>pulse_2_cnt − −</entry></row><row><entry /><entry>tim_pulse[2] = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="196pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>pulse_2_cnt = pulse_2_cnt</entry></row><row><entry /><entry>tim_pulse[2] = 0</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 15.4.6 Configuration Registers
1742The configuration registers in the TIM are programmed via the CPU interface. Refer to section 11.4.3 on page 69 for a description of the protocol and timing diagrams for reading and writing registers in the TIM. Note that since addresses in SoPEC are byte aligned and the CPU only supports 32-bit register reads and writes, the lower 2 bits of the CPU address bus are not required to decode the address space for the TIM. When reading a register that is less than 32 bits wide zeros should be returned on the upper unused bit(s) of tim_pcu_data. Table 92 lists the configuration registers in the TIM block.
1743<tables id="TABLE-US-00120" num="00120"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="322pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 92</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Timers Register Map</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="28pt" align="center" /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="119pt" align="center" /><tbody valign="top"><row><entry>Address</entry><entry /><entry /><entry /><entry /></row><row><entry>TIM_base+</entry><entry>Register</entry><entry>#bits</entry><entry>Reset</entry><entry>Description</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>0x00</entry><entry>WatchDogUnitSel</entry><entry>2</entry><entry>0x0</entry><entry>Specifies the units used for the</entry></row><row><entry /><entry /><entry /><entry /><entry>watchdog timer:</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - Nominal 1 μs pulse</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - Nominal 100 μs pulse</entry></row><row><entry /><entry /><entry /><entry /><entry>2 - Nominal 10 ms pulse</entry></row><row><entry /><entry /><entry /><entry /><entry>3 - pclk</entry></row><row><entry>0x04</entry><entry>WatchDogTimer</entry><entry>32</entry><entry>0xFFFF_FFFF</entry><entry>Specifies the number of units to count</entry></row><row><entry /><entry /><entry /><entry /><entry>before watchdog timer triggers.</entry></row><row><entry>0x08</entry><entry>WatchDogIntThres</entry><entry>32</entry><entry>0x0000_0000</entry><entry>Specifies the threshold value below</entry></row><row><entry /><entry /><entry /><entry /><entry>which the watchdog timer issues an</entry></row><row><entry /><entry /><entry /><entry /><entry>interrupt</entry></row><row><entry>0x0C–0x10</entry><entry>FreeRunCount[1:0]</entry><entry>2 × 32</entry><entry>0x0000_0000</entry><entry>Direct access to the free running</entry></row><row><entry /><entry /><entry /><entry /><entry>counter register.</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 0 - Access to bits 31–0</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 1 - Access to bits 63–32</entry></row><row><entry>0x14 to 0x1C</entry><entry>GenCntStartValue[2:0]</entry><entry>3 × 32</entry><entry>0x0000_0000</entry><entry>Generic timer counter start value,</entry></row><row><entry /><entry /><entry /><entry /><entry>number of units to count before event</entry></row><row><entry>0x20 to 0x28</entry><entry>GenCntValue[2:0]</entry><entry>3 × 32</entry><entry>0x0000_0000</entry><entry>Direct access to generic timer counter</entry></row><row><entry /><entry /><entry /><entry /><entry>registers</entry></row><row><entry>0x2C to 0x34</entry><entry>GenCntUnitSel[2:0]</entry><entry>3 × 2</entry><entry>0x0</entry><entry>Generic counter unit select. Selects the</entry></row><row><entry /><entry /><entry /><entry /><entry>timing units used with</entry></row><row><entry /><entry /><entry /><entry /><entry>corresponding counter:</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - Nominal 1 μs pulse</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - Nominal 100 μs pulse</entry></row><row><entry /><entry /><entry /><entry /><entry>2 - Nominal 10 ms pulse</entry></row><row><entry /><entry /><entry /><entry /><entry>3 - pclk</entry></row><row><entry>0x38 to 0x40</entry><entry>GenCntAuto[2:0]</entry><entry>3 × 1</entry><entry>0x0</entry><entry>Generic counter auto re-start select.</entry></row><row><entry /><entry /><entry /><entry /><entry>When high timer automatically</entry></row><row><entry /><entry /><entry /><entry /><entry>restarts, otherwise timer stops.</entry></row><row><entry>0x44 to 0x4C</entry><entry>GenCntEnable[2:0]</entry><entry>3 × 1</entry><entry>0x0</entry><entry>Generic counter enable.</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - Counter disabled</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - Counter enabled</entry></row><row><entry>0x50</entry><entry>GenCntUserModeEnable</entry><entry>3</entry><entry>0x0</entry><entry>User Mode Access enable to generic</entry></row><row><entry /><entry /><entry /><entry /><entry>timer configuration register. When 1</entry></row><row><entry /><entry /><entry /><entry /><entry>user access is enabled.</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 0 - Generic timer 0</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 1 - Generic timer 1</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 2 - Generic timer 2</entry></row><row><entry>0x54 to 0x5C</entry><entry>TimerStartValue[2:0]</entry><entry>3 × 8</entry><entry>0x7F,</entry><entry>Timing pulse generator start value.</entry></row><row><entry /><entry /><entry /><entry>0x63,</entry><entry>Indicates the start value for each</entry></row><row><entry /><entry /><entry /><entry>0x63</entry><entry>timing pulse timers. For timer 0 the</entry></row><row><entry /><entry /><entry /><entry /><entry>start value specifies the timer period</entry></row><row><entry /><entry /><entry /><entry /><entry>in pclk cycles − 1.</entry></row><row><entry /><entry /><entry /><entry /><entry>For timer 1 the start value specifies</entry></row><row><entry /><entry /><entry /><entry /><entry>the timer period in timer 0 intervals − 1.</entry></row><row><entry /><entry /><entry /><entry /><entry>For timer 2 the start value specifies</entry></row><row><entry /><entry /><entry /><entry /><entry>the timer period in timer 1 intervals − 1.</entry></row><row><entry /><entry /><entry /><entry /><entry>Nominally the timers generate pulses</entry></row><row><entry /><entry /><entry /><entry /><entry>at 1 us, 100 us and 10 ms intervals</entry></row><row><entry /><entry /><entry /><entry /><entry>respectively.</entry></row><row><entry>0x60</entry><entry>DebugSelect[6:2]</entry><entry>5</entry><entry>0x00</entry><entry>Debug address select. Indicates the</entry></row><row><entry /><entry /><entry /><entry /><entry>address of the register to report on</entry></row><row><entry /><entry /><entry /><entry /><entry>the tim_cpu_data bus when it is not</entry></row><row><entry /><entry /><entry /><entry /><entry>otherwise being used.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="322pt" align="left" /><tbody valign="top"><row><entry>Read Only</entry></row><row><entry>Registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>0x64</entry><entry>PulseTimerStatus</entry><entry>24</entry><entry>0x00</entry><entry>Current pulse timer values, and</entry></row><row><entry /><entry /><entry /><entry /><entry>pulses</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="49pt" align="left" /><colspec colname="6" colwidth="70pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry /><entry /><entry>7:0 -</entry><entry>Timer 0 count</entry></row><row><entry /><entry /><entry /><entry /><entry>15:8 -</entry><entry>Timer 1 count</entry></row><row><entry /><entry /><entry /><entry /><entry>23:16 -</entry><entry>Timer 2 count</entry></row><row><entry /><entry /><entry /><entry /><entry>24 -</entry><entry>Timer 0 pulse</entry></row><row><entry /><entry /><entry /><entry /><entry>25 -</entry><entry>Timer 1 pulse</entry></row><row><entry /><entry /><entry /><entry /><entry>26 -</entry><entry>Timer 2 pulse</entry></row><row><entry namest="1" nameend="6" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 15.4.6.1 Supervisor and User Mode Access
1744The configuration registers block examines the CPU access type (cpu_acode signal) and determines if the access is allowed to that particular register, based on configured user access registers. If an access is not allowed the block will issue a bus error by asserting the tim_cpu_berr signal.
1745The timers block is fully accessible in supervisor data mode, all registers can written to and read from. In user mode access is denied to all registers in the block except for the generic timer configuration registers that are granted user data access. User data access for a generic timer is granted by setting corresponding bit in the GenCntUserModeEnable register. This can only be changed in supervisor data mode. If a particular timer is granted user data access then all registers for configuring that timer will be accessible. For example if timer 0 is granted user data access the GenCntStartValue[0], GenCntUnitSel[0], GenCntAuto[0], GenCntEnable[0] and GenCntValue[0] registers can all be written to and read from without any restriction.
1746Attempts to access a user data mode disabled timer configuration register will result in a bus error. Table 93 details the access modes allowed for registers in the TIM block. In supervisor data mode all registers are accessable. All forbidden accesses will result in a bus error (tim_cpu_berr asserted).
1747<tables id="TABLE-US-00121" num="00121"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 93</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>TIM supervisor and user access modes</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="91pt" align="left" /><tbody valign="top"><row><entry>Register</entry><entry /><entry /></row><row><entry>Address</entry><entry>Registers</entry><entry>Access Permission</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>0x00</entry><entry>WatchDogUnitSel</entry><entry>Supervisor data mode only</entry></row><row><entry>0x04</entry><entry>WatchDogTimer</entry><entry>Supervisor data mode only</entry></row><row><entry>0x08</entry><entry>WatchDogIntThres</entry><entry>Supervisor data mode only</entry></row><row><entry>0x0C–0x10</entry><entry>FreeRunCount</entry><entry>Supervisor data mode only</entry></row><row><entry>0x14</entry><entry>GenCntStartValue[0]</entry><entry>GenCntUserModeEnable[0]</entry></row><row><entry>0x18</entry><entry>GenCntStartValue[1]</entry><entry>GenCntUserModeEnable[1]</entry></row><row><entry>0x1C</entry><entry>GenCntStartValue[2]</entry><entry>GenCntUserModeEnable[2]</entry></row><row><entry>0x20</entry><entry>GenCntValue[0]</entry><entry>GenCntUserModeEnable[0]</entry></row><row><entry>0x24</entry><entry>GenCntValue[1]</entry><entry>GenCntUserModeEnable[1]</entry></row><row><entry>0x28</entry><entry>GenCntValue[2]</entry><entry>GenCntUserModeEnable[2]</entry></row><row><entry>0x2C</entry><entry>GenCntUnitSel[0]</entry><entry>GenCntUserModeEnable[0]</entry></row><row><entry>0x30</entry><entry>GenCntUnitSel[1]</entry><entry>GenCntUserModeEnable[1]</entry></row><row><entry>0x34</entry><entry>GenCntUnitSel[2]</entry><entry>GenCntUserModeEnable[2]</entry></row><row><entry>0x38</entry><entry>GenCntAuto[0]</entry><entry>GenCntUserModeEnable[0]</entry></row><row><entry>0x3C</entry><entry>GenCntAuto[1]</entry><entry>GenCntUserModeEnable[1]</entry></row><row><entry>0x40</entry><entry>GenCntAuto[2]</entry><entry>GenCntUserModeEnable[2]</entry></row><row><entry>0x44</entry><entry>GenCntEnable[0]</entry><entry>GenCntUserModeEnable[0]</entry></row><row><entry>0x48</entry><entry>GenCntEnable[1]</entry><entry>GenCntUserModeEnable[1]</entry></row><row><entry>0x4C</entry><entry>GenCntEnable[2]</entry><entry>GenCntUserModeEnable[2]</entry></row><row><entry>0x50</entry><entry>GenCntUserModeEnable</entry><entry>Supervisor data mode only</entry></row><row><entry>0x54–0x5C</entry><entry>TimerStartValue[2:0]</entry><entry>Supervisor data mode only</entry></row><row><entry>0x60</entry><entry>DebugSelect</entry><entry>Supervisor data mode only</entry></row><row><entry>0x64</entry><entry>PulseTimerStatus</entry><entry>Supervisor data mode only</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 16 Clocking, Power and Reset (CPR)
1748The CPR block provides all of the clock, power enable and reset signals to the SoPEC device.
000016.1 Powerdown Modes
1749The CPR block is capable of powering down certain sections of the SoPEC device. When a section is powered down (i.e. put in sleep mode) no state is retained (except the PSS storage), the CPU must re-initialize the section before it can be used again.
1750For the purpose of powerdown the SoPEC device is divided into sections:
1751<tables id="TABLE-US-00122" num="00122"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 94</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Powerdown sectioning</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="112pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry>Section</entry><entry>Block</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>Print Engine Pipeline</entry><entry>PCU</entry></row><row><entry /><entry>Subsystem (Section 0)</entry><entry>CDU</entry></row><row><entry /><entry /><entry>CFU</entry></row><row><entry /><entry /><entry>LBD</entry></row><row><entry /><entry /><entry>SFU</entry></row><row><entry /><entry /><entry>TE</entry></row><row><entry /><entry /><entry>TFU</entry></row><row><entry /><entry /><entry>HCU</entry></row><row><entry /><entry /><entry>DNC</entry></row><row><entry /><entry /><entry>DWU</entry></row><row><entry /><entry /><entry>LLU</entry></row><row><entry /><entry /><entry>PHI</entry></row><row><entry /><entry>CPU-DRAM (Section 1)</entry><entry>DRAM</entry></row><row><entry /><entry /><entry>CPU/MMU</entry></row><row><entry /><entry /><entry>DIU</entry></row><row><entry /><entry /><entry>TIM</entry></row><row><entry /><entry /><entry>ROM</entry></row><row><entry /><entry /><entry>LSS</entry></row><row><entry /><entry /><entry>PSS</entry></row><row><entry /><entry /><entry>ICU</entry></row><row><entry /><entry>ISI Subsystem (Section 2)</entry><entry>ISI (SCB)</entry></row><row><entry /><entry /><entry>DMA Ctrl (SCB)</entry></row><row><entry /><entry /><entry>GPIO</entry></row><row><entry /><entry>USB Subsystem (Section 3)</entry><entry>USB (SCB)</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
1752Note that the CPR block is not located in any section. All configuration registers in the CPR block are clocked by an ungateable clock and have special reset conditions.
000016.1.1 Sleep Mode
1753Each section can be put into sleep mode by setting the corresponding bit in the SleepModeEnable register. To re-enable the section the sleep mode bit needs to be cleared and then the section should be reset by writing to the relevant bit in the ResetSection register. Each block within the section should then be re-configured by the CPU.
1754If the CPU system (section 1) is put into sleep mode, the SoPEC device will remain in sleep mode until a system level reset is initiated from the reset pin, or a wakeup reset by the SCB block as a result of activity on either the USB or ISI bus. The watchdog timer cannot reset the device as it is in section 1 also, and will be in sleep mode.
1755If the CPU and ISI subsystem are in sleep mode only a reset from the USB or a hardware reset will re-activate the SoPEC device.
1756If all sections are put into sleep mode, then only a system level reset initiated by the reset pin will re-activate the SoPEC device.
1757Like all software resets in SoPEC the ResetSection register is active-low i e. a 0 should be written to each bit position requiring a reset. The ResetSection register is self-reseting.
000016.1.2 Sleep Mode Powerdown Procedure
1758When powering down a section, the section may retain it's current state (although not gauranteed to). It is possible when powering back up a section that inconsistencies between interface state machines could cause incorrect operation. In order to prevent such condition from happening, all blocks in a section must be disabled before powering down. This will ensure that blocks are restored in a benign state when powered back up.
1759In the case of PEP section units setting the Go bit to zero will disable the block. The DRAM subsystem can be effectively disabled by setting the RotationSync bit to zero, and the SCB system disabled by setting the DMAAccessEn bits to zero turning off the DMA access to DRAM. Other CPU subsystem blocks without any DRAM access do not need to be disabled.
000016.2 Reset Source
1760The SoPEC device can be reset by a number of sources. When a reset from an internal source is initiated the reset source register (ResetSrc) stores the reset source value. This register can then be used by the CPU to determine the type of boot sequence required.
000016.3 Clock Relationship
1761The crystal oscillator excites a 32 MHz crystal through the xtalin and xtalout pins. The 32 MHz output is used by the PLL to derive the master VCO frequency of 960 MHz. The master clock is then divided to produce 320 MHz clock (clk<b>320</b>), 160 MHz clock (clk<b>160</b>) and 48 MHz (clk<b>48</b>) clock sources.
1762The phase relationship of each clock from the PLL will be defined. The relationship of internal clocks clk<b>320</b>, clk<b>48</b> and clk<b>160</b> to xtalin will be undefined.
1763At the output of the clock block, the skew between each pclk domain (pclk_section[2:0] and jclk) should be within skew tolerances of their respective domains (defined as less than the hold time of a D-type flip flop).
1764The skew between doclk and pclk should also be less than the skew tolerances of their respective domains.
1765The usbclk is derived from the PLL output and has no relationship with the other clocks in the system and is considered asynchronous.
000016.4 PLL Control
1766The PLL in SoPEC can be adjusted by programming the PLLRangeA, PLLRangeB, PLLTunebits and PLLMult registers. If these registers are changed by the CPU the values are not updated until the PLLUpdate register is written to. Writing to the PLLUpdate register triggers the PLL control state machine to update the PLL configuration in a safe way. When an update is active (as indicated by PLLUpdate register) the CPU must not change any of the configuration registers, doing so could cause the PLL to lose lock indefintely, requiring a hardware reset to recover. Configuring the PLL registers in an inconsistent way can also cause the PLL to lose lock, care must taken to keep the PLL configuration within specified parameters.
1767The VCO frequency of the PLL is calculated by the number of divider in the feedback path. PLL output A is used as the feedback source. <br /><i>VCO</i>freq=REF<i>CLK×PLL</i>Mult×<i>PLL</i>Range<i>A</i>×External divider<br /><i>VCO</i>freq=32×3×10×1=960 Mhz.
1768In the default PLL setup, PLLMult is set to 3, PLLRangeA is set to 3 which corresponds to a divide by 10, PLLRangeB is set to 5 which corresponds to a divide by 3. <br /><i>PLL</i>out<i>a=VCO</i>freq/<i>PLL</i>Range<i>A</i>=960 Mhz/10=96 Mhz<br /><i>PLL</i>out<i>b=VCO</i>freq/<i>PLL</i>Range<i>B</i>=960 Mhz/3=320 Mhz
1769See [16] for complete PLL setup parameters.
000016.5 Implementation
000016.5.1 Definitions of I/O
1770<tables id="TABLE-US-00123" num="00123"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 95</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>CPR I/O definition</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="28pt" align="left" /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="70pt" align="left" /><tbody valign="top"><row><entry>Port name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Clocks and Resets</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="28pt" align="left" /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="70pt" align="left" /><tbody valign="top"><row><entry>Xtalin</entry><entry>1</entry><entry>In</entry><entry>Crystal input,</entry></row><row><entry /><entry /><entry /><entry>direct from IO</entry></row><row><entry /><entry /><entry /><entry>pin.</entry></row><row><entry>Xtalout</entry><entry>1</entry><entry>Inout</entry><entry>Crystal output,</entry></row><row><entry /><entry /><entry /><entry>direct to IO</entry></row><row><entry /><entry /><entry /><entry>pin.</entry></row><row><entry>pclk_section[3:0]</entry><entry>4</entry><entry>Out</entry><entry>System clocks</entry></row><row><entry /><entry /><entry /><entry>for each section</entry></row><row><entry>Doclk</entry><entry>1</entry><entry>Out</entry><entry>Data out clock</entry></row><row><entry /><entry /><entry /><entry>(2× pclk) for</entry></row><row><entry /><entry /><entry /><entry>the PHI block</entry></row><row><entry>Jclk</entry><entry>1</entry><entry>Out</entry><entry>Gated version of</entry></row><row><entry /><entry /><entry /><entry>system clock</entry></row><row><entry /><entry /><entry /><entry>used to clock</entry></row><row><entry /><entry /><entry /><entry>the JPEG decoder</entry></row><row><entry /><entry /><entry /><entry>core in the CDU</entry></row><row><entry>Usbclk</entry><entry>1</entry><entry>Out</entry><entry>USB clock,</entry></row><row><entry /><entry /><entry /><entry>nominally at</entry></row><row><entry /><entry /><entry /><entry>48 Mhz</entry></row><row><entry>jclk_enable</entry><entry>1</entry><entry>In</entry><entry>Gating signal for</entry></row><row><entry /><entry /><entry /><entry>jclk. When 1 jclk</entry></row><row><entry /><entry /><entry /><entry>is enabled</entry></row><row><entry>reset_n</entry><entry>1</entry><entry>In</entry><entry>Reset signal</entry></row><row><entry /><entry /><entry /><entry>from the</entry></row><row><entry /><entry /><entry /><entry>reset_n pin</entry></row><row><entry>usb_cpr_reset_n</entry><entry>1</entry><entry>In</entry><entry>Reset signal</entry></row><row><entry /><entry /><entry /><entry>from the USB block</entry></row><row><entry>isi_cpr_reset_n</entry><entry>1</entry><entry>In</entry><entry>Reset signal</entry></row><row><entry /><entry /><entry /><entry>from the ISI block</entry></row><row><entry>tim_cpr_reset_n</entry><entry>1</entry><entry>In</entry><entry>Reset signal from</entry></row><row><entry /><entry /><entry /><entry>watch dog timer.</entry></row><row><entry>gpio_cpr_wakeup</entry><entry>1</entry><entry>In</entry><entry>SoPEC wake up</entry></row><row><entry /><entry /><entry /><entry>from the GPIO,</entry></row><row><entry /><entry /><entry /><entry>active high.</entry></row><row><entry>prst_n_section[3:0]</entry><entry>4</entry><entry>Out</entry><entry>System resets</entry></row><row><entry /><entry /><entry /><entry>for each section,</entry></row><row><entry /><entry /><entry /><entry>synchronous</entry></row><row><entry /><entry /><entry /><entry>active low</entry></row><row><entry>dorst_n</entry><entry>1</entry><entry>Out</entry><entry>Reset for PHI</entry></row><row><entry /><entry /><entry /><entry>block, synchronous</entry></row><row><entry /><entry /><entry /><entry>to doclk</entry></row><row><entry>jrst_n</entry><entry>1</entry><entry>Out</entry><entry>Reset for JPEG</entry></row><row><entry /><entry /><entry /><entry>decoder core in</entry></row><row><entry /><entry /><entry /><entry>CDU block,</entry></row><row><entry /><entry /><entry /><entry>synchronous</entry></row><row><entry /><entry /><entry /><entry>to jclk</entry></row><row><entry>usbrst_n</entry><entry>1</entry><entry>Out</entry><entry>Reset for the</entry></row><row><entry /><entry /><entry /><entry>USB block,</entry></row><row><entry /><entry /><entry /><entry>synchronous</entry></row><row><entry /><entry /><entry /><entry>to usbclk</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>CPU interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="28pt" align="left" /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="70pt" align="left" /><tbody valign="top"><row><entry>cpu_adr[5:2]</entry><entry>3</entry><entry>In</entry><entry>CPU address bus.</entry></row><row><entry /><entry /><entry /><entry>Only 4 bits are</entry></row><row><entry /><entry /><entry /><entry>required to</entry></row><row><entry /><entry /><entry /><entry>decode the address</entry></row><row><entry /><entry /><entry /><entry>space for the</entry></row><row><entry /><entry /><entry /><entry>CPR block</entry></row><row><entry>cpu_dataout[31:0]</entry><entry>32</entry><entry>In</entry><entry>Shared write</entry></row><row><entry /><entry /><entry /><entry>data bus from</entry></row><row><entry /><entry /><entry /><entry>the CPU</entry></row><row><entry>cpr_cpu_data[31:0]</entry><entry>32</entry><entry>Out</entry><entry>Read data bus</entry></row><row><entry /><entry /><entry /><entry>to the CPU</entry></row><row><entry>cpu_rwn</entry><entry>1</entry><entry>In</entry><entry>Common read/not-</entry></row><row><entry /><entry /><entry /><entry>write signal</entry></row><row><entry /><entry /><entry /><entry>from the CPU</entry></row><row><entry>cpu_cpr_sel</entry><entry>1</entry><entry>In</entry><entry>Block select from</entry></row><row><entry /><entry /><entry /><entry>the CPU. When</entry></row><row><entry /><entry /><entry /><entry>cpu_cpr_sel is</entry></row><row><entry /><entry /><entry /><entry>high both cpu_adr</entry></row><row><entry /><entry /><entry /><entry>and cpu_dataout</entry></row><row><entry /><entry /><entry /><entry>are valid</entry></row><row><entry>cpr_cpu_rdy</entry><entry>1</entry><entry>Out</entry><entry>Ready signal to</entry></row><row><entry /><entry /><entry /><entry>the CPU. When</entry></row><row><entry /><entry /><entry /><entry>cpr_cpu_rdy is</entry></row><row><entry /><entry /><entry /><entry>high it indicates</entry></row><row><entry /><entry /><entry /><entry>the last cycle of</entry></row><row><entry /><entry /><entry /><entry>the access. For a</entry></row><row><entry /><entry /><entry /><entry>write cycle this</entry></row><row><entry /><entry /><entry /><entry>means cpu_dataout</entry></row><row><entry /><entry /><entry /><entry>has been</entry></row><row><entry /><entry /><entry /><entry>registered by the</entry></row><row><entry /><entry /><entry /><entry>block and for a</entry></row><row><entry /><entry /><entry /><entry>read cycle this</entry></row><row><entry /><entry /><entry /><entry>means the data on</entry></row><row><entry /><entry /><entry /><entry>cpr_cpu_data is</entry></row><row><entry /><entry /><entry /><entry>valid.</entry></row><row><entry>cpr_cpu_berr</entry><entry>1</entry><entry>Out</entry><entry>Bus error signal</entry></row><row><entry /><entry /><entry /><entry>to the CPU</entry></row><row><entry /><entry /><entry /><entry>indicating an</entry></row><row><entry /><entry /><entry /><entry>invalid access.</entry></row><row><entry>cpu_acode[1:0]</entry><entry>2</entry><entry>In</entry><entry>CPU Access Code</entry></row><row><entry /><entry /><entry /><entry>signals. These</entry></row><row><entry /><entry /><entry /><entry>decode as follows:</entry></row><row><entry /><entry /><entry /><entry>00 - User</entry></row><row><entry /><entry /><entry /><entry>program access</entry></row><row><entry /><entry /><entry /><entry>01 - User</entry></row><row><entry /><entry /><entry /><entry>data access</entry></row><row><entry /><entry /><entry /><entry>10 - Supervisor</entry></row><row><entry /><entry /><entry /><entry>program access</entry></row><row><entry /><entry /><entry /><entry>11 - Supervisor</entry></row><row><entry /><entry /><entry /><entry>data access</entry></row><row><entry>cpr_cpu_debug_valid</entry><entry>1</entry><entry>Out</entry><entry>Debug Data valid</entry></row><row><entry /><entry /><entry /><entry>on cpr_cpu_data</entry></row><row><entry /><entry /><entry /><entry>bus. Active high</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 16.5.2 Configuration Registers
1771The configuration registers in the CPR are programmed via the CPU interface. Refer to section 11.4 on page 69 for a description of the protocol and timing diagrams for reading and writing registers in the CPR. Note that since addresses in SoPEC are byte aligned and the CPU only supports 32-bit register reads and writes, the lower 2 bits of the CPU address bus are not required to decode the address space for the CPR. When reading a register that is less than 32 bits wide zeros should be returned on the upper unused bit(s) of cpr_pcu_data. Table 96 lists the configuration registers in the CPR block.
1772The CPR block will only allow supervisor data mode accesses (i.e. cpu_acode[1:0]=SUPERVISOR_DATA). All other accesses will result in cpr_cpu_berr being asserted.
1773<tables id="TABLE-US-00124" num="00124"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 96</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>CPR Register Map</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="56pt" align="left" /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="28pt" align="left" /><colspec colname="5" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>Address</entry><entry /><entry /><entry /><entry /></row><row><entry>CPR_base+</entry><entry>Register</entry><entry>#bits</entry><entry>Reset</entry><entry>Description</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="56pt" align="left" /><colspec colname="3" colwidth="21pt" align="char" char="." /><colspec colname="4" colwidth="28pt" align="left" /><colspec colname="5" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>0x00</entry><entry>SleepModeEnable</entry><entry>4</entry><entry>0x0<sup>a</sup></entry><entry>Sleep Mode enable, when high a section</entry></row><row><entry /><entry /><entry /><entry /><entry>of logic is put into powerdown.</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 0 - Controls section 0</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 1 - Controls section 1</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 2 - Controls section 2</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 3 - Controls section 3</entry></row><row><entry /><entry /><entry /><entry /><entry>Note that the SleepModeEnable register</entry></row><row><entry /><entry /><entry /><entry /><entry>has special reset conditions. See</entry></row><row><entry /><entry /><entry /><entry /><entry>Section 16.5.6 for details</entry></row><row><entry>0x04</entry><entry>ResetSrc</entry><entry>5</entry><entry>0x1<sup>a</sup></entry><entry>Reset Source register, indicating the</entry></row><row><entry /><entry /><entry /><entry /><entry>source of the last reset (or wake-up)</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 0 - External Reset</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 1 - USB wakeup reset</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 2 - ISI wakeup reset</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 3 - Watchdog timer reset</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 4 - GPIO wake-up</entry></row><row><entry /><entry /><entry /><entry /><entry>(Read Only Register)</entry></row><row><entry>0x08</entry><entry>ResetSection</entry><entry>4</entry><entry>0xF</entry><entry>Active-low synchronous reset for each</entry></row><row><entry /><entry /><entry /><entry /><entry>section, self-resetting.</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 0 - Controls section 0</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 1 - Controls section 1</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 2 - Controls section 2</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 3 - Controls section 3</entry></row><row><entry>0x0C</entry><entry>DebugSelect[5:2]</entry><entry>4</entry><entry>0x0</entry><entry>Debug address select. Indicates the</entry></row><row><entry /><entry /><entry /><entry /><entry>address of the register to report on the</entry></row><row><entry /><entry /><entry /><entry /><entry>cpr_cpu_data bus when it is not</entry></row><row><entry /><entry /><entry /><entry /><entry>otherwise being used.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="left" /><tbody valign="top"><row><entry>PLL Control</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="56pt" align="left" /><colspec colname="3" colwidth="21pt" align="char" char="." /><colspec colname="4" colwidth="28pt" align="left" /><colspec colname="5" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>0x10</entry><entry>PLLTuneBits</entry><entry>10</entry><entry>0x3BC</entry><entry>PLL tuning bits</entry></row><row><entry>0x14</entry><entry>PLLRangeA</entry><entry>4</entry><entry>0x3</entry><entry>PLLOUT A frequency selector (defaults</entry></row><row><entry /><entry /><entry /><entry /><entry>to 60 Mhz to 125 Mhz)</entry></row><row><entry>0x18</entry><entry>PLLRangeB</entry><entry>3</entry><entry>0x5</entry><entry>PLLOUT B frequency selector (defaults</entry></row><row><entry /><entry /><entry /><entry /><entry>to 200 Mhz to 400 Mhz)</entry></row><row><entry>0x1C</entry><entry>PLLMultiplier</entry><entry>5</entry><entry>0x03</entry><entry>PLL multiplier selector, defaults to</entry></row><row><entry /><entry /><entry /><entry /><entry>refclk × 3</entry></row><row><entry>0x20</entry><entry>PLLUpdate</entry><entry>1</entry><entry>0x0</entry><entry>PLL update control. A write (of any</entry></row><row><entry /><entry /><entry /><entry /><entry>value) to this register will cause the</entry></row><row><entry /><entry /><entry /><entry /><entry>PLL to lose lock for ~100 us. Reading</entry></row><row><entry /><entry /><entry /><entry /><entry>the register indicates the status of the</entry></row><row><entry /><entry /><entry /><entry /><entry>update.</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - PLL update complete</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - PLL update active</entry></row><row><entry /><entry /><entry /><entry /><entry>No writes to</entry></row><row><entry /><entry /><entry /><entry /><entry>PLLTuneBits, PLLRangeA, PLL-</entry></row><row><entry /><entry /><entry /><entry /><entry>RangeB, PLLMultiplier or PLLUpdate</entry></row><row><entry /><entry /><entry /><entry /><entry>are allowed while the PLL update is</entry></row><row><entry /><entry /><entry /><entry /><entry>active.</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row><row><entry namest="1" nameend="5" align="left" id="FOO-00007"><sup>a</sup>Reset value depends on reset source. External reset shown.</entry></row></tbody></tgroup></table></tables><br /> 16.5.3 CPR Sub-block Partition <br /> 16.5.4 Reset_n deglitch
1774The external reset_n signal is deglitched for about 1 μs. reset_n must maintain a state for 1 us second before the state is passed into the rest of the device. All deglitch logic is clocked on bufrefclk.
000016.5.5 Sync Reset
1775The reset synchronizer retimes an asynchronous reset signal to the clock domain that it resets. The circuit prevents the inactive edge of reset occurring when the clock is rising
000016.5.6 Reset Generator Logic
1776The reset generator logic is used to determine which clock domains should be reset, based on configured reset values (reset_section_n), the external reset (reset_n), watchdog timer reset (tim_cpr_reset_n), the USB reset (usb_cpr_reset_n), the GPIO wakeup control (gpio_cpr_wakeup) and the ISI reset (isi_cpr_reset_n). The reset direct from the IO pin (reset_n) is synchronized and de-glitched before feeding the reset logic.
1777All resets are lengthened to at least 16 pclk cycles, regardless of the duration of the input reset. The clock for a particular section must be running for the reset to have an effect. The clocks to each section can be enabled/disabled using the SleepModeEnable register.
1778Resets from the ISI or USB block reset everything except its own section (section 2 or 3).
1779<tables id="TABLE-US-00125" num="00125"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 97</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Reset domains</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="119pt" align="left" /><tbody valign="top"><row><entry /><entry>Reset signal</entry><entry>Domain</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>reset_dom[0]</entry><entry>Section 0 pclk domain (PEP)</entry></row><row><entry /><entry>reset_dom[1]</entry><entry>Section 1 pclk domain (CPU)</entry></row><row><entry /><entry>reset_dom[2]</entry><entry>Section 2 pclk domain (ISI)</entry></row><row><entry /><entry>reset_dom[3]</entry><entry>Section 3 usbclk/pclk domain</entry></row><row><entry /><entry /><entry>(USB)</entry></row><row><entry /><entry>reset_dom[4]</entry><entry>doclk domain</entry></row><row><entry /><entry>reset_dom[5]</entry><entry>jclk domain</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
1780The logic is given by
1781<tables id="TABLE-US-00126" num="00126"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>if (reset_dg_n = = 0) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><colspec colname="3" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry>reset_dom[5:0]</entry><entry>= 0x00</entry><entry>// reset everything</entry></row><row><entry /><entry>reset_src[4:0]</entry><entry>= 0x01</entry></row><row><entry /><entry>cfg_reset_n</entry><entry>= 0</entry></row><row><entry /><entry>sleep_mode_en[3:0]</entry><entry>= 0x0</entry><entry>// re-awaken all sections</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>elsif (tim_cpr_reset_n = = 0) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><colspec colname="3" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry>reset_dom[5:0]</entry><entry> = 0x00</entry><entry> // reset everything except</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>CPR config</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>reset_src[4:0]</entry><entry>= 0x08</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><colspec colname="3" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry>cfg_reset_n</entry><entry>= 1</entry><entry>// CPR config stays the same</entry></row><row><entry /><entry>sleep_mode_en[1]</entry><entry> = 0</entry><entry> // re-awaken section 1 only</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>(awake already)</entry></row><row><entry>elsif (usb_cpr_reset_n = = 0) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><colspec colname="3" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry>reset_dom[5:0]</entry><entry> = 0x08</entry><entry> // all except USB domain +</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>CPR config</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>reset_src[4:0]</entry><entry>= 0x02</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><colspec colname="3" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry>cfg_reset_n</entry><entry>= 1</entry><entry>// CPR config stays the same</entry></row><row><entry /><entry>sleep_mode_en[1]</entry><entry> = 0</entry><entry> // re-awaken section 1 only,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>section 3 is awake</entry></row><row><entry>elsif (isi_cpr_reset_n = = 0) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><colspec colname="3" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry>reset_dom[5:0]</entry><entry> = 0x04</entry><entry> // all except ISI domain +</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>CPR config</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>reset_src[4:0]</entry><entry>= 0x04</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><colspec colname="3" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry>cfg_reset_n</entry><entry>= 1</entry><entry>// CPR config stays the same</entry></row><row><entry /><entry>sleep_mode_en[1]</entry><entry> = 0</entry><entry> // re-awaken section 1 only,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>section 2 is awake</entry></row><row><entry>elsif (gpio_cpr_wakeup = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><colspec colname="3" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry>reset_dom[5:0]</entry><entry>= 0x3C</entry><entry>// PEP and CPU sections only</entry></row><row><entry /><entry>reset_src[4:0]</entry><entry>= 0x10</entry></row><row><entry /><entry>cfg_reset_n</entry><entry>= 1</entry><entry>// CPR config stays the same</entry></row><row><entry /><entry>sleep_mode_en[1]</entry><entry> = 0</entry><entry> // re-awaken section 1 only,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>section 2 is awake</entry></row><row><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// propagate resets from reset section register</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="56pt" align="left" /><tbody valign="top"><row><entry /><entry>reset_dom[5:0]</entry><entry>= 0x3F</entry><entry>// default to on</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry>cfg_reset_n</entry><entry>= 1</entry><entry>// CPR cfg</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>registers are not in any section</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>sleep_mode_en[3:0]</entry><entry> = sleep_mode_en[3:0] // stay the same</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>by default</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>if (reset_section_n[0] = = 0) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry>reset_dom[5] = 0</entry><entry> // jclk domain</entry></row><row><entry /><entry>reset_dom[4] = 0</entry><entry> // doclk domain</entry></row><row><entry /><entry>reset_dom[0] = 0</entry><entry> // pclk section 0 domain</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>if (reset_section_n[1] = = 0) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry>reset_dom[1] = 0</entry><entry> // pclk section 1 domain</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>if (reset_section_n[2] = = 0) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="105pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry>reset_dom[2] = 0</entry><entry>// pclk section 2 domain</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>(ISI)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>if (reset_section_n[3] = = 0) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry>reset_dom[3] = 0</entry><entry> // USB domain</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 16.5.7 Sleep Logic
1782The sleep logic is used to generate gating signals for each of SoPECs clock domains. The gate enable (gate_dom) is generated based on the configured sleep_mode_en and the internally generated jclk_enable signal.
1783The logic is given by
1784<tables id="TABLE-US-00127" num="00127"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>// clock gating for sleep modes</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="119pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry>gate_dom[5:0] = 0x0</entry><entry> // default to all clocks</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>on</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="119pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry>if (sleep_mode_en[0] = = 1) then</entry><entry> // section 0 sleep</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="105pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry>gate_dom[0] = 1</entry><entry>// pclk section 0</entry></row><row><entry /><entry>gate_dom[4] = 1</entry><entry>// doclk domain</entry></row><row><entry /><entry>gate_dom[5] = 1</entry><entry>// jclk domain</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="119pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry>if (sleep_mode_en[1] = = 1) then</entry><entry> // section 1 sleep</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="105pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry>gate_dom[1] = 1</entry><entry>// pclk section 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="119pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry>if (sleep_mode_en[2] = = 1) then</entry><entry> // section 2 sleep</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="105pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry>gate_dom[2] = 1</entry><entry>// pclk section 2</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="119pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry>if (sleep_mode_en[3] = = 1) then</entry><entry> // section 3 sleep</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="105pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry>gate_dom[3] = 1</entry><entry>// usb section 3</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// the jclk can be turned off by CDU signal</entry></row><row><entry /><entry>if (jclk_enable = = 0) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>gate_dom[5] = 1</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
1785The clock gating and sleep logic is clocked with the master_pclk clock which is not gated by this logic, but is synchronous to other pclk_section and jclk domains.
1786Once a section is in sleep mode it cannot generate a reset to restart the device. For example if section 1 is in sleep mode then the watchdog timer is effectively disabled and cannot trigger a reset.
000016.5.8 Clock Gate Logic
1787The clock gate logic is used to safely gate clocks without generating any glitches on the gated clock. When the enable is high the clock is active otherwise the clock is gated
000016.5.9 Clock Generator Logic
1788The clock generator block contains the PLL, crystal oscillator, clock dividers and associated control logic. The PLL VCO frequency is at 960 MHz locked to a 32 MHz refclk generated by the crystal oscillator. In test mode the xtalin signal can be driven directly by the test clock generator, the test clock will be reflected on the refclk signal to the PLL.
000016.5.9.1 Clock Divider A
1789The clock divider A block generates the 48 MHz clock from the input 96 MHz clock (pllouta) generated by the PLL. The divider is enabled only when the PLL has acquired lock.
000016.5.9.2 Clock Divider B
1790The clock divider B block generates the 160 MHz clocks from the input 320 MHz clock (plloutb) generated by the PLL. The divider is enabled only when the PLL has acquired lock.
000016.5.9.3 PLL Control State Machine
1791The PLL will go out of lock whenever pll_reset goes high (the PLL reset is the only active high reset in the device) or if the configuration bits pll_rangea, pll_rangeb, pll_mult, pll_tune are changed. The PLL control state machine ensures that the rest of the device is protected from glitching clocks while the PLL is being reset or it's configuration is being changed.
1792In the case of a hardware reset (the reset is deglitched), the state machine first disables the output clocks (via the clk_gate signal), it then holds the PLL in reset while its configuration bits are reset to default values. The state machine then releases the PLL reset and waits approx. 100 us to allow the PLL to regain lock. Once the lock time has elapsed the state machine re-enables the output clocks and resets the remainder of the device via the reset_dg_n signal.
1793When the CPU changes any of the configuration registers it must write to the PLLupdate register to allow the state machine to update the PLL to the new configuration setup. If a PLLUpdate is detected the state machine first gates the output clocks. It then holds the PLL in reset while the PLL configuration registers are updated. Once updated the PLL reset is released and the state machine waits approx 100 us for the PLL to regain lock before re-enabling the output clocks. Any write to the PLLUpdate register will cause the state machine to perform the update operation regardless of whether the configuration values changed or not.
1794All logic in the clock generator is clocked on bufrefclk which is always an active clock regardless of the state of the PLL.
000017 ROM Block
000017.1 Overview
1795The ROM block interfaces to the CPU bus and contains the SoPEC boot code. The ROM block consists of the CPU bus interface, the ROM macro and the ChipID macro. The current ROM size is 16 KBytes implemented as a 4096×32 macro. Access to the ROM is not cached because the CPU enjoys fast (no more than one cycle slower than a cache access), unarbitrated access to the ROM. Each SoPEC device is required to have a unique ChipID which is set by blowing fuses at manufacture. IBM's 300 mm ECID macro and a custom 112-bit ECID macro are used to implement the ChipID offering 224-bits of laser fuses. The exact number of fuse bits to be used for the ChipID will be determined later but all bits are made available to the CPU. The ECID macros allows all 224 bits to be read out in parallel and the ROM block will make all 224 bits available in the FuseChipID[N] registers which are readable by the CPU in supervisor mode only.
000017.2 Boot Operation
1796The are two boot scenarios for the SoPEC device namely after power-on and after being awoken from sleep mode. When the device is in sleep mode it is hoped that power will actually be removed from the DRAM, CPU and most other peripherals and so the program code will need to be freshly downloaded each time the device wakes up from sleep mode. In order to reduce the wakeup boot time (and hence the perceived print latency) certain data items are stored in the PSS block (see section 18). These data items include the SHA-1 hash digest expected for the program(s) to be downloaded, the master/slave SoPEC id and some configuration parameters. All of these data items are stored in the PSS by the CPU prior to entering sleep mode. The SHA-1 value stored in the PSS is calculated by the CPU by decrypting the signature of the downloaded program using the appropriate public key stored in ROM. This compute intensive decryption only needs to take place once as part of the power-on boot sequence—subsequent wakeup boot sequences will simply use the resulting SHA-1 digest stored in the PSS. Note that the digest only needs to be stored in the PSS before entering sleep mode and the PSS can be used for temporary storage of any data at all other times.
1797The CPU is expected to be in supervisor mode for the entire boot sequence described by the pseudocode below. Note that the boot sequence has not been finalised but is expected to be close to the following:
1798<tables id="TABLE-US-00128" num="00128"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>if (ResetSrc = = 1) then // Reset was a power-on reset</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>configure_sopec // need to configure peris (USB, ISI,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>DMA, ICU etc.)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// Otherwise reset was a wakeup reset so peris etc. were</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>already configured</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>PAUSE: wait until IrqSemaphore != 0 // i.e. wait until an</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>interrupt has been serviced</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>if (IrqSemaphore = = DMAChan0Msg) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>parse_msg(DMAChan0MsgPtr) // this routine will parse the</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>message and take any</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="84pt" align="left" /><colspec colname="1" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>// necessary action e.g. programming</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>the DMAChannel1 registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (IrqSemaphore = = DMAChan1Msg) then // program has</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>been downloaded</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>CalculatedHash = gen_sha1(ProgramLocn, ProgramSize)</entry></row><row><entry /><entry>if (ResetSrc = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>ExpectedHash = sig_decrypt(ProgramSig,public_key)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>ExpectedHash = PSSHash</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>if (ExpectedHash = = CalculatedHash) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>jmp(PrgramLocn) // transfer control to the downloaded</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>program</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>send_host_msg(“Program Authentication Failed”)</entry></row><row><entry /><entry>goto PAUSE:</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (IrqSemaphore = = timeout) then // nothing has</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>happened</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>if (ResetSrc = = 1) then</entry></row><row><entry /><entry>sleep_mode( ) // put SoPEC into sleep mode to be woken</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>up by USB/ISI activity</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>else // we were woken up but nothing happened</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>reset_sopec(PowerOnReset)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>goto PAUSE</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
1799The boot code places no restrictions on the activity of any programs downloaded and authenticated by it other than those imposed by the configuration of the MMU i.e. the principal function of the boot code is to authenticate that any programs downloaded by it are from a trusted source. It is the responsibility of the downloaded program to ensure that any code it downloads is also authenticated and that the system remains secure. The downloaded program code is also responsible for setting the SoPEC ISIId (see section 12.5 for a description of the ISIID) in a multi-SoPEC system. See the “SoPEC Security Overview” document [9] for more details of the SoPEC security features.
000017.3 Implementation
000017.3.1 Definitions of I/O
1800<tables id="TABLE-US-00129" num="00129"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 98</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>ROM Block I/O</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="35pt" align="center" /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="70pt" align="left" /><tbody valign="top"><row><entry /><entry>Port name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry /><entry namest="offset" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Clocks and Resets</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="35pt" align="char" char="." /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="70pt" align="left" /><tbody valign="top"><row><entry /><entry>prst_n</entry><entry>1</entry><entry>In</entry><entry>Global reset.</entry></row><row><entry /><entry /><entry /><entry /><entry>Synchronous</entry></row><row><entry /><entry /><entry /><entry /><entry>to pclk,</entry></row><row><entry /><entry /><entry /><entry /><entry>active low.</entry></row><row><entry /><entry>Pclk</entry><entry>1</entry><entry>In</entry><entry>Global clock</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>CPU Interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="35pt" align="char" char="." /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="70pt" align="left" /><tbody valign="top"><row><entry /><entry>cpu_adr[14:2]</entry><entry>13</entry><entry>In</entry><entry>CPU address</entry></row><row><entry /><entry /><entry /><entry /><entry>bus. Only 13</entry></row><row><entry /><entry /><entry /><entry /><entry>bits are</entry></row><row><entry /><entry /><entry /><entry /><entry>required to</entry></row><row><entry /><entry /><entry /><entry /><entry>decode the</entry></row><row><entry /><entry /><entry /><entry /><entry>address space</entry></row><row><entry /><entry /><entry /><entry /><entry>for this block.</entry></row><row><entry /><entry>rom_cpu_data[31:0]</entry><entry>32</entry><entry>Out</entry><entry>Read data bus</entry></row><row><entry /><entry /><entry /><entry /><entry>to the CPU</entry></row><row><entry /><entry>cpu_rwn</entry><entry>1</entry><entry>In</entry><entry>Common read/</entry></row><row><entry /><entry /><entry /><entry /><entry>not-write</entry></row><row><entry /><entry /><entry /><entry /><entry>signal from</entry></row><row><entry /><entry /><entry /><entry /><entry>the CPU</entry></row><row><entry /><entry>cpu_acode[1:0]</entry><entry>2</entry><entry>In</entry><entry>CPU Access</entry></row><row><entry /><entry /><entry /><entry /><entry>Code signals.</entry></row><row><entry /><entry /><entry /><entry /><entry>These decode</entry></row><row><entry /><entry /><entry /><entry /><entry>as follows:</entry></row><row><entry /><entry /><entry /><entry /><entry>00 - User</entry></row><row><entry /><entry /><entry /><entry /><entry>program access</entry></row><row><entry /><entry /><entry /><entry /><entry>01 - User</entry></row><row><entry /><entry /><entry /><entry /><entry>data access</entry></row><row><entry /><entry /><entry /><entry /><entry>10 - Supervisor</entry></row><row><entry /><entry /><entry /><entry /><entry>program access</entry></row><row><entry /><entry /><entry /><entry /><entry>11 - Supervisor</entry></row><row><entry /><entry /><entry /><entry /><entry>data access</entry></row><row><entry /><entry>cpu_rom_sel</entry><entry>1</entry><entry>In</entry><entry>Block select</entry></row><row><entry /><entry /><entry /><entry /><entry>from the CPU.</entry></row><row><entry /><entry /><entry /><entry /><entry>When cpu_rom_sel</entry></row><row><entry /><entry /><entry /><entry /><entry>is high cpu_adr</entry></row><row><entry /><entry /><entry /><entry /><entry>is valid</entry></row><row><entry /><entry>rom_cpu_rdy</entry><entry>1</entry><entry>Out</entry><entry>Ready signal to</entry></row><row><entry /><entry /><entry /><entry /><entry>the CPU. When</entry></row><row><entry /><entry /><entry /><entry /><entry>rom_cpu_rdy is</entry></row><row><entry /><entry /><entry /><entry /><entry>high it indicates</entry></row><row><entry /><entry /><entry /><entry /><entry>the last cycle of</entry></row><row><entry /><entry /><entry /><entry /><entry>the access. For</entry></row><row><entry /><entry /><entry /><entry /><entry>a read cycle</entry></row><row><entry /><entry /><entry /><entry /><entry>this means the</entry></row><row><entry /><entry /><entry /><entry /><entry>data on</entry></row><row><entry /><entry /><entry /><entry /><entry>rom_cpu_data</entry></row><row><entry /><entry /><entry /><entry /><entry>is valid.</entry></row><row><entry /><entry>rom_cpu_berr</entry><entry>1</entry><entry>Out</entry><entry>ROM bus error</entry></row><row><entry /><entry /><entry /><entry /><entry>signal to the</entry></row><row><entry /><entry /><entry /><entry /><entry>CPU indicating an</entry></row><row><entry /><entry /><entry /><entry /><entry>invalid access.</entry></row><row><entry /><entry namest="offset" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 17.3.2 Configuration Registers
1801The ROM block will only allow read accesses to the FuseChipID registers and the ROM with supervisor data space permissions (i.e. cpu_acode[1:0]=11). Write accesses with supervisor data space permissions
0000will have no effect. All other accesses with will result in rom_cpu_berr being asserted. The CPU subsystem bus slave interface is described in more detail in section 9.4.3.
1802<tables id="TABLE-US-00130" num="00130"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 99</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>ROM Block Register Map</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="49pt" align="left" /><colspec colname="3" colwidth="28pt" align="center" /><colspec colname="4" colwidth="28pt" align="left" /><colspec colname="5" colwidth="63pt" align="left" /><tbody valign="top"><row><entry>Address</entry><entry /><entry /><entry /><entry /></row><row><entry>ROM_base+</entry><entry>Register</entry><entry>#bits</entry><entry>Reset</entry><entry>Description</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="49pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="28pt" align="left" /><colspec colname="5" colwidth="63pt" align="left" /><tbody valign="top"><row><entry>0x4000</entry><entry>FuseChipID0</entry><entry>32</entry><entry>n/a</entry><entry>Value of</entry></row><row><entry /><entry /><entry /><entry /><entry>corresponding</entry></row><row><entry /><entry /><entry /><entry /><entry>fuse bits</entry></row><row><entry /><entry /><entry /><entry /><entry>31 to 0</entry></row><row><entry /><entry /><entry /><entry /><entry>of the IBM</entry></row><row><entry /><entry /><entry /><entry /><entry>112-bit ECID</entry></row><row><entry /><entry /><entry /><entry /><entry>macro. (Read</entry></row><row><entry /><entry /><entry /><entry /><entry>only)</entry></row><row><entry>0x4004</entry><entry>FuseChipID1</entry><entry>32</entry><entry>n/a</entry><entry>Value of</entry></row><row><entry /><entry /><entry /><entry /><entry>corresponding</entry></row><row><entry /><entry /><entry /><entry /><entry>fuse bits</entry></row><row><entry /><entry /><entry /><entry /><entry>63 to 32</entry></row><row><entry /><entry /><entry /><entry /><entry>of the IBM</entry></row><row><entry /><entry /><entry /><entry /><entry>112-bit ECID</entry></row><row><entry /><entry /><entry /><entry /><entry>macro. (Read</entry></row><row><entry /><entry /><entry /><entry /><entry>only)</entry></row><row><entry>0x4008</entry><entry>FuseChipID2</entry><entry>32</entry><entry>n/a</entry><entry>Value of</entry></row><row><entry /><entry /><entry /><entry /><entry>corresponding</entry></row><row><entry /><entry /><entry /><entry /><entry>fuse bits</entry></row><row><entry /><entry /><entry /><entry /><entry>95 to 64</entry></row><row><entry /><entry /><entry /><entry /><entry>of the IBM</entry></row><row><entry /><entry /><entry /><entry /><entry>112-bit ECID</entry></row><row><entry /><entry /><entry /><entry /><entry>macro. (Read</entry></row><row><entry /><entry /><entry /><entry /><entry>only)</entry></row><row><entry>0x400C</entry><entry>FuseChipID3</entry><entry>16</entry><entry>n/a</entry><entry>Value of</entry></row><row><entry /><entry /><entry /><entry /><entry>corresponding</entry></row><row><entry /><entry /><entry /><entry /><entry>fuse bits</entry></row><row><entry /><entry /><entry /><entry /><entry>111 to 96 of</entry></row><row><entry /><entry /><entry /><entry /><entry>the IBM 112-</entry></row><row><entry /><entry /><entry /><entry /><entry>bit ECID macro.</entry></row><row><entry /><entry /><entry /><entry /><entry>(Read only)</entry></row><row><entry>0x4010</entry><entry>FuseChipID4</entry><entry>32</entry><entry>n/a</entry><entry>Value of</entry></row><row><entry /><entry /><entry /><entry /><entry>corresponding</entry></row><row><entry /><entry /><entry /><entry /><entry>fuse bits</entry></row><row><entry /><entry /><entry /><entry /><entry>31 to 0</entry></row><row><entry /><entry /><entry /><entry /><entry>of the Custom</entry></row><row><entry /><entry /><entry /><entry /><entry>112-bit ECID</entry></row><row><entry /><entry /><entry /><entry /><entry>macro. (Read</entry></row><row><entry /><entry /><entry /><entry /><entry>only)</entry></row><row><entry>0x4014</entry><entry>FuseChipID5</entry><entry>32</entry><entry>n/a</entry><entry>Value of</entry></row><row><entry /><entry /><entry /><entry /><entry>corresponding</entry></row><row><entry /><entry /><entry /><entry /><entry>fuse bits</entry></row><row><entry /><entry /><entry /><entry /><entry>63 to 32</entry></row><row><entry /><entry /><entry /><entry /><entry>of the Custom</entry></row><row><entry /><entry /><entry /><entry /><entry>112-bit ECID</entry></row><row><entry /><entry /><entry /><entry /><entry>macro. (Read</entry></row><row><entry /><entry /><entry /><entry /><entry>only)</entry></row><row><entry>0x4018</entry><entry>FuseChipID6</entry><entry>32</entry><entry>n/a</entry><entry>Value of</entry></row><row><entry /><entry /><entry /><entry /><entry>corresponding</entry></row><row><entry /><entry /><entry /><entry /><entry>fuse bits</entry></row><row><entry /><entry /><entry /><entry /><entry>95 to 64</entry></row><row><entry /><entry /><entry /><entry /><entry>of the Custom</entry></row><row><entry /><entry /><entry /><entry /><entry>112-bit ECID</entry></row><row><entry /><entry /><entry /><entry /><entry>macro. (Read</entry></row><row><entry /><entry /><entry /><entry /><entry>only)</entry></row><row><entry>0x401C</entry><entry>FuseChipID7</entry><entry>16</entry><entry>n/a</entry><entry>Value of</entry></row><row><entry /><entry /><entry /><entry /><entry>corresponding</entry></row><row><entry /><entry /><entry /><entry /><entry>fuse bits 111</entry></row><row><entry /><entry /><entry /><entry /><entry>to 96 of the</entry></row><row><entry /><entry /><entry /><entry /><entry>Custom 112-bit</entry></row><row><entry /><entry /><entry /><entry /><entry>ECID macro.</entry></row><row><entry /><entry /><entry /><entry /><entry>(Read only)</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 17.3.3 Sub-block Partition
1803IBM offer two variants of their ROM macros; A high performance version (ROMHD) and a low power version (ROMLD). It is likely that the low power version will be used unless some implementation issue requires the high performance version. Both versions offer the same bit density. The sub-block partition diagram below does not include the clocking and test signals for the ROM or ECID macros. The CPU subsystem bus interface is described in more detail in section 11.4.3.
000017.3.4
1804<tables id="TABLE-US-00131" num="00131"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 100</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>ROM Block internal signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="49pt" align="center" /><colspec colname="3" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>Port name</entry><entry>Width</entry><entry>Description</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Clocks and Resets</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="49pt" align="char" char="." /><colspec colname="3" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>prst_n</entry><entry>1</entry><entry>Global reset. Synchronous</entry></row><row><entry /><entry /><entry>to pclk, active low.</entry></row><row><entry>Pclk</entry><entry>1</entry><entry>Global clock</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Internal Signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="49pt" align="char" char="." /><colspec colname="3" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>rom_adr[11:0]</entry><entry>12</entry><entry>ROM address bus</entry></row><row><entry>rom_sel</entry><entry>1</entry><entry>Select signal to the</entry></row><row><entry /><entry /><entry>ROM macro instructing</entry></row><row><entry /><entry /><entry>it to access the</entry></row><row><entry /><entry /><entry>location at rom_adr</entry></row><row><entry>rom_oe</entry><entry>1</entry><entry>Output enable signal</entry></row><row><entry /><entry /><entry>to the ROM block</entry></row><row><entry>rom_data[31:0]</entry><entry>32</entry><entry>Data bus from the ROM</entry></row><row><entry /><entry /><entry>macro to the CPU bus</entry></row><row><entry /><entry /><entry>interface</entry></row><row><entry>rom_dvalid</entry><entry>1</entry><entry>Signal from the ROM</entry></row><row><entry /><entry /><entry>macro indicating that</entry></row><row><entry /><entry /><entry>the data on rom_data</entry></row><row><entry /><entry /><entry>is valid for the</entry></row><row><entry /><entry /><entry>address on rom_adr</entry></row><row><entry>fuse_data[31:0]</entry><entry>32</entry><entry>Data from the FuseChipID [N]</entry></row><row><entry /><entry /><entry>register addressed by</entry></row><row><entry /><entry /><entry>fuse_reg_adr</entry></row><row><entry>fuse_reg_adr[2:0]</entry><entry>3</entry><entry>Indicates which of the</entry></row><row><entry /><entry /><entry>FuseChipID registers is being</entry></row><row><entry /><entry /><entry>addressed</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> Sub-block Signal Definition <br /> 18 Power Safe Storage (PSS) Block <br /> 18.1 Overview
1805The PSS block provides 128 bytes of storage space that will maintain its state when the rest of the SoPEC device is in sleep mode. The PSS is expected to be used primarily for the storage of decrypted signatures associated with downloaded programmed code but it can also be used to store any information that needs to survive sleep mode (e.g. configuration details). Note that the signature digest only needs to be stored in the PSS before entering sleep mode and the PSS can be used for temporary storage of any data at all other times.
1806Prior to entering sleep mode the CPU should store all of the information it will need on exiting sleep mode in the PSS. On emerging from sleep mode the boot code in ROM will read the ResetSrc register in the CPR block to determine which reset source caused the wakeup. The reset source information indicates whether or not the PSS contains valid stored data, and the PSS data determines the type of boot sequence to execute. If for any reason a full power-on boot sequence should be performed (e.g. the printer driver has been updated) then this is simply achieved by initiating a full software reset.
1807Note that a reset or a powerdown (powerdown is implemented by clock gating) of the PSS block will not clear the contents of the 128 bytes of storage. If clearing of the PSS storage is required, then the CPU must write to each location individually.
000018.2 Implementation
1808The storage area of the PSS block will be implemented as a 128-byte register array. The array is located from PSS_base through to PSS_base+0x7F in the address map. The PSS block will only allow read or write accesses with supervisor data space permissions (i.e. cpu_acode[1:0]=11). All other accesses will result in pss_cpu_berr being asserted. The CPU subsystem bus slave interface is described in more detail in section 11.4.3.
000018.2.1 Definitions of I/O
1809<tables id="TABLE-US-00132" num="00132"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 101</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>PSS Block I/O</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>Port name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Clocks and Resets</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>prst_n</entry><entry>1</entry><entry>In</entry><entry>Global reset. Synchronous to pclk,</entry></row><row><entry /><entry /><entry /><entry>active low.</entry></row><row><entry>Pclk</entry><entry>1</entry><entry>In</entry><entry>Global clock</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>CPU Interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>cpu_adr[6:2]</entry><entry>5</entry><entry>In</entry><entry>CPU address bus. Only 5 bits are</entry></row><row><entry /><entry /><entry /><entry>required to decode the address</entry></row><row><entry /><entry /><entry /><entry>space for this block.</entry></row><row><entry>cpu_dataout[31:0]</entry><entry>32</entry><entry>In</entry><entry>Shared write data bus from the</entry></row><row><entry /><entry /><entry /><entry>CPU</entry></row><row><entry>pss_cpu_data[31:0]</entry><entry>32</entry><entry>Out</entry><entry>Read data bus to the CPU</entry></row><row><entry>cpus_rwn</entry><entry>1</entry><entry>In</entry><entry>Common read/not-write signal from</entry></row><row><entry /><entry /><entry /><entry>the CPU</entry></row><row><entry>cpu_acode[1:0]</entry><entry>2</entry><entry>In</entry><entry>CPU Access Code signals. These</entry></row><row><entry /><entry /><entry /><entry>decode as follows:</entry></row><row><entry /><entry /><entry /><entry>00 - User program access</entry></row><row><entry /><entry /><entry /><entry>01 - User data access</entry></row><row><entry /><entry /><entry /><entry>10 - Supervisor program access</entry></row><row><entry /><entry /><entry /><entry>11 - Supervisor data access</entry></row><row><entry>cpu_pss_sel</entry><entry>1</entry><entry>In</entry><entry>Block select from the CPU. When</entry></row><row><entry /><entry /><entry /><entry>cpu_pss_sel is high both cpu_adr</entry></row><row><entry /><entry /><entry /><entry>and cpu_dataout are valid</entry></row><row><entry>pss_cpu_rdy</entry><entry>1</entry><entry>Out</entry><entry>Ready signal to the CPU. When</entry></row><row><entry /><entry /><entry /><entry>pss_cpu_rdy is high it indi-</entry></row><row><entry /><entry /><entry /><entry>cates the last cycle of the</entry></row><row><entry /><entry /><entry /><entry>access. For a read cycle this</entry></row><row><entry /><entry /><entry /><entry>means the data on pss_cpu_data</entry></row><row><entry /><entry /><entry /><entry>is valid.</entry></row><row><entry>pss_cpu_berr</entry><entry>1</entry><entry>Out</entry><entry>PSS bus error signal to the</entry></row><row><entry /><entry /><entry /><entry>CPU indicating an invalid</entry></row><row><entry /><entry /><entry /><entry>access.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 19 Low Speed Serial Interface (LSS) <br /> 19.1 Overview
1810The Low Speed Serial Interface (LSS) provides a mechanism for the internal SoPEC CPU to communicate with external QA chips via two independent LSS buses. The LSS communicates through the GPIO block to the QA chips. This allows the QA chip pins to be reused in multi-SoPEC environments. The LSS Master system-level interface is illustrated in <figref idref="DRAWINGS">FIG. 75</figref>. Note that multiple QA chips are allowed on each LSS bus.
000019.2 QA Communication
1811The SoPEC data interface to the QA Chips is a low speed, 2 pin, synchronous serial bus. Data is transferred to the QA chips via the lss_data pin synchronously with the lss_clk pin. When the lss_clk is high the data on lss_data is deemed to be valid. Only the LSS master in SoPEC can drive the lss_clk pin, this pin is an input only to the QA chips. The LSS block must be able to interface with an open-collector pull-up bus. This means that when the LSS block should transmit a logical zero it will drive 0 on the bus, but when it should transmit a logical 1 it will leave high-impedance on the bus (i.e. it doesn't drive the bus). If all the agents on the LSS bus adhere to this protocol then there will be no issues with bus contention.
1812The LSS block controls all communication to and from the QA chips. The LSS block is the bus master in all cases. The LSS block interprets a command register set by the SoPEC CPU, initiates transactions to the QA chip in question and optionally accepts return data. Any return information is presented through the configuration registers to the SoPEC CPU. The LSS block indicates to the CPU the completion of a command or the occurrence of an error via an interrupt. The LSS protocol can be used to communicate with other LSS slave devices (other than QA chips). However should a LSS slave device hold the clock low (for whatever reason), it will be in violation of the LSS protocol and is not supported. The LSS clock is only ever driven by the LSS master.
000019.2.1 Start and Stop Conditions
1813All transmissions on the LSS bus are initiated by the LSS master issuing a STAR<sub>T </sub>condition and terminated by the LSS master issuing a STOP condition. STAR<sub>T </sub>and STOP conditions are always generated by the LSS master. As illustrated in <figref idref="DRAWINGS">FIG. 76</figref>, a STAR<sub>T </sub>condition corresponds to a high to low transition on lss_data while lss_clk is high. A STOP condition corresponds to a low to high transition on lss_data while lss_clk is high.
000019.2.2 Data Transfer
1814Data is transferred on the LSS bus via a byte orientated protocol. Bytes are transmitted serially. Each byte is sent most significant bit (MSB) first through to least significant bit (LSB) last. One clock pulse is generated for each data bit transferred. Each byte must be followed by an acknowledge bit.
1815The data on the lss_data must be stable during the HIGH period of the lss_clk clock. Data may only change when lss_clk is low. A transmitter outputs data after the falling edge of lss_clk and a receiver inputs the data at the rising edge of lss_clk. This data is only considered as a valid data bit at the next lss_clk falling edge provided a STAR<sub>T </sub>or STOP is not detected in the period before the next lss_clk falling edge. All clock pulses are generated by the LSS block. The transmitter releases the lss_data line (high) during the acknowledge clock pulse (ninth clock pulse). The receiver must pull down the lss_data line during the acknowledge clock pulse so that it remains stable low during the HIGH period of this clock pulse.
1816Data transfers follow the format shown in <figref idref="DRAWINGS">FIG. 77</figref>. The first byte sent by the LSS master after a STAR<sub>T </sub>condition is a primary id byte, where bits <b>7</b>–<b>2</b> form a 6-bit primary id (0 is a global id and will address all QA Chips on a particular LSS bus), bit <b>1</b> is an even parity bit for the primary ID, and bit <b>0</b> forms the read/write sense. Bit <b>0</b> is high if the following command is a read to the primary id given or low for a write command to that id. An acknowledge is generated by the QA chip(s) corresponding to the given id (if such a chip exists) by driving the lss_data line low synchronous with the LSS master generated ninth lss_clk.
000019.2.3 Write Procedure
1817The protocol for a write access to a QA Chip over the LSS bus is illustrated in <figref idref="DRAWINGS">FIG. 79</figref> below. The LSS master in SoPEC initiates the transaction by generating a STAR<sub>T </sub>condition on the LSS bus. It then transmits the primary id byte with a 0 in bit <b>0</b> to indicate that the following command is a write to the primary id. An acknowledge is generated by the QA chip corresponding to the given primary id. The LSS master will clock out M data bytes with the slave QA Chip acknowledging each successful byte written. Once the slave QA chip has acknowledged the M<sup>th </sup>data byte the LSS master issues a STOP condition to complete the transfer. The QA chip gathers the M data bytes together and interprets them as a command. See QA Chip Interface Specification for more details on the format of the commands used to communicate with the QA chip[8]. Note that the QA chip is free to not acknowledge any byte transmitted. The LSS master should respond by issuing an interrupt to the CPU to indicate this error. The CPU should then generate a STOP condition on the LSS bus to gracefully complete the transaction on the LSS bus.
000019.2.4 Read Procedure
1818The LSS master in SoPEC initiates the transaction by generating a STAR<sub>T </sub>condition on the LSS bus. It then transmits the primary id byte with a 1 in bit <b>0</b> to indicate that the following command is a read to the primary id. An acknowledge is generated by the QA chip corresponding to the given primary id. The LSS master releases the lss_data bus and proceeds to clock the expected number of bytes from the QA chip with the LSS master acknowledging each successful byte read. The last expected byte is not acknowledged by the LSS master. It then completes the transaction by generating a STOP condition on the LSS bus. See QA Chip Interface Specification for more details on the format of the commands used to communicate with the QA chip[8].
000019.3 Implementation
1819A block diagram of the LSS master is given in <figref idref="DRAWINGS">FIG. 80</figref>. It consists of a block of configuration registers that are programmed by the CPU and two identical LSS master units that generate the signalling protocols on the two LSS buses as well as interrupts to the CPU. The CPU initiates and terminates transactions on the LSS buses by writing an appropriate command to the command register, writes bytes to be transmitted to a buffer and reads bytes received from a buffer, and checks the sources of interrupts by reading status registers.
000019.3.1 Definitions of IO
1820<tables id="TABLE-US-00133" num="00133"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 102</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>LSS IO pins definitions</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>Port name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Clocks and Resets</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>Pclk</entry><entry>1</entry><entry>In</entry><entry>System Clock</entry></row><row><entry>prst_n</entry><entry>1</entry><entry>In</entry><entry>System reset, synchronous</entry></row><row><entry /><entry /><entry /><entry>active low</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>CPU Interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>cpu_rwn</entry><entry>1</entry><entry>In</entry><entry>Common read/not-write signal</entry></row><row><entry /><entry /><entry /><entry>from the CPU</entry></row><row><entry>cpu_adr[6:2]</entry><entry>5</entry><entry>In</entry><entry>CPU address bus. Only 5 bits</entry></row><row><entry /><entry /><entry /><entry>are required to decode the</entry></row><row><entry /><entry /><entry /><entry>address space for this block</entry></row><row><entry>cpu_dataout[31:0]</entry><entry>32</entry><entry>In</entry><entry>Shared write data bus from</entry></row><row><entry /><entry /><entry /><entry>the CPU</entry></row><row><entry>cpu_acode[1:0]</entry><entry>2</entry><entry>In</entry><entry>CPU access code signals.</entry></row><row><entry /><entry /><entry /><entry>cpu_acode[0] - Program (0)/</entry></row><row><entry /><entry /><entry /><entry>Data (1) access</entry></row><row><entry /><entry /><entry /><entry>cpu_acode[1] - User (0)/</entry></row><row><entry /><entry /><entry /><entry>Supervisor (1) access</entry></row><row><entry>cpu_lss_sel</entry><entry>1</entry><entry>In</entry><entry>Block select from the CPU. When</entry></row><row><entry /><entry /><entry /><entry>cpu_lss_sel is high both cpu_adr</entry></row><row><entry /><entry /><entry /><entry>and cpu_dataout are valid</entry></row><row><entry>lss_cpu_rdy</entry><entry>1</entry><entry>Out</entry><entry>Ready signal to the CPU. When</entry></row><row><entry /><entry /><entry /><entry>lss_cpu_rdy is high it indicates</entry></row><row><entry /><entry /><entry /><entry>the last cycle of the access.</entry></row><row><entry /><entry /><entry /><entry>For a write cycle this means</entry></row><row><entry /><entry /><entry /><entry>cpu_dataout has been registered</entry></row><row><entry /><entry /><entry /><entry>by the LSS block and for a read</entry></row><row><entry /><entry /><entry /><entry>cycle this means the data on</entry></row><row><entry /><entry /><entry /><entry>lss_cpu_data is valid.</entry></row><row><entry>lss_cpu_berr</entry><entry>1</entry><entry>Out</entry><entry>LSS bus error signal to the</entry></row><row><entry /><entry /><entry /><entry>CPU.</entry></row><row><entry>lss_cpu_data[31:0]</entry><entry>32</entry><entry>Out</entry><entry>Read data bus to the CPU</entry></row><row><entry>lss_cpu_debug_valid</entry><entry>1</entry><entry>Out</entry><entry>Active high. Indicates the</entry></row><row><entry /><entry /><entry /><entry>presence of valid debug data</entry></row><row><entry /><entry /><entry /><entry>on lss_cpu_data.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>GPIO for LSS buses</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>lss_gpio_dout[1:0]</entry><entry>2</entry><entry>Out</entry><entry>LSS bus data output</entry></row><row><entry /><entry /><entry /><entry>Bit 0 - LSS bus 0</entry></row><row><entry /><entry /><entry /><entry>Bit 1 - LSS bus 1</entry></row><row><entry>gpio_lss_din[1:0]</entry><entry>2</entry><entry>In</entry><entry>LSS bus data input</entry></row><row><entry /><entry /><entry /><entry>Bit 0 - LSS bus 0</entry></row><row><entry /><entry /><entry /><entry>Bit 1 - LSS bus 1</entry></row><row><entry>lss_gpio_e[1:0]</entry><entry>2</entry><entry>Out</entry><entry>LSS bus data output enable,</entry></row><row><entry /><entry /><entry /><entry>active high</entry></row><row><entry /><entry /><entry /><entry>Bit 0 - LSS bus 0</entry></row><row><entry /><entry /><entry /><entry>Bit 1 - LSS bus 1</entry></row><row><entry>lss_gpio_clk[1:0]</entry><entry>2</entry><entry>Out</entry><entry>LSS bus clock output</entry></row><row><entry /><entry /><entry /><entry>Bit 0 - LSS bus 0</entry></row><row><entry /><entry /><entry /><entry>Bit 1 - LSS bus 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>ICU interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>lss_icu_irq[1:0]</entry><entry>2</entry><entry>Out</entry><entry>LSS interrupt requests</entry></row><row><entry /><entry /><entry /><entry>Bit 0 - interrupt associated</entry></row><row><entry /><entry /><entry /><entry>with LSS bus 0</entry></row><row><entry /><entry /><entry /><entry>Bit 1 - interrupt associated</entry></row><row><entry /><entry /><entry /><entry>with LSS bus 1</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 19.3.2 Configuration Registers
1821The configuration registers in the LSS block are programmed via the CPU interface. Refer to section 11.4 on page 69 for the description of the protocol and timing diagrams for reading and writing registers in the LSS block. Note that since addresses in SoPEC are byte aligned and the CPU only supports 32-bit register reads and writes, the lower 2 bits of the CPU address bus are not required to decode the address space for the LSS block. Table 103 lists the configuration registers in the LSS block. When reading a register that is less than 32 bits wide zeros should be returned on the upper unused bit(s) of lss_cpu_data.
1822The input cpu_acode signal indicates whether the current CPU access is supervisor, user, program or data. The configuration registers in the LSS block can only be read or written by a supervisor data access, i.e. when cpu_acode equals b11. If the current access is a supervisor data access then the LSS responds by asserting lss_cpu_rdy for a single clock cycle.
1823If the current access is anything other than a supervisor data access, then the LSS generates a bus error by asserting lss_cpu_berr for a single clock cycle instead of lss_cpu_rdy as shown in section 11.4 on page 69. A write access will be ignored, and a read access will return zero.
1824<tables id="TABLE-US-00134" num="00134"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="350pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 103</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>LSS Control Registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><colspec colname="3" colwidth="28pt" align="center" /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="140pt" align="left" /><tbody valign="top"><row><entry>Address</entry><entry /><entry /><entry /><entry /></row><row><entry>(LSS_base +)</entry><entry>Register</entry><entry>#bits</entry><entry>Reset</entry><entry>Description</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="350pt" align="left" /><tbody valign="top"><row><entry>Control registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="140pt" align="left" /><tbody valign="top"><row><entry>0x00</entry><entry>Reset</entry><entry>1</entry><entry>0x1</entry><entry>A write to this register causes a reset of the</entry></row><row><entry /><entry /><entry /><entry /><entry>LSS.</entry></row><row><entry>0x04</entry><entry>LssClockHighLowDuration</entry><entry>16</entry><entry>0x00C8</entry><entry>Lss_clk has a 50:50 duty cycle, this register</entry></row><row><entry /><entry /><entry /><entry /><entry>defines the period of lss_clk by means of</entry></row><row><entry /><entry /><entry /><entry /><entry>specifying the duration (in pclk cycles) that</entry></row><row><entry /><entry /><entry /><entry /><entry>lss_clk is low (or high).</entry></row><row><entry /><entry /><entry /><entry /><entry>The reset value specifies transmission over</entry></row><row><entry /><entry /><entry /><entry /><entry>the LSS bus at a nominal rate of 400 kHz,</entry></row><row><entry /><entry /><entry /><entry /><entry>corresponding to a low (or high) duration of</entry></row><row><entry /><entry /><entry /><entry /><entry>200 pclk (160 Mhz) cycles.</entry></row><row><entry /><entry /><entry /><entry /><entry>Register should not be set to values less</entry></row><row><entry /><entry /><entry /><entry /><entry>than 8.</entry></row><row><entry>0x08</entry><entry>LssClocktoDataHold</entry><entry>6</entry><entry>0x3</entry><entry>Specifies the number of pclk cycles that Data</entry></row><row><entry /><entry /><entry /><entry /><entry>must remain valid for after the falling edge of</entry></row><row><entry /><entry /><entry /><entry /><entry>lss_clk.</entry></row><row><entry /><entry /><entry /><entry /><entry>Minimum value is 3 cycles, and must to</entry></row><row><entry /><entry /><entry /><entry /><entry>programmed to be less than</entry></row><row><entry /><entry /><entry /><entry /><entry>LssClockHighLowDuration.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="350pt" align="left" /><tbody valign="top"><row><entry>LSS bus 0 registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="140pt" align="left" /><tbody valign="top"><row><entry>0x10</entry><entry>Lss0IntStatus</entry><entry>3</entry><entry>0x0</entry><entry>LSS bus 0 interrupt status registers</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 0 - command completed successfully</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 1 - error during processing of command,</entry></row><row><entry /><entry /><entry /><entry /><entry>not -acknowledge received after</entry></row><row><entry /><entry /><entry /><entry /><entry>transmission of primary id byte on LSS bus 0</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 2 - error during processing of command,</entry></row><row><entry /><entry /><entry /><entry /><entry>not -acknowledge received after</entry></row><row><entry /><entry /><entry /><entry /><entry>transmission of data byte on LSS bus 0</entry></row><row><entry /><entry /><entry /><entry /><entry>All the bits in Lss0IntStatus are cleared when</entry></row><row><entry /><entry /><entry /><entry /><entry>the Lss0Cmd register gets written to.</entry></row><row><entry /><entry /><entry /><entry /><entry>(Read only register)</entry></row><row><entry>0x14</entry><entry>Lss0CurrentState</entry><entry>4</entry><entry>0x0</entry><entry>Gives the current state of the LSS bus 0</entry></row><row><entry /><entry /><entry /><entry /><entry>state machine. (Read only register).</entry></row><row><entry /><entry /><entry /><entry /><entry>(Encoding will be specified upon state</entry></row><row><entry /><entry /><entry /><entry /><entry>machine implementation)</entry></row><row><entry>0x18</entry><entry>Lss0Cmd</entry><entry>21</entry><entry>0x00_0000</entry><entry>Command register defining sequence of</entry></row><row><entry /><entry /><entry /><entry /><entry>events to perform on LSS bus 0 before</entry></row><row><entry /><entry /><entry /><entry /><entry>interrupting CPU.</entry></row><row><entry /><entry /><entry /><entry /><entry>A write to this register causes all the bits in</entry></row><row><entry /><entry /><entry /><entry /><entry>the Lss0IntStatus register to be cleared as</entry></row><row><entry /><entry /><entry /><entry /><entry>well as generating a lss0_new_cmd pulse.</entry></row><row><entry>0x1C–0x2C</entry><entry>Lss0Buffer[4:0]</entry><entry>5 × 32</entry><entry>0x0000_0000</entry><entry>LSS Data buffer. Should be filled with</entry></row><row><entry /><entry /><entry /><entry /><entry>transmit data before transmit command, or</entry></row><row><entry /><entry /><entry /><entry /><entry>read data bytes received after a valid read</entry></row><row><entry /><entry /><entry /><entry /><entry>command.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="350pt" align="left" /><tbody valign="top"><row><entry>LSS bus 1 registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="140pt" align="left" /><tbody valign="top"><row><entry>0x30</entry><entry>Lss1IntStatus</entry><entry>3</entry><entry>0x0</entry><entry>LSS bus 1 interrupt status registers</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 0 - command completed successfully</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 1 - error during processing of command,</entry></row><row><entry /><entry /><entry /><entry /><entry>not -acknowledge received after transmission</entry></row><row><entry /><entry /><entry /><entry /><entry>of primary id byte on LSS bus 1</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 2 - error during processing of command,</entry></row><row><entry /><entry /><entry /><entry /><entry>not -acknowledge received after transmission</entry></row><row><entry /><entry /><entry /><entry /><entry>of data byte on LSS bus 1</entry></row><row><entry /><entry /><entry /><entry /><entry>All the bits in Lss1IntStatus are cleared when</entry></row><row><entry /><entry /><entry /><entry /><entry>the Lss1Cmd register gets written to.</entry></row><row><entry /><entry /><entry /><entry /><entry>(Read only register)</entry></row><row><entry>0x34</entry><entry>Lss1CurrentState</entry><entry>4</entry><entry>0x0</entry><entry>Gives the current state of the LSS bus 1</entry></row><row><entry /><entry /><entry /><entry /><entry>state machine. (Read only register)</entry></row><row><entry /><entry /><entry /><entry /><entry>(Encoding will be specified upon state</entry></row><row><entry /><entry /><entry /><entry /><entry>machine implementation)</entry></row><row><entry>0x38</entry><entry>Lss1Cmd</entry><entry>21</entry><entry>0x00_0000</entry><entry>Command register defining sequence of</entry></row><row><entry /><entry /><entry /><entry /><entry>events to perform on LSS bus 1 before</entry></row><row><entry /><entry /><entry /><entry /><entry>interrupting CPU.</entry></row><row><entry /><entry /><entry /><entry /><entry>A write to this register causes all the bits in</entry></row><row><entry /><entry /><entry /><entry /><entry>the Lss1IntStatus register to be cleared as</entry></row><row><entry /><entry /><entry /><entry /><entry>well as generating a lss1_new_cmd pulse.</entry></row><row><entry>0x3C–0x4C</entry><entry>Lss1Buffer[4:0]</entry><entry>5 × 32</entry><entry>0x0000_0000</entry><entry>LSS Data buffer. Should be filled with</entry></row><row><entry /><entry /><entry /><entry /><entry>transmit data before transmit command, or</entry></row><row><entry /><entry /><entry /><entry /><entry>read data bytes received after a valid read</entry></row><row><entry /><entry /><entry /><entry /><entry>command.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="350pt" align="left" /><tbody valign="top"><row><entry>Debug registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="140pt" align="left" /><tbody valign="top"><row><entry>0x50</entry><entry>LssDebugSel[6:2]</entry><entry>5</entry><entry>0x00</entry><entry>Selects register for debug output. This value</entry></row><row><entry /><entry /><entry /><entry /><entry>is used as the input to the register decode</entry></row><row><entry /><entry /><entry /><entry /><entry>logic instead of cpu_adr[6:2] when the LSS</entry></row><row><entry /><entry /><entry /><entry /><entry>block is not being accessed by the CPU, i.e.</entry></row><row><entry /><entry /><entry /><entry /><entry>when cpu_lss_sel is 0.</entry></row><row><entry /><entry /><entry /><entry /><entry>The output lss_cpu_debug_valid is asserted</entry></row><row><entry /><entry /><entry /><entry /><entry>to indicate that the data on lss_cpu_data is</entry></row><row><entry /><entry /><entry /><entry /><entry>valid debug data. This data can be</entry></row><row><entry /><entry /><entry /><entry /><entry>multiplexed onto chip pins during debug</entry></row><row><entry /><entry /><entry /><entry /><entry>mode.</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 19.3.2.1 LSS Command Registers
1825The LSS command registers define a sequence of events to perform on the respective LSS bus before issuing an interrupt to the CPU. There is a separate command register and interrupt for each LSS bus. The format of the command is given in Table 104. The CPU writes to the command register to initiate a sequence of events on an LSS bus. Once the sequence of events has completed or an error has occurred, an interrupt is sent back to the CPU.
1826Some example commands are: <ul id="ul0164" list-style="none"><li id="ul0164-0001" num="0000"><ul id="ul0165" list-style="none"><li id="ul0165-0001" num="1827">a single STAR<sub>T </sub>condition (Start=1, IdByteEnable=0, RdWrEnable=0, Stop=0)</li><li id="ul0165-0002" num="1828">a single STOP condition (Start=0, IdByteEnable=0, RdWrEnable=0, Stop=1)</li><li id="ul0165-0003" num="1829">a STAR<sub>T </sub>condition followed by transmission of the id byte (Start=1, IdByteEnable=1, RdWrEnable=0, Stop=0, IdByte contains primary id byte)</li><li id="ul0165-0004" num="1830">a write transfer of 20 bytes from the data buffer (Start=0, IdByteEnable=0, RdWrEnable=1, RdWrSense=0, Stop=0, TxRxByteCount=20)</li><li id="ul0165-0005" num="1831">a read transfer of 8 bytes into the data buffer (Start=0, IdByteEnable=0, RdWrEnable=1, RdWrSense=1, ReadNack=0, Stop=0, TxRxByteCount=8)</li><li id="ul0165-0006" num="1832">a complete read transaction of 16 bytes (Start=1, IdByteEnable=1, RdWrEnable=1, RdWrSense=1, ReadNack=1, Stop=1, IdByte contains primary id byte, TxRxByteCount=16), etc.</li></ul></li></ul>
1833The CPU can thus program the number of bytes to be transmitted or received (up to a maximum of 20) on the LSS bus before it gets interrupted. This allows it to insert arbitrary delays in a transfer at a byte boundary. For example the CPU may want to transmit 30 bytes to a QA chip but insert a delay between the 20<sup>th </sup>and 21<sup>st </sup>bytes sent. It does this by first writing 20 bytes to the data buffer. It then writes a command to generate a STAR<sub>T </sub>condition, send the primary id byte and then transmit the 20 bytes from the data buffer. When interrupted by the LSS block to indicate successful completion of the command the CPU can then write the remaining 10 bytes to the data buffer. It can then wait for a defined period of time before writing a command to transmit the 10 bytes from the data buffer and generate a STOP condition to terminate the transaction over the LSS bus.
1834An interrupt to the CPU is generated for one cycle when any bit in LssNIntStatus is set. The CPU can read LssNIntStatus to discover the source of the interrupt. The LssNIntStatus registers are cleared when the CPU writes to the LssNCmd register. A null command write to the LssNCmd register will cause the LssNIntStatus registers to clear and no new command to start. A null command is defined as Start, IdbyteEnable, RdWrEnable and Stop all set to zero.
1835<tables id="TABLE-US-00135" num="00135"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 104</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>LSS command register description</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="center" /><colspec colname="2" colwidth="56pt" align="left" /><colspec colname="3" colwidth="133pt" align="left" /><tbody valign="top"><row><entry>bit(s)</entry><entry>name</entry><entry>Description</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>0</entry><entry>Start</entry><entry>When 1, Issue a START condition on</entry></row><row><entry /><entry /><entry>the LSS bus.</entry></row><row><entry>1</entry><entry>IdByteEnable</entry><entry>ID byte transmit enable:</entry></row><row><entry /><entry /><entry>1 - transmit byte in IdByte field</entry></row><row><entry /><entry /><entry>0 - ignore byte in IdByte field</entry></row><row><entry>2</entry><entry>RdWrEnable</entry><entry>Read/write transfer enable:</entry></row><row><entry /><entry /><entry>0 - ignore settings of RdWrSense, ReadNack</entry></row><row><entry /><entry /><entry>and TxRxByteCount</entry></row><row><entry /><entry /><entry>1 - if RdWrSense is 0, then perform a write</entry></row><row><entry /><entry /><entry>transfer of TxRxByteCount bytes from the</entry></row><row><entry /><entry /><entry>data buffer.</entry></row><row><entry /><entry /><entry>if RdWrSense is 1, then perform a read</entry></row><row><entry /><entry /><entry>transfer of TxRxByteCount bytes into the</entry></row><row><entry /><entry /><entry>data buffer. Each byte should be acknowl-</entry></row><row><entry /><entry /><entry>edged and the last byte received is</entry></row><row><entry /><entry /><entry>acknowledged/not-acknowledged according</entry></row><row><entry /><entry /><entry>to the setting of ReadNack.</entry></row><row><entry>3</entry><entry>RdWrSense</entry><entry>Read/write sense indicator:</entry></row><row><entry /><entry /><entry>0 - write</entry></row><row><entry /><entry /><entry>1 - read</entry></row><row><entry>4</entry><entry>ReadNack</entry><entry>Indicates, for a read transfer, whether to</entry></row><row><entry /><entry /><entry>issue an acknowledge or a not-acknowledge</entry></row><row><entry /><entry /><entry>after the last byte received (indicated by</entry></row><row><entry /><entry /><entry>TxRxByteCount).</entry></row><row><entry /><entry /><entry>0 - issue acknowledge after last byte</entry></row><row><entry /><entry /><entry>received</entry></row><row><entry /><entry /><entry>1 - issue not-acknowledge after last</entry></row><row><entry /><entry /><entry>byte received.</entry></row><row><entry>5</entry><entry>Stop</entry><entry>When 1, issue a STOP condition on the</entry></row><row><entry /><entry /><entry>LSS bus.</entry></row><row><entry>7:6</entry><entry>reserved</entry><entry>Must be 0</entry></row><row><entry>15:8 </entry><entry>IdByte</entry><entry>Byte to be transmitted if IdByteEnable</entry></row><row><entry /><entry /><entry>is 1. Bit 8 corresponds to the LSB.</entry></row><row><entry>20:16</entry><entry>TxRxByteCount</entry><entry>Number of bytes to be transmitted from</entry></row><row><entry /><entry /><entry>the data buffer or the number of bytes</entry></row><row><entry /><entry /><entry>to be received into the data buffer.</entry></row><row><entry /><entry /><entry>The maximum value that should be pro-</entry></row><row><entry /><entry /><entry>grammed is 20, as the size of the data</entry></row><row><entry /><entry /><entry>buffer is 20 bytes. Valid values are 1</entry></row><row><entry /><entry /><entry>to 20, 0 is valid when RdWrEnable =</entry></row><row><entry /><entry /><entry>0, other cases are invalid and un-</entry></row><row><entry /><entry /><entry>defined.</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
1836The data buffer is implemented in the LSS master block. When the CPU writes to the LssNBuffer registers the data written is presented to the LSS master block via the lssN_buffer_wrdata bus and configuration registers block pulses the lssN_buffer_wen bit corresponding to the register written. For example if LssNBuffer[2] is written to lssN_buffer_wen[2] will be pulsed. When the CPU reads the LssNBuffer registers the configuration registers block reflect the lssN_buffer_rdata bus back to the CPU.
000019.3.3 LSS Master Unit
1837The LSS master unit is instantiated for both LSS bus 0 and LSS bus 1. It controls transactions on the LSS bus by means of the state machine shown in <figref idref="DRAWINGS">FIG. 83</figref>, which interprets the commands that are written by the CPU. It also contains a single 20 byte data buffer used for transmitting and receiving data.
1838The CPU can write data to be transmitted on the LSS bus by writing to the LssNBuffer registers. It can also read data that the LSS master unit receives on the LSS bus by reading the same registers. The LSS master always transmits or receives bytes to or from the data buffer in the same order.
1839For a transmit command, LssNBuffer[0][7:0] gets transmitted first, then LssNBuffer[0][15:8], LssNBuffer[0][23:16], LssNBuffer[0][31:24], LssNBuffer[1][7:0] and so on until TxRxByteCount number of bytes are transmitted. A receive command fills data to the buffer in the same order. Each new command the buffer start point is reset.
1840All state machine outputs, flags and counters are cleared on reset. After a reset the state machine goes to the Reset state and initialises the LSS pins (lss_clk is set to 1, lss_data is tristated and allowed to be pulled up to 1). When the reset condition is removed the state machine transitions to the Wait state.
1841It remains in the Wait state until lss_new_cmd equals 1. If the Start bit of the command is 0 the state machine proceeds directly to the CheckIdByteEnable state. If the Start bit is 1 it proceeds to the GenerateStart state and issues a STAR<sub>T </sub>condition on the LSS bus.
1842In the CheckIdByteEnable state, if the IdByteEnable bit of the command is 0 the state machine proceeds directly to the CheckRdWrEnable state. If the IdByteEnable bit is 1 the state machine enters the SendIdByte state and the byte in the IdByte field of the command is transmitted on the LSS. The WaitForIdAck state is then entered. If the byte is acknowledged, the state machine proceeds to the CheckRdWrEnable state. If the byte is not-acknowledged, the state machine proceeds to the GenerateInterrupt state and issues an interrupt to indicate a not-acknowledge was received after transmission of the primary id byte.
1843In the CheckRdWrEnable state, if the RdWrEnable bit of the command is 0 the state machine proceeds directly to the CheckStop state. If the RdWrEnable bit is 1, count is loaded with the value of the TxRxByteCount field of the command and the state machine enters either the ReceiveByte state if the RdWrSense bit of the command is 1 or the TransmitByte state if the RdWrSense bit is 0.
1844For a write transaction, the state machine keeps transmitting bytes from the data buffer, decrementing count after each byte transmitted, until count is 1. If all the bytes are successfully transmitted the state machine proceeds to the CheckStop state. If the slave QA chip not-acknowledges a transmitted byte, the state machine indicates this error by issuing an interrupt to the CPU and then entering the GenerateInterrupt state.
1845For a read transaction, the state machine keeps receiving bytes into the data buffer, decrementing count after each byte transmitted, until count is 1. After each byte received the LSS master must issue an acknowledge. After the last expected byte (i.e. when count is 1) the state machine checks the ReadNack bit of the command to see whether it must issue an acknowledge or not-acknowledge for that byte. The CheckStop state is then entered.
1846In the CheckStop state, if the Stop bit of the command is 0 the state machine proceeds directly to the GenerateInterrupt state. If the Stop bit is 1 it proceeds to the GenerateStop state and issues a STOP condition on the LSS bus before proceeding to the GenerateInterrupt state. In both cases an interrupt is issued to indicate successful completion of the command.
1847The state machine then enters the Wait state to await the next command. When the state machine reenters the Wait state the output pins (lss_and lss_clk) are not changed, they retain the state of the last command. This allows the possibility of multi-command transactions. The CPU may abort the current transfer at any time by performing a write to the Reset register of the LSS block.
000019.3.3.1 STAR<sub>T </sub>and STOP Generation
1848STAR<sub>T </sub>and STOP conditions, which signal the beginning and end of data transmission, occur when the LSS master generates a falling and rising edge respectively on the data while the clock is high.
1849In the GenerateStart state, lss_gpio_clk is held high with lss_gpio_e remaining deasserted (so the data line is pulled high externally) for LssClockHighLowDuration pclk cycles. Then lss_gpio_e is asserted and lss_gpio_dout is pulled low (to drive a 0 on the data line, creating a falling edge) with lss_gpio_clk remaining high for another LssClockHighLowDuration pclk cycles. In the GenerateStop state, both lss_gpio_clk and lss_gpio_dout are pulled low followed by the assertion of lss_gpio_e to drive a 0 while the clock is low. After LssClockHighLowDuration pclk cycles, lss_gpio_clk is set high. After a further LssClockHighLowDuration pclk cycles, lss_gpio_e is deasserted to release the data bus and create a rising edge on the data bus during the high period of the clock.
1850If the bus is not in the required state for start and stop generation (lss_clk=1, lss_data=1 for start, and lss_clk=1, lss_data=0), the state machine moves the bus to the correct state and proceeds as described above. <figref idref="DRAWINGS">FIG. 82</figref> shows the transition timing from any bus state to start and stop generation
000019.3.3.2 Clock Pulse Generation
1851The LSS master holds lss_gpio_clk high while the LSS bus is inactive. A clock pulse is generated for each bit transmitted or received over the LSS bus. It is generated by first holding lss_gpio_clk low for LssClockHighLowDuration pclk cycles, and then high for LssClockHighLowDuration pclk cycles.
000019.3.3.3 Data De-glitching
1852When data is received in the LSS block it is passed to a de-glitching circuit. The de-glitch circuit samples the data 3 times on pclk and compares the samples. If all 3 samples are the same then the data is passed, otherwise the data is ignored.
1853Note that the LSS data input on SoPEC is double registered in the GPIO block before being passed to the LSS.
000019.3.3.4 Data Reception
1854The input data, gpio_lss_di, is first synchronised to the pclk domain by means of two flip-flops clocked by pclk (the double register resides in the GPIO block). The LSS master generates a clock pulse for each bit received. The output lss_gpio_e is deasserted LssClockToDataHold pclk cycles after the falling edge of lss_gpio_clk to release the data bus. The value on the synchronised gpio_lss_di is sampled Tstrobe number of clock cycles after the rising edge of lss_gpio_clk (the data is de-glitched over a further 3 stage register to avoid possible glitch detection). See <figref idref="DRAWINGS">FIG. 84</figref> for further timing information.
1855In the ReceiveByte state, the state machine generates 8 clock pulses. At each Tstrobe time after the rising edge of lss_gpio_clk the synchronised gpio_lss_di is sampled. The first bit sampled is LssNBuffer[0][7], the second LssNBuffer[0][6], etc to LssNBuffer[0][0]. For each byte received the state machine either sends an NAK or an ACK depending on the command configuration and the number of bytes received.
1856In the SendNack state the state machine generates a single clock pulse. lss_gpio_e is deasserted and the LSS data line is pulled high externally to issue a not-acknowledge.
1857In the SendAck state the state machine generates a single clock pulse. lss_gpio_e is asserted and a 0 driven on lss_gpio_dout after lss_gpio_clk falling edge to issue an acknowledge.
000019.3.3.5 Data Transmission
1858The LSS master generates a clock pulse for each bit transmitted. Data is output on the LSS bus on the falling edge of lss_gpio_clk.
1859When the LSS master drives a logical zero on the bus it will assert lss_gpio_e and drive a 0 on lss_gpio_dout after lss_gpio_clk falling edge. lss_gpio_e will remain asserted and lss_gpio_dout will remain low until the next lss_clk falling edge.
1860When the LSS master drives a logical one lss_gpio_e should be deasserted at lss_gpio_clk falling edge and remain deasserted at least until the next lss_gpio_clk falling edge. This is because the LSS bus will be externally pulled up to logical one via a pull-up resistor.
1861In the SendId byte state, the state machine generates 8 clock pulses to transmit the byte in the IdByte field of the current valid command. On each falling edge of lss_gpio_clk a bit is driven on the data bus as outlined above. On the first falling edge IdByte[7] is driven on the data bus, on the second falling edge IdByte[6] is driven out, etc.
1862In the TransmitByte state, the state machine generates 8 clock pulses to transmit the byte at the output of the transmit FIFO. On each falling edge of lss_gpio_clk a bit is driven on the data bus as outlined above. On the first falling edge LssNBuffer[0][7] is driven on the data bus, on the second falling edge LssNBuffer[0][6] is driven out, etc on to LssNBuffer[0][7] bits.
1863In the WaitForAck state, the state machine generates a single clock pulse. At Tstrobe time after the rising edge of lss_gpio_clk the synchronized gpio_lss_di is sampled. A 0 indicates an acknowledge and ack_detect is pulsed, a 1 indicates a not-acknowledge and nack_detect is pulsed.
000019.3.3.6 Data Rate Control
1864The CPU can control the data rate by setting the clock period of the LSS bus clock by programming appropriate value in LssClockHighLowDuration. The default setting for the register is 200 (pclk cycles) which corresponds to transmission rate of 400 kHz on the LSS bus (the lss_clk is high for LssClockHighLowDuration cycles then low for LssClockHighLowDuration cycles). The lss_clk will always have a 50:50 duty cycle. The LssClockHighLowDuration register should not be set to values less than 8.
1865The hold time of lss_data after the falling edge of lss_clk is programmable by the LssClocktoDataHold register. This register should not be programmed to less than 2 or greater than the LssClockHighLowDuration value.
000019.3.3.7 LSS Master Timing Parameters
1866The LSS master timing parameters are shown in <figref idref="DRAWINGS">FIG. 84</figref> and the associated values are shown in Table 105.
1867<tables id="TABLE-US-00136" num="00136"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="273pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 105</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>LSS master timing parameters</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="112pt" align="left" /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="21pt" align="left" /><colspec colname="5" colwidth="28pt" align="left" /><colspec colname="6" colwidth="42pt" align="left" /><tbody valign="top"><row><entry>Parameter</entry><entry>Description</entry><entry>min</entry><entry>nom</entry><entry>max</entry><entry>unit</entry></row><row><entry namest="1" nameend="6" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="273pt" align="left" /><tbody valign="top"><row><entry>LSS Master Driving</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="112pt" align="left" /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="21pt" align="left" /><colspec colname="5" colwidth="28pt" align="left" /><colspec colname="6" colwidth="42pt" align="left" /><tbody valign="top"><row><entry>Tp</entry><entry>LSS clock period divided by 2</entry><entry>8</entry><entry>200</entry><entry>FFFF</entry><entry>pclk cycles</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="112pt" align="left" /><colspec colname="3" colwidth="77pt" align="left" /><colspec colname="4" colwidth="42pt" align="left" /><tbody valign="top"><row><entry>Tstart_delay</entry><entry>Time to start data edge from rising</entry><entry>Tp +</entry><entry>pclk cycles</entry></row><row><entry /><entry>clock edge</entry><entry>LssClocktoDataHold</entry></row><row><entry>Tstop_delay</entry><entry>Time to stop data edge from rising</entry><entry>Tp +</entry><entry>pclk cycles</entry></row><row><entry /><entry>clock edge</entry><entry>LssClocktoDataHold</entry></row><row><entry>Tdata_setup</entry><entry>Time from data setup to rising clock</entry><entry>Tp − 2 −</entry><entry>pclk cycles</entry></row><row><entry /><entry>edge</entry><entry>LssClocktoDataHold</entry></row><row><entry>Tdata_hold</entry><entry>Time from falling clock edge to data</entry><entry>LssClocktoDataHold</entry><entry>pclk cycles</entry></row><row><entry /><entry>hold</entry></row><row><entry>Tack_setup</entry><entry>Time that outgoing (N)Ack is setup</entry><entry>Tp − 2 −</entry><entry>pclk cycles</entry></row><row><entry /><entry>before lss_clk rising edge</entry><entry>LssClocktoDataHold</entry></row><row><entry>Tack_hold</entry><entry>Time that outgoing (N)Ack is held</entry><entry>LssClocktoDataHold</entry><entry>pclk cycles</entry></row><row><entry /><entry>after lss_clk falling edge</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="273pt" align="left" /><tbody valign="top"><row><entry>LSS Master Sampling</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="112pt" align="left" /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="21pt" align="left" /><colspec colname="5" colwidth="28pt" align="left" /><colspec colname="6" colwidth="42pt" align="left" /><tbody valign="top"><row><entry>Tstrobe</entry><entry>LSS master strobe point for</entry><entry>Tp − 2</entry><entry /><entry>Tp − 2</entry><entry>pclk cycles</entry></row><row><entry /><entry>incoming data and (N)Ack values</entry></row><row><entry namest="1" nameend="6" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
1868DRAM Subsystem
000020 DRAM Interface Unit (DIU)
000020.1 Overview
1869<figref idref="DRAWINGS">FIG. 85</figref> shows how the DIU provides the interface between the on-chip 20 Mbit embedded DRAM and the rest of SoPEC. In addition to outlining the functionality of the DIU, this chapter provides a top-level overview of the memory storage and access patterns of SoPEC and the buffering required in the various SoPEC blocks to support those access requirements.
1870The main functionality of the DIU is to arbitrate between requests for access to the embedded DRAM and provide read or write accesses to the requesters. The DIU must also implement the initialisation sequence and refresh logic for the embedded DRAM.
1871The arbitration scheme uses a fully programmable timeslot mechanism for non-CPU requesters to meet the bandwidth and latency requirements for each unit, with unused slots re-allocated to provide best effort accesses. The CPU is allowed high priority access, giving it minimum latency, but allowing bounds to be placed on its bandwidth consumption.
1872The interface between the DIU and the SoPEC requesters is similar to the interface on PEC1 i.e. separate control, read data and write data busses.
1873The embedded DRAM is used principally to store: <ul id="ul0166" list-style="none"><li id="ul0166-0001" num="0000"><ul id="ul0167" list-style="none"><li id="ul0167-0001" num="1874">CPU program code and data.</li><li id="ul0167-0002" num="1875">PEP (re)programming commands.</li><li id="ul0167-0003" num="1876">Compressed pages containing contone, bi-level and raw tag data and header information.</li><li id="ul0167-0004" num="1877">Decompressed contone and bi-level data.</li><li id="ul0167-0005" num="1878">Dotline store during a print.</li><li id="ul0167-0006" num="1879">Print setup information such as tag format structures, dither matrices and dead nozzle information. <br /> 20.2 IBM Cu-11 Embedded DRAM <br /> 20.2.1 Single Bank </li></ul></li></ul>
1880SoPEC will use the 1.5 V core voltage option in IBM's 0.13 μm class Cu-11 process.
1881The random read/write cycle time and the refresh cycle time is 3 cycles at 160 MHz [16]. An open page access will complete in 1 cycle if the page mode select signal is clocked at 320 MHz or 2 cycles if the page mode select signal is clocked every 160 MHz cycle. The page mode select signal will be clocked at 160 MHz in SoPEC in order to simplify timing closure. The DRAM word size is 256 bits.
1882Most SoPEC requesters will make single 256 bit DRAM accesses (see Section 20.4). These accesses will take 3 cycles as they are random accesses i.e. they will most likely be to a different memory row than the previous access.
1883The entire 20 Mbit DRAM will be implemented as a single memory bank. In Cu-11, the maximum single instance size is 16 Mbit. The first 1 Mbit tile of each instance contains an area overhead so the cheapest solution in terms of area is to have only 2 instances. 16 Mbit and 4 Mbit instances would together consume an area of 14.63 mm<sup>2 </sup>as would 2 times 10 Mbit instances. 4 times 5 Mbit instances would require 17.2 mm<sup>2</sup>.
1884The instance size will determine the frequency of refresh. Each refresh requires 3 clock cycles. In Cu-11 each row consists of 8 columns of 256-bit words. This means that 10 Mbit requires 5120 rows. A complete DRAM refresh is required every 3.2 ms. Two times 10 Mbit instances would require a refresh every 100 clock cycles, if the instances are refreshed in parallel.
1885The SoPEC DRAM will be constructed as two 10 Mbit instances implemented as a single memory bank.
000020.3 SoPEC Memory Usage Requirements
1886The memory usage requirements for the embedded DRAM are shown in Table 106.
1887<tables id="TABLE-US-00137" num="00137"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 106</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Memory Usage Requirements</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="63pt" align="center" /><colspec colname="3" colwidth="98pt" align="left" /><tbody valign="top"><row><entry>Block</entry><entry>Size</entry><entry>Description</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="28pt" align="right" /><colspec colname="3" colwidth="35pt" align="left" /><colspec colname="4" colwidth="98pt" align="left" /><tbody valign="top"><row><entry>Compressed</entry><entry>2048</entry><entry>Kbytes</entry><entry>Compressed data page store for</entry></row><row><entry>page</entry><entry /><entry /><entry>Bi-level and contone data</entry></row><row><entry>store</entry></row><row><entry>Decompressed</entry><entry>108</entry><entry>Kbyte</entry><entry>13824 lines with scale factor</entry></row><row><entry>Contone</entry><entry /><entry /><entry>6 = 2304 pixels, store 12</entry></row><row><entry>Store</entry><entry /><entry /><entry>lines, 4 colors = 108 kB</entry></row><row><entry /><entry /><entry /><entry>13824 lines with scale factor</entry></row><row><entry /><entry /><entry /><entry>5 = 2765 pixels, store 12</entry></row><row><entry /><entry /><entry /><entry>lines, 4 colors = 130 kB</entry></row><row><entry>Spot line</entry><entry>5.1</entry><entry>Kbyte</entry><entry>13824 dots/line so 3 lines</entry></row><row><entry>store</entry><entry /><entry /><entry>is 5.1 kB</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="63pt" align="center" /><colspec colname="3" colwidth="98pt" align="left" /><tbody valign="top"><row><entry>Tag Format</entry><entry>Typically</entry><entry>55 kB in for 384 dot line tags</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="28pt" align="right" /><colspec colname="3" colwidth="35pt" align="left" /><colspec colname="4" colwidth="98pt" align="left" /><tbody valign="top"><row><entry>Structure</entry><entry>12</entry><entry>Kbyte</entry><entry>2.5 mm tags (1/10th inch) @</entry></row><row><entry /><entry>(2.5</entry><entry>mm</entry><entry>1600 dpi require 160 dot lines =</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="63pt" align="center" /><colspec colname="3" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry>tags @</entry><entry>160/384 × 55 or 23 kB</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="28pt" align="right" /><colspec colname="3" colwidth="35pt" align="left" /><colspec colname="4" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry>800</entry><entry>dpi)</entry><entry>2.5 mm tags (1/10th inch) @</entry></row><row><entry /><entry /><entry /><entry>800 dpi require 80/384 × 55 =</entry></row><row><entry /><entry /><entry /><entry>12 kB</entry></row><row><entry>Dither Matrix</entry><entry>4</entry><entry>Kbytes</entry><entry>64 × 64 dither matrix is 4 kB</entry></row><row><entry>store</entry><entry /><entry /><entry>128 × 128 dither matrix is 16 kB</entry></row><row><entry /><entry /><entry /><entry>256 × 256 dither matrix is 64 kB</entry></row><row><entry>DNC Dead</entry><entry>1.4</entry><entry>Kbytes</entry><entry>Delta encoded, (10 bit delta</entry></row><row><entry>Nozzle Table</entry><entry /><entry /><entry>position + 6 dead nozzle</entry></row><row><entry /><entry /><entry /><entry>mask) × % Dnozzle</entry></row><row><entry /><entry /><entry /><entry>5% dead nozzles requires</entry></row><row><entry /><entry /><entry /><entry>(10 + 6) ×</entry></row><row><entry /><entry /><entry /><entry>692 Dnozzles = 1.4 Kbytes</entry></row><row><entry>Dot-line</entry><entry>369.6</entry><entry>Kbytes</entry><entry>Assume each color row is sepa-</entry></row><row><entry>store</entry><entry /><entry /><entry>rated by 5 dot lines on the</entry></row><row><entry /><entry /><entry /><entry>print head</entry></row><row><entry /><entry /><entry /><entry>The dot line store will be</entry></row><row><entry /><entry /><entry /><entry>0 + 5 + 10 . . . 50 + 55 =</entry></row><row><entry /><entry /><entry /><entry>330 half dot lines + 48 extra</entry></row><row><entry /><entry /><entry /><entry>half dot lines (4 per dot row) +</entry></row><row><entry /><entry /><entry /><entry>60 extra half dot lines estimated</entry></row><row><entry /><entry /><entry /><entry>to account for printhead mis-</entry></row><row><entry /><entry /><entry /><entry>alignment = 438 half dot lines.</entry></row><row><entry /><entry /><entry /><entry>438 half dot lines of 6912</entry></row><row><entry /><entry /><entry /><entry>dots = 369.6 Kbytes</entry></row><row><entry>PCU Program</entry><entry>8</entry><entry>Kbytes</entry><entry>1024 commands of 64 bits =</entry></row><row><entry>code</entry><entry /><entry /><entry>8 KB</entry></row><row><entry>CPU</entry><entry>64</entry><entry>Kbytes</entry><entry>Program code and data</entry></row><row><entry>TOTAL</entry><entry>2620</entry><entry>Kbytes</entry></row><row><entry /><entry>(12</entry><entry>Kbyte</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="63pt" align="center" /><colspec colname="3" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry>TFS storage)</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry namest="1" nameend="3" align="left" id="FOO-00008">Note:</entry></row><row><entry namest="1" nameend="3" align="left" id="FOO-00009">Total storage is fixed to 2560 Kbytes to align to 20 Mbit DRAM. This will mean that less space than noted in Table may be available for the compressed band store.</entry></row></tbody></tgroup></table></tables><br /> 20.4 SoPEC Memory Access Patterns
1888Table 107 shows a summary of the blocks on SoPEC requiring access to the embedded DRAM and their individual memory access patterns. Most blocks will access the DRAM in single 256-bit accesses. All accesses must be padded to 256-bits except for 64-bit CDU write accesses and CPU write accesses. Bits which should not be written are masked using the individual DRAM bit write inputs or byte write inputs, depending on the foundry. Using single 256-bit accesses means that the buffering required in the SoPEC DRAM requesters will be minimized.
1889<tables id="TABLE-US-00138" num="00138"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 107</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Memory access patterns of SoPEC DRAM Requesters</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><colspec colname="3" colwidth="140pt" align="left" /><tbody valign="top"><row><entry>DRAM</entry><entry /><entry /></row><row><entry>requester</entry><entry>Direction</entry><entry>Memory access pattern</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>CPU</entry><entry>R</entry><entry>Single 256-bit reads.</entry></row><row><entry /><entry>W</entry><entry>Single 32-bit, 16-bit or 8-bit writes.</entry></row><row><entry>SCB</entry><entry>R</entry><entry>Single 256-bit reads.</entry></row><row><entry /><entry>W</entry><entry>Single 256-bit writes, with byte enables.</entry></row><row><entry>CDU</entry><entry>R</entry><entry>Single 256-bit reads of the compressed</entry></row><row><entry /><entry /><entry>contone data.</entry></row><row><entry /><entry>W</entry><entry>Each CDU access is a write to 4 consecutive</entry></row><row><entry /><entry /><entry>DRAM words in the same row but only 64 bits</entry></row><row><entry /><entry /><entry>of each word are written with the remaining</entry></row><row><entry /><entry /><entry>bits write masked.</entry></row><row><entry /><entry /><entry>The access time for this 4 word page mode</entry></row><row><entry /><entry /><entry>burst is 3 + 2 + 2 + 2 = 9 cycles</entry></row><row><entry /><entry /><entry>if the page mode select signal is clocked</entry></row><row><entry /><entry /><entry>at 160 MHz.</entry></row><row><entry>CFU</entry><entry>R</entry><entry>Single 256 bit reads.</entry></row><row><entry>LBD</entry><entry>R</entry><entry>Single 256 bit reads.</entry></row><row><entry>SFU</entry><entry>R</entry><entry>Separate single 256 bit reads for previous</entry></row><row><entry /><entry /><entry>and current line but sharing the same DIU</entry></row><row><entry /><entry /><entry>interface</entry></row><row><entry /><entry>W</entry><entry>Single 256 bit writes.</entry></row><row><entry>TE(TD)</entry><entry>R</entry><entry>Single 256 bit reads. Each read returns 2</entry></row><row><entry /><entry /><entry>times 128 bit tags.</entry></row><row><entry>TE(TFS)</entry><entry>R</entry><entry>Single 256 bit reads. TFS is 136 bytes.</entry></row><row><entry /><entry /><entry>This means there is unused data in the</entry></row><row><entry /><entry /><entry>fifth 256 bit read. A total of 5 reads</entry></row><row><entry /><entry /><entry>is required.</entry></row><row><entry>HCU</entry><entry>R</entry><entry>Single 256 bit reads. 128 × 128 dither matrix</entry></row><row><entry /><entry /><entry>requires 4 reads per line with double buffering.</entry></row><row><entry /><entry /><entry>256 × 256 dither matrix requires 8 reads at</entry></row><row><entry /><entry /><entry>the end of the line with single buffering.</entry></row><row><entry>DNC</entry><entry>R</entry><entry>Single 256 bit dead nozzle table reads. Each</entry></row><row><entry /><entry /><entry>dead nozzle table read contains 16 dead-nozzle</entry></row><row><entry /><entry /><entry>tables entries each of 10 delta bits plus 6</entry></row><row><entry /><entry /><entry>dead nozzle mask bits.</entry></row><row><entry>DWU</entry><entry>W</entry><entry>Single 256 bit writes since enable/disable</entry></row><row><entry /><entry /><entry>DRAM access per color plane.</entry></row><row><entry>LLU</entry><entry>R</entry><entry>Single 256 bit reads since enable/disable</entry></row><row><entry /><entry /><entry>DRAM access per color plane.</entry></row><row><entry>PCU</entry><entry>R</entry><entry>Single 256 bit reads. Each PCU command is</entry></row><row><entry /><entry /><entry>64 bits so each 256 bit word can contain</entry></row><row><entry /><entry /><entry>4 PCU commands.</entry></row><row><entry /><entry /><entry>PCU reads from DRAM used for repro-</entry></row><row><entry /><entry /><entry>gramming PEP should be executed with</entry></row><row><entry /><entry /><entry>minimum latency.</entry></row><row><entry /><entry /><entry>If this occurs between pages then there</entry></row><row><entry /><entry /><entry>will be free bandwidth as most of the</entry></row><row><entry /><entry /><entry>other SoPEC Units will not be requesting</entry></row><row><entry /><entry /><entry>from DRAM. If this occurs between bands</entry></row><row><entry /><entry /><entry>then the LDB, CDU and TE bandwidth will</entry></row><row><entry /><entry /><entry>be free. So the PCU should have a high</entry></row><row><entry /><entry /><entry>priority to access to any spare bandwidth.</entry></row><row><entry>Refresh</entry><entry /><entry>Single refresh.</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 20.5 Buffering Required in SoPEC DRAM Requesters
1890If each DIU access is a single 256-bit access then we need to provide a 256-bit double buffer in the DRAM requester. If the DRAM requester has a 64-bit interface then this can be implemented as an 8×64-bit FIFO.
1891<tables id="TABLE-US-00139" num="00139"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="287pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 108</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Buffer sizes in SoPEC DRAM requesters</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="35pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><colspec colname="3" colwidth="126pt" align="left" /><colspec colname="4" colwidth="91pt" align="left" /><tbody valign="top"><row><entry>DRAM</entry><entry /><entry /><entry>Buffering required in</entry></row><row><entry>Requester</entry><entry>Direction</entry><entry>Access patterns</entry><entry>block</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="35pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><colspec colname="3" colwidth="126pt" align="left" /><colspec colname="4" colwidth="84pt" align="left" /><colspec colname="5" colwidth="7pt" align="left" /><tbody valign="top"><row><entry>CPU</entry><entry>R</entry><entry>Single 256-bit reads.</entry><entry>Cache.</entry><entry /></row><row><entry /><entry>W</entry><entry>Single 32-bit writes but allowing 16-bit or</entry><entry>None.</entry></row><row><entry /><entry /><entry>byte addressable writes.</entry></row><row><entry>SCB</entry><entry>R</entry><entry>Single 256-bit reads.</entry><entry>Double 256-bit buffer.</entry></row><row><entry /><entry>W</entry><entry>Single 256-bit writes, with byte enables.</entry><entry>Double 256-bit buffer.</entry></row><row><entry>CDU</entry><entry>R</entry><entry>Single 256-bit reads of the compressed</entry><entry>Double 256-bit buffer.</entry></row><row><entry /><entry /><entry>contone data.</entry></row><row><entry /><entry>W</entry><entry>Each CDU access is a write to 4</entry><entry>Double half JPEG block</entry></row><row><entry /><entry /><entry>consecutive DRAM words in the same</entry><entry>buffer.</entry></row><row><entry /><entry /><entry>row but only 64 bits of each word are</entry></row><row><entry /><entry /><entry>written with the remaining bits write</entry></row><row><entry /><entry /><entry>masked.</entry></row><row><entry>CFU</entry><entry>R</entry><entry>Single 256 bit reads.</entry><entry>Triple 256-bit buffer.</entry></row><row><entry>LBD</entry><entry>R</entry><entry>Single 256 bit reads.</entry><entry>Double 256-bit buffer.</entry></row><row><entry>SFU</entry><entry>R</entry><entry>Separate single 256 bit reads for</entry><entry>Double 256-bit buffer for</entry></row><row><entry /><entry /><entry>previous and current line but sharing</entry><entry>each read channel.</entry></row><row><entry /><entry /><entry>the same DIU interface</entry></row><row><entry /><entry>W</entry><entry>Single 256 bit writes.</entry><entry>Double 256-bit buffer.</entry></row><row><entry>TE(TD)</entry><entry>R</entry><entry>Single 256 bit reads.</entry><entry>Double 256-bit buffer.</entry></row><row><entry>TE(TFS)</entry><entry>R</entry><entry>Single 256 bit reads. TFS is 136 bytes.</entry><entry>Double line-buffer for</entry></row><row><entry /><entry /><entry>This means there is unused data in the</entry><entry>136 bytes implemented</entry></row><row><entry /><entry /><entry>fifth 256 bit read. A total of 5 reads is</entry><entry>in TE.</entry></row><row><entry /><entry /><entry>required.</entry></row><row><entry>HCU</entry><entry>R</entry><entry>Single 256 bit reads. 128 × 128 dither</entry><entry>Configurable between</entry></row><row><entry /><entry /><entry>matrix requires 4 reads per line with</entry><entry>double 128 byte buffer</entry></row><row><entry /><entry /><entry>double buffering. 256 × 256 dither matrix</entry><entry>and single 256 byte buffer.</entry></row><row><entry /><entry /><entry>requires 8 reads at the end of the line</entry></row><row><entry /><entry /><entry>with single buffering.</entry></row><row><entry>DNC</entry><entry>R</entry><entry>Single 256 bit reads</entry><entry>Double 256-bit buffer.</entry></row><row><entry /><entry /><entry /><entry>Deeper buffering could</entry></row><row><entry /><entry /><entry /><entry>be specified to cope with</entry></row><row><entry /><entry /><entry /><entry>local clusters of dead</entry></row><row><entry /><entry /><entry /><entry>nozzles.</entry></row><row><entry>DWU</entry><entry>W</entry><entry>Single 256 bit writes per enabled</entry><entry>Double 256-bit buffer per</entry></row><row><entry /><entry /><entry>odd/even color plane.</entry><entry>color plane.</entry></row><row><entry>LLU</entry><entry>R</entry><entry>Single 256 bit reads per enabled</entry><entry>Double 256-bit buffer per</entry></row><row><entry /><entry /><entry>odd/even color plane.</entry><entry>color plane.</entry></row><row><entry>PCU</entry><entry>R</entry><entry>Single 256 bit reads. Each PCU</entry><entry>Single 256-bit buffer.</entry></row><row><entry /><entry /><entry>command is 64 bits so each 256 bit</entry></row><row><entry /><entry /><entry>DRAM read can contain 4 PCU com-</entry></row><row><entry /><entry /><entry>mands. Requested command is read</entry></row><row><entry /><entry /><entry>from DRAM together with the next 3</entry></row><row><entry /><entry /><entry>contiguous 64-bits which are cached to</entry></row><row><entry /><entry /><entry>avoid unnecessary DRAM reads.</entry></row><row><entry>Refresh</entry><entry /><entry>Single refresh.</entry><entry>None.</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 20.6 SoPEC DIU Bandwidth Requirements
1892<tables id="TABLE-US-00140" num="00140"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="301pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 109</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>SoPEC DIU Bandwidth Requirements</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="1" colwidth="35pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><colspec colname="3" colwidth="63pt" align="left" /><colspec colname="4" colwidth="56pt" align="left" /><colspec colname="5" colwidth="56pt" align="left" /><colspec colname="6" colwidth="56pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Number of</entry><entry /><entry /><entry /></row><row><entry /><entry /><entry>cycles between</entry><entry>Peak</entry></row><row><entry /><entry /><entry>each 256-bit</entry><entry>Bandwidth</entry><entry /><entry>Example</entry></row><row><entry /><entry /><entry>DRAM access</entry><entry>which must</entry><entry>Average</entry><entry>number of</entry></row><row><entry>Block</entry><entry /><entry>to meet peak</entry><entry>be supplied</entry><entry>Bandwidth</entry><entry>allocated</entry></row><row><entry>Name</entry><entry>Direction</entry><entry>bandwidth</entry><entry>bits/cycle)</entry><entry>(bits/cycle)</entry><entry>timeslots<sup>1</sup></entry></row><row><entry namest="1" nameend="6" align="center" rowsep="1" /></row><row><entry>CPU</entry><entry>R</entry><entry /><entry /><entry /><entry /></row><row><entry /><entry>W</entry></row><row><entry>SCB</entry><entry>R</entry></row><row><entry /><entry>W</entry><entry>3482</entry><entry>0.734</entry><entry>0.3933</entry><entry>1</entry></row><row><entry>CDU</entry><entry>R</entry><entry>128 (SF = 4),</entry><entry>64/n2 (SF = n),</entry><entry>32/10*n2</entry><entry>1 (SF = 6)</entry></row><row><entry /><entry /><entry>288 (SF = 6),</entry><entry>1.8 (SF = 6),</entry><entry>(SF = n),</entry><entry>2 (SF = 4)</entry></row><row><entry /><entry /><entry>1:1 compression4</entry><entry>4 (SF = 4)</entry><entry>0.09 (SF = 6),</entry></row><row><entry /><entry /><entry /><entry>(1:1 compression)</entry><entry>0.2 (SF = 4)</entry></row><row><entry /><entry /><entry /><entry /><entry>(10:1 com-</entry></row><row><entry /><entry /><entry /><entry /><entry>pression)5</entry></row><row><entry /><entry>W</entry><entry>For individual</entry><entry>64/n2 (SF = n),</entry><entry>32/n2 (SF = n)7,</entry><entry>2 (SF = 6)8</entry></row><row><entry /><entry /><entry>accesses: 16</entry><entry>1.8 (SF = 6),</entry><entry>0.9 (SF = 6),</entry><entry>4 (SF = 4)</entry></row><row><entry /><entry /><entry>cycles (SF = 4),</entry><entry>4 (SF = 4)</entry><entry>2 (SF = 4)</entry></row><row><entry /><entry /><entry>36 cycles (SF = 6),</entry></row><row><entry /><entry /><entry>n2 cycles (SF = n).</entry></row><row><entry /><entry /><entry>Will be</entry></row><row><entry /><entry /><entry>implemented as a</entry></row><row><entry /><entry /><entry>page mode burst of</entry></row><row><entry /><entry /><entry>4 accesses every</entry></row><row><entry /><entry /><entry>64 cycles (SF = 4),</entry></row><row><entry /><entry /><entry>144 (SF = 6), 4*n2</entry></row><row><entry /><entry /><entry>(SF = n) cycles6</entry></row><row><entry>CFU</entry><entry>R</entry><entry>32 (SF = 4),</entry><entry>32/n (SF = n),</entry><entry>32/n (SF = n),</entry><entry>6 (SF = 6)</entry></row><row><entry /><entry /><entry>48 (SF = 6)9</entry><entry>5.4 (SF = 6),</entry><entry>5.4 (SF = 6),</entry><entry>8 (SF = 4)</entry></row><row><entry /><entry /><entry /><entry>8 (SF = 4)</entry><entry>8 (SF = 4)</entry></row><row><entry>LBD</entry><entry>R</entry><entry>256 (1:1 com-</entry><entry>1 (1:1 com-</entry><entry>0.1 (10:1 com-</entry><entry>1</entry></row><row><entry /><entry /><entry>pression)10</entry><entry>pression)</entry><entry>pression)11</entry></row><row><entry>SFU</entry><entry>R</entry><entry>12812</entry><entry>2</entry><entry>2</entry><entry>2</entry></row><row><entry /><entry>W</entry><entry>25613</entry><entry>1</entry><entry>1</entry><entry>1</entry></row><row><entry>TE(TD)</entry><entry>R</entry><entry>25214</entry><entry>1.02</entry><entry>1.02</entry><entry>1</entry></row><row><entry>TE(TFS)</entry><entry>R</entry><entry>5 reads per line 15</entry><entry>0.093</entry><entry>0.093</entry><entry>0</entry></row><row><entry>HCU</entry><entry>R</entry><entry>4 reads per line</entry><entry>0.074</entry><entry>0.074</entry><entry>0</entry></row><row><entry /><entry /><entry>for 128 × 128</entry></row><row><entry /><entry /><entry>dither matrix16</entry></row><row><entry>DNC</entry><entry>R</entry><entry>106 (5% dead-</entry><entry>2.4 (clump of</entry><entry>0.8 (equally</entry><entry>3</entry></row><row><entry /><entry /><entry>nozzles 10-bit</entry><entry>dead nozzles)</entry><entry>spaced dead</entry></row><row><entry /><entry /><entry>delta encoded)17</entry><entry /><entry>nozzles)</entry></row><row><entry>DWU</entry><entry>W</entry><entry>6 writes every</entry><entry>6</entry><entry>6</entry><entry>6</entry></row><row><entry /><entry /><entry>25618</entry></row><row><entry>LLU</entry><entry>R</entry><entry>8 reads every</entry><entry>8</entry><entry>6</entry><entry>8</entry></row><row><entry /><entry /><entry>25619</entry></row><row><entry>PCU</entry><entry>R</entry><entry>25620</entry><entry>1</entry><entry>1</entry><entry>1</entry></row><row><entry>Refresh</entry><entry /><entry>10021</entry><entry>2.56</entry><entry>2.56</entry><entry>3 (effective)</entry></row><row><entry>TOTAL</entry><entry /><entry /><entry>SF = 6:34.9</entry><entry>SF = 6:27.5</entry><entry>SF = 6:36</entry></row><row><entry /><entry /><entry /><entry>SF = 4:41.9</entry><entry>SF = 4:31.2</entry><entry>excluding CPU.</entry></row><row><entry /><entry /><entry /><entry>excluding CPU</entry><entry>excluding CPU</entry><entry>SF = 4:41</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry>excluding CPU</entry></row><row><entry namest="1" nameend="6" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> Notes: <ul id="ul0168" list-style="none"><li id="ul0168-0001" num="1893">1: The number of allocated timeslots is based on 64 timeslots each of 1 bit/cycle but broken down to a granularity of 0.25 bit/cycle. Bandwidth is allocated based on peak bandwidth.</li><li id="ul0168-0002" num="1894">2: Wire-speed bandwidth for a 4 wire SCB configuration is 32 Mbits/s for each wire plus 12 Mbit/s for USB. This is a maximum of 138 Mbit/s. The maximum effective data rate is 26 Mbits/s for each wire plus 8 Mbit/s for USB. This is 112 Mbit/s. 112 Mbit/s is 0.734 bits/cycle or 256 bits every 348 cycles.</li><li id="ul0168-0003" num="1895">3: Wire-speed bandwidth for a 2 wire SCB configuration is 32 Mbits/s for each wire plus 12 Mbit/s for USB. This is a maximum of 74 Mbit/s. The maximum effective data rate is 26 Mbits/s for each wire plus 8 Mbit/s for USB. This is 60 Mbit/s. 60 Mbit/s is 0.393 bits/cycle or 256 bits every 650 cycles.</li><li id="ul0168-0004" num="1896">4: At 1:1 compression CDU must read a 4 color pixel (32 bits) every SF<sup>2 </sup>cycles.</li><li id="ul0168-0005" num="1897">5: At 10:1 average compression CDU must read a 4 color pixel (32 bits) every 10*SF<sup>2</sup>cycles.</li><li id="ul0168-0006" num="1898">6: 4 color pixel (32 bits) is required, on average, by the CFU every SF<sup>2 </sup>(scale factor) cycles.</li></ul>
1899The time available to write the data is a function of the size of the buffer in DRAM. 1.5 buffering means 4 color pixel (32 bits) must be written every SF<sup>2</sup>/2 (scale factor) cycles. Therefore, at a scale factor of SF, 64 bits are required every SF<sup>2 </sup>cycles.
1900Since 64 valid bits are written per 256-bit write (Figure n page379 on page Error! Bookmark n t defined.) then the DRAM is accessed every SF<sup>2 </sup>cycles i.e. at SF4 an access every 16 cycles, at SF6 an access every 36 cycles.
1901If a page mode burst of 4 accesses is used then each access takes (3+2+2+2) equals 9 cycles. This means at SF, a set of 4 back-to-back accesses must occur every 4*SF<sup>2 </sup>cycles. This assumes the page mode select signal is clocked at 160 MHz. CDU timeslots therefore take 9 cycles.
1902For scale factors lower than 4 double buffering will be used. <ul id="ul0169" list-style="none"><li id="ul0169-0001" num="1903">7: The peak bandwidth is twice the average bandwidth in the case of 1.5 buffering.</li><li id="ul0169-0002" num="1904">8: Each CDU(W) burst takes 9 cycles instead of 4 cycles for other accesses so CDU timeslots are longer.</li><li id="ul0169-0003" num="1905">9: 4 color pixel (32 bits) read by CFU every SF cycles. At SF4, 32 bits is required every 4 cycles or 256 bits every 32 cycles. At SF6, 32bits every 6 cycles or 256 bits every 48 cycles.</li><li id="ul0169-0004" num="1906">10: At 1:1 compression require 1 bit/cycle or 256 bits every 256 cycles.</li><li id="ul0169-0005" num="1907">11: The average bandwidth required at 10:1 compression is 0.1 bits/cycle.</li><li id="ul0169-0006" num="1908">12: Two separate reads of 1 bit/cycle.</li><li id="ul0169-0007" num="1909">13: Write at 1 bit/cycle.</li><li id="ul0169-0008" num="1910">14: Each tag can be consumed in at most 126 dot cycles and requires 128 bits. This is a maximum rate of 256 bits every 252 cycles.</li><li id="ul0169-0009" num="1911">15: 17×64 bit reads per line in PEC1 is 5×256 bit reads per line in SoPEC. Double-line buffered storage.</li><li id="ul0169-0010" num="1912">16: 128 bytes read per line is 4×256 bit reads per line. Double-line buffered storage.</li><li id="ul0169-0011" num="1913">17: 5% dead nozzles 10-bit delta encoded stored with 6-bit dead nozzle mask requires 0.8 bits/cycle read access or a 256-bit access every 320 cycles. This assumes the dead nozzles are evenly spaced out. In practice dead nozzles are likely to be clumped. Peak bandwidth is estimated as 3 times average bandwidth.</li><li id="ul0169-0012" num="1914">18: 6 bits/cycle requires 6×256 bit writes every 256 cycles.</li><li id="ul0169-0013" num="1915">19: 6 bits/160 MHz SoPEC cycle average but will peak at 2×6 bits per 106 MHz print head cycle or 8 bits/ SoPEC cycle. The PHI can equalise the DRAM access rate over the line so that the peak rate equals the average rate of 6 bits/cycle. The print head is clocked at an effective speed of 106 MHz.</li><li id="ul0169-0014" num="1916">20: Assume one 256 read per 256 cycles is sufficient i.e. maximum latency of 256 cycles per access is allowable.</li><li id="ul0169-0015" num="1917">21: Refresh must occur every 3.2 ms. Refresh occurs row at a time over 5120 rows of 2 parallel 10 Mbit instances. Refresh must occur every 100 cycles. Each refresh takes 3 cycles. <br /> 20.7 DIU BUS Topology <br /> 20.7.1 Basic Topology </li></ul>
1918<tables id="TABLE-US-00141" num="00141"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 110</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>SoPEC DIU Requesters</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="56pt" align="left" /><colspec colname="3" colwidth="63pt" align="left" /><tbody valign="top"><row><entry /><entry>Read</entry><entry>Write</entry><entry>Other</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row><row><entry /><entry>CPU</entry><entry>CPU</entry><entry>Refresh</entry></row><row><entry /><entry>SCB</entry><entry>SCB</entry></row><row><entry /><entry>CDU</entry><entry>CDU</entry></row><row><entry /><entry>CFU</entry><entry>SFU</entry></row><row><entry /><entry>LBD</entry><entry>DWU</entry></row><row><entry /><entry>SFU</entry></row><row><entry /><entry>TE(TD)</entry></row><row><entry /><entry>TE(TFS)</entry></row><row><entry /><entry>HCU</entry></row><row><entry /><entry>DNC</entry></row><row><entry /><entry>LLU</entry></row><row><entry /><entry>PCU</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
1919Table 110 shows the DIU requesters in SoPEC. There are 12 read requesters and 5 write requesters in SoPEC as compared with 8 read requesters and 4 write requesters in PEC1. Refresh is an additional requester.
1920In PEC1, the interface between the DIU and the DIU requesters had the following main features: <ul id="ul0170" list-style="none"><li id="ul0170-0001" num="0000"><ul id="ul0171" list-style="none"><li id="ul0171-0001" num="1921">separate control and address signals per DIU requester multiplexed in the DIU according to the arbitration scheme,</li><li id="ul0171-0002" num="1922">separate 64-bit write data bus for each DRAM write requester multiplexed in the DIU,</li><li id="ul0171-0003" num="1923">common 64-bit read bus from the DIU with separate enables to each DIU read requester.</li></ul></li></ul>
1924Timing closure for this bussing scheme was straight-forward in PEC1. This suggests that a similar scheme will also achieve timing closure in SoPEC. SoPEC has 5 more DRAM requesters but it will be in a 0.13 um process with more metal layers and SoPEC will run at approximately the same speed as PEC1.
1925Using 256-bit busses would match the data width of the embedded DRAM but such large busses may result in an increase in size of the DIU and the entire SoPEC chip. The SoPEC requestors would require double 256-bit wide buffers to match the 256-bit busses. These buffers, which must be implemented in flip-flops, are less area efficient than 8-deep 64-bit wide register arrays which can be used with 64-bit busses. SoPEC will therefore use 64-bit data busses. Use of 256-bit busses would however simplify the DIU implementation as local buffering of 256-bit DRAM data would not be required within the DIU.
000020.7.1.1 CPU DRAM Access
1926The CPU is the only DIU requestor for which access latency is critical. All DIU write requesters transfer write data to the DIU using separate point-to-point busses. The CPU will use the cpu_dataout[31:0] bus. CPU reads will not be over the shared 64-bit read bus. Instead, CPU reads will use a separate 256-bit read bus.
000020.7.2 Making More Efficient Use of DRAM Bandwidth
1927The embedded DRAM is 256-bits wide. The 4 cycles it takes to transfer the 256-bits over the 64-bit data busses of SoPEC means that effectively each access will be at least 4 cycles long. It takes only 3 cycles to actually do a 256-bit random DRAM access in the case of IBM DRAM.
000020.7.2.1 Common Read Bus
1928If we have a common read data bus, as in PEC1, then if we are doing back to back read accesses the next DRAM read cannot start until the read data bus is free. So each DRAM read access can occur only every 4 cycles. This is shown in <figref idref="DRAWINGS">FIG. 86</figref> with the actual DRAM access taking 3 cycles leaving 1 unused cycle per access.
000020.7.2.2 Interleaving CPU and Non-CPU Read Accesses
1929The CPU has a separate 256-bit read bus. All other read accesses are 256-bit accesses are over a shared 64-bit read bus. Interleaving CPU and non-CPU read accesses means the effective duration of an interleaved access timeslot is the DRAM access time (3 cycles) rather than 4 cycles.
1930<figref idref="DRAWINGS">FIG. 87</figref> shows interleaved CPU and non-CPU read accesses.
000020.7.2.3 Interleaving Read and Write Accesses
1931Having separate write data busses means write accesses can be interleaved with each other and with read accesses. So now the effective duration of an interleaved access timeslot is the DRAM access time (3 cycles) rather than 4 cycles. Interleaving is achieved by ordering the DIU arbitration slot allocation appropriately.
1932<figref idref="DRAWINGS">FIG. 88</figref> shows interleaved read and write accesses. <figref idref="DRAWINGS">FIG. 89</figref> shows interleaved write accesses.
1933256-bit write data takes 4 cycles to transmit over 64-bit busses so a 256-bit buffer is required in the DIU to gather the write data from the write requester. The exception is CPU write data which is transferred in a single cycle.
1934<figref idref="DRAWINGS">FIG. 89</figref> shows multiple write accesses being interleaved to obtain 3 cycle DRAM access. Since two write accesses can overlap two sets of 256-bit write buffers and multiplexors to connect two write requestors simultaneously to the DIU are required.
1935Write requestors only require approximately one third of the total non-CPU bandwidth. This means that a rule can be introduced such that non-CPU write requestors are not allocated adjacent timeslots. This means that a single 256-bit write buffer and multiplexor to connect the one write requestor at a time to the DIU is all that is required.
1936Note that if the rule prohibiting back-to-back non-CPU writes is not adhered to, then the second write slot of any attempted such pair will be disregarded and re-allocated under the unused read round-robin scheme.
000020.7.3 Bus Widths Summary
1937<tables id="TABLE-US-00142" num="00142"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 111</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>SoPEC DIU Requesters Data Bus Width</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="56pt" align="center" /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="56pt" align="center" /><colspec colname="5" colwidth="35pt" align="left" /><tbody valign="top"><row><entry>Read</entry><entry>Bus access width</entry><entry>Write</entry><entry>Bus access width</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="8"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="56pt" align="center" /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="56pt" align="center" /><colspec colname="5" colwidth="14pt" align="left" /><colspec colname="6" colwidth="7pt" align="left" /><colspec colname="7" colwidth="7pt" align="left" /><colspec colname="8" colwidth="7pt" align="left" /><tbody valign="top"><row><entry>CPU</entry><entry><sup> </sup>256 (separate)</entry><entry>CPU</entry><entry>32</entry><entry /><entry /><entry /><entry /></row><row><entry>SCB</entry><entry>64 (shared)</entry><entry>SCB</entry><entry>64</entry></row><row><entry>CDU</entry><entry>64 (shared)</entry><entry>CDU</entry><entry>64</entry></row><row><entry>CFU</entry><entry>64 (shared)</entry><entry>SFU</entry><entry>64</entry></row><row><entry>LBD</entry><entry>64 (shared)</entry><entry>DWU</entry><entry>64</entry></row><row><entry>SFU</entry><entry>64 (shared)</entry></row><row><entry>TE(TD)</entry><entry>64 (shared)</entry></row><row><entry>TE(TFS)</entry><entry>64 (shared)</entry></row><row><entry>HCU</entry><entry>64 (shared)</entry></row><row><entry>DNC</entry><entry>64 (shared)</entry></row><row><entry>LLU</entry><entry>64 (shared)</entry></row><row><entry>PCU</entry><entry>64 (shared)</entry></row><row><entry namest="1" nameend="8" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 20.7.4 CONCLUSIONS
1938Timeslots should be programmed to maximise interleaving of shared read bus accesses with other accesses for 3 cycle DRAM access. The interleaving is achieved by ordering the DIU arbitration slot allocation appropriately. CPU arbitration has been designed to maximise interleaving with non-CPU requesters
000020.8 SoPEC DRAM Addressing Scheme
1939The embedded DRAM is composed of 256-bit words. However the CPU-subsystem may need to write individual bytes of DRAM. Therefore it was decided to make the DIU byte addressable. 22 bits are required to byte address 20 Mbit of DRAM.
1940Most blocks read or write 256 bit words of DRAM. Therefore only the top 17 bits i.e. bits <b>21</b> to <b>5</b> are required to address 256-bit word aligned locations.
1941The exceptions are <ul id="ul0172" list-style="none"><li id="ul0172-0001" num="0000"><ul id="ul0173" list-style="none"><li id="ul0173-0001" num="1942">CDU which can write 64-bits so only the top 19 address bits i.e. bits <b>21</b>–<b>3</b> are required.</li><li id="ul0173-0002" num="1943">CPU writes can be 8, 16 or 32-bits. The cpu_diu_wmask[1:0] pins indicate whether to write 8, 16 or 32 bits.</li></ul></li></ul>
1944All DIU accesses must be within the same 256-bit aligned DRAM word. The exception is the CDU write access which is a write of 64-bits to each of 4 contiguous 256-bit DRAM words.
000020.8.1 Write Address Constaints Specific to the CDU
1945Note the following conditions which apply to the CDU write address, due to the four masked page-mode writes which occur whenever a CDU write slot is arbitrated. <ul id="ul0174" list-style="none"><li id="ul0174-0001" num="0000"><ul id="ul0175" list-style="none"><li id="ul0175-0001" num="1946">The CDU address presented to the DIU is cdu_diu_wadr[21:3].</li><li id="ul0175-0002" num="1947">Bits [4:3] indicate which 64-bit segment out of 256 bits should be written in 4 successive masked page-mode writes.</li><li id="ul0175-0003" num="1948">Each 10-Mbit DRAM macro has an input address port of width [15:0]. Of these bits, [2:0] are the “page address”. Page-mode writes, where you just vary these LSBs (i.e. the “page” or column address), but keep the rest of the address constant, are faster than random writes. This is taken advantage of for CDU writes.</li><li id="ul0175-0004" num="1949">To guarantee against trying to span a page boundary, the DIU treats “cdu_diu_wadr[6:5]” as being fixed at “00”.</li><li id="ul0175-0005" num="1950">From cdu_diu_wadr[21:3], a initial address of cdu_diu_wadr[21:7], concatenated with “00”, is used as the starting location for the first CDU write. This address is then auto-incremented a further three times. <br /> 20.9 DIU Protocols </li></ul></li></ul>
1951The DIU protocols are <ul id="ul0176" list-style="none"><li id="ul0176-0001" num="0000"><ul id="ul0177" list-style="none"><li id="ul0177-0001" num="1952">Pipelined i.e. the following transaction is initiated while the previous transfer is in progress.</li><li id="ul0177-0002" num="1953">Split transaction i.e. the transaction is split into independent address and data transfers. <br /> 20.9.1 Read Protocol Except CPU </li></ul></li></ul>
1954The SoPEC read requestors, except for the CPU, perform single 256-bit read accesses with the read data being transferred from the DIU in 4 consecutive cycles over a shared 64-bit read bus, diu_data[63:0]. The read address <unit>_diu_radr[21:5] is 256-bit aligned.
1955The read protocol is: <ul id="ul0178" list-style="none"><li id="ul0178-0001" num="0000"><ul id="ul0179" list-style="none"><li id="ul0179-0001" num="1956"><unit>_diu_rreq is asserted along with a valid <unit>_diu_radr[21:5].</li><li id="ul0179-0002" num="1957">The DIU acknowledges the request with diu_<unit>_rack. The request should be deasserted. The minimum number of cycles between <unit>_diu_rreq being asserted and the DIU generating an diu_<unit>_rack strobe is 2 cycles (1 cycle to register the request, 1 cycle to perform the arbitration—see Section 20.14.10).</li><li id="ul0179-0003" num="1958">The read data is returned on diu_data[63:0] and its validity is indicated by diu_<unit>_rvalid. The overall 256 bits of data are transferred over four cycles in the order: [63:0]->[127:64]->[191:128]->[255:192].</li><li id="ul0179-0004" num="1959">When four diu_<unit>_rvalid pulses have been received then if there is a further request <unit>_diu_rreq should be asserted again. diu_<unit>_rvalid will be always be asserted by the DIU for four consecutive cycles. There is a fixed gap of 2 cycles between diu_<unit>_rack and the first diu_<unit>_rvalid pulse. For more detail on the timing of such reads and the implications for back-to-back sequences, see Section 20.14.10. <br /> 20.9.2 Read Protocol for CPU </li></ul></li></ul>
1960The CPU performs single 256-bit read accesses with the read data being transferred from the DIU over a dedicated 256-bit read bus for DRAM data, dram_cpu_data[255.0]. The read address cpu_adr[21:5] is 256-bit aligned.
1961The CPU DIU read protocol is: <ul id="ul0180" list-style="none"><li id="ul0180-0001" num="0000"><ul id="ul0181" list-style="none"><li id="ul0181-0001" num="1962">cpu_diu_rreq is asserted along with a valid cpu_adr[21:5].</li><li id="ul0181-0002" num="1963">The DIU acknowledges the request with diu_cpu_rack. The request should be deasserted. The minimum number of cycles between cpu_diu_rreq being asserted and the DIU generating a cpu_diu_rack strobe is 1 cycle (1 cycle to perform the arbitration—see Section 20.14.10).</li><li id="ul0181-0003" num="1964">The read data is returned on dram_cpu_data[255:0] and its validity is indicated by diu_cpu_rvalid.</li><li id="ul0181-0004" num="1965">When the diu_cpu_rvalid pulse has been received then if there is a further request cpu_diu_rreq should be asserted again. The diu_cpu_rvalid pulse with a gap of 1 cycle after rack (1 cycle for the read data to be returned from the DRAM—see Section 20.14.10). <br /> 20.9.3 Write Protocol Except CPU and CDU </li></ul></li></ul>
1966The SoPEC write requestors, except for the CPU and CDU, perform single 256-bit write accesses with the write data being transferred to the DIU in 4 consecutive cycles over dedicated point-to-point 64-bit write data busses. The write address <unit>_diu_wadr[21:5] is 256-bit aligned.
1967The write protocol is: <ul id="ul0182" list-style="none"><li id="ul0182-0001" num="0000"><ul id="ul0183" list-style="none"><li id="ul0183-0001" num="1968"><unit>_diu_wreq is asserted along with a valid <unit>_diu_wadr[21:5].</li><li id="ul0183-0002" num="1969">The DIU acknowledges the request with diu_<unit>_wack. The request should be deasserted. The minimum number of cycles between <unit>_diu_wreq being asserted and the DIU generating an diu_<unit>_wack strobe is 2 cycles (1 cycle to register the request, 1 cycle to perform the arbitration—see Section 20.14.10).</li><li id="ul0183-0003" num="1970">In the clock cycles following diu_<unit>_wack the SoPEC Unit outputs the <unit>_diu_data[63:0], asserting <unit>_diu_wvalid. The first <unit>_diu_wvalid pulse can occur the clock cycle after diu_<unit>_wack. <unit>_diu_wvalid remains asserted for the following 3 clock cycles. This allows for reading from an SRAM where new data is available in the clock cycle after the address has changed e.g. the address for the second 64-bits of write data is available the cycle after diu_<unit>_wack meaning the second 64-bits of write data is a further cycle later. The overall 256 bits of data is transferred over four cycles in the order: [63:0]->[127:64]->[191:128]->[255:192].</li><li id="ul0183-0004" num="1971">Note that for SCB writes, each 64-bit quarter-word has an 8-bit byte enable mask associated with it. A different mask is used with each quarter-word. The 4 mask values are transferred along with their associated data, as shown in <figref idref="DRAWINGS">FIG. 92</figref>.</li><li id="ul0183-0005" num="1972">If four consecutive <unit>_diu_wvalid pulses are not provided by the requester, then the arbitration logic will disregard the write and re-allocate the slot under the unused read round-robin scheme.</li></ul></li></ul>
1973Once all the write data has been output then if there is a further request <unit>_diu_wreq should be asserted again.
000020.9.4 CPU Write Protocol
1974The CPU performs single 128-bit writes to the DIU on a dedicated write bus, cpu_diu_wdata[127:0]. There is an accompanying write mask, cpu_diu_wmask[15:0], consisting of 16 byte enables and the CPU also supplies a 128-bit aligned write address on cpu_diu_wadr[21:4]. Note that writes are posted by the CPU to the DIU and stored in a 1-deep buffer. When the DAU subsequently arbitrates in favour of the CPU, the contents of the buffer are written to DRAM.
1975The CPU write protocol, illustrated in <figref idref="DRAWINGS">FIG. 93</figref>, is as follows:— <ul id="ul0184" list-style="none"><li id="ul0184-0001" num="0000"><ul id="ul0185" list-style="none"><li id="ul0185-0001" num="1976">The DIU signals to the CPU via diu_cpu_write_rdy that its write buffer is empty and that the CPU may post a write whenever it wishes.</li><li id="ul0185-0002" num="1977">The CPU asserts cpu_diu_wdatavalid to enable a write into the buffer and to confirm the validity of the write address, data and mask.</li><li id="ul0185-0003" num="1978">The DIU de-asserts diu_cpu_write_rdy in the following cycle to indicate that its buffer is full and that the posted write is pending execution.</li><li id="ul0185-0004" num="1979">When the CPU is next awarded a DRAM access by the DAU, the buffer's contents are written to memory. The DIU re-asserts diu_cpu_write_rdy once the write data has been captured by DRAM, namely in the “MSN1” DCU state.</li><li id="ul0185-0005" num="1980">The CPU can then, if it wishes, asynchronously use the new value of .diu_cpu_write_rdy to enable a new posted write in the same “MSN1” cycle. <br /> 20.9.5 CDU Write Protocol </li></ul></li></ul>
1981The CDU performs four 64-bit word writes to 4 contiguous 256-bit DRAM addresses with the first address specified by cdu_diu_wadr[21:3]. The write address cdu_diu_wadr[21:5] is 256-bit aligned with bits cdu_diu_wadr[4:3] allowing the 64-bit word to be selected.
1982The write protocol is: <ul id="ul0186" list-style="none"><li id="ul0186-0001" num="0000"><ul id="ul0187" list-style="none"><li id="ul0187-0001" num="1983">cdu_diu_wdata is asserted along with a valid cdu_diu_wadr[21:3].</li><li id="ul0187-0002" num="1984">The DIU acknowledges the request with diu_cdu_wack. The request should be deasserted. The minimum number of cycles between cdu_diu_wreq being asserted and the DIU generating an diu_cdu_wack strobe is 2 cycles (1 cycle to register the request, 1 cycle to perform the arbitration—see Section 20.14.10).</li><li id="ul0187-0003" num="1985">In the clock cycles following diu_cdu_wack the CDU outputs the cdu_diu_data[63:0], together with asserted cdu_diu_wvalid. The first cdu_diu_wvalid pulse can occur the clock cycle after diu_cdu_wack. cdu_diu_wvalid remains asserted for the following 3 clock cycles. This allows for reading from an SRAM where new data is available in the clock cycle after the address has changed e.g. the address for the second 64-bits of write data is available the cycle after diu_cdu_wack meaning the second 64-bits of write data is a further cycle later. Data is transferred over the 4-cycle window in an order, such that each successive 64 bits will be written to a monotonically increasing (by 1 location) 256-bit DRAM word.</li><li id="ul0187-0004" num="1986">If four consecutive cdu_diu_wvalid pulses are not provided with the data, then the arbitration logic will disregard the write and re-allocate the slot under the unused read round-robin scheme.</li><li id="ul0187-0005" num="1987">Once all the write data has been output then if there is a further request cdu_diu_wreq should be asserted again. <br /> 20.10 DIU Arbitration Mechanism </li></ul></li></ul>
1988The DIU will arbitrate access to the embedded DRAM. The arbitration scheme is outlined in the next sections.
000020.10.1 Timeslot Based Arbitration Scheme
1989Table summarised the bandwidth requirements of the SoPEC requestors to DRAM. If we allocate the DIU requestors in terms of peak bandwidth then we require 35.25 bits/cycle (at SF=6) and 40.75 bits/cycle (at SF=4) for all the requestors except the CPU.
1990A timeslot scheme is defined with 64 main timeslots. The number of used main timeslots is programmable between 1 and 64.
1991Since DRAM read requesters, except for the CPU, are connected to the DIU via a 64-bit data bus each 256-bit DRAM access requires 4 pclk cycles to transfer the read data over the shared read bus. The timeslot rotation period for 64 timeslots each of 4 pclk cycles is 256 pclk cycles or 1.6 μs, assuming pclk is 160 MHz. Each timeslot represents a 256-bit access every 256 pclk cycles or 1 bit/cycle. This is the granularity of the majority of DIU requesters bandwidth requirements in Table.
1992The SoPEC DIU requesters can be represented using 4 bits (Table n page 288 on page 268). Using 64 timeslots means that to allocate each timeslot to a requester, a total of 64×5-bit configuration registers are required for the 64 main timeslots.
1993Timeslot based arbitration works by having a pointer point to the current timeslot. When re-arbitration is signaled the arbitration winner is the current timeslot and the pointer advances to the next timeslot. Each timeslot denotes a single access. The duration of the timeslot depends on the access.
1994Note that advancement through the timeslot rotation is dependent on an enable bit, RotationSync, being set. The consequences of clearing and setting this bit are described in section 20.14.12.2.1 on page 295.
1995If the SoPEC Unit assigned to the current timeslot is not requesting then the unused timeslot arbitration mechanism outlined in Section 20.10.6 is used to select the arbitration winner.
1996Note that there is always an arbitration winner for every slot. This is because the unused read re-allocation scheme includes refresh in its round-robin protocol. If all other blocks are not requesting, an early refresh will act as fall-back for the slot.
000020.10.2 Separate Read and Write Arbitration Windows
1997For write accesses, except the CPU, 256-bits of write data are transferred from the SoPEC DIU write requestors over 64-bit write busses in 4 clock cycles. This write data transfer latency means that writes accesses, except for CPU writes and also the CDU, must be arbitrated 4 cycles in advance. (The CDU is an exception because CDU writes can start once the first 64-bits of write data have been transferred since each 64-bits is associated with a write to a different 256-bit word).
1998Since write arbitration must occur 4 cycles in advance, and the minimum duration of a timeslot duration is 3 cycles, the arbitration rules must be modified to initiate write accesses in advance. Accordingly, there is a write timeslot lookahead pointer shown in <figref idref="DRAWINGS">FIG. 96</figref> two timeslots in advance of the current timeslot pointer.
1999The following examples illustrate separate read and write timeslot arbitration with no adjacent write timeslots. (Recall rule on adjacent write timeslots introduced in Section 20.7.2.3 on page 238.)
2000In <figref idref="DRAWINGS">FIG. 97</figref> writes are arbitrated two timeslots in advance. Reads are arbitrated in the same timeslot as they are issued. Writes can be arbitrated in the same timeslot as a read. During arbitration the command address of the arbitrated SoPEC Unit is captured.
2001Other examples are shown in <figref idref="DRAWINGS">FIG. 98</figref> and <figref idref="DRAWINGS">FIG. 99</figref>. The actual timeslot order is always the same as the programmed timeslot order i.e. out of order accesses do not occur and data coherency is never an issue.
2002Each write must always incur a latency of two timeslots.
2003Startup latency may vary depending on the position of the first write timeslot. This startup latency is not important.
2004Table 112 shows the 4 scenarios depending on whether the current timeslot and write timeslot lookahead pointers point to read or write accesses.
2005<tables id="TABLE-US-00143" num="00143"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 112</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Arbitration with separate windows for read and write accesses</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry>current</entry><entry>write timeslot</entry><entry /></row><row><entry /><entry>timeslot</entry><entry>lookahead</entry></row><row><entry /><entry>pointer</entry><entry>pointer</entry><entry>actions</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row><row><entry /><entry>Read</entry><entry>write</entry><entry>Initiate DRAM read,</entry></row><row><entry /><entry /><entry /><entry>Initiate write arbitration</entry></row><row><entry /><entry>Read1</entry><entry>read2</entry><entry>Initiate DRAM read1.</entry></row><row><entry /><entry>Write1</entry><entry>write2</entry><entry>Initiate write2 arbitration.</entry></row><row><entry /><entry /><entry /><entry>Execute DRAM write1.</entry></row><row><entry /><entry>Write</entry><entry>read</entry><entry>Execute DRAM write.</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2006If the current timeslot pointer points to a read access then this will be initiated immediately.
2007If the write timeslot lookahead pointer points to a write access then this access is arbitrated immediately, or immediately after the read access associated with the current timeslot pointer is initiated.
2008When a write access is arbitrated the DIU will capture the write address. When the current timeslot pointer advances to the write timeslot then the actual DRAM access will be initiated.
2009Writes will therefore be arbitrated 2 timeslots in advance of the DRAM write occurring.
2010At initialisation, the write lookahead pointer points to the first timeslot. The current timeslot pointer is invalid until the write lookahead pointer advances to the third timeslot when the current timeslot pointer will point to the first timeslot. Then both pointers advance in tandem.
2011CPU write accesses are excepted from the lookahead mechanism.
2012If the selected SoPEC Unit is not requesting then there will be separate read and write selection for unused timeslots. This is described in Section 20.10.6.
000020.10.3 Arbitration of CPU Accesses
2013What distinguishes the CPU from other SoPEC requesters, is that the CPU requires minimum latency DRAM access i.e. preferably the CPU should get the next available timeslot whenever it requests.
2014The minimum CPU read access latency is estimated in Table 113. This is the time between the CPU making a request to the DIU and receiving the read data back from the DIU.
2015<tables id="TABLE-US-00144" num="00144"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 113</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Estimated CPU read access latency ignoring caching</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><colspec colname="2" colwidth="56pt" align="left" /><tbody valign="top"><row><entry /><entry>CPU read access latency</entry><entry>Duration</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>CPU cache miss</entry><entry>1 cycle</entry></row><row><entry /><entry>CPU MMU logic issues request and</entry><entry>1 cycle</entry></row><row><entry /><entry>DIU arbitration completes</entry></row><row><entry /><entry>Transfer the read address to the DRAM</entry><entry>1 cycle</entry></row><row><entry /><entry>DRAM read latency</entry><entry>1 cycle</entry></row><row><entry /><entry>Register the read data in CPU bridge</entry><entry>1 cycle</entry></row><row><entry /><entry>Register the read data in CPU</entry><entry>1 cycle</entry></row><row><entry /><entry>CPU cache miss</entry><entry>1 cycle</entry></row><row><entry /><entry>CPU MMU logic issues request and</entry><entry>1 cycle</entry></row><row><entry /><entry>DIU arbitration completes</entry><entry /></row><row><entry /><entry>TOTAL gap between requests</entry><entry>6 cycles</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2016If the CPU, as is likely, requests DRAM access again immediately after receiving data from the DIU then the CPU could access every second timeslot if the access latency is 6 cycles. This assumes that interleaving is employed so that timeslots last 3 cycles. If the CPU access latency were 7 cycles, then the CPU would only be able to access every third timeslot.
2017If a cache hit occurs the CPU does not require DRAM access. For its next DIU access it will have to wait for its next assigned DIU slot. Cache hits therefore will reduce the number of DRAM accesses but not speed up any of those accesses.
2018To avoid the CPU having to wait for its next timeslot it is desirable to have a mechanism for ensuring that the CPU always gets the next available timeslot without incurring any latency on the non-CPU timeslots.
2019This can be done by defining each timeslot as consisting of a CPU access preceding a non-CPU access. Each timeslot will last 6 cycles i.e. a CPU access of 3 cycles and a non-CPU access of 3 cycles. This is exactly the interleaving behaviour outlined in Section 20.7.2.2. If the CPU does not require an access, the timeslot will take 3 or 4 and the timeslot rotation will go faster. A summary is given in Table 114.
2020<tables id="TABLE-US-00145" num="00145"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 114</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Timeslot access times.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="49pt" align="left" /><colspec colname="3" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry>Access</entry><entry>Duration</entry><entry>Explanation</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row><row><entry /><entry>CPU access +</entry><entry>3 + 3 = 6</entry><entry>Interleaved access</entry></row><row><entry /><entry>non-CPU access</entry><entry>cycles</entry></row><row><entry /><entry>non-CPU access</entry><entry>4 cycles</entry><entry>Access and preceding</entry></row><row><entry /><entry /><entry /><entry>access both to shared</entry></row><row><entry /><entry /><entry /><entry>read bus</entry></row><row><entry /><entry>non-CPU access</entry><entry>3 cycles</entry><entry>Access and preceding</entry></row><row><entry /><entry /><entry /><entry>access not both to</entry></row><row><entry /><entry /><entry /><entry>shared read bus</entry></row><row><entry /><entry>CDU write access</entry><entry>3 + 2 + 2 +</entry><entry>Page mode select signal</entry></row><row><entry /><entry /><entry>2 = 9 cycles</entry><entry>is clocked at 160 MHz</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2021CDU write accesses require 9 cycles. CDU write accesses preceded by a CPU access require 12 cycles. CDU timeslots therefore take longer than all other DIU requestors timeslots.
2022With a 256 cycle rotation there can be 42 accesses of 6 cycles.
2023For low scale factor applications, it is desirable to have more timeslots available in the same 256 cycle rotation. So two counters of 4-bits each are defined allowing the CPU to get a maximum of (CPUPreAccessTimeslots+1) pre-accesses for every (CPUTotalTimeslots+1) main slots. A timeslot counter starts at CPUTotalTimeslots and decrements every timeslot, while another counter starts at CPUPreAccessTimeslots and decrements every timeslot in which the CPU uses its access. When the CPU pre-access counter goes to zero before CPUTotalTimeslots, no further CPU accesses are allowed. When the CPUTotalTimeslots counter reaches zero both counters are reset to their respective initial values.
2024The CPU is not included in the list of SoPEC DIU requesters, Table, for the main timeslot allocations. The CPU cannot therefore be allocated main timeslots. It relies on pre-accesses in advance of such slots as the sole method for DRAM transfers.
2025CPU access to DRAM can never be fully disabled, since to do so would render SoPEC inoperable. Therefore the CPUPreAccessTimeslots and CPUTotalTimeslots register values are interpreted as follows: In each succeeding window of (CPUTotalTimeslots+1) slots, the maximum quota of CPU pre-accesses allowed is (CPUPreAccessTimeslots+1). The “+1” implementations mean that the CPU quota cannot be made zero.
2026The various modes of operation are summarised in Table 115 with a nominal rotation period of 256 cycles.
2027<tables id="TABLE-US-00146" num="00146"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 115</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>CPU timeslot allocation modes with nominal</entry></row><row><entry>rotation period of 256 cycles</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><colspec colname="3" colwidth="35pt" align="left" /><colspec colname="4" colwidth="56pt" align="left" /><tbody valign="top"><row><entry /><entry>Nominal</entry><entry /><entry /></row><row><entry /><entry>Timeslot</entry><entry>Number of</entry></row><row><entry>Access Type</entry><entry>duration</entry><entry>timeslots</entry><entry>Notes</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>CPU Pre-access</entry><entry>6</entry><entry>42</entry><entry>Each access is</entry></row><row><entry>i.e.</entry><entry>cycles</entry><entry>timeslots</entry><entry>CPU + non-CPU.</entry></row><row><entry>CPUPreAccessTimeslots =</entry><entry /><entry /><entry>If CPU does not</entry></row><row><entry>CPUTotalTimeslots</entry><entry /><entry /><entry>use a timeslot</entry></row><row><entry /><entry /><entry /><entry>then rotation</entry></row><row><entry /><entry /><entry /><entry>is faster.</entry></row><row><entry>Fractional CPU</entry><entry>4 or 6</entry><entry>42–64</entry><entry>Each CPU + non-</entry></row><row><entry>Pre-access i.e.</entry><entry>cycles</entry><entry>timeslots</entry><entry>CPU access</entry></row><row><entry>CPUPreAccessTimeslots <</entry><entry /><entry /><entry>requires a 6</entry></row><row><entry>CPUTotalTimeslots</entry><entry /><entry /><entry>cycle timeslot.</entry></row><row><entry /><entry /><entry /><entry>Individual non-</entry></row><row><entry /><entry /><entry /><entry>CPU timeslots</entry></row><row><entry /><entry /><entry /><entry>take 4 cycles</entry></row><row><entry /><entry /><entry /><entry>if current</entry></row><row><entry /><entry /><entry /><entry>access and pre-</entry></row><row><entry /><entry /><entry /><entry>ceding access</entry></row><row><entry /><entry /><entry /><entry>are both to</entry></row><row><entry /><entry /><entry /><entry>shared read</entry></row><row><entry /><entry /><entry /><entry>bus.</entry></row><row><entry /><entry /><entry /><entry>Individual non-</entry></row><row><entry /><entry /><entry /><entry>CPU timeslots</entry></row><row><entry /><entry /><entry /><entry>take 3 cycles</entry></row><row><entry /><entry /><entry /><entry>if current ac-</entry></row><row><entry /><entry /><entry /><entry>cess and pre-</entry></row><row><entry /><entry /><entry /><entry>ceding access</entry></row><row><entry /><entry /><entry /><entry>are not both</entry></row><row><entry /><entry /><entry /><entry>to shared read</entry></row><row><entry /><entry /><entry /><entry>bus.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 20.10.4 CDU Accesses
2028As indicated in Section 20.10.3, CDU write accesses require 9 cycles. CDU write accesses preceded by a CPU access require 12 cycles. CDU timeslots therefore take longer than all other DIU requestors timeslots. This means that when a write timeslot is unused it cannot be re-allocated to a CDU write as CDU accesses take 9 cycles. The write accesses which the CDU write could otherwise replace require only 3 or 4 cycles.
2029Unused CDU write accesses can be replaced by any other write access according to 20.10.6.1 Unused write timeslots allocation on page 247.
000020.10.5 Refresh Controller
2030Refresh is not included in the list of SoPEC DIU requesters, Table, for the main timeslot allocations. Timeslots cannot therefore be allocated to refresh.
2031The DRAM must be refreshed every 3.2 ms. Refresh occurs row at a time over 5120 rows of 2 parallel 10 Mbit instances. A refresh operation must therefore occur every 100 cycles. The refresh_period register has a default value of 99. Each refresh takes 3 cycles.
2032A refresh counter will count down the number of cycles between each refresh. When the down-counter reaches 0, the refresh controller will issue a refresh request and the down-counter is reloaded with the value in refresh_period and the count-down resumes immediately. Allocation of main slots must take into account that a refresh is required at least once every 100 cycles. Refresh is included in the unused read and write timeslot allocation. If unused timeslot allocation results in refresh occurring early by N cycles, then the refresh counter will have counted down to N. In this case, the refresh counter is reset to refresh_period and the count-down recommences. Refresh can be preceded by a CPU access in the same way as any other access. This is controlled by the CPUPreAccessTimeslots and CPUTotalTimeslots configuration registers. Refresh will therefore not affect CPU performance. A sequence of accesses including refresh might therefore be CPU, refresh, CPU, actual timeslot.
000020.10.6 Allocating Unused Timeslots
2033Unused slots are re-allocated separately depending on whether the unused access was a read access or a write access. This is best-effort traffic. Only unused non-CPU accesses are re-allocated.
000020.10.6.1 Unused Write Timeslots Allocation
2034Unused write timeslots are re-allocated according to a fixed priority order shown in Table 116.
2035<tables id="TABLE-US-00147" num="00147"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 116</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Unused write timeslot priority order</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="105pt" align="left" /><colspec colname="2" colwidth="84pt" align="center" /><tbody valign="top"><row><entry /><entry /><entry>Priority</entry></row><row><entry /><entry>Name</entry><entry>Order</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>SCB(W)</entry><entry>1</entry></row><row><entry /><entry>SFU(W)</entry><entry>2</entry></row><row><entry /><entry>DWU</entry><entry>3</entry></row><row><entry /><entry>Unused read timeslot allocation</entry><entry>4</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2036CDU write accesses cannot be included in the unused timeslot allocation for write as CDU accesses take 9 cycles. The write accesses which the CDU write could otherwise replace require only 3 or 4 cycles.
2037Unused write timeslot allocation occurs two timeslots in advance as noted in Section 20.10.2. If the units at priorities 1–3 are not requesting then the timeslot is re-allocated according to the unused read timeslot allocation scheme described in Section 20.10.6.2. However, the unused read timeslot allocation will occur when the current timeslot pointer of <figref idref="DRAWINGS">FIG. 96</figref> reaches the timeslot i.e. it will not occur in advance.
000020.10.6.2 Unused Read Timeslots Allocation
2038Unused read timeslots are re-allocated according to a two level round-robin scheme. The SoPEC Units included in read timeslot re-allocation is shown in Table 117.
2039<tables id="TABLE-US-00148" num="00148"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 117</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Unused read timeslot allocation</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="84pt" align="left" /><colspec colname="1" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>Name</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row><row><entry /><entry>SCB(R)</entry></row><row><entry /><entry>CDU(R)</entry></row><row><entry /><entry>CFU</entry></row><row><entry /><entry>LBD</entry></row><row><entry /><entry>SFU(R)</entry></row><row><entry /><entry>TE(TD)</entry></row><row><entry /><entry>TE(TFS)</entry></row><row><entry /><entry>HCU</entry></row><row><entry /><entry>DNC</entry></row><row><entry /><entry>LLU</entry></row><row><entry /><entry>PCU</entry></row><row><entry /><entry>CPU/Refresh</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2040Each SoPEC requestor has an associated bit, ReadRoundRobinLevel, which indicates whether it is in level 1 or level 2 round-robin.
2041<tables id="TABLE-US-00149" num="00149"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 118</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Read round-robin level selection</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="119pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><tbody valign="top"><row><entry /><entry>Level</entry><entry>Action</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>ReadRoundRobinLevel = 0</entry><entry>Level 1</entry></row><row><entry /><entry>ReadRoundRobinLevel = 1</entry><entry>Level 2</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2042A pointer points to the most recent winner on each of the round-robin levels. Re-allocation is carried out by traversing level 1 requesters, starting with the one immediately succeeding the last level 1 winner. If a requesting unit is found, then it wins arbitration and the level 1 pointer is shifted to its position. If no level 1 unit wants the slot, then level 2 is similarly examined and its pointer adjusted.
2043Since refresh occupies a (shared) position on one of the two levels and continually requests access, there will always be some round-robin winner for any unused slot.
000020.10.6.2.1 Shared CPU/Refresh Round-Robin Position
2044Note that the CPU can conditionally be allowed to take part in the unused read round-robin scheme. Its participation is controlled via the configuration bit EnableCPURoundRobin. When this bit is set, the CPU and refresh share a joint position in the round-robin order, shown in Table. When cleared, the position is occupied by refresh alone.
2045If the shared position is next in line to be awarded an unused non-CPU read/write slot, then the CPU will have first option on the slot. Only if the CPU doesn't want the access, will it be granted to refresh. If the CPU is excluded from the round robin, then any awards to the position benefit refresh.
000020.11 Guidelines for Programming the DIU
2046Some guidelines for programming the DIU arbitration scheme are given in this section together with an example.
000020.11.1 Circuit Latency
2047Circuit latency is a fixed service delay which is incurred, as and from the acceptance by the DIU arbitration logic of a block's pending read/write request. It is due to the processing time of the request, readying the data, plus the DRAM access time. Latencies differ for read and write requests. See Tables 79 and 80 for respective breakdowns.
2048If a requesting block is currently stalled, then the longest time it will have to wait between issuing a new request for data and actually receiving it would be its timeslot period, plus the circuit latency overhead, along with any intervening non-standard slot durations, such as refresh and CDU(W). In any case, a stalled block will always incur this latency as an additional overhead, when coming out of a stall.
2049In the case where a block starts up or unstalls, it will start processing newly-received data at a time beyond its serviced timeslot equivalent to the circuit latency. If the block's timeslots are evenly spaced apart in time to match its processing rate, (in the hope of minimising stalls,) then the earliest that the block could restall, if not re-serviced by the DIU, would be the same latency delay beyond its next timeslot occurrence. Put another way, the latency incurred at start-up pushes the potential DIU-induced stall point out by the same fixed delta beyond each successive timeslot allocated to the block. This assumes that a block re-requests access well in advance of its upcoming timeslots. Thus, for a given stall-free run of operation, the circuit latency overhead is only incurred inititially when unstalling.
2050While a block can be stalled as a result of how quickly the DIU services its DRAM requests, it is also prone to stalls caused by its upstream or downstream neighbours being able to supply or consume data which is transferred between the blocks directly, (as opposed to via the DIU). Such neighbour-induced stalls, often occurring at events like end of line, will have the effect that a block's DIU read buffer will tend to fill, as the block stops processing read data. Its DIU write buffer will also tend to fill, unable to despatch to DRAM until the downstream block frees up shared-access DRAM locations. This scenario is beneficial, in that when a block unstalls as a result of its neighbour releasing it, then that block's read/write DIU buffers will have a fill state less likely to stall it a second time, as a result of DIU service delays.
2051A block's slots should be scheduled with a service guarantee in mind. This is dictated by the block's processing rate and hence, required access to the DRAM. The rate is expressed in terms of bits per cycle across a processing window, which is typically (though not always) 256 cycles. Slots should be evenly interspersed in this window (or “rotation”) so that the DIU can fulfill the block's service needs.
2052The following ground rules apply in calculating the distribution of slots for a given non-CPU block:— <ul id="ul0188" list-style="none"><li id="ul0188-0001" num="0000"><ul id="ul0189" list-style="none"><li id="ul0189-0001" num="2053">The block can, at maximum, suffer a stall once in the rotation, (i.e. unstall and restall) and hence incur the circuit latency described above.</li></ul></li></ul>
2054This rule is, by definition, always fulfilled by those blocks which have a service requirement of only <ul id="ul0190" list-style="none"><li id="ul0190-0001" num="0000"><ul id="ul0191" list-style="none"><li id="ul0191-0001" num="2055">1 bit/cycle (equivalent to 1 slot/rotation) or fewer. It can be shown that the rule is also satisfied by those blocks requiring more than 1 bit/cycle. See Section 20.12.1 Slot Distributions and Stall Calculations for Individual Blocks, on page 255.</li><li id="ul0191-0002" num="2056">Within the rotation, certain slots will be unavailable, due to their being used for refresh. (See Section 20.11.2 Refresh latencies)</li><li id="ul0191-0003" num="2057">In programming the rotation, account must be taken of the fact that any CDU(W) accesses will consume an extra 6 cycles/access, over and above the norm, in CPU pre-access mode, or 5 cycles/access without pre-access.</li><li id="ul0191-0004" num="2058">The total delay overhead due to latency, refreshes and CDU(W) can be factored into the service guarantee for all blocks in the rotation by deleting once, (i.e. reducing the rotation window,) that number of slots which equates to the cumulative duration of these various anomalies.</li><li id="ul0191-0005" num="2059">The use of lower scale factors will imply a more frequent demand for slots by non-CPU blocks. The percentage of slots in the overall rotation which can therefore be designated as CPU pre-access ones should be calculated last, based on what can be accommodated in the light of the non-CPU slot need.</li></ul></li></ul>
2060Read latency is summarised below in Table 119.
2061<tables id="TABLE-US-00150" num="00150"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 119</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Read latency</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="126pt" align="left" /><colspec colname="2" colwidth="77pt" align="center" /><tbody valign="top"><row><entry /><entry>Non-CPU read access latency</entry><entry>Duration</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="126pt" align="left" /><colspec colname="2" colwidth="28pt" align="right" /><colspec colname="3" colwidth="49pt" align="left" /><tbody valign="top"><row><entry /><entry>non-CPU read requestor internally</entry><entry>1</entry><entry>cycle</entry></row><row><entry /><entry>generates DIU request</entry></row><row><entry /><entry>register the non- CPU read request</entry><entry>1</entry><entry>cycle</entry></row><row><entry /><entry>complete the arbitration of the request</entry><entry>1</entry><entry>cycle</entry></row><row><entry /><entry>transfer the read address to the DRAM</entry><entry>1</entry><entry>cycle</entry></row><row><entry /><entry>DRAM read latency</entry><entry>1</entry><entry>cycle</entry></row><row><entry /><entry>register the DRAM read data in DIU</entry><entry>1</entry><entry>cycle</entry></row><row><entry /><entry>register the 1st 64-bits of read data in</entry><entry>1</entry><entry>cycle</entry></row><row><entry /><entry>requester</entry></row><row><entry /><entry>register the 2nd 64-bits of read data in</entry><entry>1</entry><entry>cycle</entry></row><row><entry /><entry>requester</entry></row><row><entry /><entry>register the 3rd 64-bits of read data in</entry><entry>1</entry><entry>cycle</entry></row><row><entry /><entry>requester</entry></row><row><entry /><entry>register the 4th 64-bits of read data in</entry><entry>1</entry><entry>cycle</entry></row><row><entry /><entry>requester</entry><entry /><entry /></row><row><entry /><entry>TOTAL</entry><entry>10</entry><entry>cycles</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2062Write latency is summarised in Table 120.
2063<tables id="TABLE-US-00151" num="00151"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 120</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Write latency</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="154pt" align="left" /><colspec colname="2" colwidth="49pt" align="left" /><tbody valign="top"><row><entry /><entry>Non-CPU write access latency</entry><entry>Duration</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>non-CPU write requestor internally generates</entry><entry>1 cycle</entry></row><row><entry /><entry>DIU request</entry></row><row><entry /><entry>register the non-CPU write request</entry><entry>1 cycle</entry></row><row><entry /><entry>complete the arbitration of the request</entry><entry>1 cycle</entry></row><row><entry /><entry>transfer the acknowledge to the write requester</entry><entry>1 cycle</entry></row><row><entry /><entry>transfer the 1st 64 bits of write data to the</entry><entry>1 cycle DIU</entry></row><row><entry /><entry>transfer the 2nd 64 bits of write data to the</entry><entry>1 cycle DIU</entry></row><row><entry /><entry>transfer the 3rd 64 bits of write data to the</entry><entry>1 cycle DIU</entry></row><row><entry /><entry>transfer the 4th 64 bits of write data to the</entry><entry>1 cycle DIU</entry></row><row><entry /><entry>Write to DRAM with locally registered write</entry><entry>1 cycle</entry></row><row><entry /><entry>data</entry><entry /></row><row><entry /><entry>TOTAL</entry><entry>9 cycles</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2064Timeslots removed to allow for read latency will also cover write latency, since the former is the larger of the two.
000020.11.2 Refresh Latencies
2065The number of allocated timeslots for each requester needs to take into account that a refresh must occur every 100 cycles. This can be achieved by deleting timeslots from the rotation since the number of timeslots is made programmable.
2066Refresh is preceded by a CPU access in the same way as any other access. This is controlled by the CPUPreAccessTimeslots and CPUTotalTimeslots configuration registers. Refresh will therefore not affect CPU performance.
2067As an example, in CPU pre-access mode each timeslot will last 6 cycles. If the timeslot rotation has 50 timeslots then the rotation will last 300 cycles. The refresh controller will trigger a refresh every 100 cycles. Up to 47 timeslots can be allocated to the rotation ignoring refresh. Three timeslots deleted from the 50 timeslot rotation will allow for the latency of a refresh every 100 cycles.
000020.11.3 Ensuring Sufficient DNC and PCU Access
2068PCU command reads from DRAM are exceptional events and should complete in as short a time as possible. Similarly, we must ensure there is sufficient free bandwidth for DNC accesses e.g. when clusters of dead nozzles occur. In Table DNC is allocated 3 times average bandwidth. PCU and DNC can also be allocated to the level 1 round-robin allocation for unused timeslots so that unused timeslot bandwidth is preferentially available to them.
000020.11.4 Basing Timeslot Allocation on Peak Bandwidths
2069Since the embedded DRAM provides sufficient bandwidth to use 1:1 compression rates for the CDU and LBD, it is possible to simplify the main timeslot allocation by basing the allocation on peak bandwidths. As combined bi-level and tag bandwidth at 1:1 scaling is only 5 bits/cycle, we will usually only consider the contone scale factor as the variable in determining timeslot allocations.
2070If slot allocation is based on peak bandwidth requirements then DRAM access will be guaranteed to all SoPEC requesters. If we do not allocate slots for peak bandwidth requirements then we can also allow for the peaks deterministically by adding some cycles to the print line time.
000020.11.5 Adjacent Timeslot Restrictions
000020.11.5.1 Non-CPU Write Adjacent Timeslot Restrictions
2071Non-CPU write requesters should not be assigned adjacent timeslots as described in Section 20.7.2.3. This is because adjacent timeslots assigned to non-CPU requestors would require two sets of 256-bit write buffers and multiplexors to connect two write requestors simultaneously to the DIU. Only one 256-bit write buffer and multiplexor is implemented. Recall from section 20.7.2.3 on page 238 that if adjacent non-CPU writes are attempted, that the second write of any such pair will be disregarded and re-allocated under the unused read scheme.
000020.11.5.2 Same DIU Requestor Adjacent Timeslot Restrictions
2072All DIU requesters have state-machines which request and transfer the read or write data before requesting again. From <figref idref="DRAWINGS">FIG. 90</figref> read requests have a minimum separation of 9 cycles. From <figref idref="DRAWINGS">FIG. 92</figref> write requests have a minimum separation of 7 cycles. Therefore adjacent timeslots should not be assigned to a particular DIU requester because the requester will not be able to make use of all these slots.
2073In the case that a CPU access precedes a non-CPU access timeslots last 6 cycles so write and read requesters can only make use of every second timeslot. In the case that timeslots are not preceded by CPU accesses timeslots last 4 cycles so the same write requester can use every second timeslot but the same read requestor can use only every third timeslot. Some DIU requestors may introduce additional pipeline delays before they can request again. Therefore timeslots should be separated by more than the minimum to allow a margin.
000020.11.6 Line Margin
2074The SFU must output 1 bit/cycle to the HCU. Since HCUNumDots may not be a multiple of 256 bits the last 256-bit DRAM word on the line can contain extra zeros. In this case, the SFU may not be able to provide 1 bit/cycle to the HCU. This could lead to a stall by the SFU. This stall could then propagate if the margins being used by the HCU are not sufficient to hide it. The maximum stall can be estimated by the calculation: DRAM service period—X scale factor * dots used from last DRAM read for HCU line.
2075Similarly, if the line length is not a multiple of 256-bits then e.g. the LLU could read data from DRAM which contains padded zeros. This could lead to a stall. This stall could then propagate if the page margins cannot hide it.
2076A single addition of 256 cycles to the line time will suffice for all DIU requesters to mask these stalls.
000020.12 Example Outline DIU Programming
2077<tables id="TABLE-US-00152" num="00152"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 121</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Timeslot allocation based on peak bandwidth</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><colspec colname="3" colwidth="63pt" align="left" /><colspec colname="4" colwidth="63pt" align="center" /><tbody valign="top"><row><entry /><entry /><entry /><entry>Peak Bandwidth</entry><entry /></row><row><entry /><entry /><entry /><entry>which must be</entry></row><row><entry /><entry>Block</entry><entry>Direc-</entry><entry>supplied</entry><entry>MainTimeslots</entry></row><row><entry /><entry>Name</entry><entry>tion</entry><entry>(bits/cycle)</entry><entry>allocated</entry></row><row><entry /><entry namest="offset" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><colspec colname="3" colwidth="63pt" align="left" /><colspec colname="4" colwidth="21pt" align="right" /><colspec colname="5" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry>SCB</entry><entry>R</entry><entry /><entry /><entry /></row><row><entry /><entry /><entry>W</entry><entry>0.734<sup>7</sup></entry><entry>1</entry></row><row><entry /><entry>CDU</entry><entry>R</entry><entry>0.9 (SF = 6),</entry><entry>1</entry><entry>(SF = 6)</entry></row><row><entry /><entry /><entry /><entry>2 (SF = 4)</entry><entry>2</entry><entry>(SF = 4)</entry></row><row><entry /><entry /><entry>W</entry><entry>1.8 (SF = 6),<sup>8</sup></entry><entry>2</entry><entry>(SF = 6)</entry></row><row><entry /><entry /><entry /><entry>4 (SF = 4)</entry><entry>4</entry><entry>(SF = 4)</entry></row><row><entry /><entry>CFU</entry><entry>R</entry><entry>5.4 (SF = 6),</entry><entry>6</entry><entry>(SF = 6)</entry></row><row><entry /><entry /><entry /><entry>8 (SF = 4)</entry><entry>8</entry><entry>(SF = 4)</entry></row><row><entry /><entry>LBD</entry><entry>R</entry><entry>1</entry><entry>1</entry></row><row><entry /><entry>SFU</entry><entry>R</entry><entry>2</entry><entry>2</entry></row><row><entry /><entry /><entry>W</entry><entry>1</entry><entry>1</entry></row><row><entry /><entry>TE(TD)</entry><entry>R</entry><entry>1.02</entry><entry>1</entry></row><row><entry /><entry>TE(TFS)</entry><entry>R</entry><entry>0.093</entry><entry>0</entry></row><row><entry /><entry>HCU</entry><entry>R</entry><entry>0.074</entry><entry>0</entry></row><row><entry /><entry>DNC</entry><entry>R</entry><entry>2.4</entry><entry>3</entry></row><row><entry /><entry>DWU</entry><entry>W</entry><entry>6</entry><entry>6</entry></row><row><entry /><entry>LLU</entry><entry>R</entry><entry>8</entry><entry>8</entry></row><row><entry /><entry>PCU</entry><entry>R</entry><entry>1</entry><entry>1</entry><entry>(SF = 6)</entry></row><row><entry /><entry>TOTAL</entry><entry /><entry /><entry>33</entry><entry>(SF = 6)</entry></row><row><entry /><entry /><entry /><entry /><entry>38</entry><entry>(SF = 4)</entry></row><row><entry /><entry namest="offset" nameend="5" align="center" rowsep="1" /></row><row><entry /><entry namest="offset" nameend="5" align="left" id="FOO-00010"><sup>7</sup>The SCB figure of 0.734 bits/cycl applies to multi-SoPEC systems. For single-SoPEC systems, the figur is 0.050 bits/cycle.</entry></row><row><entry /><entry namest="offset" nameend="5" align="left" id="FOO-00011"><sup>8</sup>Bandwidth for CDU(W) is peak value. Because of 1.5 buffering in DRAM, peak CDU(W) b/w quals 2 × average CDU(W) b/w. For CDU(R), peak b/w = average CDU(R) b/w.</entry></row></tbody></tgroup></table></tables>
2078Table 121 shows an allocation of main timeslots based on the peak bandwidths of Table
2079The bandwidth required for each unit is calculated allowing extra cycles for read and write circuit latency for each access requiring a bandwidth of more than 1 bit/cycle. Fractional bandwidth is supplied via unused read slots.
2080The timeslot rotation is 256 cycles. Timeslots are deleted from the rotation to allow for circuit latencies for accesses of up to 1 bit per cycle i.e. 1 timeslot per rotation.
EXAMPLE 1
Scale-factor=6
2081Program the MainTimeslot configuration register (Table) for peak required bandwidths of SoPEC Units according to the scale factor.
2082Program the read round-robin allocation to share unused read slots. Allocate PCU, DNC, HCU and TFS to level 1 read round-robin. <ul id="ul0192" list-style="none"><li id="ul0192-0001" num="0000"><ul id="ul0193" list-style="none"><li id="ul0193-0001" num="2083">Assume scale-factor of 6 and peak bandwidths from Table <ul id="ul0194" list-style="none"><li id="ul0194-0001" num="2084">Assign all DIU requestors except TE(TFS) and HCU to multiples of 1 timeslot, as indicated in Table, where each timeslot is 1 bit/cycle. This requires 33 timeslots.</li><li id="ul0194-0002" num="2085">No timeslots are explicitly allocated for the fractional bandwidth requirements of TE(TFS) and HCU accesses. Instead, these units are serviced via unused read slots.</li><li id="ul0194-0003" num="2086">Allow 3 timeslots to allow for 3 refreshes in the rotation.</li><li id="ul0194-0004" num="2087">Therefore, 36 scheduled slots are used in the rotation for main timeslots and refreshes, some or all of which may be able to have a CPU pre-access, provided they fit in the rotation window.</li><li id="ul0194-0005" num="2088">Each of the 2 CDU(W) accesses requires 9 cycles. Per access, this implies an overhead of 1 slot (12 cycles instead of 6) in pre-access mode, or 1.25 slots (9 cycles instead of 4) for no pre-access. The cumulative overhead of the two accesses is either 2 slots (pre-access) or 3 slots (no pre-access).</li><li id="ul0194-0006" num="2089">Assuming all blocks require a service guarantee of no more than a single stall across 256 bits, allow 10 cycles for read latency, which also takes care of 9-cycle write latency. This can be accounted for by reserving 2 six-cycle slots (CPU pre-access) or 3 four-cycle slots (no pre-access).</li></ul></li></ul></li><li id="ul0192-0002" num="2090">Assume a 256 cycle timeslot rotation.</li><li id="ul0192-0003" num="2091">CDU(W) and read latency reduce the number of available cycles in a rotation to: 256−2×6−2×6=232 cycles (CPU pre-access) or 256−3×4−3×4=232 cycles (no pre-access).</li><li id="ul0192-0004" num="2092">As a result, 232 cycles available for 36 accesses implies each access can take 232/36=6.44 cycles maximum. So, all accesses can have a pre-access.</li><li id="ul0192-0005" num="2093">Therefore the CPU achieves a pre-access ratio of 36/36=100% of slots in the rotation.</li></ul>
EXAMPLE 2
Scale-factor=4
2094Program the MainTimeslot configuration register (Table) for peak required bandwidths of SoPEC Units according to the scale factor. Program the read round-robin allocation to share unused read slots. Allocate PCU, DNC, HCU and TFS to level 1 read round-robin. <ul id="ul0195" list-style="none"><li id="ul0195-0001" num="0000"><ul id="ul0196" list-style="none"><li id="ul0196-0001" num="2095">Assume scale-factor of 4 and peak bandwidths from Table</li><li id="ul0196-0002" num="2096">Assign all DIU requestors except TE(TFS) and HCU multiples of 1 timeslot, as indicated in Table, where each timeslot is 1 bit/cycle. This requires 38 timeslots.</li><li id="ul0196-0003" num="2097">No timeslots are explicitly allocated for the fractional bandwidth requirements of TE(TFS) and HCU accesses. Instead, these units are serviced via unused read slots.</li><li id="ul0196-0004" num="2098">Allow 3 timeslots to allow for 3 refreshes in the rotation.</li><li id="ul0196-0005" num="2099">Therefore, 41 scheduled slots are used in the rotation for main timeslots and refreshes, some or all of which can have a CPU pre-access, provided they fit in the rotation window.</li><li id="ul0196-0006" num="2100">Each of the 4 CDU(W) accesses requires 9 cycles. Per access, this implies an overhead of 1 slot (12 cycles instead of 6) for pre-access mode, or 1.25 slots (9 cycles instead of 4) for no pre-access. The cumulative overhead of the four accesses is either 4 slots (pre-access) or 5 slots (no pre-access).</li><li id="ul0196-0007" num="2101">Assuming all blocks require a service guarantee of no more than a single stall across 256 bits, allow 10 cycles for read latency, which also takes care of 9-cycle write latency. This can be accounted for by reserving 2 six-cycle slots (CPU pre-access) or 3 four-cycle slots (no pre-access).</li><li id="ul0196-0008" num="2102">Assume a 256 cycle timeslot rotation.</li><li id="ul0196-0009" num="2103">CDU(W) and read latency reduce the number of available cycles in a rotation to: 256−4×6−2×6=220 cycles (CPU pre-access) or 256−5×4−3×4=224 cycles (no pre-access).</li><li id="ul0196-0010" num="2104">As a result, between 220 and 224 cycles are available for 41 accesses, which implies each access can take between 220/41=5.36 cycles and 224/41=5.46 cycles.</li><li id="ul0196-0011" num="2105">Work out how many slots can have a pre-access: For the lower number of 220 cycles, this implies (41−n)*6+n*4<=220, where n=number of slots with no pre-access cycle. Solving the equation gives n>=13. Check answer: 28*6+0.13*4=220.</li><li id="ul0196-0012" num="2106">So 28 slots out of the 41 in the rotation can have CPU pre-accesses.</li><li id="ul0196-0013" num="2107">The CPU thus achieves a pre-access ratio of 28/41=68.3% of slots in the rotation. <br /> 20.12.1 Slot Distributions and Stall Calculations for Individual Blocks </li></ul></li></ul>
2108The following sections show how the slots for blocks with a service requirement greater than 1 bit/cycle should be distributed. Calculations are included to check that such blocks will not suffer more than one stall per rotation.
20.12.1.1 SFU
2109This has 2 bits/cycle on read but this is two separate channels of 1 bit/cycle sharing the same DIU interface so it is effectively 2 channels each of 1 bit/cycle so allowing the same margins as the LBD will work.
20.12.1.2 DWU
2110The DWU has 12 double buffers in each of the 6 colour planes, odd and even. These buffers are filled by the DNC and will request DIU access when double buffers fill. The DNC supplies 6 bits to the DWU every cycle (6 odd in one cycle, 6 even in the next cycle). So the service deadline is 512 cycles, given 6 accesses per 256-cycle rotation.
20.12.1.3 CFU
2111Here the requirement is that the DIU stall should be less than the time taken for the CFU to consume one third of its triple buffer. The total DIU stall=refresh latency+extra CDU(W) latency+read circuit latency=3+5 (for 4 cycle timeslots)+10=18 cycles. The CFU can consume its data at 8 bits/cycle at SF=4. Therefore 256 bits of data will last 32 cycles so the triple buffer is safe. In fact we only need an extra 144 bits of buffering or 3×64 bits. But it is safer to have the full extra 256 bits or 4×64 bits of buffering.
20.12.1.4 LLU
2112The LLU has 2 channels, each of which could request at 6 bits/106 MHz channel or 4 bits/160 MHz cycle, giving a total of 8 bits/160 MHz cycle. The service deadline for each channel is 256×106 MHz cycles, i.e. all 6 colours must be transferred in 256 cycles to feed the printhead. This equates to 384×160 MHz cycles.
2113Over a span of 384 cycles, there will be 6 CDU(W) accesses, 4 refreshes and one read latency encountered at most. Assuming CPU pre-accesses for these occurrences, this means the number of available cycles is given by 384−6×6−4×6−10=314 cycles.
2114For a CPU pre-access slot rate of 50%, 314 cycles implies 31 CPU and 63 non-CPU accesses (31×6+32×4=314). For 12 LLU accesses interspersed amongst these 63 non-CPU slots, implies an LLU allocation rate of approximately one slot in 5.
2115If the CPU pre-access is 100% across all slots, then 314 cycles gives 52 slots each to CPU and non-CPU accesses, (52×6=312 cycles). Twelve accesses spread over 52 slots, implies a 1-in-4 slot allocation to the LLU.
2116The same LLU slot allocation rate (1 slot in 5, or 1 in 4) can be applied to programming slots across a 256-cycle rotation window. The window size does not affect the occurrence of LLU slots, so the 384-cycle service requirement will be fulfilled.
20.12.1.5 DNC
2117This has a 2.4 bits/cycle bandwidth requirement. Each access will see the DIU stall of 18 cycles. 2.4 bits/cycle corresponds to an access every 106 cycles within a 256 cycle rotation. So to allow for DIU latency we need an access every 106–18 or 88 cycles. This is a bandwidth of 2.9 bits/cycle, requiring 3 timeslots in the rotation.
20.12.1.6 CDU
2118The JPEG decoder produces 8 bits/cycle. Peak CDUR[ead] bandwidth is 4 bits/cycle (SF=4), peak CDUW[rite] bandwidth is 4 bits/cycle (SF=4). both with 1.5 DRAM buffering.
2119The CDU(R) does a DIU read every 64 cycles at scale factor 4 with 1.5 DRAM buffering. The delay in being serviced by the DIU could be read circuit latency (10)+refresh (3)+extra CDU(W) cycles (6)=19 cycles. The JPEG decoder can consume each 256 bits of DIU-supplied data at 8 bits/cycle, i.e. in 32 cycles. If the DIU is 19 cycles late (due to latency) in supplying the read data then the JPEG decoder will have finished processing the read data 32+19=49 cycles after the DIU access. This is 64−49=15 cycles in advance of the next read. This 15 cycles is the upper limit on how much the DIU read service can further be delayed, without causing a stall. Given this margin, a stall on the read side will not occur.
2120On the write side, for scale factor 4, the access pattern is a DIU writes every 64 cycles with 1.5 DRAM buffereing. The JPEG decoder runs at 8 bits cycle and consumes 256 bits in 32 cycles. The CDU will not stall if the JPEG decode time (32)+DIU stall (19)<64, which is true.
000020.13 CPU DRAM Access Performance
2121The CPU's share of the timeslots can be specified in terms of guaranteed bandwidth and average bandwidth allocations. <ul id="ul0197" list-style="none"><li id="ul0197-0001" num="0000"><ul id="ul0198" list-style="none"><li id="ul0198-0001" num="2122">The CPU's access rate to memory depends on the CPU read access latency i.e. the time between the CPU making a request to the DIU and receiving the read data back from the DIU.</li><li id="ul0198-0002" num="2123">how often it can get access to DIU timeslots.</li></ul></li></ul>
2124Table estimated the CPU read latency as 6 cycles.
2125How often the CPU can get access to DIU timeslots depends on the access type. This is summarised in Table 122.
2126<tables id="TABLE-US-00153" num="00153"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 122</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>CPU DRAM access performance</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="49pt" align="left" /><colspec colname="4" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry>Nominal</entry><entry /><entry /></row><row><entry>Access</entry><entry>Timeslot</entry><entry>CPU DRAM</entry></row><row><entry>Type</entry><entry>Duration</entry><entry>access rate</entry><entry>Notes</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>CPU Pre-</entry><entry>6</entry><entry>Lower bound</entry><entry>CPU can access</entry></row><row><entry>access</entry><entry>cycles</entry><entry>(guaranteed</entry><entry>every timeslot.</entry></row><row><entry /><entry /><entry>bandwidth)</entry></row><row><entry /><entry /><entry>is 160 MHz/</entry></row><row><entry /><entry /><entry>6 =</entry></row><row><entry /><entry /><entry>26.27 MHz</entry></row><row><entry>Frac-</entry><entry>4 or 6</entry><entry>Lower bound</entry><entry>CPU accesses precede</entry></row><row><entry>tional</entry><entry>cycles</entry><entry>(guaranteed</entry><entry>a fraction N of time-</entry></row><row><entry>CPU</entry><entry /><entry>bandwidth)</entry><entry>slots where N = C/T.</entry></row><row><entry>Pre-</entry><entry /><entry>is (160</entry><entry>C =</entry></row><row><entry>access</entry><entry /><entry>MHz * N/P)</entry><entry>CPUPreAccessTimeslots</entry></row><row><entry /><entry /><entry /><entry>T =</entry></row><row><entry /><entry /><entry /><entry>CPUTotalTimeslots</entry></row><row><entry /><entry /><entry /><entry>P =</entry></row><row><entry /><entry /><entry /><entry>(6*C + 4*(T − C))/T</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2127In both CPU Pre-access and Fractional CPU Pre-access modes, if the CPU is not requesting the timeslots will have a duration of 3 or 4 cycles depending on whether the current access and preceding access are both to the shared read bus. This will mean that the timeslot rotation will run faster and more bandwidth is available.
2128If the CPU runs out of its instruction cache then instruction fetch performance is only limited by the on-chip bus protocol. If data resides in the data cache then 160 MHz performance is achieved. Accessing memory mapped registers, PSS or ROM with a 3 cycle bus protocol (address cycle+data cycle) gives 53 MHz performance.
2129Due to the action of CPU caching, some bandwidth limiting of the CPU in Fractional CPU Pre-access mode is expected to have little or no impact on the overall CPU performance.
000020.14 Implementation
2130The DRAM Interface Unit (DIU) is partitioned into 2 logical blocks to facilitate design and verification.
2131a. The DRAM Arbitration Unit (DAU) which interfaces with the SoPEC DIU requesters.
2132b. The DRAM Controller Unit (DCU) which accesses the embedded DRAM.
2133The basic principle in design of the DIU is to ensure that the eDRAM is accessed at its maximum rate while keeping the CPU read access latency as low as possible.
2134The DCU is designed to interface with single bank 20 Mbit IBM Cu-11 embedded DRAM performing random accesses every 3 cycles. Page mode burst of 4 write accesses, associated with the CDU, are also supported.
2135The DAU is designed to support interleaved accesses allowing the DRAM to be accessed every 3 cycles where back-to-back accesses do not occur over the shared 64-bit read data bus.
000020.14.1 DIU Partition
000020.14.2 Definition of DCU IO
2136<tables id="TABLE-US-00154" num="00154"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 123</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>DCU interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>Port Name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Clocks and Resets</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>pclk</entry><entry>1</entry><entry>In</entry><entry>SoPEC Functional clock</entry></row><row><entry>dau_dcu<sub>—</sub></entry><entry>1</entry><entry>In</entry><entry>Active-low, synchronous reset in</entry></row><row><entry>reset_n</entry><entry /><entry /><entry>pclk domain. Incorporates DAU</entry></row><row><entry /><entry /><entry /><entry>hard and soft resets.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Inputs from DAU</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>dau_dcu<sub>—</sub></entry><entry>1</entry><entry>In</entry><entry>Signal indicating from DAU</entry></row><row><entry>msn2stall</entry><entry /><entry /><entry>Arbitration Logic which when</entry></row><row><entry /><entry /><entry /><entry>asserted stalls DCU in MSN2</entry></row><row><entry /><entry /><entry /><entry>state.</entry></row><row><entry>dau_dcu<sub>—</sub></entry><entry>17</entry><entry>In</entry><entry>Signal indicating the address</entry></row><row><entry>adr[21:5]</entry><entry /><entry /><entry>for the DRAM access. This is a</entry></row><row><entry /><entry /><entry /><entry>256-bit aligned DRAM address.</entry></row><row><entry>dau_dcu_rwn</entry><entry>1</entry><entry>In</entry><entry>Signal indicating the direction</entry></row><row><entry /><entry /><entry /><entry>for the DRAM access</entry></row><row><entry /><entry /><entry /><entry>(1 = read, 0 = write).</entry></row><row><entry>dau_dcu<sub>—</sub></entry><entry>1</entry><entry>In</entry><entry>Signal indicating if access is</entry></row><row><entry>cduwpage</entry><entry /><entry /><entry>a CDU write page mode access</entry></row><row><entry /><entry /><entry /><entry>(1 = CDU page mode, 0 = not</entry></row><row><entry /><entry /><entry /><entry>CDU page mode).</entry></row><row><entry>dau_dcu_refresh</entry><entry>1</entry><entry>In</entry><entry>Signal indicating that a refresh</entry></row><row><entry /><entry /><entry /><entry>command is to be issued. If</entry></row><row><entry /><entry /><entry /><entry>asserted dau_dcu_adr,</entry></row><row><entry /><entry /><entry /><entry>dau_dcu_rwn and</entry></row><row><entry /><entry /><entry /><entry>dau_dcu_cduwpage are ignored.</entry></row><row><entry>dau_dcu_wdata</entry><entry>256</entry><entry>In</entry><entry>256-bit write data to DCU</entry></row><row><entry>dau_dcu_wmask</entry><entry>32</entry><entry>In</entry><entry>Byte encoded write data mask for</entry></row><row><entry /><entry /><entry /><entry>256-bit dau_dcu_wdata to DCU</entry></row><row><entry /><entry /><entry /><entry>Polarity: A “1” in a bit</entry></row><row><entry /><entry /><entry /><entry>field of dau_dcu_wmask means</entry></row><row><entry /><entry /><entry /><entry>that the corresponding byte</entry></row><row><entry /><entry /><entry /><entry>in the 256-bit dau_dcu_wdata</entry></row><row><entry /><entry /><entry /><entry>is written to DRAM.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Outputs to DAU</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>dcu_dau_adv</entry><entry>1</entry><entry>Out</entry><entry>Signal indicating to DAU to supply</entry></row><row><entry /><entry /><entry /><entry>next command to DCU</entry></row><row><entry>dcu_dau_wadv</entry><entry>1</entry><entry>Out</entry><entry>Signal indicating to DAU to ini-</entry></row><row><entry /><entry /><entry /><entry>tiate next non-CPU write</entry></row><row><entry>dcu_dau<sub>—</sub></entry><entry>1</entry><entry>Out</entry><entry>Signal indicating that the DCU has</entry></row><row><entry>refreshcomplete</entry><entry /><entry /><entry>completed a refresh.</entry></row><row><entry>dcu_dau_rdata</entry><entry>256</entry><entry>Out</entry><entry>256-bit read data from DCU.</entry></row><row><entry>dcu_dau_rvalid</entry><entry>1</entry><entry>Out</entry><entry>Signal indicating valid read data</entry></row><row><entry /><entry /><entry /><entry>on dcu_dau_rdata.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 20.14.3 DRAM Access Types
2137The DRAM access types used in SoPEC are summarised in Table 124. For a refresh operation the DRAM generates the address internally.
2138<tables id="TABLE-US-00155" num="00155"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 124</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>SoPEC DRAM access types</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>Type</entry><entry>Access</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>Read</entry><entry>Random 256-bit read</entry></row><row><entry /><entry>Write</entry><entry>Random 256-bit write with byte write masking</entry></row><row><entry /><entry /><entry>Page mode write for burst of 4 256-bit words with</entry></row><row><entry /><entry /><entry>byte write masking</entry></row><row><entry /><entry>Refresh</entry><entry>Single refresh</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 20.14.4 Constructing the 20 Mbit DRAM from Two 10 Mbit Instances
2139The 20 Mbit DRAM is constructed from two 10 Mbit instances. The address ranges of the two instances are shown in Table 125.
2140<tables id="TABLE-US-00156" num="00156"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 125</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Address ranges of the two 10 Mbit</entry></row><row><entry>instances in the 20 Mbit DRAM</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="35pt" align="left" /><colspec colname="4" colwidth="77pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Hex</entry><entry /></row><row><entry /><entry /><entry>256-bit</entry></row><row><entry /><entry /><entry>word</entry><entry>Binary 256-bit</entry></row><row><entry>Instance</entry><entry>Address</entry><entry>address</entry><entry>word address</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>Instance0</entry><entry>First word</entry><entry>00000</entry><entry>0 0000 0000 0000 0000</entry></row><row><entry /><entry>in lower 10 Mbit</entry></row><row><entry>Instance0</entry><entry>Last word</entry><entry>09FFF</entry><entry>0 1001 1111 1111 1111</entry></row><row><entry /><entry>in lower 10 Mbit</entry></row><row><entry>Instance1</entry><entry>First word</entry><entry>0A000</entry><entry>0 1010 0000 0000 0000</entry></row><row><entry /><entry>in upper 10 Mbit</entry></row><row><entry>Instance1</entry><entry>Last word</entry><entry>13FFF</entry><entry>1 0011 1111 1111 1111</entry></row><row><entry /><entry>in upper 10 Mbit</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2141There are separate macro select signals, inst0_MSN and inst1_MSN, for each instance and separate dataout busses inst0_DO and inst1_DO, which are multiplexed in the DCU. Apart from these signals both instances share the DRAM output pins of the DCU.
2142The DRAM Arbitration Unit (DAU) generates a 17 bit address, dau_dcu_adr[21:5], sufficient to address all 256-bit words in the 20 Mbit DRAM. The upper 5 bits are used to select between the two memory instances by gating their MSN pins. If instance1 is selected then the lower 16-bits are translated to map into the 10 Mbit range of that instance. The multiplexing and address translation rules are shown in Table 126.
2143In the case that the DAU issues a refresh, indicated by dau_dcu_refresh, then both macros are selected. The other control signals
2144<tables id="TABLE-US-00157" num="00157"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="315pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 126</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Instance selection and address translation</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="1" colwidth="56pt" align="center" /><colspec colname="2" colwidth="70pt" align="center" /><colspec colname="3" colwidth="35pt" align="left" /><colspec colname="4" colwidth="42pt" align="left" /><colspec colname="5" colwidth="42pt" align="left" /><colspec colname="6" colwidth="70pt" align="left" /><tbody valign="top"><row><entry /><entry>DAU Address</entry><entry /><entry /><entry /><entry /></row><row><entry /><entry>bits</entry><entry>Instance</entry></row><row><entry>dau_dcu_refresh</entry><entry>dau_dcu_adr[21:17]</entry><entry>selected</entry><entry>inst0_MSN</entry><entry>inst1_MSN</entry><entry>Address translation</entry></row><row><entry namest="1" nameend="6" align="center" rowsep="1" /></row><row><entry>0</entry><entry> <01010</entry><entry>Instance0</entry><entry>MSN</entry><entry>1</entry><entry>A[15:0] =</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry>dau_dcu_adr[20:5]</entry></row><row><entry /><entry>>=01010</entry><entry>Instance1</entry><entry>1</entry><entry>MSN</entry><entry>A[15:0] =</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry>dau_dcu_adr[21:5] −</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry>hA000</entry></row><row><entry>1</entry><entry>—</entry><entry>Instance0</entry><entry>MSN</entry><entry>MSN</entry><entry>—</entry></row><row><entry /><entry /><entry>and</entry></row><row><entry /><entry /><entry>Instance1</entry></row><row><entry namest="1" nameend="6" align="center" rowsep="1" /></row><row><entry namest="1" nameend="6" align="left" id="FOO-00012">dau_dcu_adr[21:5], dau_dcu_rwn and dau_dcu_cduwpage are ignored.</entry></row></tbody></tgroup></table></tables>
2145The instance selection and address translation logic is shown in <figref idref="DRAWINGS">FIG. 102</figref>.
2146The address translation and instance decode logic also increments the address presented to the DRAM in the case of a page mode write. Pseudo code is given below.
2147<tables id="TABLE-US-00158" num="00158"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>if rising edge(dau_dcu_valid) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>//capture the address from the DAU</entry></row><row><entry /><entry>next_cmdadr[21:5] = dau_dcu_adr[21:5]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif pagemode_adr_inc = = 1 then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>//increment the address</entry></row><row><entry /><entry>next_cmdadr[21:5] = cmdadr[21:5] + 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>next_cmdadr[21:5] = cmdadr[21:5]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>if rising_edge(dau_dcu_valid) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>//capture the address from the DAU</entry></row><row><entry /><entry>adr_var[21:5]:= dau_dcu_adr[21:5]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>adr_var[21:5]:= cmdadr[21:5]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>if adr_var[21:17] < 01010 then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>//choose instance0</entry></row><row><entry /><entry>instance_sel = 0</entry></row><row><entry /><entry>A[15:0] = adr_var[20:5]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>//choose instance1</entry></row><row><entry /><entry>instance_sel = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="63pt" align="left" /><colspec colname="1" colwidth="154pt" align="left" /><tbody valign="top"><row><entry /><entry>A[15:0] = adr_var[21:5] − hA000</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2148Pseudo code for the select logic, SEL0, for DRAM Instance0 is given below.
2149<tables id="TABLE-US-00159" num="00159"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="196pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>//instance0 selected or refresh</entry></row><row><entry /><entry>if instance_sel = = 0 OR dau_dcu_ref resh = = 1 then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>inst0_MSN = MSN</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="196pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>inst0_MSN = 1</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2150Pseudo code for the select logic, SEL1, for DRAM instance1 is given below.
2151<tables id="TABLE-US-00160" num="00160"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>//instance1 selected or refresh</entry></row><row><entry /><entry>if instance_sel = = 1 OR dau_dcu_refresh = = 1 then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>inst1_MSN = MSN</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>inst1_MSN = 1</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2152During a random read, the read data is returned, on dcu_dau_rdata, after time T<sub>acc</sub>, the random access time, which varies between 3 and 8 ns (see Table). To avoid any metastability issues the read data must be captured by a flip-flop which is enabled 2 pclk cycles or 12.5 ns after the DRAM access has been started. The DCU generates the enable signal dcu_dau_rvalid to capture dcu_dau_rdata.
2153The byte write mask dau_dcu_wmask[31:0] must be expanded to the bit write mask bitwritemask[255:0 needed by the DRAM.
000020.14.5 DAU-DCU Interface Description
2154The DCU asserts dcu_dau_adv in the MSN2 state to indicate to the DAU to supply the next command. dcu_dau_adv causes the DAU to perform arbitration in the MSN2 cycle. The resulting command is available to the DCU in the following cycle, the RST state. The timing is shown in <figref idref="DRAWINGS">FIG. 103</figref>. The command to the DRAM must be valid in the RST and MSN1 states, or at least meet the hold time requirement to the MSN falling edge at the start of the MSN1 state.
2155Note that the DAU issues a valid arbitration result following every dcu_dau_adv pulse. If no unit is requesting DRAM access, then a fall-back refresh request will be issued. When dau_dcu_refresh is asserted the operation is a refresh and dau_dcu_adr, dau_dcu_rwn and dau_dcu_cduwpage are ignored.
2156The DCU generates a second signal, dcu_dau_wadv, which is asserted in the RST state.
2157This indicates to the DAU that it can perform arbitration in advance for non-CPU writes.
2158The reason for performing arbitration in advance for non-CPU writes is explained in “Command Multiplexor Sub-block
2159<tables id="TABLE-US-00161" num="00161"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 136</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Command Multiplexor Sub-block IO Definition</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>Port name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Clocks and Resets</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>pclk</entry><entry>1</entry><entry>In</entry><entry>System Clock</entry></row><row><entry>prst_n</entry><entry>1</entry><entry>In</entry><entry>System reset, synchronous active</entry></row><row><entry /><entry /><entry /><entry>low</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>DIU Read Interface to SoPEC Units</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="119pt" align="left" /><tbody valign="top"><row><entry><unit>_diu<sub>—</sub></entry><entry>17</entry><entry>In</entry><entry>Read address to DIU</entry></row><row><entry>radr[21:5]</entry><entry /><entry /><entry>17 bits wide (256-bit aligned</entry></row><row><entry /><entry /><entry /><entry>word).</entry></row><row><entry>diu_<unit><sub>—</sub></entry><entry>1</entry><entry>Out</entry><entry>Acknowledge from DIU that read</entry></row><row><entry>rack</entry><entry /><entry /><entry>request has been accepted and new</entry></row><row><entry /><entry /><entry /><entry>read address can be placed on</entry></row><row><entry /><entry /><entry /><entry><unit>_diu_radr</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>DIU Write Interface to SoPEC Units</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="119pt" align="left" /><tbody valign="top"><row><entry><unit>_diu<sub>—</sub></entry><entry>17</entry><entry>In</entry><entry>Write address to DIU except CPU,</entry></row><row><entry>wadr[21:5]</entry><entry /><entry /><entry>SCB, CDU</entry></row><row><entry /><entry /><entry /><entry>17 bits wide (256-bit aligned</entry></row><row><entry /><entry /><entry /><entry>word)</entry></row><row><entry>cpu_diu<sub>—</sub></entry><entry>22</entry><entry>In</entry><entry>CPU Write address to DIU</entry></row><row><entry>wadr[21:4]]</entry><entry /><entry /><entry>(128-bit aligned address.)</entry></row><row><entry>cpu_diu_wmask</entry><entry>16</entry><entry>In</entry><entry>Byte enables for CPU write.</entry></row><row><entry>cdu_diu<sub>—</sub></entry><entry>19</entry><entry>In</entry><entry>CDU Write address to DIU</entry></row><row><entry>wadr[21:3]</entry><entry /><entry /><entry>19 bits wide (64-bit aligned</entry></row><row><entry /><entry /><entry /><entry>word)</entry></row><row><entry /><entry /><entry /><entry>Addresses cannot cross a 256-bit</entry></row><row><entry /><entry /><entry /><entry>word DRAM boundary.</entry></row><row><entry>diu_<unit><sub>—</sub></entry><entry>1</entry><entry>Out</entry><entry>Acknowledge from DIU that write</entry></row><row><entry>wack</entry><entry /><entry /><entry>request has been accepted and new</entry></row><row><entry /><entry /><entry /><entry>write address can be placed on</entry></row><row><entry /><entry /><entry /><entry><unit>_diu_wadr</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Outputs to CPU Interface and Arbitration Logic sub-block</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>re_arbitrate</entry><entry>1</entry><entry>Out</entry><entry>Signalling telling the arbitration</entry></row><row><entry /><entry /><entry /><entry>logic to choose the next arbitra-</entry></row><row><entry /><entry /><entry /><entry>tion winner.</entry></row><row><entry>re_arbitrate<sub>—</sub></entry><entry>1</entry><entry>Out</entry><entry>Signal telling the arbitration</entry></row><row><entry>wadv</entry><entry /><entry /><entry>logic to choose the next arbitra-</entry></row><row><entry /><entry /><entry /><entry>tion winner for non-CPU writes</entry></row><row><entry /><entry /><entry /><entry>2 timeslots in advance</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Debug Outputs to CPU Configuration and Arbitration Logic Sub-block</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>write_sel</entry><entry>5</entry><entry>Out</entry><entry>Signal indicating the SoPEC Unit</entry></row><row><entry /><entry /><entry /><entry>for which the current write trans-</entry></row><row><entry /><entry /><entry /><entry>action is occurring. Encoding is</entry></row><row><entry /><entry /><entry /><entry>described in Table .</entry></row><row><entry>write<sub>—</sub></entry><entry>1</entry><entry>Out</entry><entry>Signal indicating that write trans-</entry></row><row><entry>complete</entry><entry /><entry /><entry>action to SoPEC Unit indicated by</entry></row><row><entry /><entry /><entry /><entry>write_sel is complete.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Inputs from CPU Interface and Arbitration Logic sub-block</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>arb_gnt</entry><entry>1</entry><entry>In</entry><entry>Signal lasting 1 cycle which indi-</entry></row><row><entry /><entry /><entry /><entry>cates arbitration has occurred and</entry></row><row><entry /><entry /><entry /><entry>arb_sel is valid.</entry></row><row><entry>arb_sel</entry><entry>5</entry><entry>In</entry><entry>Signal indicating which requesting</entry></row><row><entry /><entry /><entry /><entry>SoPEC Unit has won arbitration.</entry></row><row><entry /><entry /><entry /><entry>Encoding is described in Table .</entry></row><row><entry>dir_sel</entry><entry>2</entry><entry>In</entry><entry>Signal indicating which sense of</entry></row><row><entry /><entry /><entry /><entry>access associated with arb_sel</entry></row><row><entry /><entry /><entry /><entry>00: issue non-CPU write</entry></row><row><entry /><entry /><entry /><entry>01: read winner</entry></row><row><entry /><entry /><entry /><entry>10: write winner</entry></row><row><entry /><entry /><entry /><entry>11: refresh winner</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Inputs from Read Write Multiplexor Sub-block</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>write_data<sub>—</sub></entry><entry>2</entry><entry>In</entry><entry>Signal indicating that valid write</entry></row><row><entry>valid</entry><entry /><entry /><entry>data is available for the current</entry></row><row><entry /><entry /><entry /><entry>command.</entry></row><row><entry /><entry /><entry /><entry>00 = not valid</entry></row><row><entry /><entry /><entry /><entry>01 = CPU write data valid</entry></row><row><entry /><entry /><entry /><entry>10 = non-CPU write data valid</entry></row><row><entry /><entry /><entry /><entry>11 = both CPU and non-CPU write</entry></row><row><entry /><entry /><entry /><entry>data valid</entry></row><row><entry>wdata</entry><entry>256</entry><entry>In</entry><entry>256-bit non-CPU write data</entry></row><row><entry>cpu_wdata</entry><entry>32</entry><entry>In</entry><entry>32-bit CPU write data</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Outputs to Read Write Multiplexor Sub-block</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>write_data<sub>—</sub></entry><entry>2</entry><entry>Out</entry><entry>Signal indicating the Command</entry></row><row><entry>accept</entry><entry /><entry /><entry>Multiplexor has accepted the write</entry></row><row><entry /><entry /><entry /><entry>data from the write multiplexor</entry></row><row><entry /><entry /><entry /><entry>00 = not valid</entry></row><row><entry /><entry /><entry /><entry>01 = accepts CPU write data</entry></row><row><entry /><entry /><entry /><entry>10 = accepts non-CPU write data</entry></row><row><entry /><entry /><entry /><entry>11 = not valid</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Inputs from DCU</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>dcu_dau_adv</entry><entry /><entry>In</entry><entry>Signal indicating to DAU to sup-</entry></row><row><entry /><entry /><entry /><entry>ply next command to DCU</entry></row><row><entry>dcu_dau_wadv</entry><entry /><entry>In</entry><entry>Signal indicating to DAU to ini-</entry></row><row><entry /><entry /><entry /><entry>tiate next non-CPU write</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Outputs to DCU</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>dau_dcu<sub>—</sub></entry><entry>17</entry><entry>Out</entry><entry>Signal indicating the address for</entry></row><row><entry>adr[21:5]</entry><entry /><entry /><entry>the DRAM access. This is a 256-</entry></row><row><entry /><entry /><entry /><entry>bit aligned DRAM address.</entry></row><row><entry>dau_dcu_rwn</entry><entry>1</entry><entry>Out</entry><entry>Signal indicating the direction</entry></row><row><entry /><entry /><entry /><entry>for the DRAM access</entry></row><row><entry /><entry /><entry /><entry>(1 = read, 0 = write).</entry></row><row><entry>dau_dcu<sub>—</sub></entry><entry>1</entry><entry>Out</entry><entry>Signal indicating if access is a</entry></row><row><entry>cduwpage</entry><entry /><entry /><entry>CDU write page mode access</entry></row><row><entry /><entry /><entry /><entry>(1 = CDU page mode, 0 = not</entry></row><row><entry /><entry /><entry /><entry>CDU page mode).</entry></row><row><entry>dau_dcu<sub>—</sub></entry><entry>1</entry><entry>Out</entry><entry>Signal indicating that a refresh</entry></row><row><entry>refresh</entry><entry /><entry /><entry>command is to be issued. If</entry></row><row><entry /><entry /><entry /><entry>asserted dau_dcu_adr, dau_dcu_rwn</entry></row><row><entry /><entry /><entry /><entry>and dau_dcu_cduwpage are ignored.</entry></row><row><entry>dau_dcu_wdata</entry><entry>256</entry><entry>Out</entry><entry>256-bit write data to DCU</entry></row><row><entry>dau_dcu_wmask</entry><entry>32</entry><entry>Out</entry><entry>Byte encoded write data mask for</entry></row><row><entry /><entry /><entry /><entry>256-bit dau_dcu_wdata to DCU</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2160The DCU state-machine can stall in the MSN2 state when the signal dau_dcu_msn2stall is asserted by the DAU Arbitration Logic,
2161The states of the DCU state-machine are summarised in Table 127.
2162<tables id="TABLE-US-00162" num="00162"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 127</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>States of the DCU state-machine</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry>State</entry><entry>Description</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>RST</entry><entry>Restore state</entry></row><row><entry /><entry>MSN1</entry><entry>Macro select state 1</entry></row><row><entry /><entry>MSN2</entry><entry>Macro select state 2</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 20.14.6 DCU State Machines
2163The IBM DRAM has a simple SRAM like interface. The DRAM is accessed as a single bank. The state machine to access the DRAM is shown in <figref idref="DRAWINGS">FIG. 104</figref>.
2164The signal pagemode_adr_inc is exported from the DCU as dcu_dau_cduwaccept. dcu_dau_cduwaccept tells the DAU to supply the next write data to the DRAM
000020.14.7 CU-11DRAM Timing Diagrams
2165The IBM Cu-11 embedded DRAM datasheet is referenced as [16].
2166Table 128 shows the timing parameters which must be obeyed for the IBM embedded DRAM.
2167<tables id="TABLE-US-00163" num="00163"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 128</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>1.5 V Cu-11 DRAM a.c. parameters</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><colspec colname="3" colwidth="35pt" align="center" /><colspec colname="4" colwidth="21pt" align="center" /><colspec colname="5" colwidth="35pt" align="center" /><tbody valign="top"><row><entry>Symbol</entry><entry>Parameter</entry><entry>Min</entry><entry>Max</entry><entry>Units</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><colspec colname="3" colwidth="35pt" align="char" char="." /><colspec colname="4" colwidth="21pt" align="center" /><colspec colname="5" colwidth="35pt" align="center" /><tbody valign="top"><row><entry>T<sub>set</sub></entry><entry>Input setup to MSN/PGN</entry><entry>1</entry><entry>—</entry><entry>ns</entry></row><row><entry>T<sub>hld</sub></entry><entry>Input hold to MSN/PGN</entry><entry>2</entry><entry>—</entry><entry>ns</entry></row><row><entry>T<sub>acc</sub></entry><entry>Random access time</entry><entry>3</entry><entry>8</entry><entry>ns</entry></row><row><entry>T<sub>act</sub></entry><entry>MSN active time</entry><entry>8</entry><entry>100 k</entry><entry>ns</entry></row><row><entry>T<sub>res</sub></entry><entry>MSN restore time</entry><entry>4</entry><entry>—</entry><entry>ns</entry></row><row><entry>T<sub>cyc</sub></entry><entry>Random R/W cycle time</entry><entry>12</entry><entry>—</entry><entry>ns</entry></row><row><entry>T<sub>rfc</sub></entry><entry>Refresh cycle time</entry><entry>12</entry><entry>—</entry><entry>ns</entry></row><row><entry>T<sub>accp</sub></entry><entry>Page mode access time</entry><entry>1</entry><entry> 3.9</entry><entry>ns</entry></row><row><entry>T<sub>pa</sub></entry><entry>PGN active time</entry><entry>1.6</entry><entry>—</entry><entry>ns</entry></row><row><entry>T<sub>pr</sub></entry><entry>PGN restore time</entry><entry>1.6</entry><entry>—</entry><entry>ns</entry></row><row><entry>T<sub>pcyc</sub></entry><entry>PGN cycle time</entry><entry>4</entry><entry>—</entry><entry>ns</entry></row><row><entry>T<sub>mprd</sub></entry><entry>MSN to PGN restore delay</entry><entry>6</entry><entry>—</entry><entry>ns</entry></row><row><entry>T<sub>actp</sub></entry><entry>MSN active for page mode</entry><entry>12</entry><entry>—</entry><entry>ns</entry></row><row><entry>T<sub>ref</sub></entry><entry>Refresh period</entry><entry>—</entry><entry> 3.2</entry><entry>ms</entry></row><row><entry>T<sub>pamr</sub></entry><entry>Page active to MSN restore</entry><entry>4</entry><entry>—</entry><entry>ns</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2168The IBM DRAM is asynchronous. In SoPEC it interfaces to signals clocked on pclk. The following timing diagrams show how the timing parameters in Table 129 are satisfied in SoPEC.
000020.14.8 Definition of DAU IO
2169<tables id="TABLE-US-00164" num="00164"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 129</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>DAU interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>Port Name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Clocks and Resets</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>pclk</entry><entry>1</entry><entry>In</entry><entry>SoPEC Functional clock</entry></row><row><entry>prst_n</entry><entry>1</entry><entry>In</entry><entry>Active-low, synchronous reset</entry></row><row><entry /><entry /><entry /><entry>in pclk domain</entry></row><row><entry>dau_dcu_reset_n</entry><entry>1</entry><entry>Out</entry><entry>Active-low, synchronous reset</entry></row><row><entry /><entry /><entry /><entry>in pclk domain. This reset</entry></row><row><entry /><entry /><entry /><entry>signal, exported to the DCU,</entry></row><row><entry /><entry /><entry /><entry>incorporates the locally</entry></row><row><entry /><entry /><entry /><entry>captured DAU version of</entry></row><row><entry /><entry /><entry /><entry>hard reset (prst_n) and the</entry></row><row><entry /><entry /><entry /><entry>soft reset configuration</entry></row><row><entry /><entry /><entry /><entry>register bit “Reset”.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>CPU Interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>cpu_adr</entry><entry>22</entry><entry>In</entry><entry>CPU address bus for both DRAM</entry></row><row><entry /><entry /><entry /><entry>and configuration register</entry></row><row><entry /><entry /><entry /><entry>access.</entry></row><row><entry /><entry /><entry /><entry>9 bits (bits 10:2) are required</entry></row><row><entry /><entry /><entry /><entry>to decode the configuration</entry></row><row><entry /><entry /><entry /><entry>register address space.</entry></row><row><entry /><entry /><entry /><entry>22 bits can address the DRAM</entry></row><row><entry /><entry /><entry /><entry>at byte level. DRAM addresses</entry></row><row><entry /><entry /><entry /><entry>cannot cross a 256-bit word</entry></row><row><entry /><entry /><entry /><entry>DRAM boundary.</entry></row><row><entry>cpu_dataout</entry><entry>32</entry><entry>In</entry><entry>Shared write data bus from</entry></row><row><entry /><entry /><entry /><entry>the CPU for DRAM and</entry></row><row><entry /><entry /><entry /><entry>configuration data</entry></row><row><entry>diu_cpu_data</entry><entry>32</entry><entry>Out</entry><entry>Configuration, status and</entry></row><row><entry /><entry /><entry /><entry>debug read data bus to</entry></row><row><entry /><entry /><entry /><entry>the CPU</entry></row><row><entry>diu_cpu<sub>—</sub></entry><entry>1</entry><entry>Out</entry><entry>Signal indicating the data</entry></row><row><entry>debug_valid</entry><entry /><entry /><entry>on the diu_cpu_data bus is</entry></row><row><entry /><entry /><entry /><entry>valid debug data.</entry></row><row><entry>cpu_rwn</entry><entry>1</entry><entry>In</entry><entry>Common read/not-write signal</entry></row><row><entry /><entry /><entry /><entry>from the CPU</entry></row><row><entry>cpu_acode</entry><entry>2</entry><entry>In</entry><entry>CPU access code signals.</entry></row><row><entry /><entry /><entry /><entry>cpu_acode[0] - Program (0)/</entry></row><row><entry /><entry /><entry /><entry>Data (1) access</entry></row><row><entry /><entry /><entry /><entry>cpu_acode[1] - User (0)/</entry></row><row><entry /><entry /><entry /><entry>Supervisor (1) access</entry></row><row><entry /><entry /><entry /><entry>The DAU will only allow super-</entry></row><row><entry /><entry /><entry /><entry>visor mode accesses to data</entry></row><row><entry /><entry /><entry /><entry>space.</entry></row><row><entry>cpu_diu_sel</entry><entry>1</entry><entry>In</entry><entry>Block select from the CPU. When</entry></row><row><entry /><entry /><entry /><entry>cpu_diu_sel is high both cpu_adr</entry></row><row><entry /><entry /><entry /><entry>and cpu_dataout are valid</entry></row><row><entry>diu_cpu_rdy</entry><entry>1</entry><entry>Out</entry><entry>Ready signal to the CPU.</entry></row><row><entry /><entry /><entry /><entry>When diu_cpu_rdy is high</entry></row><row><entry /><entry /><entry /><entry>it indicates the last cycle</entry></row><row><entry /><entry /><entry /><entry>of the access. For a write</entry></row><row><entry /><entry /><entry /><entry>cycle this means</entry></row><row><entry /><entry /><entry /><entry>cpu_dataout has been</entry></row><row><entry /><entry /><entry /><entry>registered by the block</entry></row><row><entry /><entry /><entry /><entry>and for a read cycle this</entry></row><row><entry /><entry /><entry /><entry>means the data on</entry></row><row><entry /><entry /><entry /><entry>diu_cpu_data is valid.</entry></row><row><entry>diu_cpu_berr</entry><entry>1</entry><entry>Out</entry><entry>Bus error signal to the CPU</entry></row><row><entry /><entry /><entry /><entry>indicating an invalid access.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>DIU Read Interface to SoPEC Units</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="105pt" align="left" /><tbody valign="top"><row><entry><unit>_diu_rreq</entry><entry>1</entry><entry>In</entry><entry>SoPEC unit requests DRAM read.</entry></row><row><entry /><entry /><entry /><entry>A read request must be</entry></row><row><entry /><entry /><entry /><entry>accompanied by a valid</entry></row><row><entry /><entry /><entry /><entry>read address.</entry></row><row><entry><unit>_diu<sub>—</sub></entry><entry>17</entry><entry>In</entry><entry>Read address to DIU</entry></row><row><entry>radr[21:5]</entry><entry /><entry /><entry>17 bits wide (256-bit aligned</entry></row><row><entry /><entry /><entry /><entry>word).</entry></row><row><entry /><entry /><entry /><entry>Note: “<unit>” refers to</entry></row><row><entry /><entry /><entry /><entry>non-CPU requesters only.</entry></row><row><entry /><entry /><entry /><entry>CPU addresses are provided</entry></row><row><entry /><entry /><entry /><entry>via “cpu_adr”.</entry></row><row><entry>diu_<unit><sub>—</sub></entry><entry>1</entry><entry>Out</entry><entry>Acknowledge from DIU that</entry></row><row><entry>rack</entry><entry /><entry /><entry>read request has been</entry></row><row><entry /><entry /><entry /><entry>accepted and new read</entry></row><row><entry /><entry /><entry /><entry>address can be placed</entry></row><row><entry /><entry /><entry /><entry>on <unit>_diu_radr</entry></row><row><entry>diu_data</entry><entry>64</entry><entry>Out</entry><entry>Data from DIU to SoPEC Units</entry></row><row><entry /><entry /><entry /><entry>except CPU.</entry></row><row><entry /><entry /><entry /><entry>First 64-bits is bits 63:0 of</entry></row><row><entry /><entry /><entry /><entry>256 bit word</entry></row><row><entry /><entry /><entry /><entry>Second 64-bits is bits 127:64</entry></row><row><entry /><entry /><entry /><entry>of 256 bit word</entry></row><row><entry /><entry /><entry /><entry>Third 64-bits is bits 191:128</entry></row><row><entry /><entry /><entry /><entry>of 256 bit word</entry></row><row><entry /><entry /><entry /><entry>Fourth 64-bits is bits 255:192</entry></row><row><entry /><entry /><entry /><entry>of 256 bit word</entry></row><row><entry>dram_cpu_data</entry><entry>256</entry><entry>Out</entry><entry>256-bit data from DRAM to</entry></row><row><entry /><entry /><entry /><entry>CPU.</entry></row><row><entry>diu_<unit><sub>—</sub></entry><entry>1</entry><entry>Out</entry><entry>Signal from DIU telling SoPEC</entry></row><row><entry>rvalid</entry><entry /><entry /><entry>Unit that valid read data is</entry></row><row><entry /><entry /><entry /><entry>on the diu_data bus</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>DIU Write Interface to SoPEC Units</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="105pt" align="left" /><tbody valign="top"><row><entry><unit>_diu<sub>—</sub></entry><entry>1</entry><entry>In</entry><entry>SoPEC unit requests DRAM write.</entry></row><row><entry>wreq</entry><entry /><entry /><entry>A write request must be</entry></row><row><entry /><entry /><entry /><entry>accompanied by a valid</entry></row><row><entry /><entry /><entry /><entry>write address.</entry></row><row><entry /><entry /><entry /><entry>Note: “<unit>” refers to</entry></row><row><entry /><entry /><entry /><entry>non-CPU requesters only.</entry></row><row><entry><unit>_diu<sub>—</sub></entry><entry>17</entry><entry>In</entry><entry>Write address to DIU except</entry></row><row><entry>wadr[21:5]</entry><entry /><entry /><entry>CPU, CDU</entry></row><row><entry /><entry /><entry /><entry>17 bits wide (256-bit aligned</entry></row><row><entry /><entry /><entry /><entry>word)</entry></row><row><entry /><entry /><entry /><entry>Note: “<unit>” refers to</entry></row><row><entry /><entry /><entry /><entry>non-CPU requesters, excluding</entry></row><row><entry /><entry /><entry /><entry>the CDU.</entry></row><row><entry>scb_diu<sub>—</sub></entry><entry>8</entry><entry>In</entry><entry>Byte write enables applicable</entry></row><row><entry>wmask[7:0]</entry><entry /><entry /><entry>to a given 64-bit quarter-word</entry></row><row><entry /><entry /><entry /><entry>transferred from the SCB. Note</entry></row><row><entry /><entry /><entry /><entry>that different mask values are</entry></row><row><entry /><entry /><entry /><entry>used with each quarter-word.</entry></row><row><entry /><entry /><entry /><entry>Requirement for the USB host</entry></row><row><entry /><entry /><entry /><entry>core.</entry></row><row><entry>diu_cpu<sub>—</sub></entry><entry>1</entry><entry>Out</entry><entry>Flag indicating that the CPU</entry></row><row><entry>write_rdy</entry><entry /><entry /><entry>posted write buffer is empty.</entry></row><row><entry>cpu_diu<sub>—</sub></entry><entry>1</entry><entry>In</entry><entry>Write enable for the CPU</entry></row><row><entry>wdatavalid</entry><entry /><entry /><entry>posted write buffer. Also</entry></row><row><entry /><entry /><entry /><entry>confirms that the CPU write</entry></row><row><entry /><entry /><entry /><entry>data, address and mask</entry></row><row><entry /><entry /><entry /><entry>are valid.</entry></row><row><entry>cpu_diu_wdata</entry><entry>128</entry><entry>In</entry><entry>CPU write data which is loaded</entry></row><row><entry /><entry /><entry /><entry>into the posted write buffer.</entry></row><row><entry>cpu_diu<sub>—</sub></entry><entry>18</entry><entry>In</entry><entry>128-bit aligned CPU write</entry></row><row><entry>wadr[21:4]</entry><entry /><entry /><entry>address.</entry></row><row><entry>cpu_diu<sub>—</sub></entry><entry>16</entry><entry>In</entry><entry>Byte enables for 128-bit CPU</entry></row><row><entry>wmask[15:0]</entry><entry /><entry /><entry>posted write.</entry></row><row><entry>cdu_diu<sub>—</sub></entry><entry>19</entry><entry>In</entry><entry>CDU Write address to DIU</entry></row><row><entry>wadr[21:3]</entry><entry /><entry /><entry>19 bits wide (64-bit aligned</entry></row><row><entry /><entry /><entry /><entry>word)</entry></row><row><entry /><entry /><entry /><entry>Addresses cannot cross a</entry></row><row><entry /><entry /><entry /><entry>256-bit word DRAM boundary.</entry></row><row><entry>diu_<unit><sub>—</sub></entry><entry>1</entry><entry>Out</entry><entry>Acknowledge from DIU that</entry></row><row><entry>wack</entry><entry /><entry /><entry>write request has been</entry></row><row><entry /><entry /><entry /><entry>accepted and new write</entry></row><row><entry /><entry /><entry /><entry>address can be placed on</entry></row><row><entry /><entry /><entry /><entry><unit>_diu_wadr</entry></row><row><entry><unit>_diu<sub>—</sub></entry><entry>64</entry><entry>In</entry><entry>Data from SoPEC Unit to DIU</entry></row><row><entry>data[63:0]</entry><entry /><entry /><entry>except CPU.</entry></row><row><entry /><entry /><entry /><entry>First 64-bits is bits 63:0 of</entry></row><row><entry /><entry /><entry /><entry>256 bit word</entry></row><row><entry /><entry /><entry /><entry>Second 64-bits is bits 127:64</entry></row><row><entry /><entry /><entry /><entry>of 256 bit word</entry></row><row><entry /><entry /><entry /><entry>Third 64-bits is bits 191:128</entry></row><row><entry /><entry /><entry /><entry>of 256 bit word</entry></row><row><entry /><entry /><entry /><entry>Fourth 64-bits is bits 255:192</entry></row><row><entry /><entry /><entry /><entry>of 256 bit word</entry></row><row><entry /><entry /><entry /><entry>Note: “<unit>” refers to</entry></row><row><entry /><entry /><entry /><entry>non-CPU requesters only.</entry></row><row><entry><unit>_diu<sub>—</sub></entry><entry>1</entry><entry>In</entry><entry>Signal from SoPEC Unit</entry></row><row><entry>wvalid</entry><entry /><entry /><entry>indicating that data on</entry></row><row><entry /><entry /><entry /><entry><unit>_diu_data is</entry></row><row><entry /><entry /><entry /><entry>valid.</entry></row><row><entry /><entry /><entry /><entry>Note: “<unit>” refers to</entry></row><row><entry /><entry /><entry /><entry>non-CPU requesters only.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Outputs to DCU</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>dau_dcu<sub>—</sub></entry><entry>1</entry><entry>Out</entry><entry>Signal indicating from DAU</entry></row><row><entry>msn2stall</entry><entry /><entry /><entry>Arbitration Logic which when</entry></row><row><entry /><entry /><entry /><entry>de-asserted stalls DCU</entry></row><row><entry /><entry /><entry /><entry>in MSN2 state.</entry></row><row><entry>dau_dcu<sub>—</sub></entry><entry>17</entry><entry>Out</entry><entry>Signal indicating the address</entry></row><row><entry>adr[21:5]</entry><entry /><entry /><entry>for the DRAM access. This is</entry></row><row><entry /><entry /><entry /><entry>a 256-bit aligned DRAM address.</entry></row><row><entry>dau_dcu_rwn</entry><entry>1</entry><entry>Out</entry><entry>Signal indicating the direction</entry></row><row><entry /><entry /><entry /><entry>for the DRAM access</entry></row><row><entry /><entry /><entry /><entry>(1 = read, 0 = write).</entry></row><row><entry>dau_dcu<sub>—</sub></entry><entry>1</entry><entry>Out</entry><entry>Signal indicating if access</entry></row><row><entry>cduwpage</entry><entry /><entry /><entry>is a CDU write page mode</entry></row><row><entry /><entry /><entry /><entry>access</entry></row><row><entry /><entry /><entry /><entry>(1 = CDU page mode,</entry></row><row><entry /><entry /><entry /><entry>0 = not CDU page mode).</entry></row><row><entry>dau_dcu_refresh</entry><entry>1</entry><entry>Out</entry><entry>Signal indicating that a</entry></row><row><entry /><entry /><entry /><entry>refresh command is to be</entry></row><row><entry /><entry /><entry /><entry>issued. If asserted</entry></row><row><entry /><entry /><entry /><entry>dau_dcu_cmd_adr,</entry></row><row><entry /><entry /><entry /><entry>dau_dcu_rwn and</entry></row><row><entry /><entry /><entry /><entry>dau_dcu_cduwpage</entry></row><row><entry /><entry /><entry /><entry>are ignored.</entry></row><row><entry>dau_dcu_wdata</entry><entry>256</entry><entry>Out</entry><entry>256-bit write data to DCU</entry></row><row><entry>dau_dcu_wmask</entry><entry>32</entry><entry>Out</entry><entry>Byte-encoded write data mask</entry></row><row><entry /><entry /><entry /><entry>for 256-bit dau_dcu_wdata</entry></row><row><entry /><entry /><entry /><entry>to DCU</entry></row><row><entry /><entry /><entry /><entry>Polarity: A “1” in a bit</entry></row><row><entry /><entry /><entry /><entry>field of dau_dcu_wmask means</entry></row><row><entry /><entry /><entry /><entry>that the corresponding byte</entry></row><row><entry /><entry /><entry /><entry>in the 256-bit dau_dcu_wdata</entry></row><row><entry /><entry /><entry /><entry>is written to DRAM.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Inputs from DCU</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>dcu_dau_adv</entry><entry>1</entry><entry>In</entry><entry>Signal indicating to DAU to</entry></row><row><entry /><entry /><entry /><entry>supply next command to DCU</entry></row><row><entry>dcu_dau_wadv</entry><entry>1</entry><entry>In</entry><entry>Signal indicating to DAU to</entry></row><row><entry /><entry /><entry /><entry>initiate next non-CPU write</entry></row><row><entry>dcu_dau<sub>—</sub></entry><entry>1</entry><entry>In</entry><entry>Signal indicating that the DCU</entry></row><row><entry>refreshcomplete</entry><entry /><entry /><entry>has completed a refresh.</entry></row><row><entry>dcu_dau_rdata</entry><entry>256</entry><entry>In</entry><entry>256-bit read data from DCU.</entry></row><row><entry>dcu_dau_rvalid</entry><entry>1</entry><entry>In</entry><entry>Signal indicating valid read</entry></row><row><entry /><entry /><entry /><entry>data on dcu_dau_rdata.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2170The CPU subsystem bus interface is described in more detail in Section 11.4.3. The DAU block will only allow supervisor-mode accesses to update its configuration registers (i.e. cpu_acode[1:0]=b11). All other accesses will result in diu_cpu_berr being asserted.
000020.14.9 DAU Configuration Registers
2171<tables id="TABLE-US-00165" num="00165"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="350pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 130</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>DAU configuration registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="28pt" align="center" /><colspec colname="4" colwidth="56pt" align="left" /><colspec colname="5" colwidth="140pt" align="left" /><tbody valign="top"><row><entry>Address,</entry><entry /><entry>#</entry><entry /><entry /></row><row><entry>(DIU base+)</entry><entry>Register</entry><entry>bits</entry><entry>Reset</entry><entry>Description</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="350pt" align="left" /><tbody valign="top"><row><entry>Reset</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="56pt" align="left" /><colspec colname="5" colwidth="140pt" align="left" /><tbody valign="top"><row><entry>0x00</entry><entry>Reset</entry><entry>1</entry><entry>0x1</entry><entry>A write to this register causes a reset</entry></row><row><entry /><entry /><entry /><entry /><entry>of the DIU.</entry></row><row><entry /><entry /><entry /><entry /><entry>This register can be read to indicate</entry></row><row><entry /><entry /><entry /><entry /><entry>the reset state:</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - reset in progress</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - reset not in progress</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="350pt" align="left" /><tbody valign="top"><row><entry>Refresh</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="56pt" align="left" /><colspec colname="5" colwidth="140pt" align="left" /><tbody valign="top"><row><entry>0x04</entry><entry>RefreshPeriod</entry><entry>9</entry><entry>0x063</entry><entry>Refresh controller.</entry></row><row><entry /><entry /><entry /><entry /><entry>When set to 0 refresh is off, other-</entry></row><row><entry /><entry /><entry /><entry /><entry>wise the value indicates the number of</entry></row><row><entry /><entry /><entry /><entry /><entry>cycles, less one, between each refresh.</entry></row><row><entry /><entry /><entry /><entry /><entry>[Note that for a system clock frequency</entry></row><row><entry /><entry /><entry /><entry /><entry>of 160 MHz, a value exceeding 0x63</entry></row><row><entry /><entry /><entry /><entry /><entry>(indicating a 100-cycle refresh period)</entry></row><row><entry /><entry /><entry /><entry /><entry>should not be programmed, or the DRAM</entry></row><row><entry /><entry /><entry /><entry /><entry>will malfunction.]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="350pt" align="left" /><tbody valign="top"><row><entry>Timeslot allocation and control</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="56pt" align="left" /><colspec colname="5" colwidth="140pt" align="left" /><tbody valign="top"><row><entry>0x08</entry><entry>NumMainTimeslots</entry><entry>6</entry><entry>0x01</entry><entry>Number of main timeslots (1–64) less</entry></row><row><entry /><entry /><entry /><entry /><entry>one</entry></row><row><entry>0x0C</entry><entry>CPUPreAccessTimeslots</entry><entry>4</entry><entry>0x0</entry><entry>(CPUPreAccessTimeslots + 1) main slots</entry></row><row><entry /><entry /><entry /><entry /><entry>out of a total of (CPUTotalTimeslots + 1)</entry></row><row><entry /><entry /><entry /><entry /><entry>are preceded by a CPU access.</entry></row><row><entry>0x10</entry><entry>CPUTotalTimeslots</entry><entry>4</entry><entry>0x0</entry><entry>(CPUPreAccessTimeslots + 1) main slots</entry></row><row><entry /><entry /><entry /><entry /><entry>out of a total of (CPUTotalTimeslots + 1)</entry></row><row><entry /><entry /><entry /><entry /><entry>are preceded by a CPU access.</entry></row><row><entry>0x100–0x1FC</entry><entry>MainTimeslot[63:0]</entry><entry>64 × 4</entry><entry>[63:1][3:0] = 0x0</entry><entry>Programmable main timeslots (up to</entry></row><row><entry /><entry /><entry /><entry>[0][3:0] = 0xE</entry><entry>64 main timeslots).</entry></row><row><entry>0x200</entry><entry>ReadRoundRobinLevel</entry><entry>12</entry><entry>0x000</entry><entry>For each read requester plus refresh</entry></row><row><entry /><entry /><entry /><entry /><entry>0 = level1 of round-robin</entry></row><row><entry /><entry /><entry /><entry /><entry>1 = level2 of round-robin</entry></row><row><entry /><entry /><entry /><entry /><entry>The bit order is defined in Table .</entry></row><row><entry>0x204</entry><entry>EnableCPURoundRobin</entry><entry>1</entry><entry>0x1</entry><entry>Allows the CPU to particpate in the</entry></row><row><entry /><entry /><entry /><entry /><entry>unused read round-robin scheme. If</entry></row><row><entry /><entry /><entry /><entry /><entry>disabled, the shared CPU/refresh</entry></row><row><entry /><entry /><entry /><entry /><entry>round-robin position is dedicated</entry></row><row><entry /><entry /><entry /><entry /><entry>solely to refresh.</entry></row><row><entry>0x208</entry><entry>RotationSync</entry><entry>1</entry><entry>0x1</entry><entry>Writing 0, followed by 1 to this bit</entry></row><row><entry /><entry /><entry /><entry /><entry>allows the timeslot rotation to advance</entry></row><row><entry /><entry /><entry /><entry /><entry>on a cycle basis which can be determined</entry></row><row><entry /><entry /><entry /><entry /><entry>by the CPU.</entry></row><row><entry>0x20C</entry><entry>minNonCPUReadAdr</entry><entry>12</entry><entry>0x800</entry><entry>12 MSBs of lowest DRAM address which may</entry></row><row><entry /><entry /><entry /><entry /><entry>be read by non-CPU requesters.</entry></row><row><entry>0x210</entry><entry>minDWUWriteAdr</entry><entry>12</entry><entry>0x800</entry><entry>12 MSBs of lowest DRAM address which may</entry></row><row><entry /><entry /><entry /><entry /><entry>be written to by the DWU.</entry></row><row><entry>0x214</entry><entry>minNonCPUWriteAdr</entry><entry>12</entry><entry>0x800</entry><entry>12 MSBs of lowest DRAM address which may</entry></row><row><entry /><entry /><entry /><entry /><entry>be written to by non-CPU requesters other</entry></row><row><entry /><entry /><entry /><entry /><entry>than the DWU.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="350pt" align="left" /><tbody valign="top"><row><entry>Debug</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="56pt" align="left" /><colspec colname="5" colwidth="140pt" align="left" /><tbody valign="top"><row><entry>0x300</entry><entry>DebugSelect[11:2]</entry><entry>10</entry><entry>0x304</entry><entry>Debug address select. Indicates the</entry></row><row><entry /><entry /><entry /><entry /><entry>address of the register to report on</entry></row><row><entry /><entry /><entry /><entry /><entry>the diu_cpu_data bus when it is not</entry></row><row><entry /><entry /><entry /><entry /><entry>otherwise being used.</entry></row><row><entry /><entry /><entry /><entry /><entry>When this signal carries debug informa-</entry></row><row><entry /><entry /><entry /><entry /><entry>tion the signal diu_cpu_debug_valid</entry></row><row><entry /><entry /><entry /><entry /><entry>will be asserted.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="350pt" align="left" /><tbody valign="top"><row><entry>Debug: arbitration and performance</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="56pt" align="left" /><colspec colname="5" colwidth="140pt" align="left" /><tbody valign="top"><row><entry>0x304</entry><entry>Arbitration History</entry><entry>22</entry><entry>—</entry><entry>Bit 0 = arb_gnt</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 1 = arb_executed</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 6:2 = arb_sel[4:0]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 12:7 = timeslot_number[5:0]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 15:13 = access_type[2:0]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 16 = back2back_non_cpu_write</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 17 = sticky_back2back_non_cpu_write</entry></row><row><entry /><entry /><entry /><entry /><entry>(Sticky version of same, cleared on reset.)</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 18 = rotation_sync</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 20:19 = rotation_state</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 21 = sticky_invalid_non_cpu_adr</entry></row><row><entry /><entry /><entry /><entry /><entry>See Section 20.14.9.2 DIU Debug for</entry></row><row><entry /><entry /><entry /><entry /><entry>a description of the fields.</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x308</entry><entry>DIUPerformance</entry><entry>31</entry><entry>—</entry><entry>Bit 0 = cpu_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 1 = scb_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 2 = cdu_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 3 = cfu_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 4 = lbd_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 5 = sfu_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 6 = td_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 7 = tfs_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 8 = hcu_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 9 = dnc_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 10 = llu_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 11 = pcu_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 12 = cpu_diu_wreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 13 = scb_diu_wreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 14 = cdu_diu_wreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 15 = sfu_diu_wreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 16 = dwu_diu_wreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 17 = refresh_req</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 22:18 = read_sel[4:0]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 23 = read_complete</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 28:24 = write_sel[4:0]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 29 = write_complete</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 30 = dcu_dau_refreshcomplete</entry></row><row><entry /><entry /><entry /><entry /><entry>See Section 20.14.9.2 DIU Debug for</entry></row><row><entry /><entry /><entry /><entry /><entry>a description of the fields.</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="350pt" align="left" /><tbody valign="top"><row><entry>Debug DIU read requesters interface signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="56pt" align="left" /><colspec colname="5" colwidth="140pt" align="left" /><tbody valign="top"><row><entry>0x30C</entry><entry>CPUReadInterface</entry><entry>25</entry><entry>—</entry><entry>Bit 0 = cpu_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 22:1 = cpu_adr[21:0]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 23 = diu_cpu_rack</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 24 = diu_cpu_rvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x310</entry><entry>SCBReadInterface</entry><entry>20</entry><entry>—</entry><entry>Bit 0 = scb_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 17:1 = scb_diu_radr[21:5]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 18 = diu_scb_rack</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 19 = diu_scb_rvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x314</entry><entry>CDUReadInterface</entry><entry>20</entry><entry>—</entry><entry>Bit 0 = cdu_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 17:1 = cdu_diu_radr[21:5]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 18 = diu_cdu_rack</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 19 = diu_cdu_rvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x318</entry><entry>CFUReadInterface</entry><entry>20</entry><entry>—</entry><entry>Bit 0 = cfu_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 17:1 = cfu_diu_radr[21:5]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 18 = diu_cfu_rack</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 19 = diu_cfu_rvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x31C</entry><entry>LBDReadInterface</entry><entry>20</entry><entry>—</entry><entry>Bit 0 = lbd_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 17:1 = lbd_diu_radr[21:5]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 18 = diu_lbd_rack</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 19 = diu_lbd_rvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x320</entry><entry>SFUReadInterface</entry><entry>20</entry><entry>—</entry><entry>Bit 0 = sfu_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 17:1 = sfu_diu_radr[21:5]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 18 = diu_sfu_rack</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 19 = diu_sfu_rvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x324</entry><entry>TDReadInterface</entry><entry>20</entry><entry>—</entry><entry>Bit 0 = td_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 17:1 = td_diu_radr[21:5]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 18 = diu_td_rack</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 19 = diu_td_rvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x328</entry><entry>TFSReadInterface</entry><entry>20</entry><entry>—</entry><entry>Bit 0 = tfs_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 17:1 = tfs_diu_radr[21:5]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 18 = diu_tfs_rack</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 19 = diu_tfs_rvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x32C</entry><entry>HCUReadInterface</entry><entry>20</entry><entry>—</entry><entry>Bit 0 = hcu_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 17:1 = hcu_diu_radr[21 :5]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 18 = diu_hcu_rack</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 19 = diu_hcu_rvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x330</entry><entry>DNCReadInterface</entry><entry>20</entry><entry>—</entry><entry>Bit 0 = dnc_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 17:1 = dnc_diu_radr[21:5]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 18 = diu_dnc_rack</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 19 = diu_dnc_rvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x334</entry><entry>LLUReadInterface</entry><entry>20</entry><entry>—</entry><entry>Bit 0 = llu_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 17:1 = lluu_diu_radr[21:5]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 18 = diu_llu_rack</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 19 = diu_llu_rvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x338</entry><entry>PCUReadInterface</entry><entry>20</entry><entry>—</entry><entry>Bit 0 = pcu_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 17:1 = pcu_diu_radr[21:5]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 18 = diu_pcu_rack</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 19 = diu_pcu_rvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="350pt" align="left" /><tbody valign="top"><row><entry>Debug DIU write requesters interface signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="56pt" align="left" /><colspec colname="5" colwidth="140pt" align="left" /><tbody valign="top"><row><entry>0x33C</entry><entry>CPUWriteInterface</entry><entry>27</entry><entry>—</entry><entry>Bit 0 = cpu_diu_wreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 22:1 = cpu_adr[21:0]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 24:23 = cpu_diu_wmask[1:0]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 25 = diu_cpu_wack</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 26 = cpu_diu_wvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x340</entry><entry>SCBWriteInterface</entry><entry>20</entry><entry>—</entry><entry>Bit 0 = scb_diu_wreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 17:1 = scb_diu_wadr[21:5]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 18 = diu_scb_wack</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 19 = scb_diu_wvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x344</entry><entry>CDUWriteInterface</entry><entry>22</entry><entry>—</entry><entry>Bit 0 = cdu_diu_wreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 19:1 = cdu_diu_wadr[21:3]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 20 = diu_cdu_wack</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 21 = cdu_diu_wvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x348</entry><entry>SFUWriteInterface</entry><entry>20</entry><entry>—</entry><entry>Bit 0 = sfu_diu_wreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 17:1 = sfu_diu_wadr[21:5]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 18 = diu_sfu_wack</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 19 = sfu_diu_wvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x34C</entry><entry>DWUWriteInterface</entry><entry>20</entry><entry>—</entry><entry>Bit 0 = dwu_diu_wreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 17:1 = dwu_diu_wadr[21:5]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 18 = diu_dwu_wack</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 19 = dwu_diu_wvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="350pt" align="left" /><tbody valign="top"><row><entry>Debug DAU-DCU interface signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="56pt" align="left" /><colspec colname="5" colwidth="140pt" align="left" /><tbody valign="top"><row><entry>0x350</entry><entry>DAU-DCUInterface</entry><entry>25</entry><entry>—</entry><entry>Bit 16:0 = dau_dcu_adr[21:5]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 17 = dau_dcu_rwn</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 18 = dau_dcu_cduwpage</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 19 = dau_dcu_refresh</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 20 = dau_dcu_msn2stall</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 21 = dcu_dau_adv</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 22 = dcu_dau_wadv</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 23 = dcu_dau_refreshcomplete</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 24 = dcu_dau_rvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2172Each main timeslot can be assigned a SoPEC DIU requestor according to Table 131.
2173<tables id="TABLE-US-00166" num="00166"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 131</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>SoPEC DIU requester encoding for main timeslots.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="56pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Index</entry><entry>Index</entry></row><row><entry /><entry>Name</entry><entry>(binary)</entry><entry>(HEX)</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Write</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="56pt" align="left" /><tbody valign="top"><row><entry /><entry>SCB(W)</entry><entry>b0_0000</entry><entry>0x00</entry></row><row><entry /><entry>CDU(W)</entry><entry>b0001</entry><entry>0x1</entry></row><row><entry /><entry>SFU(W)</entry><entry>b0010</entry><entry>0x2</entry></row><row><entry /><entry>DWU</entry><entry>b0011</entry><entry>0x3</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Read</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="56pt" align="left" /><tbody valign="top"><row><entry /><entry>SCB(R)</entry><entry>b0100</entry><entry>0x4</entry></row><row><entry /><entry>CDU(R)</entry><entry>b0101</entry><entry>0x5</entry></row><row><entry /><entry>CFU</entry><entry>b0110</entry><entry>0x6</entry></row><row><entry /><entry>LBD</entry><entry>b0111</entry><entry>0x7</entry></row><row><entry /><entry>SFU(R)</entry><entry>b1000</entry><entry>0x8</entry></row><row><entry /><entry>TE(TD)</entry><entry>b1001</entry><entry>0x9</entry></row><row><entry /><entry>TE(TFS)</entry><entry>b1010</entry><entry>0xA</entry></row><row><entry /><entry>HCU</entry><entry>b1011</entry><entry>0xB</entry></row><row><entry /><entry>DNC</entry><entry>b1100</entry><entry>0xC</entry></row><row><entry /><entry>LLU</entry><entry>b1101</entry><entry>0xD</entry></row><row><entry /><entry>PCU</entry><entry>b1110</entry><entry>0xE</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2174ReadRoundRobinLevel and ReadRoundRobinEnable registers are encoded in the bit order defined in Table 132.
2175<tables id="TABLE-US-00167" num="00167"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 132</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Read round-robin registers bit order</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="119pt" align="center" /><tbody valign="top"><row><entry /><entry /><entry>Bit</entry></row><row><entry /><entry>Name</entry><entry>index</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="119pt" align="char" char="." /><tbody valign="top"><row><entry /><entry>SCB(R)</entry><entry>0</entry></row><row><entry /><entry>CDU(R)</entry><entry>1</entry></row><row><entry /><entry>CFU</entry><entry>2</entry></row><row><entry /><entry>LBD</entry><entry>3</entry></row><row><entry /><entry>SFU(R)</entry><entry>4</entry></row><row><entry /><entry>TE(TD)</entry><entry>5</entry></row><row><entry /><entry>TE(TFS)</entry><entry>6</entry></row><row><entry /><entry>HCU</entry><entry>7</entry></row><row><entry /><entry>DNC</entry><entry>8</entry></row><row><entry /><entry>LLU</entry><entry>9</entry></row><row><entry /><entry>PCU</entry><entry>10</entry></row><row><entry /><entry>CPU/Refresh</entry><entry>11</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 20.14.9.1 Configuration Register Reset State
2176The RefreshPeriod configuration register has a reset value of 0x063 which ensures that a refresh will occur every 100 cycles and the contents of the DRAM will remain valid.
2177The CPUPreAccessTimeslots and CPUTotalTimeslots configuration registers both have a reset value of 0x0. Matching values in these two registers means that every slot has a CPU pre-acess. NumMainTimeslots is reset to 0x1, so there are just 2 main timeslots in the rotation initially. These slots alternate between SCB writes and PCU reads, as defined by the reset value of MainTimeslot[63:0], thus respecting at reset time the general rule that adjacent non-CPU writes are not permitted.
2178The first access issued by the DIU after reset will be a refresh.
000020.14.9.2 DIU Debug
2179External visibility of the DIU must be provided for debug purposes. To facilitate this debug registers are added to the DIU address space.
2180The DIU CPU system data bus diu_cpu_data[31:0] returns configuration and status register information to the CPU. When a configuration or status register is not being read by the CPU debug data is returned on diu_cpu_data[31:0] instead. An accompanying active high diu_cpu_debug_valid signal is used to indicate when the data bus contains valid debug data. The DIU features a DebugSelect register that controls a local multiplexor to determine which register is output on diu_cpu_data[31:0].
2181Three kinds of debug information are gathered:
2182a. The order and access type of DIU requesters winning arbitration.
2183This information can be obtained by observing the signals in the ArbitrationHistory debug register at DIU_Base+0x304 described in Table 133.
2184<tables id="TABLE-US-00168" num="00168"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 133</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>ArbitrationHistory debug register description, DIU_base + 0x304</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>Field name</entry><entry>Bits</entry><entry>Description</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>arb_gnt</entry><entry>1</entry><entry>Signal lasting 1 cycle which is</entry></row><row><entry /><entry /><entry>asserted in the cycle following a</entry></row><row><entry /><entry /><entry>main arbitration or pre-arbitration.</entry></row><row><entry>arb_executed</entry><entry>1</entry><entry>Signal lasting 1 cycle which indi-</entry></row><row><entry /><entry /><entry>cates that an arbitration result</entry></row><row><entry /><entry /><entry>has actually been executed. Is used</entry></row><row><entry /><entry /><entry>to differentiate between *pre*-</entry></row><row><entry /><entry /><entry>arbitration and *main* arbitration,</entry></row><row><entry /><entry /><entry>both of which cause arb_gnt to be</entry></row><row><entry /><entry /><entry>asserted. If arb_executed and</entry></row><row><entry /><entry /><entry>arb_gnt are both high, then a main</entry></row><row><entry /><entry /><entry>(executed) arbitration is indicated.</entry></row><row><entry>arb_sel</entry><entry>5</entry><entry>Signal indicating which requesting</entry></row><row><entry /><entry /><entry>SoPEC Unit has won arbitration.</entry></row><row><entry /><entry /><entry>Encoding is described in Table .</entry></row><row><entry /><entry /><entry>Refresh winning arbitration is</entry></row><row><entry /><entry /><entry>indicated by access_type.</entry></row><row><entry>timeslot_number</entry><entry>6</entry><entry>Signal indicating which main time-</entry></row><row><entry /><entry /><entry>slot is either currently being</entry></row><row><entry /><entry /><entry>serviced, or about to be serviced.</entry></row><row><entry /><entry /><entry>The latter case applies where a main</entry></row><row><entry /><entry /><entry>slot is preempted by a CPU pre-access</entry></row><row><entry /><entry /><entry>or a scheduled refresh.</entry></row><row><entry>access_type</entry><entry>3</entry><entry>Signal indicating the origin of the</entry></row><row><entry /><entry /><entry>winning arbitration</entry></row><row><entry /><entry /><entry>000 = Standard CPU pre-access.</entry></row><row><entry /><entry /><entry>001 = Scheduled refresh.</entry></row><row><entry /><entry /><entry>010 = Standard non-CPU timeslot.</entry></row><row><entry /><entry /><entry>011 = CPU access via unused read/</entry></row><row><entry /><entry /><entry>write slot, re-allocated by round</entry></row><row><entry /><entry /><entry>robin.</entry></row><row><entry /><entry /><entry>100 = Non-CPU write via unused write</entry></row><row><entry /><entry /><entry>slot, re-allocated at prearbitration.</entry></row><row><entry /><entry /><entry>101 = Non-CPU read via unused read/</entry></row><row><entry /><entry /><entry>write slot, re-allocated by round</entry></row><row><entry /><entry /><entry>robin.</entry></row><row><entry /><entry /><entry>110 = Refresh via unused read/write</entry></row><row><entry /><entry /><entry>slot, re-allocated by round robin.</entry></row><row><entry /><entry /><entry>111 = CPU/Refresh access due to</entry></row><row><entry /><entry /><entry>RotationSync = 0.</entry></row><row><entry>back2back<sub>—</sub></entry><entry>1</entry><entry>Instantaneous indicator of attempted</entry></row><row><entry>non_cpu_write</entry><entry /><entry>illegal back-to-back non-CPU write.</entry></row><row><entry /><entry /><entry>(Recall from section 20.7.2.3 on</entry></row><row><entry /><entry /><entry>page 212 that the second write of</entry></row><row><entry /><entry /><entry>any such pair is disregarded and</entry></row><row><entry /><entry /><entry>re-allocated via the unused read</entry></row><row><entry /><entry /><entry>round-robin scheme.)</entry></row><row><entry>sticky_back2back<sub>—</sub></entry><entry>1</entry><entry>Sticky version of same, cleared on</entry></row><row><entry>non_cpu_write</entry><entry /><entry>reset.</entry></row><row><entry>rotation_sync</entry><entry>1</entry><entry>Current value of the RotationSync</entry></row><row><entry /><entry /><entry>configuration bit.</entry></row><row><entry>rotation_state</entry><entry>2</entry><entry>These bits indicate the current</entry></row><row><entry /><entry /><entry>status of pre-arbitation and main</entry></row><row><entry /><entry /><entry>timeslot rotation, as a result of</entry></row><row><entry /><entry /><entry>the RotationSync setting.</entry></row><row><entry /><entry /><entry>00 = Pre-arb enabled, rotation</entry></row><row><entry /><entry /><entry>enabled.</entry></row><row><entry /><entry /><entry>01 = Pre-arb disabled, rotation</entry></row><row><entry /><entry /><entry>enabled.</entry></row><row><entry /><entry /><entry>10 = Pre-arb disabled, rotation</entry></row><row><entry /><entry /><entry>disabled.</entry></row><row><entry /><entry /><entry>11 = Pre-arb enabled, rotation</entry></row><row><entry /><entry /><entry>disabled.</entry></row><row><entry /><entry /><entry>00 is the normal functional setting</entry></row><row><entry /><entry /><entry>when RotationSync is 1.</entry></row><row><entry /><entry /><entry>01 indicates that pre-arbitration has</entry></row><row><entry /><entry /><entry>halted at the end of its rotation</entry></row><row><entry /><entry /><entry>because of RotationSync having been</entry></row><row><entry /><entry /><entry>cleared. However the main arbitration</entry></row><row><entry /><entry /><entry>has yet to finish its current rota-</entry></row><row><entry /><entry /><entry>tion.</entry></row><row><entry /><entry /><entry>10 indicates that both pre-arb and</entry></row><row><entry /><entry /><entry>the main rotation have halted, due</entry></row><row><entry /><entry /><entry>to RotationSync being 0 and that</entry></row><row><entry /><entry /><entry>only CPU accesses and refreshes</entry></row><row><entry /><entry /><entry>are allowed.</entry></row><row><entry /><entry /><entry>11 indicates that RotationSync has</entry></row><row><entry /><entry /><entry>just been changed from 0 to 1 and</entry></row><row><entry /><entry /><entry>that pre-arbitration is being given</entry></row><row><entry /><entry /><entry>a head start to look ahead for non-</entry></row><row><entry /><entry /><entry>CPU writes, in advance of the main</entry></row><row><entry /><entry /><entry>rotation starting up again.</entry></row><row><entry>sticky_invalid<sub>—</sub></entry><entry>1</entry><entry>Sticky bit to indicate an attempted</entry></row><row><entry>non_cpu_adr</entry><entry /><entry>non-CPU access with an invalid ad-</entry></row><row><entry /><entry /><entry>dress. Cleared by reset or by an</entry></row><row><entry /><entry /><entry>explicit write by the CPU.</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2185<tables id="TABLE-US-00169" num="00169"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 134</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>arb_sel, read_sel and write_sel encoding</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="56pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Index</entry><entry>Index</entry></row><row><entry /><entry>Name</entry><entry>(binary)</entry><entry>(HEX)</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Write</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="56pt" align="left" /><tbody valign="top"><row><entry /><entry>SCB(W)</entry><entry>b0_0000</entry><entry>0x00</entry></row><row><entry /><entry>CDU(W)</entry><entry>b0_0001</entry><entry>0x01</entry></row><row><entry /><entry>SFU(W)</entry><entry>b0_0010</entry><entry>0x02</entry></row><row><entry /><entry>DWU</entry><entry>b0_0011</entry><entry>0x03</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Read</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="56pt" align="left" /><tbody valign="top"><row><entry /><entry>SCB(R)</entry><entry>b0_0100</entry><entry>0x04</entry></row><row><entry /><entry>CDU(R)</entry><entry>b0_0101</entry><entry>0x05</entry></row><row><entry /><entry>CFU</entry><entry>b0_0110</entry><entry>0x06</entry></row><row><entry /><entry>LBD</entry><entry>b0_0111</entry><entry>0x07</entry></row><row><entry /><entry>SFU(R)</entry><entry>b0_1000</entry><entry>0x08</entry></row><row><entry /><entry>TE(TD)</entry><entry>b0_1001</entry><entry>0x09</entry></row><row><entry /><entry>TE(TFS)</entry><entry>b0_1010</entry><entry>0x0A</entry></row><row><entry /><entry>HCU</entry><entry>b0_1011</entry><entry>0x0B</entry></row><row><entry /><entry>DNC</entry><entry>b0_1100</entry><entry>0x0C</entry></row><row><entry /><entry>LLU</entry><entry>b0_1101</entry><entry>0x0D</entry></row><row><entry /><entry>PCU</entry><entry>b0_1110</entry><entry>0x0E</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Refresh</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="56pt" align="left" /><tbody valign="top"><row><entry /><entry>Refresh</entry><entry>b0_1111</entry><entry>0x0F</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>CPU</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="56pt" align="left" /><tbody valign="top"><row><entry /><entry>CPU(R)</entry><entry>b1_0000</entry><entry>0x10</entry></row><row><entry /><entry>CPU(W)</entry><entry>b1_0001</entry><entry>0x11</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2186The encoding for arb_sel is described in Table 134.
2187b. The time between a DIU requester requesting an access and completing the access. This information can be obtained by observing the signals in the DIUPerformance debug register at DIU_Base+0x308 described in Table 135. The encoding for read_sel and write_sel is described in Table. The data collected from DIUPerformance can be post-processed to count the number of cycles between a unit requesting DIU access and the access being completed.
2188<tables id="TABLE-US-00170" num="00170"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 135</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>DIUPerformance debug register description, DIU_base + 0x308</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="42pt" align="center" /><colspec colname="3" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>Field name</entry><entry>Bits</entry><entry>Description</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="42pt" align="char" char="." /><colspec colname="3" colwidth="119pt" align="left" /><tbody valign="top"><row><entry><unit>_diu<sub>—</sub></entry><entry>12</entry><entry>Signal indicating that SoPEC unit</entry></row><row><entry>rreq</entry><entry /><entry>requests DRAM read.</entry></row><row><entry><unit>_diu<sub>—</sub></entry><entry>5</entry><entry>Signal indicating that SoPEC unit</entry></row><row><entry>wreq</entry><entry /><entry>requests DRAM write.</entry></row><row><entry>refresh_req</entry><entry>1</entry><entry>Signal indicating that refresh has</entry></row><row><entry /><entry /><entry>requested a DIU access.</entry></row><row><entry>read_sel[4:0]</entry><entry>5</entry><entry>Signal indicating the SoPEC Unit for</entry></row><row><entry /><entry /><entry>which the current read transaction</entry></row><row><entry /><entry /><entry>is occurring. Encoding is described</entry></row><row><entry /><entry /><entry>in Table .</entry></row><row><entry>read_complete</entry><entry>1</entry><entry>Signal indicating that read trans-</entry></row><row><entry /><entry /><entry>action to SoPEC Unit indicated by</entry></row><row><entry /><entry /><entry>read_sel is complete i.e. that the</entry></row><row><entry /><entry /><entry>last read data has been output by</entry></row><row><entry /><entry /><entry>the DIU.</entry></row><row><entry>write_sel[4:0]</entry><entry>5</entry><entry>Signal indicating the SoPEC Unit for</entry></row><row><entry /><entry /><entry>which the current write transaction</entry></row><row><entry /><entry /><entry>is occurring. Encoding is described</entry></row><row><entry /><entry /><entry>in Table .</entry></row><row><entry>write_complete</entry><entry>1</entry><entry>Signal indicating that write trans-</entry></row><row><entry /><entry /><entry>action to SoPEC Unit indicated by</entry></row><row><entry /><entry /><entry>write_sel is complete i.e. that the</entry></row><row><entry /><entry /><entry>last write data has been transferred</entry></row><row><entry /><entry /><entry>to the DIU.</entry></row><row><entry>dcu_refresh<sub>—</sub></entry><entry>1</entry><entry>Signal indicating that refresh has</entry></row><row><entry>complete</entry><entry /><entry>completed.</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2189c. Interface signals to DIU requestors and DAU-DCU interface.
2190All interface signals with the exception of data busses at the interfaces between the DAU and DCU and DIU write and read requestors can be monitored in debug mode by observing debug registers DIU_Base+0x314 to DIU_Base+0x354.
000020.14.10 DRAM Arbitration Unit (DAU)
2191The DAU is shown in <figref idref="DRAWINGS">FIG. 101</figref>.
2192The DAU is composed of the following sub-blocks
2193a. CPU Configuration and Arbitration Logic sub-block.
2194b. Command Multiplexor sub-block.
2195c. Read and Write Data Multiplexor sub-block.
2196The function of the DAU is to supply DRAM commands to the DCU. <ul id="ul0199" list-style="none"><li id="ul0199-0001" num="0000"><ul id="ul0200" list-style="none"><li id="ul0200-0001" num="2197">The DCU requests a command from the DAU by asserting dcu_dau_adv.</li><li id="ul0200-0002" num="2198">The DAU Command Multiplexor requests the Arbitration Logic sub-block to arbitrate the next DRAM access. The Command Multiplexor passes dcu_dau_adv as the re_arbitrate signal to the Arbitration Logic sub-block.</li><li id="ul0200-0003" num="2199">If the RotationSync bit has been cleared, then the arbitration logic grants exclusive access to the CPU and scheduled refreshes. If the bit has been set, regular arbitration occurs. A detailed description of RotationSync is given in section 20.14.12.2.1 on page 295.</li><li id="ul0200-0004" num="2200">Until the Arbitration Logic has a valid result it stalls the DCU by asserting dau_dcu_msn2stall. The Arbitration Logic then returns the selected arbitration winner to the Command Multiplexor which issues the command to the DRAM. The Arbitration Logic could stall for example if it selected a shared read bus access but the Read Multiplexor indicated it was busy by de-asserting read_cmd_rdy[1].</li><li id="ul0200-0005" num="2201">In the case of a read command the read data from the DRAM is multiplexed back to the read requestor by the Read Multiplexor. In the case of a write operation the Write Multiplexor multiplexes the write data from the selected DIU write requester to the DCU before the write command can occur. If the write data is not available then the Command Multiplexor will keep dau_dcu_valid de-asserted. This will stall the DCU until the write command is ready to be issued.</li><li id="ul0200-0006" num="2202">Arbitration for non-CPU writes occurs in advance. The DCU provides a signal dcu_dau_wadv which the Command Multiplexor issues to the Arbitrate Logic as re_arbitrate_wadv. If arbitration is blocked by the Write Multiplexor being busy, as indicated by write_cmd_rdy[1] being de-asserted, then the Arbitration Logic will stall the DCU by asserting dau_dcu_msn2stall until the Write Multiplexor is ready. <br /> 20.14.10.1 Read Accesses </li></ul></li></ul>
2203The timing of a non-CPU DIU read access are shown in <figref idref="DRAWINGS">FIG. 109</figref>. Note re_arbitrate is asserted in the MSN2 state of the previous access.
2204Note the fixed timing relationship between the read acknowledgment and the first rvalid for all non-CPU reads. This means that the second and any later reads in a back-to-back non-CPU sequence have their acknowledgments asserted one cycle later, i.e. in the “MSN1” DCU state. The timing of a CPU DIU read access is shown in <figref idref="DRAWINGS">FIG. 110</figref>. Note re_arbitrate is asserted in the MSN2 state of the previous access.
2205Some points can be noted from <figref idref="DRAWINGS">FIG. 109</figref> and <figref idref="DRAWINGS">FIG. 110</figref>.
2206DIU requests: <ul id="ul0201" list-style="none"><li id="ul0201-0001" num="0000"><ul id="ul0202" list-style="none"><li id="ul0202-0001" num="2207">For non-CPU accesses the <unit>_diu_rreq signals are registered before the arbitration can occur.</li><li id="ul0202-0002" num="2208">For CPU accesses the cpu_diu_rreq signal is not registered to reduce CPU DIU access latency.</li></ul></li></ul>
2209Arbitration occurs when the dcu_dau_adv signal from the DCU is asserted. The DRAM address for the arbitration winner is available in the next cycle, the RST state of the DCU.
2210The DRAM access starts in the MSN1 state of the DCU and completes in the RST state of the DCU.
2211Read data is available: <ul id="ul0203" list-style="none"><li id="ul0203-0001" num="0000"><ul id="ul0204" list-style="none"><li id="ul0204-0001" num="2212">In the MSN2 cycle where it is output unregistered to the CPU</li><li id="ul0204-0002" num="2213">In the MSN2 cycle and registered in the DAU before being output in the next cycle to all other read requesters in order to ease timing.</li></ul></li></ul>
2214The DIU protocol is in fact: <ul id="ul0205" list-style="none"><li id="ul0205-0001" num="0000"><ul id="ul0206" list-style="none"><li id="ul0206-0001" num="2215">Pipelined i.e. the following transaction is initiated while the previous transfer is in progress.</li><li id="ul0206-0002" num="2216">Split transaction i.e. the transaction is split into independent address and data transfers.</li></ul></li></ul>
2217Some general points should be noted in the case of CPU accesses: <ul id="ul0207" list-style="none"><li id="ul0207-0001" num="0000"><ul id="ul0208" list-style="none"><li id="ul0208-0001" num="2218">Since the CPU request is not registered in the DIU before arbitration, then the CPU must generate the request, route it to the DAU and complete arbitration all in 1 cycle. To facilitate this CPU access is arbitrated late in the arbitration cycle (see Section 20.14.12.2).</li><li id="ul0208-0002" num="2219">Since the CPU read data is not registered in the DAU and CPU read data is available 8 ns after the start of the access then 4.5 ns are available for routing and any shallow logic before the CPU read data is captured by the CPU (see Section 20.14.4).</li></ul></li></ul>
2220The phases of CPU DIU read access are shown in <figref idref="DRAWINGS">FIG. 111</figref>. This matches the timing shown in Table 135.
000020.14.10.2 Write Accesses
2221CPU writes are posted into a 1-deep write buffer in the DIU and written to DRAM as shown below in <figref idref="DRAWINGS">FIG. 112</figref>.
2222The sequence of events is as follows:— <ul id="ul0209" list-style="none"><li id="ul0209-0001" num="0000"><ul id="ul0210" list-style="none"><li id="ul0210-0001" num="2223">[1] The DIU signals that its buffer for CPU posted writes is empty (and has been for some time in the case shown).</li><li id="ul0210-0002" num="2224">[2] The CPU asserts “cpu_diu_wdatavalid” to enable a write to the DIU buffer and presents valid address, data and write mask. The CPU considers the write posted and thus complete in the cycle following [2] in the diagram below.</li><li id="ul0210-0003" num="2225">[3] The DIU stores the address/data/mask in its buffer and indicates to the arbitration logic that a posted write wishes to participate in any upcoming arbitration.</li><li id="ul0210-0004" num="2226">[4] Provided the CPU still has a pre-access entitlement left, or is next in line for a round-robin award, a slot is arbitrated in favour of the posted write. Note that posted CPU writes have higher arbitration priority than simultaneous CPU reads.</li><li id="ul0210-0005" num="2227">[5] The DRAM write occurs.</li><li id="ul0210-0006" num="2228">[6] The earliest that “diu_cpu_write_rdy” can be re-asserted in the “MSN1” state of the DRAM write. In the same cycle, having seen the re-assertion, the CPU can asynchronously turn around “cpu_diu_wdatavalid” and enable a subsequent posted write, should it wish to do so. The timing of a non-CPU/non-CDU DIU write access is shown below in <figref idref="DRAWINGS">FIG. 113</figref>.</li></ul></li></ul>
2229Compared to a read access, write data is only available from the requester 4 cycles after the address. An extra cycle is used to ensure that data is first registered in the DAU, before being despatched to DRAM. As a result, writes are pre-arbitrated 5 cycles in advance of the main arbitration decision to actually write the data to memory.
2230The diagram above shows the following sequence of events:— <ul id="ul0211" list-style="none"><li id="ul0211-0001" num="0000"><ul id="ul0212" list-style="none"><li id="ul0212-0001" num="2231">[1] A non-CPU block signals a write request.</li><li id="ul0212-0002" num="2232">[2] A registered version of this is available to the DAU arbitration logic.</li><li id="ul0212-0003" num="2233">[3] Write pre-arbitration occurs in favour of the requester.</li><li id="ul0212-0004" num="2234">[4] A write acknowledgment is returned by the DIU.</li><li id="ul0212-0005" num="2235">[5] The pre-arbitration will only be upheld if the requester supplies 4 consecutive write data quarter-words, qualified by an asserted wvalid flag.</li><li id="ul0212-0006" num="2236">[6] Provided this has happened, the main arbitration logic is in a position at [6] to reconfirm the pre-arbitration decision. Note however that such reconfirmation may have to wait a further one or two DRAM accesses, if the write is pre-empted by a CPU pre-access and/or a scheduled refresh.</li><li id="ul0212-0007" num="2237">[7] This is the earliest that the write to DRAM can occur.</li><li id="ul0212-0008" num="2238">Note that neither the arbitration at [8] nor the pre-arbitration at [9] can award its respective slot to a non-CPU write, due to the ban on back-to-back accesses.</li></ul></li></ul>
2239The timing of a CDU DIU write access is shown overleaf in <figref idref="DRAWINGS">FIG. 114</figref>.
2240This is simular to a regular non-CPU write access, but uses page mode to carry out 4 consecutive DRAM writes to contiguous addresses. As a consequence, subsequent accesses are delayed by 6 cycles, as shown in the diagram. Note that a new write can be pre-arbitrated at [10] in <figref idref="DRAWINGS">FIG. 114</figref>.
000020.14.11 Command Multiplexor Sub-block
2241<tables id="TABLE-US-00171" num="00171"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 136</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Command Multiplexor Sub-block IO Definition</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>Port name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Clocks and Resets</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>pclk</entry><entry>1</entry><entry>In</entry><entry>System Clock</entry></row><row><entry>prst_n</entry><entry>1</entry><entry>In</entry><entry>System reset, synchronous active</entry></row><row><entry /><entry /><entry /><entry>low</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>DIU Read Interface to SoPEC Units</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry><unit>_diu<sub>—</sub></entry><entry>17</entry><entry>In</entry><entry>Read address to DIU</entry></row><row><entry>radr[21:5]</entry><entry /><entry /><entry>17 bits wide (256-bit aligned</entry></row><row><entry /><entry /><entry /><entry>word).</entry></row><row><entry>diu_<unit><sub>—</sub></entry><entry>1</entry><entry>Out</entry><entry>Acknowledge from DIU that read</entry></row><row><entry>rack</entry><entry /><entry /><entry>request has been accepted and</entry></row><row><entry /><entry /><entry /><entry>new read address can be placed</entry></row><row><entry /><entry /><entry /><entry>on <unit>_diu_radr</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>DIU Write Interface to SoPEC Units</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry><unit>_diu<sub>—</sub></entry><entry>17</entry><entry>In</entry><entry>Write address to DIU except CPU,</entry></row><row><entry>wadr[21:5]</entry><entry /><entry /><entry>SCB, CDU</entry></row><row><entry /><entry /><entry /><entry>17 bits wide (256-bit aligned</entry></row><row><entry /><entry /><entry /><entry>word)</entry></row><row><entry>cpu_diu<sub>—</sub></entry><entry>22</entry><entry>In</entry><entry>CPU Write address to DIU</entry></row><row><entry>wadr[21:4]]</entry><entry /><entry /><entry>(128-bit aligned address.)</entry></row><row><entry>cpu_diu<sub>—</sub></entry><entry>16</entry><entry>In</entry><entry>Byte enables for CPU write.</entry></row><row><entry>wmask</entry></row><row><entry>cdu_diu<sub>—</sub></entry><entry>19</entry><entry>In</entry><entry>CDU Write address to DIU</entry></row><row><entry>wadr[21:3]</entry><entry /><entry /><entry>19 bits wide (64-bit aligned</entry></row><row><entry /><entry /><entry /><entry>word)</entry></row><row><entry /><entry /><entry /><entry>Addresses cannot cross a</entry></row><row><entry /><entry /><entry /><entry>256-bit word DRAM boundary.</entry></row><row><entry>diu_<unit><sub>—</sub></entry><entry>1</entry><entry>Out</entry><entry>Acknowledge from DIU that write</entry></row><row><entry>wack</entry><entry /><entry /><entry>request has been accepted and</entry></row><row><entry /><entry /><entry /><entry>new write address can be placed</entry></row><row><entry /><entry /><entry /><entry>on <unit>_diu_wadr</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Outputs to CPU Interface and Arbitration Logic sub-block</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>re_arbitrate</entry><entry>1</entry><entry>Out</entry><entry>Signalling telling the arbitration</entry></row><row><entry /><entry /><entry /><entry>logic to choose the next arbi-</entry></row><row><entry /><entry /><entry /><entry>tration winner.</entry></row><row><entry>re_arbitrate<sub>—</sub></entry><entry>1</entry><entry>Out</entry><entry>Signal telling the arbitration</entry></row><row><entry>wadv</entry><entry /><entry /><entry>logic to choose the next arbi-</entry></row><row><entry /><entry /><entry /><entry>tration winner for non-CPU</entry></row><row><entry /><entry /><entry /><entry>writes 2 timeslots in advance</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Debug Outputs to CPU Configuration and Arbitration Logic Sub-block</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>write_sel</entry><entry>5</entry><entry>Out</entry><entry>Signal indicating the SoPEC Unit</entry></row><row><entry /><entry /><entry /><entry>for which the current write trans-</entry></row><row><entry /><entry /><entry /><entry>action is occurring. Encoding is</entry></row><row><entry /><entry /><entry /><entry>described in Table .</entry></row><row><entry>write<sub>—</sub></entry><entry>1</entry><entry>Out</entry><entry>Signal indicating that write trans-</entry></row><row><entry>complete</entry><entry /><entry /><entry>action to SoPEC Unit indicated by</entry></row><row><entry /><entry /><entry /><entry>write_sel is complete.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Inputs from CPU Interface and Arbitration Logic sub-block</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>arb_gnt</entry><entry>1</entry><entry>In</entry><entry>Signal lasting 1 cycle which indi-</entry></row><row><entry /><entry /><entry /><entry>cates arbitration has occurred</entry></row><row><entry /><entry /><entry /><entry>and arb_sel is valid.</entry></row><row><entry>arb_sel</entry><entry>5</entry><entry>In</entry><entry>Signal indicating which requesting</entry></row><row><entry /><entry /><entry /><entry>SoPEC Unit has won arbitration.</entry></row><row><entry /><entry /><entry /><entry>Encoding is described in Table .</entry></row><row><entry>dir_sel</entry><entry>2</entry><entry>In</entry><entry>Signal indicating which sense of</entry></row><row><entry /><entry /><entry /><entry>access associated with arb_sel</entry></row><row><entry /><entry /><entry /><entry>00: issue non-CPU write</entry></row><row><entry /><entry /><entry /><entry>01: read winner</entry></row><row><entry /><entry /><entry /><entry>10: write winner</entry></row><row><entry /><entry /><entry /><entry>11: refresh winner</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Inputs from Read Write Multiplexor Sub-block</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>write_data<sub>—</sub></entry><entry>2</entry><entry>In</entry><entry>Signal indicating that valid write</entry></row><row><entry>valid</entry><entry /><entry /><entry>data is available for the current</entry></row><row><entry /><entry /><entry /><entry>command.</entry></row><row><entry /><entry /><entry /><entry>00 = not valid</entry></row><row><entry /><entry /><entry /><entry>01 = CPU write data valid</entry></row><row><entry /><entry /><entry /><entry>10 = non-CPU write data valid</entry></row><row><entry /><entry /><entry /><entry>11 = both CPU and non-CPU</entry></row><row><entry /><entry /><entry /><entry>write data valid</entry></row><row><entry>wdata</entry><entry>256</entry><entry>In</entry><entry>256-bit non-CPU write data</entry></row><row><entry>cpu_wdata</entry><entry>32</entry><entry>In</entry><entry>32-bit CPU write data</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Outputs to Read Write Multiplexor Sub-block</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>write_data<sub>—</sub></entry><entry>2</entry><entry>Out</entry><entry>Signal indicating the Command</entry></row><row><entry>accept</entry><entry /><entry /><entry>Multiplexor has accepted the</entry></row><row><entry /><entry /><entry /><entry>write data from the write</entry></row><row><entry /><entry /><entry /><entry>multiplexor</entry></row><row><entry /><entry /><entry /><entry>00 = not valid</entry></row><row><entry /><entry /><entry /><entry>01 = accepts CPU write data</entry></row><row><entry /><entry /><entry /><entry>10 = accepts non-CPU write data</entry></row><row><entry /><entry /><entry /><entry>11 = not valid</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Inputs from DCU</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>dcu_dau<sub>—</sub></entry><entry>1</entry><entry>In</entry><entry>Signal indicating to DAU to</entry></row><row><entry>adv</entry><entry /><entry /><entry>supply next command to DCU</entry></row><row><entry>dcu_dau<sub>—</sub></entry><entry>1</entry><entry>In</entry><entry>Signal indicating to DAU to</entry></row><row><entry>wadv</entry><entry /><entry /><entry>initiate next non-CPU write</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Outputs to DCU</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>dau_dcu<sub>—</sub></entry><entry>17</entry><entry>Out</entry><entry>Signal indicating the address</entry></row><row><entry>adr[21:5]</entry><entry /><entry /><entry>for the DRAM access. This is a</entry></row><row><entry /><entry /><entry /><entry>256-bit aligned DRAM address.</entry></row><row><entry>dau_dcu<sub>—</sub></entry><entry>1</entry><entry>Out</entry><entry>Signal indicating the direction</entry></row><row><entry>rwn</entry><entry /><entry /><entry>for the DRAM access (1 =</entry></row><row><entry /><entry /><entry /><entry>read, 0 = write).</entry></row><row><entry>dau_dcu<sub>—</sub></entry><entry>1</entry><entry>Out</entry><entry>Signal indicating if access is</entry></row><row><entry>cduwpage</entry><entry /><entry /><entry>a CDU write page mode access</entry></row><row><entry /><entry /><entry /><entry>(1 = CDU page mode,</entry></row><row><entry /><entry /><entry /><entry>0 = not CDU page mode).</entry></row><row><entry>dau_dcu<sub>—</sub></entry><entry>1</entry><entry>Out</entry><entry>Signal indicating that a refresh</entry></row><row><entry>refresh</entry><entry /><entry /><entry>command is to be issued. If asserted</entry></row><row><entry /><entry /><entry /><entry>dau_dcu_adr, dau_dcu_rwn and</entry></row><row><entry /><entry /><entry /><entry>dau_dcu_cduwpage are ignored.</entry></row><row><entry>dau_dcu<sub>—</sub></entry><entry>256</entry><entry>Out</entry><entry>256-bit write data to DCU</entry></row><row><entry>wdata</entry></row><row><entry>dau_dcu<sub>—</sub></entry><entry>32</entry><entry>Out</entry><entry>Byte encoded write data mask for</entry></row><row><entry>wmask</entry><entry /><entry /><entry>256-bit dau_dcu_wdata to DCU</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 20.14.11.1 Command Multiplexor Sub-block Description
2242The Command Multiplexor sub-block issues read, write or refresh commands to the DCU, according to the SoPEC Unit selected for DRAM access by the Arbitration Logic. The Command Multiplexor signals the Arbitration Logic to perform arbitration to select the next SoPEC Unit for DRAM access. It does this by asserting the re_arbitrate signal. re_arbitrate is asserted when the DCU indicates on dcu_dau_adv that it needs the next command.
2243The Command Multiplexor is shown in <figref idref="DRAWINGS">FIG. 115</figref>.
2244Initially, the issuing of commands is described. Then the additional complexity of handling non-CPU write commands arbitrated in advance is introduced.
0000DAU-DCU Interface
2245See Section 20.14.5 for a description of the DAU-DCU interface.
0000Generating re_arbitrate
2246The condition for asserting re_arbitrate is that the DCU is looking for another command from the DAU. This is indicated by dcu_dau_adv being asserted. <br /><i>re</i>_arbitrate=<i>dcu</i><sub>—</sub><i>dau</i><sub>—</sub><i>adv</i><br /> Interface to SoPEC DIU Requestors
2247When the Command Multiplexor initiates arbitration by asserting re_arbitrate to the Arbitration Logic sub-block, the arbitration winner is indicated by the arb_sel[4:0] and dir_sel[1:0] signals returned from the Arbitration Logic. The validity of these signals is indicated by arb_gnt. The encoding of arb_sel[4:0] is shown in Table.
2248The value of arb_sel[4:0] is used to control the steering multiplexor to select the DIU address of the winning arbitration requestor. The arb_gnt signal is decoded as an acknowledge, diu_<unit>_*ack back to the winning DIU requestor. The timing of these operations is shown in <figref idref="DRAWINGS">FIG. 116</figref>. adr[21:0] is the output of the steering multiplexor controlled by arb_sel[4:0]. The steering multiplexor can acknowledge DIU requestors in successive cycles.
0000Command Issuing Logic
2249The address presented by the winning SoPEC requestor from the steering multiplexor is presented to the command issuing logic together with arb_sel[4:0] and dir_sel[1:0].
2250The command issuing logic translates the winning command into the signals required by the DCU. adr<sub>—</sub>[21:0], arb_sel[4:0] and dir_sel[1:0] comes from the steering multiplexor. <br /><i>dau</i><sub>—</sub><i>dcu</i><sub>—</sub><i>adr</i>[21:5<i>]=adr</i>[21:5]
2251<tables id="TABLE-US-00172" num="00172"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>dau_dcu_rwn = (dir_sel[1:0] = = read)</entry></row><row><entry /><entry>dau_dcu_cduwpage = (arb_sel[4:0] = = CDU write)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>dau_dcu_refresh = (dir sel[1:0]= = refresh)</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> dau_dcu_valid indicates that a valid command is available to the DCU.
2252For a write command, dau_dcu_valid will not be asserted until there is also valid write data present. This is indicated by the signal write_data_valid[1:0] from the Read Write Data Multiplexor sub-block.
2253For a write command, the data issued to the DCU on dau_dcu_wdata[255:0] is multiplexed from cpu_wdata[31:0] and wdata[255:0] depending on whether the write is a CPU or non-CPU write. The write data from the Write Multiplexor for the CDU is available on wdata[63:0]. This data must be issued to the DCU on dau_dcu_wdata[255:0]. wdata[63:0] is copied to each 64-bit word of dau_dcu_wdata[255:0].
2254<tables id="TABLE-US-00173" num="00173"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>dau_dcu_wdata[255:0] = 0x00000000</entry></row><row><entry /><entry>if (arb_sel[4:0]= =CPU write) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>dau_dcu_wdata[31:0] = cpu_wdata[31:0]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (arb_sel[4:0]= =CDU write)) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>dau_dcu_wdata[63:0] = wdata[63:0]</entry></row><row><entry /><entry>dau_dcu_wdata[127:64] = wdata[63:0]</entry></row><row><entry /><entry>dau_dcu_wdata[191:128] = wdata[63:0]</entry></row><row><entry /><entry>dau_dcu_wdata[255:192] = wdata[63:0]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>dau_dcu_wdata[255:0] = wdata[255:0]</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> CPU Write Masking
2255The CPU write data bus is only 128 bits wide. cpu_diu_wmask[15:0] indicates how many bytes of that 128 bits should be written. The associated address cpu_diu_wadr[21:4] is a 128-bit aligned address. The actual DRAM write must be a 256-bit access. The command multiplexor issues the 256-bit DRAM address to the DCU on dau_dcu_adr[21:5]. cpu_diu_wadr[4] and cpu_diu_wmask[15:0] are used jointly to construct a byte write mask dau_dcu_wmask[31:0] for this 256-bit write access.
0000CDU Write Masking
2256The CPU performs four 64-bit word writes to 4 contiguous 256-bit DRAM addresses with the first address specified by cdu_diu_wadr[21:3]. The write address cdu_diu_wadr[21:5] is 256-bit aligned with bits cdu_diu_wadr[44:3] allowing the 64-bit word to be selected. If these 4 DRAM words lie in the same DRAM row then an efficient access will be obtained.
2257The command multiplexor logic must issue 4 successive accesses to 256-bit DRAM addresses cdu_diu_wadr[21:5],+1,+2,+3.
2258dau_dcu_wmask[31:0] indicates which 8 bytes (64-bits) of the 256-bit word are to be written.
2259dau_dcu_wmask[31:0] is calculated using cdu_diu_wadr[4:3] i.e. bits <b>8</b>*cdu_diu_wadr[4:3] to <b>8</b>*(cdu_diu_wadr[4:3]+1)−1 of dau_dcu_wmask[31:0]are asserted.
0000Arbitrating Non-CPU Writes in Advance
2260In the case of a non-CPU write commands, the write data must be transferred from the SoPEC requester before the write can occur. Arbitration should occur early to allow for any delay for the write data to be transferred to the DRAM.
2261<figref idref="DRAWINGS">FIG. 113</figref> indicates that write data transfer over 64-bit busses will take a further 4 cycles after the address is transferred. The arbitration must therefore occur 4 cycles in advance of arbitration for read accesses, <figref idref="DRAWINGS">FIG. 109</figref> and <figref idref="DRAWINGS">FIG. 110</figref>, or for CPU writes <figref idref="DRAWINGS">FIG. 112</figref>. Arbitration of CDU write accesses, <figref idref="DRAWINGS">FIG. 114</figref>, should take place 1 cycle in advance of arbitration for read and CPU write accesses. To simplify implementation CDU write accesses are arbitrated 4 cycles in advance, similar to other non-CPU writes.
2262The Command Multiplexor generates another version of re_arbitrate called re_arbitrate_wadv based on the signal dcu_dau_wadv from the DCU. In the 3 cycle DRAM access dcu_dau_adv and therefore re_arbitrate are asserted in the MSN2 state of the DCU state-machine. dcu_dau_wadv and therefore re_arbitrate_wadv will therefore be asserted in the following RST state, see <figref idref="DRAWINGS">FIG. 117</figref>. This matches the timing required for non-CPU writes shown in <figref idref="DRAWINGS">FIG. 113</figref> and <figref idref="DRAWINGS">FIG. 114</figref>. <ul id="ul0213" list-style="none"><li id="ul0213-0001" num="0000"><ul id="ul0214" list-style="none"><li id="ul0214-0001" num="2263">re_arbitrate_wadv causes the Arbitration Logic to perform an arbitration for non-CPU in advance.</li></ul></li></ul>
2264<tables id="TABLE-US-00174" num="00174"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>re_arbitrate = dcu_dau_adv</entry></row><row><entry /><entry>re_arbitrate_wadv = dcu dau_wadv</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2265If the winner of this arbitration is a non-CPU write then arb_gnt is asserted and the arbitration winner is output on arb_sel[4:0] and dir_sel[1:0]. Otherwise arb_gnt is not asserted.
2266Since non-CPU write commands are arbitrated early, the non-CPU command is not issued to the DCU immediately but instead written into an advance command register.
2267<tables id="TABLE-US-00175" num="00175"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>if (arb sel(4:0 = = non-CPU write) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>advance_cmd_register[3:0] = arb_sel[4:0]</entry></row><row><entry /><entry>advance_cmd_register[5:4] = dir_sel[1:0]</entry></row><row><entry /><entry>advance_cmd_register[27:6] = adr[21:0]</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2268If a DCU command is in progress then the arbitration in advance of a non-CPU write command will overwrite the steering multiplexor input to the command issuing logic. The arbitration in advance happens in the DCU MSN1 state. The new command is available at the steering multiplexor in the MSN2 state. The command in progress will have been latched in the DRAM by MSN falling at the start of the MSN1 state.
0000Issuing Non-CPU Write Commands
2269The arb_sel[4:0] and dir<sub>—</sub>[1:0] values generated by the Arbitration Logic reflect the out of order arbitration sequence.
2270This out of order arbitration sequence is exported to the Read Write Data Multiplexor sub-block. This is so that write data in available in time for the actual write operation to DRAM. Otherwise a latency would be introduced every time a write command is selected.
2271However, the Command Multiplexor must execute the command stream in-order. In-order command execution is achieved by waiting until re_arbitrate has advanced to the non-CPU write timeslot from which re_arbitrate_wadv has previously issued a non-CPU write written to the advance command register.
2272If re_arbitrate_wadv arbitrates a non-CPU write in advance then within the Arbitration Logic the timeslot is marked to indicate whether a write was issued.
2273When re_arbitrate advances to a write timeslot in the Arbitration Logic then one of two actions can occur depending on whether the slot was marked by re_arbitrate_wadv to indicate whether a write was issued or not. <ul id="ul0215" list-style="none"><li id="ul0215-0001" num="0000"><ul id="ul0216" list-style="none"><li id="ul0216-0001" num="2274">Non-CPU write arbitrated by re_arbitrate_wadv</li></ul></li></ul>
2275If the timeslot has been marked as having issued a write then the arbitration logic responds to re_arbitrate by issuing arb_sel[4:0], dir_sel[1:0] and asserting arb_gnt as for a normal arbitration but selecting a non-CPU write access. Normally, re_arbitrate does not issue non-CPU write accesses. Non-CPU writes are arbitrated by re_arbitrate_wadv. dir_sel[1:0]==00 indicates a non-CPU write issued by re_arbitrate.
2276The command multiplexor does not write the command into the advance command register as it has already been placed there earlier by re_arbitrate_wadv. Instead, the already present write command in the advance command register is issued when write_data_valid[1]=1. Note, that the value of arb_sel[4:0] issued by re_arbitrate could specify a different write than that in the advance command register since time has advanced. It is always the command in the advance command register that is issued. The steering multiplexor in this case must not issue an acknowledge back to SoPEC requester indicated by the value of arb_sel[4:0].
2277<tables id="TABLE-US-00176" num="00176"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>if (dir_sel[1:0] = = 00) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="126pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><tbody valign="top"><row><entry /><entry>command_issuing_logic[27:0]</entry><entry>= =</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>advance_cmd_register[27:0]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="126pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><tbody valign="top"><row><entry /><entry>command_is_suing_logic[27:0]</entry><entry>= =</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>steering_multiplexor[27:0]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>ack = arb_gnt AND NOT (dir_sel[1:0] = = 00)</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><ul id="ul0217" list-style="none"><li id="ul0217-0001" num="0000"><ul id="ul0218" list-style="none"><li id="ul0218-0001" num="2278">Non-CPU write not arbitrated by re_arbitrate_wadv</li></ul></li></ul>
2279If the timeslot has been marked as not having issued a write, the re_arbitrate will use the un-used read timeslot selection to replace the un-used write timeslot with a read timeslot according to Section 20.10.6.2 Unused read timeslots allocation.
2280The mechanism for write timeslot arbitration selects non-CPU writes in advance. But the selected non-CPU write is stored in the Command Multiplexor and issued when the write data is available.
2281This means that even if this timeslot is overwritten by the CPU reprogramming the timeslot before the write command is actually issued to the DRAM, the originally arbitrated non-CPU write will always be correctly issued.
0000Accepting Write Commands
2282When a write command is issued then write_data_accept[1:0] is asserted. This tells the Write Multiplexor that the current write data has been accepted by the DRAM and the write multiplexor can receive write data from the next arbitration winner if it is a write. write_data_accept[1:0] differentiates between CPU and non-CPU writes. A write command is known to have been issued when re_arbitrate_wadv to decide on the next command is detected.
2283In the case of CDU writes the DCU will generate a signal dcu_dau_cduwaccept which tells the Command Multiplexor to issue a write_data_accept[1]. This will result in the Write Multiplexor supplying the next CDU write data to the DRAM.
2284<tables id="TABLE-US-00177" num="00177"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>write_data_accept[0] = RISING EDGE(re_arbitrate_wadv)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="112pt" align="left" /><colspec colname="1" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry>AND</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>command_issuing_logic(dir_sel[1]= =1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="126pt" align="left" /><colspec colname="1" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry>AND</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>command_issuing_logic(arb_sel[4:0]= =CPU)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>write_data_accept[1] = (RISING EDGE(re_arbitrate_wadv)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="126pt" align="left" /><colspec colname="1" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry>AND</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>command_issuing_logic(dir_sel[1]= =1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="126pt" align="left" /><colspec colname="1" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry>AND</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>command_issuing_logic(arb_sel[4:0]= =non_CPU))</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="112pt" align="left" /><colspec colname="1" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry>OR</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>dcu_dau_cduwaccept= =1</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2285Debug logic output to CPU Configuration and Arbitration Logic sub-block write_sel[4:0] reflects the value of arb_sel[4:0] at the command issuing logic. The signal write complete is asserted when every any bit of write_data_accept[1:0] is asserted.
2286<tables id="TABLE-US-00178" num="00178"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="28pt" align="left" /><colspec colname="3" colwidth="70pt" align="left" /><colspec colname="4" colwidth="28pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="4" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>write_complete</entry><entry>=</entry><entry>write_data_accept[0]</entry><entry>OR</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>write data accept[0]</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> write_sel[4:0] and write_complete are CPU readable from the DIUPerformance nad WritePerformance status registers. When write_complete is asserted write_sel[4:0] will indicate which write access the DAU has issued. <br /> 20.14.12 CPU Configuration and Arbitration Logic Sub-block
2287<tables id="TABLE-US-00179" num="00179"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 137</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>CPU Configuration and Arbitration Logic Sub-block IO Definition</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>Port name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Clocks and Resets</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>Pclk</entry><entry>1</entry><entry>In</entry><entry>System Clock</entry></row><row><entry>prst_n</entry><entry>1</entry><entry>In</entry><entry>System reset, synchronous</entry></row><row><entry /><entry /><entry /><entry>active low</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>CPU Interface data and control signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>cpu_adr[10:2]</entry><entry>9</entry><entry>In</entry><entry>9 bits (bits 10:2) are required</entry></row><row><entry /><entry /><entry /><entry>to decode the configuration</entry></row><row><entry /><entry /><entry /><entry>register address space.</entry></row><row><entry>cpu_dataout</entry><entry>32</entry><entry>In</entry><entry>Shared write data bus from the</entry></row><row><entry /><entry /><entry /><entry>CPU for DRAM and configuration</entry></row><row><entry /><entry /><entry /><entry>data</entry></row><row><entry>diu_cpu_data</entry><entry>32</entry><entry>Out</entry><entry>Configuration, status and debug</entry></row><row><entry /><entry /><entry /><entry>read data bus to the CPU</entry></row><row><entry>diu_cpu<sub>—</sub></entry><entry>1</entry><entry>Out</entry><entry>Signal indicating the data on</entry></row><row><entry>debug_valid</entry><entry /><entry /><entry>the diu_cpu_data bus is valid</entry></row><row><entry /><entry /><entry /><entry>debug data.</entry></row><row><entry>cpu_rwn</entry><entry>1</entry><entry>In</entry><entry>Common read/not-write signal</entry></row><row><entry /><entry /><entry /><entry>from the CPU</entry></row><row><entry>cpu_acode</entry><entry>2</entry><entry>In</entry><entry>CPU access code signals.</entry></row><row><entry /><entry /><entry /><entry>cpu_acode[0] - Program (0)/</entry></row><row><entry /><entry /><entry /><entry>Data (1) access</entry></row><row><entry /><entry /><entry /><entry>cpu_acode[1] - User (0)/</entry></row><row><entry /><entry /><entry /><entry>Supervisor (1) access</entry></row><row><entry /><entry /><entry /><entry>The DAU will only allow supervisor</entry></row><row><entry /><entry /><entry /><entry>mode accesses to data space.</entry></row><row><entry>cpu_diu_sel</entry><entry>1</entry><entry>In</entry><entry>Block select from the CPU. When</entry></row><row><entry /><entry /><entry /><entry>cpu_diu_sel is high both cpu_adr</entry></row><row><entry /><entry /><entry /><entry>and cpu_dataout are valid</entry></row><row><entry>diu_cpu_rdy</entry><entry>1</entry><entry>Out</entry><entry>Ready signal to the CPU. When</entry></row><row><entry /><entry /><entry /><entry>diu_cpu_rdy is high it indicates</entry></row><row><entry /><entry /><entry /><entry>the last cycle of the access.</entry></row><row><entry /><entry /><entry /><entry>For a write cycle this means</entry></row><row><entry /><entry /><entry /><entry>cpu_dataout has been registered</entry></row><row><entry /><entry /><entry /><entry>by the block and for a read</entry></row><row><entry /><entry /><entry /><entry>cycle this means the data on</entry></row><row><entry /><entry /><entry /><entry>diu_cpu_data is valid.</entry></row><row><entry>diu_cpu_berr</entry><entry>1</entry><entry>Out</entry><entry>Bus error signal to the CPU</entry></row><row><entry /><entry /><entry /><entry>indicating an invalid access.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>DIU Read Interface to SoPEC Units</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry><unit>_diu<sub>—</sub></entry><entry>11</entry><entry>In</entry><entry>SoPEC unit requests DRAM read.</entry></row><row><entry>rreq</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>DIU Write Interface to SoPEC Units</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>diu_cpu<sub>—</sub></entry><entry>1</entry><entry>In</entry><entry>Indicator that CPU posted write</entry></row><row><entry>write_rdy</entry><entry /><entry /><entry>buffer is empty.</entry></row><row><entry><unit>_diu<sub>—</sub></entry><entry>4</entry><entry>In</entry><entry>Non- CPU SoPEC unit requests</entry></row><row><entry>wreq</entry><entry /><entry /><entry>DRAM write.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Inputs from Command Multiplexor sub-block</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>re_arbitrate</entry><entry>1</entry><entry>In</entry><entry>Signal telling the arbitration</entry></row><row><entry /><entry /><entry /><entry>logic to choose the next</entry></row><row><entry /><entry /><entry /><entry>arbitration winner.</entry></row><row><entry>re_arbitrate<sub>—</sub></entry><entry>1</entry><entry>In</entry><entry>Signal telling the arbitration</entry></row><row><entry>wadv</entry><entry /><entry /><entry>logic to choose the next</entry></row><row><entry /><entry /><entry /><entry>arbitration winner for non-CPU</entry></row><row><entry /><entry /><entry /><entry>writes 2 timeslots in advance</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Outputs to DCU</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>dau_dcu<sub>—</sub></entry><entry>1</entry><entry>Out</entry><entry>Signal indicating from DAU</entry></row><row><entry>msn2stall</entry><entry /><entry /><entry>Arbitration Logic which when</entry></row><row><entry /><entry /><entry /><entry>asserted stalls DCU in MSN2</entry></row><row><entry /><entry /><entry /><entry>state.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Inputs from Read and Write Multiplexor sub-block</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>read_cmd_rdy</entry><entry>2</entry><entry>In</entry><entry>Signal indicating that read</entry></row><row><entry /><entry /><entry /><entry>multiplexor is ready for next</entry></row><row><entry /><entry /><entry /><entry>read read command.</entry></row><row><entry /><entry /><entry /><entry>00 = not ready</entry></row><row><entry /><entry /><entry /><entry>01 = ready for CPU read</entry></row><row><entry /><entry /><entry /><entry>10 = ready for non-CPU</entry></row><row><entry /><entry /><entry /><entry>read</entry></row><row><entry /><entry /><entry /><entry>11 = ready for both CPU</entry></row><row><entry /><entry /><entry /><entry>and non-CPU reads</entry></row><row><entry>write_cmd_rdy</entry><entry>2</entry><entry>In</entry><entry>Signal indicating that write</entry></row><row><entry /><entry /><entry /><entry>multiplexor is ready for next</entry></row><row><entry /><entry /><entry /><entry>write command.</entry></row><row><entry /><entry /><entry /><entry>00 = not ready</entry></row><row><entry /><entry /><entry /><entry>01 = ready for CPU write</entry></row><row><entry /><entry /><entry /><entry>10 = ready for non-CPU write</entry></row><row><entry /><entry /><entry /><entry>11 = ready for both CPU and</entry></row><row><entry /><entry /><entry /><entry>non-CPU write</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Outputs to other DAU sub-blocks</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>arb_gnt</entry><entry>1</entry><entry>In</entry><entry>Signal lasting 1 cycle which</entry></row><row><entry /><entry /><entry /><entry>indicates arbitration has</entry></row><row><entry /><entry /><entry /><entry>occurred and arb_sel is valid.</entry></row><row><entry>arb_sel</entry><entry>5</entry><entry>In</entry><entry>Signal indicating which requesting</entry></row><row><entry /><entry /><entry /><entry>SoPEC Unit has won arbitration.</entry></row><row><entry /><entry /><entry /><entry>Encoding is described in Table .</entry></row><row><entry>dir_sel</entry><entry>2</entry><entry>In</entry><entry>Signal indicating which sense of</entry></row><row><entry /><entry /><entry /><entry>access associated with arb_sel</entry></row><row><entry /><entry /><entry /><entry>00: issue non-CPU write</entry></row><row><entry /><entry /><entry /><entry>01: read winner</entry></row><row><entry /><entry /><entry /><entry>10: write winner</entry></row><row><entry /><entry /><entry /><entry>11: refresh winner</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Debug Inputs from Read-Write Multiplexor sub-block</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>read_sel</entry><entry>5</entry><entry>In</entry><entry>Signal indicating the SoPEC Unit</entry></row><row><entry /><entry /><entry /><entry>for which the current read trans-</entry></row><row><entry /><entry /><entry /><entry>action is occurring. Encoding</entry></row><row><entry /><entry /><entry /><entry>is described in Table .</entry></row><row><entry>read_complete</entry><entry>1</entry><entry>In</entry><entry>Signal indicating that read</entry></row><row><entry /><entry /><entry /><entry>transaction to SoPEC Unit</entry></row><row><entry /><entry /><entry /><entry>indicated by read_sel is</entry></row><row><entry /><entry /><entry /><entry>complete.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Debug Inputs from Command Multiplexor sub-block</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>write_sel</entry><entry>5</entry><entry>In</entry><entry>Signal indicating the SoPEC</entry></row><row><entry /><entry /><entry /><entry>Unit for which the current</entry></row><row><entry /><entry /><entry /><entry>write transaction is occurring.</entry></row><row><entry /><entry /><entry /><entry>Encoding is described in Table .</entry></row><row><entry>write_complete</entry><entry>1</entry><entry>In</entry><entry>Signal indicating that write</entry></row><row><entry /><entry /><entry /><entry>transaction to SoPEC Unit</entry></row><row><entry /><entry /><entry /><entry>indicated by write_sel is</entry></row><row><entry /><entry /><entry /><entry>complete.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Debug Inputs from DCU</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>dcu_dau<sub>—</sub></entry><entry>1</entry><entry>In</entry><entry>Signal indicating that the DCU</entry></row><row><entry>refreshcomplete</entry><entry /><entry /><entry>has completed a refresh.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Debug Inputs from DAU IO</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>various</entry><entry>n</entry><entry>In</entry><entry>Various DAU IO signals which can</entry></row><row><entry /><entry /><entry /><entry>be monitored in debug mode</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2288The CPU Interface and Arbitration Logic sub-block is shown in <figref idref="DRAWINGS">FIG. 118</figref>.
000020.14.12.1 CPU Interface and Configuration Registers Description
2289The CPU Interface and Configuration Registers sub-block provides for the CPU to access DAU specific registers by reading or writing to the DAU address space.
2290The CPU subsystem bus interface is described in more detail in Section 11.4.3. The DAU block will only allow supervisor mode accesses to data space (i.e. cpu_acode[1:0]=b11). All other accesses will result in diu_cpu_berr being asserted.
2291The configuration registers described in Section 20.14.9
2292<tables id="TABLE-US-00180" num="00180"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="336pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 130</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>DAU configuration registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="28pt" align="center" /><colspec colname="4" colwidth="56pt" align="left" /><colspec colname="5" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>Address</entry><entry /><entry>#</entry><entry /><entry /></row><row><entry>(DIU_base +)</entry><entry>Register</entry><entry>bits</entry><entry>Reset</entry><entry>Description</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="336pt" align="left" /><tbody valign="top"><row><entry>Reset</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="56pt" align="left" /><colspec colname="5" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>0x00</entry><entry>Reset</entry><entry>1</entry><entry>0x1</entry><entry>A write to this register</entry></row><row><entry /><entry /><entry /><entry /><entry>causes a reset of the DIU.</entry></row><row><entry /><entry /><entry /><entry /><entry>This register can be read to</entry></row><row><entry /><entry /><entry /><entry /><entry>indicate the reset state:</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - reset in progress</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - reset not in progress</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="336pt" align="left" /><tbody valign="top"><row><entry>Refresh</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="56pt" align="left" /><colspec colname="5" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>0x04</entry><entry>RefreshPeriod</entry><entry>9</entry><entry>0x063</entry><entry>Refresh controller.</entry></row><row><entry /><entry /><entry /><entry /><entry>When set to 0 refresh is off,</entry></row><row><entry /><entry /><entry /><entry /><entry>otherwise the value indicates</entry></row><row><entry /><entry /><entry /><entry /><entry>the number of cycles, less one,</entry></row><row><entry /><entry /><entry /><entry /><entry>between each refresh. [Note</entry></row><row><entry /><entry /><entry /><entry /><entry>that for a system clock fre-</entry></row><row><entry /><entry /><entry /><entry /><entry>quency of 160 MHz, a value</entry></row><row><entry /><entry /><entry /><entry /><entry>exceeding 0x63 (indicating a</entry></row><row><entry /><entry /><entry /><entry /><entry>100-cycle refresh period)</entry></row><row><entry /><entry /><entry /><entry /><entry>should not be programmed, or</entry></row><row><entry /><entry /><entry /><entry /><entry>the DRAM will malfunction.]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="336pt" align="left" /><tbody valign="top"><row><entry>Timeslot allocation and control</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="56pt" align="left" /><colspec colname="5" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>0x08</entry><entry>NumMainTimeslots</entry><entry>6</entry><entry>0x01</entry><entry>Number of main timeslots</entry></row><row><entry /><entry /><entry /><entry /><entry>(1–64) less one</entry></row><row><entry>0x0C</entry><entry>CPUPreAccessTimes</entry><entry>4</entry><entry>0x0</entry><entry>(CPUPreAccessTimeslots + 1)</entry></row><row><entry /><entry>lots</entry><entry /><entry /><entry>main slots out of a total of</entry></row><row><entry /><entry /><entry /><entry /><entry>(CPUTotalTimeslots + 1) are</entry></row><row><entry /><entry /><entry /><entry /><entry>preceded by a CPU access.</entry></row><row><entry>0x10</entry><entry>CPUTotalTimeslots</entry><entry>4</entry><entry>0x0</entry><entry>(CPUPreAccessTimeslots + 1)</entry></row><row><entry /><entry /><entry /><entry /><entry>main slots out of a total of</entry></row><row><entry /><entry /><entry /><entry /><entry>(CPUTotalTimeslots + 1) are</entry></row><row><entry /><entry /><entry /><entry /><entry>preceded by a CPU access.</entry></row><row><entry>0x100–0x1FC</entry><entry>MainTimeslot[63:0]</entry><entry>64 × 4</entry><entry>[63:1][3:0] = 0x0</entry><entry>Programmable main timeslots</entry></row><row><entry /><entry /><entry /><entry>[0][3:0] = 0xE</entry><entry>(up to 64 main timeslots).</entry></row><row><entry>0x200</entry><entry>ReadRoundRobinLevel</entry><entry>12</entry><entry>0x000</entry><entry>For each read requester plus</entry></row><row><entry /><entry /><entry /><entry /><entry>refresh</entry></row><row><entry /><entry /><entry /><entry /><entry>0 = level1 of round-robin</entry></row><row><entry /><entry /><entry /><entry /><entry>1 = level2 of round-robin</entry></row><row><entry /><entry /><entry /><entry /><entry>The bit order is defined in</entry></row><row><entry /><entry /><entry /><entry /><entry>Table .</entry></row><row><entry>0x204</entry><entry>EnableCPURoundRobin</entry><entry>1</entry><entry>0x1</entry><entry>Allows the CPU to particpate</entry></row><row><entry /><entry /><entry /><entry /><entry>in the unused read round-robin</entry></row><row><entry /><entry /><entry /><entry /><entry>scheme. If disabled, the</entry></row><row><entry /><entry /><entry /><entry /><entry>shared CPU/refresh round-robin</entry></row><row><entry /><entry /><entry /><entry /><entry>position is dedicated solely</entry></row><row><entry /><entry /><entry /><entry /><entry>to refresh.</entry></row><row><entry>0x208</entry><entry>RotationSync</entry><entry>1</entry><entry>0x1</entry><entry>Writing 0, followed by 1 to</entry></row><row><entry /><entry /><entry /><entry /><entry>this bit allows the timeslot</entry></row><row><entry /><entry /><entry /><entry /><entry>rotation to advance on a cycle</entry></row><row><entry /><entry /><entry /><entry /><entry>basis which can be determined</entry></row><row><entry /><entry /><entry /><entry /><entry>by the CPU.</entry></row><row><entry>0x20C</entry><entry>minNonCPUReadAdr</entry><entry>12</entry><entry>0x800</entry><entry>12 MSBs of lowest DRAM address</entry></row><row><entry /><entry /><entry /><entry /><entry>which may be read by non-CPU</entry></row><row><entry /><entry /><entry /><entry /><entry>requesters.</entry></row><row><entry>0x210</entry><entry>minDWUWriteAdr</entry><entry>12</entry><entry>0x800</entry><entry>12 MSBs of lowest DRAM address</entry></row><row><entry /><entry /><entry /><entry /><entry>which may be written to by the</entry></row><row><entry /><entry /><entry /><entry /><entry>DWU.</entry></row><row><entry>0x214</entry><entry>minNonCPUWriteAdr</entry><entry>12</entry><entry>0x800</entry><entry>12 MSBs of lowest DRAM address</entry></row><row><entry /><entry /><entry /><entry /><entry>which may be written to by</entry></row><row><entry /><entry /><entry /><entry /><entry>non-CPU requesters other than</entry></row><row><entry /><entry /><entry /><entry /><entry>the DWU.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="336pt" align="left" /><tbody valign="top"><row><entry>Debug</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="56pt" align="left" /><colspec colname="5" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>0x300</entry><entry>DebugSelect[11:2]</entry><entry>10</entry><entry>0x304</entry><entry>Debug address select. Indicates</entry></row><row><entry /><entry /><entry /><entry /><entry>the address of the register to</entry></row><row><entry /><entry /><entry /><entry /><entry>report on the diu_cpu_data bus</entry></row><row><entry /><entry /><entry /><entry /><entry>when it is not otherwise being</entry></row><row><entry /><entry /><entry /><entry /><entry>used. When this signal carries</entry></row><row><entry /><entry /><entry /><entry /><entry>debug information the signal</entry></row><row><entry /><entry /><entry /><entry /><entry>diu_cpu_debug_valid will be</entry></row><row><entry /><entry /><entry /><entry /><entry>asserted.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="336pt" align="left" /><tbody valign="top"><row><entry>Debug: arbitration and performance</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="56pt" align="left" /><colspec colname="5" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>0x304</entry><entry>ArbitrationHistory</entry><entry>22</entry><entry>—</entry><entry>Bit 0 = arb_gnt</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 1 = arb_executed</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 6:2 = arb_sel[4:0]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 12:7 = timeslot_number[5:0]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 15:13 = access_type[2:0]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 16 = back2back_non_cpu_write</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 17 =</entry></row><row><entry /><entry /><entry /><entry /><entry>sticky_back2back_non_cpu_write</entry></row><row><entry /><entry /><entry /><entry /><entry>(Sticky version of same, cleared on reset.)</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 18 = rotation_sync</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 20:19 = rotation_state</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 21 = sticky_invalid_non_cpu_adr</entry></row><row><entry /><entry /><entry /><entry /><entry>See Section 20.14.9.2 DIU Debug</entry></row><row><entry /><entry /><entry /><entry /><entry>for a description of the fields.</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x308</entry><entry>DIUPerformance</entry><entry>31</entry><entry>—</entry><entry>Bit 0 = cpu_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 1 = scb_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 2 = cdu_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 3 = cfu_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 4 = lbd_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 5 = sfu_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 6 = td_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 7 = tfs_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 8 = hcu_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 9 = dnc_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 10 = llu_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 11 = pcu_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 12 = cpu_diu_wreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 13 = scb_diu_wreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 14 = cdu_diu_wreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 15 = sfu_diu_wreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 16 = dwu_diu_wreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 17 = refresh_req</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 22:18 = read_sel[4:0]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 23 = read_complete</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 28:24 = write_sel[4:0]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 29 = write_complete</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 30 = dcu_dau_refreshcomplete</entry></row><row><entry /><entry /><entry /><entry /><entry>See Section 20.14.9.2 DIU Debug</entry></row><row><entry /><entry /><entry /><entry /><entry>for a description of the fields.</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="336pt" align="left" /><tbody valign="top"><row><entry>Debug DIU read requesters interface signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="56pt" align="left" /><colspec colname="5" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>0x30C</entry><entry>CPUReadInterface</entry><entry>25</entry><entry>—</entry><entry>Bit 0 = cpu_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 22:1 = cpu_adr[21:0]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 23 = diu_cpu_rack</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 24 = diu_cpu_rvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x310</entry><entry>SCBReadInterface</entry><entry>20</entry><entry /><entry>Bit 0 = scb_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 17:1 = scb_diu_radr[21:5]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 18 = diu_scb_rack</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 19 = diu_scb_rvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x314</entry><entry>CDUReadInterface</entry><entry>20</entry><entry>—</entry><entry>Bit 0 = cdu_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 17:1 = cdu_diu_radr[21:5]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 18 = diu_cdu_rack</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 19 = diu_cdu_rvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x318</entry><entry>CFUReadInterface</entry><entry>20</entry><entry>—</entry><entry>Bit 0 = cfu_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 17:1 = cfu_diu_radr[21:5]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 18 = diu_cfu_rack</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 19 = diu_cfu_rvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x31C</entry><entry>LBDReadInterface</entry><entry>20</entry><entry>—</entry><entry>Bit 0 = lbd_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 17:1 = lbd_diu_radr[21:5]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 18 = diu_lbd_rack</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 19 = diu_lbd_rvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x320</entry><entry>SFUReadInterface</entry><entry>20</entry><entry>—</entry><entry>Bit 0 = sfu_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 17:1 = sfu_diu_radr[21:5]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 18 = diu_sfu_rack</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 19 = diu_sfu_rvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x324</entry><entry>TDReadInterface</entry><entry>20</entry><entry>—</entry><entry>Bit 0 = td_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 17:1 = td_diu_radr[21:5]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 18 = diu_td_rack</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 19 = diu_td_rvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x328</entry><entry>TFSReadInterface</entry><entry>20</entry><entry>—</entry><entry>Bit 0 = tfs_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 17:1 = tfs_diu_radr[21:5]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 18 = diu_tfs_rack</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 19 = diu_tfs_rvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x32C</entry><entry>HCUReadInterface</entry><entry>20</entry><entry>—</entry><entry>Bit 0 = hcu_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 17:1 = hcu_diu_radr[21:5]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 18 = diu_hcu_rack</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 19 = diu_hcu_rvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x330</entry><entry>DNCReadInterface</entry><entry>20</entry><entry>—</entry><entry>Bit 0 = dnc_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 17:1 = dnc_diu_radr[21:5]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 18 = diu_dnc_rack</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 19 = diu_dnc_rvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x334</entry><entry>LLUReadInterface</entry><entry>20</entry><entry>—</entry><entry>Bit 0 = llu_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 17:1 = lluu_diu_radr[21:5]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 18 = diu_llu_rack</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 19 = diu_llu_rvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x338</entry><entry>PCUReadInterface</entry><entry>20</entry><entry>—</entry><entry>Bit 0 = pcu_diu_rreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 17:1 = pcu_diu_radr[21:5]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 18 = diu_pcu_rack</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 19 = diu_pcu_rvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="336pt" align="left" /><tbody valign="top"><row><entry>Debug DIU write requesters interface signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="56pt" align="left" /><colspec colname="5" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>0x33C</entry><entry>CPUWriteInterface</entry><entry>27</entry><entry>—</entry><entry>Bit 0 = cpu_diu_wreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 22:1 = cpu_adr[2.1:0]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 24:23 = cpu_diu_wmask[1:0]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 25 = diu_cpu_wack</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 26 = cpu_diu_wvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x340</entry><entry>SCBWriteInterface</entry><entry>20</entry><entry>—</entry><entry>Bit 0 = scb_diu_wreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 17:1 = scb_diu_wadr[21:5]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 18 = diu_scb_wack</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 19 = scb_diu_wvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x344</entry><entry>CDUWriteInterface</entry><entry>22</entry><entry>—</entry><entry>Bit 0 = cdu_diu_wreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 19:1 = cdu_diu_wadr[21:3]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 20 = diu_cdu_wack</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 21 = cdu_diu_wvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x348</entry><entry>SFUWriteInterface</entry><entry>20</entry><entry>—</entry><entry>Bit 0 = sfu_diu_wreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 17:1 = sfu_diu_wadr[21:5]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 18 = diu_sfu_wack</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 19 = sfu_diu_wvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x34C</entry><entry>DWUWriteInterface</entry><entry>20</entry><entry>—</entry><entry>Bit 0 = dwu_diu_wreq</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 17:1 = dwu_diu_wadr[21:5]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 18 = diu_dwu_wack</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 19 = dwu_diu_wvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="336pt" align="left" /><tbody valign="top"><row><entry>Debug DAU-DCU interface signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="56pt" align="left" /><colspec colname="5" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>0x350</entry><entry>DAU-DCUInterface</entry><entry>25</entry><entry>—</entry><entry>Bit 16:0 = dau_dcu_adr[21:5]</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 17 = dau_dcu_rwn</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 18 = dau_dcu_cduwpage</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 19 = dau_dcu_refresh</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 20 = dau_dcu_msn2stall</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 21 = dcu_dau_adv</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 22 = dcu_dau_wadv</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 23 = dcu_dau_refreshcomplete</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 24 = dcu_dau_rvalid</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> are implemented here. <br /> 20.14.12.2 Arbitration Logic Description
2293Arbitration is triggered by the signal re_arbitrate from the Command Multiplexor sub-block with the signal arb_gnt indicating that arbitration has occurred and the arbitration winner is indicated by arb_sel[4:0]. The encoding of arb_sel[4:0] is shown in Table. The signal dir_sel[1:0] indicates if the arbitration winner is a read, write or refresh. Arbitration should complete within one clock cycle so arb_gnt is normally asserted the clock cycle after re_arbitrate and stays high for 1 clock cycle. arb_sel[4:0] and dir_sel[1:0] remain persistent until arbitration occurs again. The arbitration timing is shown in <figref idref="DRAWINGS">FIG. 119</figref>.
000020.14.12.2.1 Rotation Synchronisation
2294A configuration bit, RotationSync, is used to initialise advancement through the timeslot rotation, in order that the CPU will know, on a cycle basis, which timeslot is being arbitrated. This is essential for debug purposes, so that exact arbitration sequences can be reproduced.
2295In general, if RotationSync is set, slots continue to be arbitrated in the regular order specified by the timeslot rotation. When the bit is cleared, the current rotation continues until the slot pointers for pre- and main arbitration reach zero. The arbitration logic then grants DRAM access exclusively to the CPU and refreshes.
2296When the CPU again writes to RotationSync to cause a 0-to-1 transition of the bit, the rdy acknowledgment back to the CPU for this write will be exactly coincident with the RST cycle of the initial refresh which heralds the enabling of a new rotation. This refresh, along with the second access which can be either a CPU pre-access or a refresh, (depending on the CPU's request inputs), form a 2-access “preamble” before the first non-CPU requester in the new rotation can be serviced. This preamble is necessary to give the write pre-arbitration the necessary head start on the main arbitration, so that write data can be loaded in time. See <figref idref="DRAWINGS">FIG. 105</figref> below. The same preamble procedure is followed when emerging from reset.
2297The alignment of rdy with the commencement of the rotation ensures that the CPU is always able to calculate at any point how far a rotation has progressed. RotationSync has a reset value of 1 to ensure that the default power-up rotation can take place.
2298Note that any CPU writes to the DIU's other configuration registers should only be made when RotationSync is cleared. This ensures that accesses by non-CPU requesters to DRAM are not affected by partial configuration updates which have yet to be completed.
000020.14.12.2.2 Motivation for Rotation Synchronisation
2299The motivation for this feature is that communications with SoPEC from external sources are synchronised to the internal clock of our position within a DIU full timeslot rotation. This means that if an external source told SoPEC to start a print 3 separate times, it would likely be at three different points within a full DIU rotation. This difference means that the DIU arbitration for each of the runs would be different, which would manifest itself externally as anomalous or inconsistent print performance. The lack of reproducibility is the problem here.
2300However, if in response to the external source saying to start the print, we caused the internal to pass through a known state at a fixed time offset to other internal actions, this would result in reproducible prints. So, the plan is that the software would do a rotation synchronise action, then writes “Go” into various PEP units to cause the prints. This means the DIU state will be the identical with respect to the PEP units state between separate runs.
000020.14.12.2.3 Wind-down Protocol When Rotation Synchronisation is Initiated
2301When a zero is written to “RotationSync”, this initiates a “wind-down protocol” in the DIU, in which any rotation already begun must be fully completed. The protocol implements the following sequence:— <ul id="ul0219" list-style="none"><li id="ul0219-0001" num="0000"><ul id="ul0220" list-style="none"><li id="ul0220-0001" num="2302">The pre-arbitration logic must reach the end of whatever rotation it is on and stop pre-arbitrating.</li><li id="ul0220-0002" num="2303">Only when this has happened, does the main arbitration consider doing likewise with its current rotation. Note that the main arbitration lags the pre-arbitration by at least 2 DRAM accesses, subject to variation by CPU pre-accesses and/or scheduled refreshes, so that the two arbitration processes are sometimes on different rotations.</li><li id="ul0220-0003" num="2304">Once the main arbitration has reached the end of its rotation, rotation synchronisation is considered to be fully activated. Arbitration then proceeds as outlined in the next section. <br /> 20.14.12.2.4 Arbitration During Rotation Synchronisation </li></ul></li></ul>
2305Note that when RotationSync is ‘0’ and, assuming the terminating rotation has completely drained out, then DRAM arbitration is granted according to the following fixed priority order:—Scheduled Refresh->CPU(W)->CPU(R)->Default Refresh.
2306CPU pre-access counters play no part in arbitration during this period. It is only subsequently, when emerging from rotation sync, that they are reloaded with the values of CPUPreAccessTimeslots and CPUTotalTimeslots and normal service resumes.
000020.14.12.2.5 Timeslot-based Arbitration
2307Timeslot-based arbitration works by having a pointer point to the current timeslot. This is shown in <figref idref="DRAWINGS">FIG. 95</figref> repeated here as <figref idref="DRAWINGS">FIG. 121</figref>. When re-arbitration is signaled the arbitration winner is the current timeslot and the pointer advances to the next timeslot. Each timeslot denotes a single access. The duration of the timeslot depends on the access.
2308If the SoPEC Unit assigned to the current timeslot is not requesting then the unused timeslot arbitration mechanism outlined in Section 20.10.6 is used to select the arbitration winner. Note that this unused slot re-allocation is guaranteed to produce a result, because of the inclusion of refresh in the round-robin scheme.
2309Pseudo-code to represent arbitration is given below:
2310<tables id="TABLE-US-00181" num="00181"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>if re_arbitrate = = 1 then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>arb_gnt = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>if current timeslot requesting then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>choose (arb_sel, dir_sel) at current</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>timeslot</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>else // un-used timeslot scheme</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="84pt" align="left" /><colspec colname="1" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>choose winner according to un-used</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>timeslot allocation of Section 20.10.6</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>arb_gnt = 0</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 20.14.12.3 Arbitrating Non-CPU Writes in Advance
2311In the case of a non-CPU write commands, the write data must be transferred from the SoPEC requester before the write can occur. Arbitration should occur early to allow for any delay for the write data to be transferred to the DRAM.
2312<figref idref="DRAWINGS">FIG. 113</figref> indicates that write data transfer over 64-bit busses will take a further 4 cycles after the address is transferred. The arbitration must therefore occur 4 cycles in advance of arbitration for read accesses, <figref idref="DRAWINGS">FIG. 109</figref> and <figref idref="DRAWINGS">FIG. 110</figref>, or for CPU writes <figref idref="DRAWINGS">FIG. 112</figref>. Arbitration of CDU write accesses, <figref idref="DRAWINGS">FIG. 114</figref>, should take place 1 cycle in advance of arbitration for read and CPU write accesses. To simplify implementation CDU write accesses are arbitrated 4 cycles in advance, similar to other non-CPU writes.
2313The Command Multiplexor generates a second arbitration signal re_arbitrate_wadv which initiates the arbitration in advance of non-CPU write accesses.
2314The timeslot scheme is then modified to have 2 separate pointers: <ul id="ul0221" list-style="none"><li id="ul0221-0001" num="0000"><ul id="ul0222" list-style="none"><li id="ul0222-0001" num="2315">re_arbitrate can arbitrate read, refresh and CPU read and write accesses according to the position of the current timeslot pointer.</li><li id="ul0222-0002" num="2316">re_arbitrate_wadv can arbitrate only non-CPU write accesses according to the position of the write lookahead pointer.</li></ul></li></ul>
2317Pseudo-code to represent arbitration is given below:
2318<tables id="TABLE-US-00182" num="00182"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>//re_arbitrate</entry></row><row><entry>if (re_arbitrate = = 1) AND (current timeslot pointer!= non-</entry></row><row><entry>CPU write) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>arb_gnt = 1</entry></row><row><entry /><entry>if current timeslot requesting then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>choose(arb_sel, dir_sel) at current timeslot</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>else // un-used read timeslot scheme</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>choose winner according to un-used read timeslot</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>allocation of Section 20.10.6.2</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2319If the SoPEC Unit assigned to the current timeslot is not requesting then the unused read timeslot arbitration mechanism outlined in Section 20.10.6.2 is used to select the arbitration winner.
2320<tables id="TABLE-US-00183" num="00183"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>//re_arbitrate_wadv</entry></row><row><entry /><entry>if (re_arbitrate_wadv = = 1) AND (write lookahead timeslot</entry></row><row><entry /><entry>pointer = = non-CPU write) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>if write lookahead timeslot requesting then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>choose (arb_sel, dir_sel) at write lookahead timeslot</entry></row><row><entry /><entry>arb_gnt = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif un-used write timeslot scheme has a requestor</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>choose winner according to un-used write timeslot</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>allocation of Section 20.10.6.1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>arb_gnt = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>//no arbitration winner</entry></row><row><entry /><entry>arb_gnt = 0</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><ul id="ul0223" list-style="none"><li id="ul0223-0001" num="0000"><ul id="ul0224" list-style="none"><li id="ul0224-0001" num="2321">re_arbitrate is generated in the MSN2 state of the DCU state-machine, whereas</li><li id="ul0224-0002" num="2322">re_arbitrate_wadv is generated in the RST state. See <figref idref="DRAWINGS">FIG. 103</figref>.</li></ul></li></ul>
2323The write lookahead pointer points two timeslots in advance of the current timeslot pointer. Therefore re_arbitrate_wadv causes the Arbitration Logic to perform an arbitration for non-CPU two timeslots in advance. As noted in Table, each timeslot lasts at least 3 cycles. Therefor re_arbitrate_wadv arbitrates at least 4 cycles in advance.
2324At initialisation, the write lookahead pointer points to the first timeslot. The current timeslot pointer is invalid until the write lookahead pointer advances to the third timeslot when the current timeslot pointer will point to the first timeslot. Then both pointers advance in tandem.
2325Some accesses can be preceded by a CPU access as in Table. These CPU accesses are not allocated timeslots. If this is the case the timeslot will last 3 (CPU access)+3 (non-CPU access)=6 cycles. In that case, a second write lookahead pointer, the CPU pre-access write lookahead pointer, is selected which points only one timeslot in advance. re_arbitrate_wadv will still arbitrate 4 cycles in advance.
000020.14.12.3.1 Issuing Non-CPU Write Commands
2326Although the Arbitration Logic will arbitrate non-CPU writes in advance, the Command Multiplexor must issue all accesses in the timeslot order. This is achieved as follows:
2327If re_arbitrate_wadv arbitrates a non-CPU write in advance then within the Arbitration Logic the timeslot is marked to indicate whether a write was issued.
2328<tables id="TABLE-US-00184" num="00184"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>//re_arbitrate_wadv</entry></row><row><entry>if (re_arbitrate_wadv = = 1) AND (write lookahead timeslot</entry></row><row><entry>pointer = = non-CPU write) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>if write lookahead timeslot requesting then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>choose (arb_sel, dir_sel) at write lookahead timeslot</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>arb_gnt = 1</entry></row><row><entry /><entry>MARK_timeslot = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif un-used write timeslot scheme has a requestor</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>choose winner according to un-used write timeslot</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>allocation of Section 20.10.6.1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>arb_gnt = 1</entry></row><row><entry /><entry>MARK_timeslot = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>//no pre-arbitration winner</entry></row><row><entry /><entry>arb_gnt = 0</entry></row><row><entry /><entry>MARK_timeslot = 0</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2329When re_arbitrate advances to a write timeslot in the Arbitration Logic then one of two actions can occur depending on whether the slot was marked by re_arbitrate_wadv to indicate whether a write was issued or not. <ul id="ul0225" list-style="none"><li id="ul0225-0001" num="0000"><ul id="ul0226" list-style="none"><li id="ul0226-0001" num="2330">Non-CPU write arbitrated by re_arbitrate_wadv</li></ul></li></ul>
2331If the timeslot has been marked as having issued a write then the arbitration logic responds to re_arbitrate by issuing arb_sel[4:0], dir_sel[1:0] and asserting arb gnt as for a normal arbitration but selecting a non-CPU write access. Normally, re_arbitrate does not issue non-CPU write accesses. Non-CPU writes are arbitrated by re_arbitrate_wadv. dir_sel[1:0]==00 indicates a non-CPU write issued by re_arbitrate. <ul id="ul0227" list-style="none"><li id="ul0227-0001" num="0000"><ul id="ul0228" list-style="none"><li id="ul0228-0001" num="2332">Non-CPU write not arbitrated by re_arbitrate_wadv</li></ul></li></ul>
2333If the timeslot has been marked as not having issued a write, the re_arbitrate will use the un-used read timeslot selection to replace the un-used write timeslot with a read timeslot according to Section 20.10.6.2 Unused read timeslots allocation.
2334<tables id="TABLE-US-00185" num="00185"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>//re_arbitrate except for non-CPU writes</entry></row><row><entry>if (re_arbitrate = = 1) AND (current timeslot pointer!= non-</entry></row><row><entry>CPU write) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>arb_gnt = 1</entry></row><row><entry /><entry>if current timeslot requesting then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>choose(arb_sel, dir_sel) at current timeslot</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>else // un-used read timeslot scheme</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>choose winner according to un-used read timeslot</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>allocation of Section 20.10.6.2</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>arb_gnt = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>//non-CPU write MARKED as issued</entry></row><row><entry>elsif (re_arbitrate = = 1) AND (current timeslot pointer = =</entry></row><row><entry>non-CPU write) AND</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>(MARK_timeslot = = 1) then</entry></row><row><entry /><entry>//indicate to Command Multiplexor that non-CPU write</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>has been arbitrated in</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>//advance</entry></row><row><entry /><entry>arb_gnt = 1</entry></row><row><entry /><entry>dir_sel[1:0] = = 00</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>//non-CPU write not MARKED as issued</entry></row><row><entry>elsif (re_arbitrate = = 1) AND (current timeslot pointer = =</entry></row><row><entry>non-CPU write) AND</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>(MARK_timeslot = = 0) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>choose winner according to un-used read timeslot</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>allocation of Section 20.10.6.2</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>arb_gnt = 1</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 20.14.12.4 Flow Control
2335If read commands are to win arbitration, the Read Multiplexor must be ready to accept the read data from the DRAM. This is indicated by the read_cmd_rdy[1:0] signal. read_cmd_rdy[1:0] supplies flow control from the Read Multiplexor.
2336<tables id="TABLE-US-00186" num="00186"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>read_cmd_rdy[0]= =1 //Read multiplexor ready for CPU</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>read</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>read_cmd_rdy[1]= =1 //Read multiplexor ready for non-CPU</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>read</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2337The Read Multiplexor will normally always accept CPU reads, see Section 20.14.13.1, so read_cmd_rdy[0]==1 should always apply.
2338Similarly, if write commands are to win arbitration, the Write Multiplexor must be ready to accept the write data from the winning SoPEC requestor. This is indicated by the write_cmd_rdy[1:0] signal. write_cmd_rdy[1:0] supplies flow control from the Write Multiplexor.
2339<tables id="TABLE-US-00187" num="00187"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>write_cmd_rdy[0]= =1 //Write multiplexor ready for CPU</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>write</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>write_cmd_rdy[1]= =1 //Write multiplexor ready for non-</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>CPU write</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2340The Write Multiplexor will normally always accept CPU writes, see Section 20.14.13.2, so write_cmd_rdy[0]==1 should always apply.
0000Non-CPU Read Flow Control
2341If re_arbitrate selects an access then the signal dau_dcu_msn2stall is asserted until the Read Write Multiplexor is ready.
2342arb_gnt is not asserted until the Read Write Multiplexor is ready.
2343This mechanism will stall the DCU access to the DRAM until the Read Write Multiplexor is ready to accept the next data from the DRAM in the case of a read.
2344<tables id="TABLE-US-00188" num="00188"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>//other access flow control</entry></row><row><entry /><entry>dau_dcu_msn2stall = (((re_arbitrate selects CPU read) AND</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>read_cmd rdy[0]= =0) OR</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="84pt" align="left" /><colspec colname="1" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>(re_arbitrate selects non-CPU</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>read) AND read_cmd_rdy[1]= =0))</entry></row><row><entry /><entry>arb_gnt not asserted until dau_dcu_msn2stall de-asserts</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 20.14.12.5 Arbitration Hierarchy
2345CPU and refresh are not included in the timeslot allocations defined in the DAU configuration registers of Table.
2346The hierarchy of arbitration under normal operation is
2347a. CPU access
2348b. Refresh access
2349c. Timeslot access.
2350This is shown in <figref idref="DRAWINGS">FIG. 124</figref>. The first DRAM access issued after reset must be a refresh.
2351As shown in <figref idref="DRAWINGS">FIG. 118</figref>, the DIU request signals <unit>_diu_rreq, <unit>_diu_wreq are registered at the input of the arbitration block to ease timing. The exceptions are the refresh_req signal, which is generated locally in the sub-block and cpu_diu_rreq. The CPU read request signal is not registered so as to keep CPU DIU read access latency to a minimum. Since CPU writes are posted, cpu_diu_wreq is registered so that the DAU can process the write at a later juncture. The arbitration logic is coded to perform arbitration of non-CPU requests first and then to gate the result with the CPU requests. In this way the CPU can make the requests available late in the arbitration cycle.
2352Note that when RotationSync is set to ‘0’, a modified hierarchy of arbitration is used. This is outlined in section 20.14.12.2.3 on page 280.
000020.14.12.6 Timeslot Access
2353The basic timeslot arbitration is based on the MainTimeslot configuration registers. Arbitration works by the timeslot pointed to by either the current or write lookahead pointer winning arbitration. The pointers then advance to the next timeslot. This was shown in <figref idref="DRAWINGS">FIG. 90</figref>.
2354Each main timeslot pointer gets advanced each time it is accessed regardless of whether the slot is used.
000020.14.12.7 Unused Timeslot Allocation
2355If an assigned slot is not used (because its corresponding SoPEC Unit is not requesting) then it is reassigned according to the scheme described in Section 20.10.6.
2356Only used non-CPU accesses are reallocated. CDU write accesses cannot be included in the unused timeslot allocation for write as CDU accesses take 6 cycles. The write accesses which the CDU write could otherwise replace require only 3 or 4 cycles.
2357Unused write accesses are re-allocated according to the fixed priority scheme of Table. Unused read timeslots are re-allocated according to the two-level round-robin scheme described in Section 20.10.6.2.
2358A pointer points to the most recently re-allocated unit in each of the round-robin levels. If the unit immediately succedling the pointer is requesting, then this unit wins the arbitration and the pointer is advanced to reflect the new winner. If this is not the case, then the subsequent units (wrapping back eventually to the pointed unit) in the level 1 round-robin are examined. When a requesting unit is found this unit wins the arbitration and the pointer is adjusted. If no unit is requesting then the pointer does not advance and the second level of round-robin is examined in a similar fashion. In the following pseudo-code the bit indices are for the ReadRoundRobinLevel configuration register described in Table.
2359<tables id="TABLE-US-00189" num="00189"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>//choose the winning arbitration level</entry></row><row><entry /><entry>level1 = 0</entry></row><row><entry /><entry>level2 = 0</entry></row><row><entry /><entry>for i = 0 to 11</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>if unit(i) requesting AND ReadRoundRobinLevel(i) =</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>0 then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>level1 = 1</entry></row><row><entry /><entry>if unit(i) requesting AND ReadRoundRobinLevel(i) =</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>1 then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>level2 = 1</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2360Round-robin arbitration is effectively a priority assignment with the units assigned a priority according to the round-robin order of Table but starting at the unit currently pointed to.
2361<tables id="TABLE-US-00190" num="00190"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>//levelptr is pointer of selected round robin level</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>priority is array 0 to 11 // index 0 is SCBR(0) etc.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>from Table</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>//assign decreasing priorities from the current</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>pointer; maximum priority is 11</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>for i = 1 to 12</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>priority (levelptr + i) = 12 − i</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>i++</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2362The arbitration winner is the one with the highest priority provided it is requesting and its ReadRoundRobinLevel bit points to the chosen level. The levelptr is advanced to the arbitration winner.
2363The priority comparison can be done in the hierarchical manner shown in <figref idref="DRAWINGS">FIG. 125</figref>.
000020.14.12.8 How Non-CPU Address Restrictions Affect Arbitration
2364Recall from Table “DAU configuration registers,” on page 288, “DAU configuration registers,” on page 268 that there are minimum valid DRAM addresses for non-CPU accesses, defined by minNonCPUReadAdr, minDWUWriteAdr and minNonCPUWriteAdr. Similarly, a non-CPU requester may not try to access a location above the high memory mark.
2365To ensure compliance with these address restrictions, the following DIU response occurs for any incorrectly addressed non-CPU writes:— <ul id="ul0229" list-style="none"><li id="ul0229-0001" num="0000"><ul id="ul0230" list-style="none"><li id="ul0230-0001" num="2366">Issue a write acknowledgment at pre-arbitration time, to prevent the write requester from hanging.</li><li id="ul0230-0002" num="2367">Disregard the incoming write data and write valids and void the pre-arbitration.</li><li id="ul0230-0003" num="2368">Subsequently re-allocate the write slot at main arbitration time via the round robin.</li></ul></li></ul>
2369For any incorrectly addressed non-CPU reads, the response is:— <ul id="ul0231" list-style="none"><li id="ul0231-0001" num="0000"><ul id="ul0232" list-style="none"><li id="ul0232-0001" num="2370">Arbitrate the slot in favour of the scheduled, misbehaving requester.</li><li id="ul0232-0002" num="2371">Issue the read acknowledgement and rvalids to keep the requester from hanging.</li><li id="ul0232-0003" num="2372">Intercept the read data coming from the DCU and send back all zeros instead.</li></ul></li></ul>
2373If an invalidly addressed non-CPU access is attempted, then a sticky bit, sticky_invalid_non_cpu_adr, is set in the ArbitrationHistory configuration register. See Table n page 293 on page 275 for details.
000020.14.12.9 Refresh Controller Description
2374The refresh controller implements the functionality described in detail in Section 20.10.5. Refresh is not included in the timeslot allocations.
2375CPU and refresh have priority over other accesses. If the refresh controller is requesting i.e. refresh_req is asserted, then the refresh request will win any arbitration initiated by re_arbitrate. When the refresh has won the arbitration refresh_req is de-asserted.
2376The refresh counter is reset to RefreshPeriod[8:0] i.e. the number of cycles between each refresh. Every time this counter decrements to 0, a refresh is issued by asserting refresh_req. The counter immediately reloads with the value in RefreshPeriod[8:0] and continues its countdown. It does not wait for an acknowledgment, since the priority of a refresh request supersedes that of any pending non-CPU access and it will be serviced immediately. In this way, a refresh request is guaranteed to occur every (RefreshPeriod[8:0]+1) cycles. A given refresh request may incur some incidental delay in being serviced, due to alignment with DRAM accesses and the possibility of a higher-priority CPU pre-access.
2377Refresh is also included in the unused read and write timeslot allocation, having second option on awards to a round-robin position shared with the CPU. A refresh issued as a result of an unused timeslot allocation also causes the refresh counter to reload with the value in RefreshPeriod[8:0]. The first access issued by the DAU after reset must be a refresh. This assures that refreshes for all DRAM words fall within the required 3.2 ms window.
2378<tables id="TABLE-US-00191" num="00191"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>//issue a refresh request if counter reaches 0 or at</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>reset or for re-allocated slot</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>if RefreshPeriod != 0 AND (refresh_cnt = = 0 OR</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>diu_soft_reset_n = = 0 OR</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="49pt" align="left" /><colspec colname="3" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry>prst_n</entry><entry>= =0</entry><entry>OR</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>unused_timeslot_allocation = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>refresh_req = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>//de-assert refresh request when refresh acked</entry></row><row><entry /><entry>else if refresh_ack = = 1 then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>refresh_req = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>//refresh counter</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>if refresh_cnt = = 0 OR diu_soft_reset_n = = 0 OR prst_n = =0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="84pt" align="left" /><colspec colname="1" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>OR unused timeslot allocation = =</entry></row><row><entry /><entry>1 then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>refresh_cnt = RefreshPeriod</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>refresh_cnt = refresh_cnt − 1</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2379Refresh can preceded by a CPU access in the same way as any other access. This is controlled by the CPUPreAccessTimeslots and CPUTotalTimeslots configuration registers. Refresh will therefore not affect CPU performance. A sequence of accesses including refresh might therefore be CPU, refresh, CPU, actual timeslot.
000020.14.12.10 CPU Timeslot Controller Description
2380CPU accesses have priority over all other accesses. CPU access is not included in the timeslot allocations. CPU access is controlled by the CPUPreAccessTimeslots and CPUTotalTimeslots configuration registers.
2381To avoid the CPU having to wait for its next timeslot it is desirable to have a mechanism for ensuring that the CPU always gets the next available timeslot without incurring any latency on the non-CPU timeslots.
2382This is be done by defining each timeslot as consisting of a CPU access preceding a non-CPU access. Two counters of 4-bits each are defined allowing the CPU to get a maximum of (CPUPreAccessTimeslots+1) pre-accesses out of a total of (CPUTotalTimeslots+1) main slots. A timeslot counter starts at CPUTotalTimeslots and decrements every timeslot, while another counter starts at CPUPreAccessTimeslots and decrements every timeslot in which the CPU uses its access. If the pre-access entitlement is used up before (CPUTotalTimeslots+1) slots, no further CPU accesses are allowed. When the CPUTotalTimeslots counter reaches zero both counters are reset to their respective initial values.
2383When CPUPreAccessTimeslots is set to zero then only one pre-access will occur during every (CPUTotalTimeslots+1) slots.
000020.14.12.10.1 Conserving CPU Pre-accesses
2384In section 20.10.6.2.1 on page 249, it is described how the CPU can be allowed participate in the unused read round-robin scheme. When enabled by the configuration bit EnableCPURoundRobin, the CPU shares a joint position in the round robin with refresh. In this case, the CPU has priority, ahead of refresh, in availing of any unused slot awarded to this position.
2385Such CPU round-robin accesses do not count towards depleting the CPU's quota of pre-accesses, specified by CPUPreAccessTimeslots. Note that in order to conserve these pre-accesses, the arbitration logic, when faced with the choice of servicing a CPU request either by a pre-access or by an immediately following unused read slot which the CPU is poised to win, will opt for the latter.
000020.14.13 Read and Write Data Multiplexor Sub-block
2386<tables id="TABLE-US-00192" num="00192"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 138</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Read and Write Multiplexor Sub-block IO Definition</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>Port name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Clocks and Resets</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>Pclk</entry><entry>1</entry><entry>In</entry><entry>System Clock</entry></row><row><entry>prst_n</entry><entry>1</entry><entry>In</entry><entry>System reset, synchronous active low</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>DIU Read Interface to SoPEC Units</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>diu_data</entry><entry>64</entry><entry>Out</entry><entry>Data from DIU to SoPEC Units except</entry></row><row><entry /><entry /><entry /><entry>CPU.</entry></row><row><entry /><entry /><entry /><entry>First 64-bits is bits 63:0 of 256</entry></row><row><entry /><entry /><entry /><entry>bit word</entry></row><row><entry /><entry /><entry /><entry>Second 64-bits is bits 127:64 of</entry></row><row><entry /><entry /><entry /><entry>256 bit word</entry></row><row><entry /><entry /><entry /><entry>Third 64-bits is bits 191:128 of</entry></row><row><entry /><entry /><entry /><entry>256 bit word</entry></row><row><entry /><entry /><entry /><entry>Fourth 64-bits is bits 255:192 of</entry></row><row><entry /><entry /><entry /><entry>256 bit word</entry></row><row><entry>dram_cpu<sub>—</sub></entry><entry>256</entry><entry>Out</entry><entry>256-bit data from DRAM to CPU.</entry></row><row><entry>data</entry></row><row><entry>diu_<unit><sub>—</sub></entry><entry>1</entry><entry>Out</entry><entry>Signal from DIU telling SoPEC Unit</entry></row><row><entry>rvalid</entry><entry /><entry /><entry>that valid read data is on the</entry></row><row><entry /><entry /><entry /><entry>diu_data bus</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>DIU Write Interface to SoPEC Units</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="119pt" align="left" /><tbody valign="top"><row><entry><unit>_diu<sub>—</sub></entry><entry>64</entry><entry>In</entry><entry>Data from SoPEC Unit to DIU except</entry></row><row><entry>data</entry><entry /><entry /><entry>CPU.</entry></row><row><entry /><entry /><entry /><entry>First 64-bits is bits 63:0 of 256</entry></row><row><entry /><entry /><entry /><entry>bit word</entry></row><row><entry /><entry /><entry /><entry>Second 64-bits is bits 127:64 of</entry></row><row><entry /><entry /><entry /><entry>256 bit word</entry></row><row><entry /><entry /><entry /><entry>Third 64-bits is bits 191:128 of</entry></row><row><entry /><entry /><entry /><entry>256 bit word</entry></row><row><entry /><entry /><entry /><entry>Fourth 64-bits is bits 255:192 of</entry></row><row><entry /><entry /><entry /><entry>256 bit word</entry></row><row><entry>cpu_diu<sub>—</sub></entry><entry>128</entry><entry>In</entry><entry>Write data from CPU to DIU.</entry></row><row><entry>wdatat</entry></row><row><entry><unit>_diu<sub>—</sub></entry><entry>1</entry><entry>In</entry><entry>Signal from SoPEC Unit indicating</entry></row><row><entry>wvalid</entry><entry /><entry /><entry>that data on <unit>_diu_data is</entry></row><row><entry /><entry /><entry /><entry>valid. Note that “unit” refers</entry></row><row><entry /><entry /><entry /><entry>to non-CPU requesters only.</entry></row><row><entry>cpu_diu<sub>—</sub></entry><entry>1</entry><entry>In</entry><entry>Write enable for the CPU posted</entry></row><row><entry>wdatavalid</entry><entry /><entry /><entry>write buffer. Also confirms the</entry></row><row><entry /><entry /><entry /><entry>validity of cpu_diu_wdata.</entry></row><row><entry>diu_cpu<sub>—</sub></entry><entry>1</entry><entry>Out</entry><entry>Indicator that the CPU posted write</entry></row><row><entry>write_rdy</entry><entry /><entry /><entry>buffer is empty.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Inputs from CPU Configuration and Arbitration Logic Sub-block</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>arb_gnt</entry><entry>1</entry><entry>In</entry><entry>Signal lasting 1 cycle which indi-</entry></row><row><entry /><entry /><entry /><entry>cates arbitration has occurred</entry></row><row><entry /><entry /><entry /><entry>and arb_sel is valid.</entry></row><row><entry>arb_sel</entry><entry>5</entry><entry>In</entry><entry>Signal indicating which requesting</entry></row><row><entry /><entry /><entry /><entry>SoPEC Unit has won arbitration.</entry></row><row><entry /><entry /><entry /><entry>Encoding is described in Table .</entry></row><row><entry>dir_sel</entry><entry>2</entry><entry>In</entry><entry>Signal indicating which sense of</entry></row><row><entry /><entry /><entry /><entry>access associated with arb_sel</entry></row><row><entry /><entry /><entry /><entry>00: issue non-CPU write</entry></row><row><entry /><entry /><entry /><entry>01: read winner</entry></row><row><entry /><entry /><entry /><entry>10: write winner</entry></row><row><entry /><entry /><entry /><entry>11: refresh winner</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Outputs to Command Multiplexor Sub-block</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>write_data<sub>—</sub></entry><entry>2</entry><entry>Out</entry><entry>Signal indicating that valid write</entry></row><row><entry>valid</entry><entry /><entry /><entry>data is available for the current</entry></row><row><entry /><entry /><entry /><entry>command.</entry></row><row><entry /><entry /><entry /><entry>00 = not valid</entry></row><row><entry /><entry /><entry /><entry>01 = CPU write data valid</entry></row><row><entry /><entry /><entry /><entry>10 = non-CPU write data valid</entry></row><row><entry /><entry /><entry /><entry>11 = both CPU and non-CPU write</entry></row><row><entry /><entry /><entry /><entry>data valid</entry></row><row><entry>wdata</entry><entry>256</entry><entry>Out</entry><entry>256-bit non-CPU write data</entry></row><row><entry>cpu_wdata</entry><entry>32</entry><entry>Out</entry><entry>32-bit CPU write data</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Inputs from Command Multiplexor Sub-block</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>write_data<sub>—</sub></entry><entry>2</entry><entry>In</entry><entry>Signal indicating the Command</entry></row><row><entry>accept</entry><entry /><entry /><entry>Multiplexor has accepted the</entry></row><row><entry /><entry /><entry /><entry>write data from the write</entry></row><row><entry /><entry /><entry /><entry>multiplexor</entry></row><row><entry /><entry /><entry /><entry>00 = not valid</entry></row><row><entry /><entry /><entry /><entry>01 = accepts CPU write data</entry></row><row><entry /><entry /><entry /><entry>10 = accepts non-CPU write</entry></row><row><entry /><entry /><entry /><entry>data</entry></row><row><entry /><entry /><entry /><entry>11 = not valid</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Inputs from DCU</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>dcu_dau<sub>—</sub></entry><entry>256</entry><entry>In</entry><entry>256-bit read data from DCU.</entry></row><row><entry>rdata</entry></row><row><entry>dcu_dau<sub>—</sub></entry><entry>1</entry><entry>In</entry><entry>Signal indicating valid read data</entry></row><row><entry>rvalid</entry><entry /><entry /><entry>on dcu_dau_rdata.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Outputs to CPU Configuration and Arbitration Logic Sub-block</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>read_cmd<sub>—</sub></entry><entry>2</entry><entry>Out</entry><entry>Signal indicating that read multi-</entry></row><row><entry>rdy</entry><entry /><entry /><entry>plexor is ready for next read</entry></row><row><entry /><entry /><entry /><entry>read command.</entry></row><row><entry /><entry /><entry /><entry>00 = not ready</entry></row><row><entry /><entry /><entry /><entry>01 = ready for CPU read</entry></row><row><entry /><entry /><entry /><entry>10 = ready for non-CPU read</entry></row><row><entry /><entry /><entry /><entry>11 = ready for both CPU and</entry></row><row><entry /><entry /><entry /><entry>non-CPU reads</entry></row><row><entry>write_cmd<sub>—</sub></entry><entry>2</entry><entry>Out</entry><entry>Signal indicating that write</entry></row><row><entry>rdy</entry><entry /><entry /><entry>multiplexor is ready for next</entry></row><row><entry /><entry /><entry /><entry>write command.</entry></row><row><entry /><entry /><entry /><entry>00 = not ready</entry></row><row><entry /><entry /><entry /><entry>01 = ready for CPU write</entry></row><row><entry /><entry /><entry /><entry>10 = ready for non-CPU write</entry></row><row><entry /><entry /><entry /><entry>11 = ready for both CPU and</entry></row><row><entry /><entry /><entry /><entry>non-CPU writes</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Debug Outputs to CPU Configuration and Arbitration Logic Sub-block</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>read_sel</entry><entry>5</entry><entry>Out</entry><entry>Signal indicating the SoPEC Unit</entry></row><row><entry /><entry /><entry /><entry>for which the current read trans-</entry></row><row><entry /><entry /><entry /><entry>action is occurring. Encoding is</entry></row><row><entry /><entry /><entry /><entry>described in Table .</entry></row><row><entry>read<sub>—</sub></entry><entry>1</entry><entry>Out</entry><entry>Signal indicating that read trans-</entry></row><row><entry>complete</entry><entry /><entry /><entry>action to SoPEC Unit indicated by</entry></row><row><entry /><entry /><entry /><entry>read_sel is complete.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 20.14.13.1 Read Multiplexor Logic Description
2387The Read Multiplexor has 2 read channels <ul id="ul0233" list-style="none"><li id="ul0233-0001" num="0000"><ul id="ul0234" list-style="none"><li id="ul0234-0001" num="2388">a separate read bus for the CPU, dram_cpu_data[255:0].</li><li id="ul0234-0002" num="2389">and a shared read bus for the rest of SoPEC, diu_data[63:0].</li></ul></li></ul>
2390The validity of data on the data busses is indicated by signals diu_<unit>_rvalid.
2391Timing waveforms for non-CPU and CPU DIU read accesses are shown in <figref idref="DRAWINGS">FIG. 90</figref> and <figref idref="DRAWINGS">FIG. 91</figref>, respectively.
2392The Read Multiplexor timing is shown in <figref idref="DRAWINGS">FIG. 127</figref>. <figref idref="DRAWINGS">FIG. 127</figref> shows both CPU and non-CPU reads. Both CPU and non-CPU channels are independent i.e. data can be output on the CPU read bus while non-CPU data is being transmitted in 4 cycles over the shared 64-bit read bus. CPU read data, dram_cpu_data[255.0], is available in the same cycle as output from the DCU. CPU read data needs to be registered immediately on entering the CPU by a flip-flop enabled by the diu_cpu_rvalid signal.
2393To ease timing, non-CPU read data from the DCU is first registered in the Read Multiplexor by capturing it in the shared read data buffer of <figref idref="DRAWINGS">FIG. 126</figref> enabled by the dcu_dau_rvalid signal.
2394The data is then partitioned in 64-bit words on diu_data[63:0].
000020.14.13.1.1 Non-CPU Read Data Coherency
2395Note that for data coherency reasons, a non-CPU read will always result in read data being returned to the requester which includes the after-effects of any pending (i.e. pre-arbitrated, but not yet executed) non-CPU write to the same address, which is currently cached in the non-CPU write buffer. This is shown graphically in Figure n page 319 on page Err r! B kmark not defined.
2396Should the pending write be partially masked, then the read data returned must take account of that mask. Pending, masked writes by the CDU and SCB, as well as all unmasked non-CPU writes are fully supported.
2397Since CPU writes are dealt with on a dedicated write channel, no attempt is made to implement coherency between posted, unexecuted CPU writes and non-CPU reads to the same address.
000020.14.13.1.2 Read Multiplexor Command Queue
2398When the Arbitration Logic sub-block issues a read command the associated value of arb_sel[4:0], which indicates which SoPEC Unit has won arbitration, is written into a buffer, the read command queue.
2399<tables id="TABLE-US-00193" num="00193"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>write_en = arb_gnt AND dir_sel[1:0]= =“01”</entry></row><row><entry /><entry>if write_en= =1 then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>WRITE arb_sel into read command queue</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2400The encoding of arb_sel[4:0] is given in Table. dir_sel[1:0]==“01” indicates that the operation is a read. The read command queue is shown in <figref idref="DRAWINGS">FIG. 128</figref>.
2401The command queue could contain values of arb_sel[4:0] for 3 reads at a time. <ul id="ul0235" list-style="none"><li id="ul0235-0001" num="0000"><ul id="ul0236" list-style="none"><li id="ul0236-0001" num="2402">In the scenario of <figref idref="DRAWINGS">FIG. 127</figref> the command queue can contain 2 values of arb_sel[4:0] i.e. for the simultaneous CDU and CPU accesses.</li><li id="ul0236-0002" num="2403">In the scenario of <figref idref="DRAWINGS">FIG. 130</figref>, the command queue can contain 3 values of arb_sel[4:0] i.e. at the time of the second dcu_dau_rvalid pulse the command queue will contain an arb_sel[4:0] for the arbitration performed in that cycle, and the two previous arb_sel[4:0] values associated with the data for the first two dcu_dau_rvalid pulses, the data associated with the first dcu_dau_rvalid pulse not having been fully transfered over the shared read data bus.</li></ul></li></ul>
2404The read command queue is specified as 4 deep so it is never expected to fill.
2405The top of the command queue is a signal read_type[4:0] which indicates the destination of the current read data. The encoding of read_type[4:0] is given in Table.
000020.14.13.1.3 CPU Reads
2406Read data for the CPU goes straight out on dram_cpu_data[255:0] and dcu_dau_rvalid is output on diu_cpu_rvalid.
2407cpu_read_complete(0) is asserted when a CPU read at the top of the read command queue occurs. cpu_read_complete(0) causes the read command queue to be popped.
2408<tables id="TABLE-US-00194" num="00194"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>cpu_read_complete(0) = (read_type[4:0] = = CPU read) AND</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>(dcu_dau_rvalid = = 1)</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2409If the current read command queue location points to a non-CPU access and the second read command queue location points to a CPU access then the next dcu_dau_rvalid pulse received is associated with a CPU access. This is the scenario illustrated in <figref idref="DRAWINGS">FIG. 127</figref>. The dcu_dau_rvalid pulse from the DCU must be output to the CPU as diu_cpu_rvalid. This is achieved by using cpu_read_complete(1) to multiplex dcu_dau_rvalid to diu_cpu_rvalid. cpu_read_complete(1) is also used to pop the second from top read command queue location from the read command queue.
2410<tables id="TABLE-US-00195" num="00195"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>cpu_read_complete(1) = (read_type = = non-CPU read)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="98pt" align="left" /><colspec colname="1" colwidth="35pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry>AND</entry><entry>SECOND (read_type</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>= = CPU read) AND (dcu_dau_rvalid = = 1)</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 20.14.13.1.4 Multiplexing dcu_dau_rvalid
2411read_type[4:0] and cpu_read_complete(1) multiplexes the data valid signal, dcu_dau_rvalid, from the DCU, between the CPU and the shared read bus logic. diu_cpu_rvalid is the read valid signal going to the CPU. noncpu_rvalid is the read valid signal used by the Read Multiplexor control logic to generate read valid signals for non-CPU reads.
2412<tables id="TABLE-US-00196" num="00196"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>if read_type[4:0] = = CPU-read then</entry></row><row><entry /><entry>//select CPU</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>diu_cpu_rvalid:= 1</entry></row><row><entry /><entry>noncpu_rvalid:= 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="63pt" align="left" /><colspec colname="4" colwidth="21pt" align="left" /><tbody valign="top"><row><entry /><entry>if</entry><entry>(read_type[4:0]= =</entry><entry>non-CPU-read)</entry><entry>AND</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>SECOND(read_type[4:0]= = CPU-read)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>AND dcu_dau_rvalid = = 1 then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>//select CPU</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>diu_cpu_rvalid:= 1</entry></row><row><entry /><entry>noncpu_rval_id:= 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>//select shared read bus logic</entry></row><row><entry /><entry>diu_cpu_rvalid:= 0</entry></row><row><entry /><entry>noncpu_rvalid:= 1</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 20.14.13.1.5 Non-CPU Reads
2413Read data for the shared read bus is registered in the shared read data buffer using noncpu_rvalid. The shared read buffer has 5 locations of 64 bits with separate read pointer, read_ptr[2:0], and write pointer, write_ptr[2:0].
2414<tables id="TABLE-US-00197" num="00197"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>if noncpu_rvalid = = 1 and (4 spaces in shared read</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>buffer) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><colspec colname="2" colwidth="49pt" align="center" /><tbody valign="top"><row><entry /><entry>shared_read_data_buffer[write_ptr]</entry><entry>=</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>dcu_dau_data[63:0]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><colspec colname="2" colwidth="49pt" align="center" /><tbody valign="top"><row><entry /><entry>shared_read_data_buffer[write_ptr+1]</entry><entry>=</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>dcu_dau_data[127:64]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><colspec colname="2" colwidth="49pt" align="center" /><tbody valign="top"><row><entry /><entry>shared_read_data_buffer[write_ptr+2]</entry><entry>=</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>dcu_dau_data[191:128]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><colspec colname="2" colwidth="49pt" align="center" /><tbody valign="top"><row><entry /><entry>shared_read_data_buffer[write_ptr+3]</entry><entry>=</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>dcu_dau_data[255:192]</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2415The data written into the shared read buffer must be output to the correct SoPEC DIU read requestor according to the value of read_type[4:0] at the top of the command queue. The data is output 64 bits at a time on diu_data[63:0] according to a multiplexor controlled by read_ptr[2:0]. <ul id="ul0237" list-style="none"><li id="ul0237-0001" num="0000"><ul id="ul0238" list-style="none"><li id="ul0238-0001" num="2416">diu_data[63:0=shared_read_data_buffer[read_ptr]</li></ul></li></ul>
2417<figref idref="DRAWINGS">FIG. 126</figref> shows how read_type[4:0] also selects which shared read bus requesters diu_<unit>_rvalid signal is connected to shared_rvalid. Since the data from the DCU is registered in the Read Multiplexor then shared_rvalid is a delayed version of noncpu_rvalid.
2418When the read valid, diu_<unit>_rvalid, for the command associated with read_type[4:0] has been asserted for 4 cycles then a signal shared_read_complete is asserted. This indicates that the read has completed. shared_read_complete causes the value of read_type[4:0] in the read command queue to be popped.
2419A state machine for shared read bus access is shown in <figref idref="DRAWINGS">FIG. 129</figref>. This show the generation of shared_rvalid, shared_read_complete and the shared read data buffer read pointer, read_ptr[2:0], being incremented.
2420Some points to note from <figref idref="DRAWINGS">FIG. 129</figref> are: <ul id="ul0239" list-style="none"><li id="ul0239-0001" num="0000"><ul id="ul0240" list-style="none"><li id="ul0240-0001" num="2421">shared_rvalid is asserted the cycle after dcu_dau_rvalid associated with a shared read bus access. This matches the cycle delay in capturing dau_dcu_data[255:0] in the shared read data buffer. shared_rvalid remains asserted in the case of back to back shared read bus accesses.</li><li id="ul0240-0002" num="2422">shared_read_complete is asserted in the last shared_rvalid cycle of a non-CPU access. shared_read_complete causes the shared read data queue to be popped. <br /> 20.14.13.1.6 Read Command Queue Read Pointer Logic </li></ul></li></ul>
2423The read command queue read pointer logic works as follows.
2424<tables id="TABLE-US-00198" num="00198"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>if shared_read_complete = = 1 OR cpu_read_complete(0) = = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>POP top of read command queue</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>if cpu_read_complete(1) = = 1 then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>POP second read command queue location</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 20.14.13.1.7 Debug Signals
2425shared_read_complete and cpu_read_complete together define read_which indicates to the debug logic that a read has completed. The source of the read is indicated on read_sel[4:0].
2426<tables id="TABLE-US-00199" num="00199"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="28pt" align="left" /><colspec colname="3" colwidth="84pt" align="left" /><colspec colname="4" colwidth="14pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="4" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>read_complete</entry><entry>=</entry><entry>shared_read_complete</entry><entry>OR</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>cpu_read_complete(0)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="98pt" align="left" /><colspec colname="1" colwidth="119pt" align="left" /><tbody valign="top"><row><entry /><entry>OR cpu_read_complete(1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>if cpu_read_complete(1) = = 1 then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>read_sel:= SECOND(read_type)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>read_sel:= read_type</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 20.14.13.1.8 Flow Control
2427There are separate indications that the Read Multiplexor is able to accept CPU and shared read bus commands from the Arbitration Logic. These are indicated by read_cmd_rdy[1:0].
2428The Arbitration Logic can always issue CPU reads except if the read command queue fills. The read command queue should be large enough that this should never occur.
2429<tables id="TABLE-US-00200" num="00200"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>//Read Multiplexor ready for Arbitration Logic to</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="196pt" align="left" /><tbody valign="top"><row><entry /><entry>issue CPU reads</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>read_cmd_rdy[0] = = read command queue not full</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2430For the shared read data, the Read Multiplexor deasserts the shared read bus read_cmd_rdy[1] indication until a space is available in the read command queue. The read command queue should be large enough that this should never occur.
2431read_cmd_rdy[1] is also deasserted to provide flow control back to the Arbitration Logic to keep the shared read data bus just full.
2432<tables id="TABLE-US-00201" num="00201"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>//Read Multiplexor not ready for Arbitration Logic to</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>issue non-CPU reads</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>read_cmd_rdy[1] = (read command queue not full) AND</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>(flow_control = 0)</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2433The flow control condition is that DCU read data from the second of two back-to-back shared read bus accesses becomes available. This causes read_cmd rdy[1] to de-assert for 1 cycle, resulting in a repeated MSN2 DCU state. The timing is shown in <figref idref="DRAWINGS">FIG. 130</figref>.
2434<tables id="TABLE-US-00202" num="00202"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>flow_control = (read_type[4:0] = = non-CPU read)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="77pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>AND SECOND(read type[4:0] = = non-</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="196pt" align="left" /><tbody valign="top"><row><entry /><entry>CPU read)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="77pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>AND (current DCU state = = MSN2)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="63pt" align="left" /><colspec colname="1" colwidth="154pt" align="left" /><tbody valign="top"><row><entry /><entry>AND (previous DCU state = = MSN1).</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2435<figref idref="DRAWINGS">FIG. 130</figref> shows a series of back to back transfers over the shared read data bus. The exact timing of the implementation must not introduce any additional latency on shared read bus read transfers i.e. arbitration must be re-enabled just in time to keep back to back shared read bus data full.
2436The following sequence of events is illustrated in <figref idref="DRAWINGS">FIG. 130</figref>: <ul id="ul0241" list-style="none"><li id="ul0241-0001" num="0000"><ul id="ul0242" list-style="none"><li id="ul0242-0001" num="2437">Data from the first DRAM access is written into the shared read data buffer.</li><li id="ul0242-0002" num="2438">Data from the second access is available 3 cycles later, but its transfer into the shared read buffer is delayed by a cycle, due to the MSN2 stall condition. (During this delay, read data for access 2 is maintained at the output of the DRAM.) A similar 1-cycle delay is introduced for every subsequent read access until the back-to-back sequence comes to an end.</li><li id="ul0242-0003" num="2439">Note that arbitration always occurs during the last MSN2 state of any access. So, for the second and later of any back-to-back non-CPU reads, arbitration is delayed by one cycle, i.e. it occurs every fourth cycle instead of the standard every third.</li></ul></li></ul>
2440This mechanism provides flow control back to the Arbitration Logic sub-block. Using this mechanism means that the access rate will be limited to which ever takes longer—DRAM access or transfer of read data over the shared read data bus. CPU reads are always be accepted by the Read Multiplexor.
000020.14.13.2 Write Multiplexor Logic Description
2441The Write Multiplexor supplies write data to the DCU.
2442There are two separate write channels, one for CPU data on cpu_diu<sub>—</sub>[127:0], one for non-CPU data on non_cpu_wdata[255:0]. A signal write_data valid[1:0] indicates to the Command Multiplexor that the data is valid. The Command Multiplexor then asserts a signal write_data_accept[1:0] indicating that the data has been captured by the DRAM and the appropriate channel in the Write Multiplexor can accept the next write data.
2443Timing waveforms for write accesses are shown in <figref idref="DRAWINGS">FIG. 92</figref> to <figref idref="DRAWINGS">FIG. 94</figref>, respectively.
2444There are 3 types of write accesses: <ul id="ul0243" list-style="none"><li id="ul0243-0001" num="0000"><ul id="ul0244" list-style="none"><li id="ul0244-0001" num="2445">CPU accesses</li></ul></li></ul>
2446CPU write data on cpu_diu_wdata[127:0] is output on cpu_wdata[127:0]. Since CPU writes are posted, a local buffer is used to store the write data, address and mask until the CPU wins arbitration. This buffer is one position deep. write_data_valid[0], which is synonymous with !diu_cpu_w_write_rdy, remains asserted until the Command Multiplexor indicates it has been written to the DRAM by asserting write_data_accept[0]. The CPU write buffer can then accept new posted writes.
2447For non-CPU writes, the Write Multiplexor multiplexes the write data from the DIU write requester to the write data buffer and the <unit>_diu_wvalid signal to the write multiplexor control logic. <ul id="ul0245" list-style="none"><li id="ul0245-0001" num="0000"><ul id="ul0246" list-style="none"><li id="ul0246-0001" num="2448">CDU accesses <ul id="ul0247" list-style="none"><li id="ul0247-0001" num="2449">64-bits of write data each for a masked write to a separate 256-bit word are transferred to the Write Multiplexor over 4 cycles.</li></ul></li></ul></li></ul>
2450When a CDU write is selected the first 64-bits of write data on cdu_diu_wdata[63:0] are multiplexed to non_cpu_wdata[63:0]. write_data_valid[1] is asserted to indicate a non-CPU access when cdu_diu_wvalid is asserted. The data is also written into the first location in the write data buffer. This is so that the data can continue to be output on non_cpu_wdata[63:0] and write_data_valid[1] remains asserted until the Command Multiplexor indicates it has been written to the DRAM by asserting write_data_accept[1]. Data continues to be accepted from the CDU and is written into the other locations in the write data buffer. Successive write_data_accept[1] pulses cause the successive 64-bit data words to be output on wdata[63:0] together with write_data_valid[1]. The last write_data_accept[1] means the write buffer is empty and new write data can be accepted. <ul id="ul0248" list-style="none"><li id="ul0248-0001" num="0000"><ul id="ul0249" list-style="none"><li id="ul0249-0001" num="2451">Other write accesses. <ul id="ul0250" list-style="none"><li id="ul0250-0001" num="2452">256-bits of write data are transferred to the Write Multiplexor over 4 successive cycles.</li><li id="ul0250-0002" num="2453">When a write is selected the first 64-bits of write data on <unit>_diu_wdata[63:0] are written into the write data buffer. The next 64-bits of data are written to the buffer in successive cycles. Once the last 64-bit word is available on <unit>_diu_wdata[63:0] the entire word is output on non_cpu_wdata[255:0], write_data_valid [1] is asserted to indicate a non-CPU access, and the last 64-bit word is written into the last location in the write data buffer. Data continues to be output on non_cpu_wdata[255:0] and write_data_valid[1] remains asserted until the Command Multiplexor indicates it has been written to the DRAM by asserting write_data_accept[1]. New write data can then be written into the write buffer.</li></ul></li></ul></li></ul>
2454CPU write multiplexor control logic
2455When the Command Multiplexor has issued the CPU write it asserts write_data_accept[0]. write_data_accept[0] causes the write multiplexor to assert write_cmd_rdy[0].
2456The signal write_cmd_rdy[0] tells the Arbitration Logic sub-block that it can issue another CPU write command i.e. the CPU write data buffer is empty.
0000Non-CPU Write Multiplexor Control Logic
2457The signal write_cmd_rdy[1] tells the Arbitration Logic sub-block that the Write Multiplexor is ready to accept another non-CPU write command. When write_cmd_rdy[1] is asserted the Arbitration Logic can issue a write command to the Write Multiplexor. It does this by writing the value of arb_sel[4:0] which indicates which SoPEC Unit has won arbitration into a write command register, write_cmd[3:0].
2458<tables id="TABLE-US-00203" num="00203"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>write_en = arb_gnt AND dir_sel[1]= =1 AND arb_sel = non-</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>CPU</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>if write_en= =1 then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>write_cmd = arb_sel</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2459The encoding of arb_sel[4:0] is given in Table. dir_sel[1]==1 indicates that the operation is a write. arb_sel[4:0] is only written to the write command register if the write is a non-CPU write.
2460A rule was introduced in Section 20.7.2.3 Interleaving read and write accesses to the effect that non-CPU write accesses would not be allocated adjacent timeslots. This means that a single write command register is required.
2461The write command register, write_cmd[3:0], indicates the source of the write data. write_cmd[3:0] multiplexes the write data <unit>_diu_wdata, and the data valid signal, <unit>_diu_wvalid, from the selected write requestor to the write data buffer. Note, that CPU write data is not included in the multiplex as the CPU has its own write channel. The <unit>_diu_wvalid are counted to generate the signal word_sel[1:0] which decides which 64-bit word of the write data buffer to store the data from <unit>_diu_wdata.
2462<tables id="TABLE-US-00204" num="00204"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="196pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>//when the Command Multiplexor accepts the write data</entry></row><row><entry /><entry>if write_data_accept[1] = 1 then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>//reset the word select signal</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>word_sel[1:0]=00</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="196pt" align="left" /><tbody valign="top"><row><entry /><entry>//when wvalid is asserted</entry></row><row><entry /><entry>if wvalid = 1 then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>//increment the word select signal</entry></row><row><entry /><entry>if word_sel[1:0] = = 11 then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>word_sel[1:0] = = 00</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>word_sel[1:0] = = word_sel[1:0] + 1</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> wvalid is the <unit>_diu_wvalid signal multiplexed by write_cmd[3:0]. word_sel[1:0] is reset when the Command Multiplexor accepts the write data. This is to ensure that word_sel[1:0] is always starts at 00 for the first wvalid pulse of a 4 cycle write data transfer.
2463The write command register is able to accept the next write when the Command Multiplexor accepts the write data by asserting write_data_accept[1]. Only the last write_data_accept[1] pulse associated with a CDU access (there are 4) will cause the write command register to be ready to accept the next write data.
2464Flow control back to the Command Multiplexor <ul id="ul0251" list-style="none"><li id="ul0251-0001" num="2465">write_cmd rdy[0] is asserted when the CPU data buffer is empty.</li><li id="ul0251-0002" num="2466">write_cmd_rdy[1] is asserted when both the write command register and the write data buffer is empty. <br /> PEP Subsystem <br /> 21 PEP Controller Unit (PCU) <br /> 21.1 Overview </li></ul>
2467The PCU has three functions: <ul id="ul0252" list-style="none"><li id="ul0252-0001" num="0000"><ul id="ul0253" list-style="none"><li id="ul0253-0001" num="2468">The first is to act as a bus bridge between the CPU-bus and the PCU-bus for reading and writing PEP configuration registers.</li></ul></li></ul>
2469The second is to support page banding by allowing the PEP blocks to be reprogrammed between bands by retrieving commands from DRAM instead of being programmed directly by the CPU.
2470The third is to send register debug information to the RDU, within the CPU subsystem, when the PCU is in Debug Mode.
000021.2 Interfaces Between PCU and Other Units
000021.3 Bus Bridge
2471The PCU is a bus-bridge between the CPU-bus and the PCU-bus. The PCU is a slave on the CPU-bus but is the only master on the PCU-bus. See Figure page 39 on page Error! Bookmark not defined.
000021.3.1 CPU Accessing PEP
2472All the blocks in the PEP can be addressed by the CPU via the PCU. The MMU in the CPU-subsystem will decode a PCU select signal, cpu_pcu_sel, for all the PCU mapped addresses (see section 11.4.3 on page 69). Using cpu_adr bits <b>15</b>–<b>12</b> the PCU will decode individual block selects for each of the blocks within the PEP. The PEP blocks then decode the remaining address bits needed to address their PCU-bus mapped registers. Note: the CPU is only permitted to perform supervisor-mode data-type accesses of the PEP, i.e. cpu_acode=11. If the PCU is selected by the CPU and any other code is present on the cpu_acode bus the access is ignored by the PCU and the pcu_cpu_berr signal is strobed,
2473CPU commands have priority over DRAM commands. When the PCU is executing each set of four commands retrieved from DRAM the CPU can access PCU-bus registers. In the case that DRAM commands are being executed and the CPU resets the CmdSource to zero, the contents of the DRAM CmdFifo is invalidated and no further commands from the fifo are executed. The CmdPending and NextBandCmdEnable work registers are also cleared.
2474When a DRAM command writes to the CmdAdr register it means the next DRAM access will occur at the address written to CmdAdr. Therefore if the JUMP instruction is the first command in a group of four, the other three commands get executed and then the PCU will issue a read request to DRAM at the address specified by the JUMP instruction. If the JUMP instruction is the second command then the following two commands will be executed before the PCU requests from the new DRAM address specified by the JUMP instruction etc. Therefore the PCU will always execute the remaining commands in each four command group before carrying out the JUMP instruction.
000021.4 Page Banding
2475The PCU can be programmed to associate microcode in DRAM with each finishedband signal. When a finishedband signal is asserted the PCU will read commands from DRAM and execute these commands. These commands are each 64-bits (see Section 21.8.5) and consist of 32-bit address bits and 32 data bits and allow PCU mapped registers to be programmed directly by the PCU.
2476If more than one finishedband signal is received at the same time, or others are received while microcode is already executing, the PCU will hold the commands as pending, and will execute them at the first opportunity.
2477Each microcode program associated with cdu_finishedband, lbd_finishedband and te_finishedband would simply restart the appropriate unit with new addresses—a total of about 4 or 5 microcode instructions. As well, or alternatively, pcu_finishedband can be used to set up all of the units and therefore involves many more instructions. This minimizes the time that a unit is idle in between bands. The pcu_finishedband control signal is issued once the specified combination of CDU, LBD and TE (programmed in BandSelectMask) have finished their processing for a band.
000021.5 Interrupts, Address Legality and Security
2478Interrupts are generated when the various page expansion units have finished a particular band of data from DRAM. The cdu_finishedband, lbd_finishedband and te_finishedband signals are combined in the PCU into a single interrupt pcu_finishedband which is exported by the PCU to the interrupt controller.
2479The PCU mapped registers should only be accessible from Supervisor Data Mode. The area of DRAM where PCU commands are stored should be a Supervisor Mode only DRAM area, although this is not enforced by the PCU.
2480When the PCU is executing commands from DRAM, any block-address decoded from a command which is not part of the PEP block-address map will cause the PCU to ignore the command and strobe the pcu_icu_address_invalid interrupt signal. The CPU can then interrogate the PCU to find the source of the illegal command. The MMU will ensure that the CPU cannot address an invalid PEP subsystem block.
2481When the PCU is executing commands from DRAM, any address decoded from a command which is not part of the PEP address map will cause the PCU to: <ul id="ul0254" list-style="none"><li id="ul0254-0001" num="0000"><ul id="ul0255" list-style="none"><li id="ul0255-0001" num="2482">Cease execution of current command and flush all remaining commands already retrieved from DRAM.</li><li id="ul0255-0002" num="2483">Clear CmdPending work-register.</li><li id="ul0255-0003" num="2484">Clear NextBandCmdEnable registers.</li><li id="ul0255-0004" num="2485">Set CmdSource to zero.</li></ul></li></ul>
2486In addition to cancelling all current and pending DRAM accesses the PCU strobes the pcu_icu_address_invalid interrupt signal. The CPU can then interrogate the PCU to find the source of the illegal command.
000021.6 Debug Mode
2487When the need to monitor the (possibly changing) value in any PEP configuration register the PCU may be placed in Debug Mode. This is done via the CPU setting certain Debug Address register within the PCU. Once in Debug Mode the PCU continually reads the target PEP configuration register and sends the read value to the RDU. Debug Mode has the lowest priority of all PCU functions: if the CPU wishes to perform an access or there are DRAM commands to be executed they will interrupt the Debug access, and the PCU will resume Debug access once a CPU or DRAM command has completed.
000021.7 Implementation
000021.7.1 Definitions of I/O
2488<tables id="TABLE-US-00205" num="00205"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 139</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>PCU Port List</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>Port Name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Clocks and Resets</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>Pclk</entry><entry>1</entry><entry>In</entry><entry>SoPEC functional clock</entry></row><row><entry>prst_n</entry><entry>1</entry><entry>In</entry><entry>Active-low, synchronous reset</entry></row><row><entry /><entry /><entry /><entry>in pclk domain</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>End of Band Functionality</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>cdu<sub>—</sub></entry><entry>1</entry><entry>In</entry><entry>Finished band signal from CDU</entry></row><row><entry>finishedband</entry></row><row><entry>lbd<sub>—</sub></entry><entry>1</entry><entry>In</entry><entry>Finished band signal from LBD</entry></row><row><entry>finishedband</entry></row><row><entry>te<sub>—</sub></entry><entry>1</entry><entry>In</entry><entry>Finished band signal from TE</entry></row><row><entry>finishedband</entry></row><row><entry>pcu<sub>—</sub></entry><entry>1</entry><entry>Out</entry><entry>Asserted once the specified</entry></row><row><entry>finishedband</entry><entry /><entry /><entry>combination of CDU, LBD, and</entry></row><row><entry /><entry /><entry /><entry>TE have finished their pro-</entry></row><row><entry /><entry /><entry /><entry>cessing for a band.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>PCU address error</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>pcu_icu<sub>—</sub></entry><entry>1</entry><entry>Out</entry><entry>Strobed if PCU decodes a non</entry></row><row><entry>address<sub>—</sub></entry><entry /><entry /><entry>PEP address from commands</entry></row><row><entry>invalid</entry><entry /><entry /><entry>retrieved from DRAM or CPU.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>CPU Subsystem Interface Signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>cpu_adr[15:2]</entry><entry>14</entry><entry>In</entry><entry>CPU address bus. 14 bits are</entry></row><row><entry /><entry /><entry /><entry>required to decode the address</entry></row><row><entry /><entry /><entry /><entry>space for the PEP.</entry></row><row><entry>cpu_dataout</entry><entry>32</entry><entry>In</entry><entry>Shared write data bus from</entry></row><row><entry>[31:0]</entry><entry /><entry /><entry>the CPU</entry></row><row><entry>pcu_cpu<sub>—</sub></entry><entry>32</entry><entry>Out</entry><entry>Read data bus to the CPU</entry></row><row><entry>data[31:0]</entry></row><row><entry>cpu_rwn</entry><entry>1</entry><entry>In</entry><entry>Common read/not-write signal</entry></row><row><entry /><entry /><entry /><entry>from the CPU</entry></row><row><entry>cpu_acode</entry><entry>2</entry><entry>In</entry><entry>CPU Access Code signals.</entry></row><row><entry>[1:0]</entry><entry /><entry /><entry>These decode as follows:</entry></row><row><entry /><entry /><entry /><entry>00 - User program access</entry></row><row><entry /><entry /><entry /><entry>01 - User data access</entry></row><row><entry /><entry /><entry /><entry>10 - Supervisor program access</entry></row><row><entry /><entry /><entry /><entry>11 - Supervisor data access</entry></row><row><entry>cpu_pcu_sel</entry><entry>1</entry><entry>In</entry><entry>Block select from the CPU. When</entry></row><row><entry /><entry /><entry /><entry>cpu_pcu_sel is high both cpu_adr</entry></row><row><entry /><entry /><entry /><entry>and cpu_dataout are valid</entry></row><row><entry>pcu_cpu_rdy</entry><entry>1</entry><entry>Out</entry><entry>Ready signal to the CPU. When</entry></row><row><entry /><entry /><entry /><entry>pcu_cpu_rdy is high it indi-</entry></row><row><entry /><entry /><entry /><entry>cates the last cycle of the</entry></row><row><entry /><entry /><entry /><entry>access. For a write cycle</entry></row><row><entry /><entry /><entry /><entry>this means cpu_dataout has</entry></row><row><entry /><entry /><entry /><entry>been registered by the block</entry></row><row><entry /><entry /><entry /><entry>and for a read cycle</entry></row><row><entry /><entry /><entry /><entry>this means the data on</entry></row><row><entry /><entry /><entry /><entry>pcu_cpu_data is valid.</entry></row><row><entry>pcu_cpu_berr</entry><entry>1</entry><entry>Out</entry><entry>Bus error signal to the CPU</entry></row><row><entry /><entry /><entry /><entry>indicating an invalid access.</entry></row><row><entry>pcu_cpu<sub>—</sub></entry><entry>1</entry><entry>Out</entry><entry>Debug Data valid on</entry></row><row><entry>debug_valid</entry><entry /><entry /><entry>pcu_cpu_data bus.</entry></row><row><entry /><entry /><entry /><entry>Active high.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>PCU Interface to PEP blocks</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>pcu_adr[11:2]</entry><entry>10</entry><entry>Out</entry><entry>PCU address bus. The 10 least</entry></row><row><entry /><entry /><entry /><entry>significant bits of cpu_adr</entry></row><row><entry /><entry /><entry /><entry>[15:2] allow 1024 32-bit</entry></row><row><entry /><entry /><entry /><entry>word addressable locations per</entry></row><row><entry /><entry /><entry /><entry>PEP block. Only the number of</entry></row><row><entry /><entry /><entry /><entry>bits required to decode the</entry></row><row><entry /><entry /><entry /><entry>address space are exported to</entry></row><row><entry /><entry /><entry /><entry>each block.</entry></row><row><entry>pcu_dataout</entry><entry>32</entry><entry>Out</entry><entry>Shared write data bus from the</entry></row><row><entry>[31:0]</entry><entry /><entry /><entry>PCU</entry></row><row><entry><unit>_pcu<sub>—</sub></entry><entry>32</entry><entry>In</entry><entry>Read data bus from each PEP</entry></row><row><entry>datain[31:0]</entry><entry /><entry /><entry>subblock to the PCU</entry></row><row><entry>pcu_rwn</entry><entry>1</entry><entry>Out</entry><entry>Common read/not-write signal</entry></row><row><entry /><entry /><entry /><entry>from the PCU</entry></row><row><entry>pcu_<unit><sub>—</sub></entry><entry>1</entry><entry>Out</entry><entry>Block select for each PEP block</entry></row><row><entry>sel</entry><entry /><entry /><entry>from the PCU. Decoded from the</entry></row><row><entry /><entry /><entry /><entry>4 most significant bits of</entry></row><row><entry /><entry /><entry /><entry>cpu_adr[15:2]. When</entry></row><row><entry /><entry /><entry /><entry>pcu_<unit>_sel is high both</entry></row><row><entry /><entry /><entry /><entry>pcu_adr and pcu_dataout are</entry></row><row><entry /><entry /><entry /><entry>valid</entry></row><row><entry><unit>_pcu<sub>—</sub></entry><entry>1</entry><entry>In</entry><entry>Ready from each PEP block signal</entry></row><row><entry>rdy</entry><entry /><entry /><entry>to the PCU. When <unit>_pcu_rdy</entry></row><row><entry /><entry /><entry /><entry>is high it indicates the last</entry></row><row><entry /><entry /><entry /><entry>cycle of the access. For a write</entry></row><row><entry /><entry /><entry /><entry>cycle this means pcu_dataout has</entry></row><row><entry /><entry /><entry /><entry>been registered by the block and</entry></row><row><entry /><entry /><entry /><entry>for a read cycle this means the</entry></row><row><entry /><entry /><entry /><entry>data on <unit>_pcu_datain is valid.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>DIU Read Interface signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>pcu_diu_rreq</entry><entry>1</entry><entry>Out</entry><entry>PCU requests DRAM read. A read</entry></row><row><entry /><entry /><entry /><entry>request must be accompanied by a</entry></row><row><entry /><entry /><entry /><entry>valid read address.</entry></row><row><entry>pcu_diu_radr</entry><entry>17</entry><entry>Out</entry><entry>Read address to DIU</entry></row><row><entry>[21:5]</entry><entry /><entry /><entry>17 bits wide (256-bit aligned</entry></row><row><entry /><entry /><entry /><entry>word).</entry></row><row><entry>diu_pcu_rack</entry><entry>1</entry><entry>In</entry><entry>Acknowledge from DIU that read</entry></row><row><entry /><entry /><entry /><entry>request has been accepted and</entry></row><row><entry /><entry /><entry /><entry>new read address can be placed</entry></row><row><entry /><entry /><entry /><entry>on pcu_diu_radr</entry></row><row><entry>diu_data[63:0]</entry><entry>64</entry><entry>In</entry><entry>Data from DIU to PCU.</entry></row><row><entry /><entry /><entry /><entry>First 64-bits is bits 63:0 of</entry></row><row><entry /><entry /><entry /><entry>256 bit word</entry></row><row><entry /><entry /><entry /><entry>Second 64-bits is bits 127:64</entry></row><row><entry /><entry /><entry /><entry>of 256 bit word</entry></row><row><entry /><entry /><entry /><entry>Third 64-bits is bits 191:128</entry></row><row><entry /><entry /><entry /><entry>of 256 bit word</entry></row><row><entry /><entry /><entry /><entry>Fourth 64-bits is bits 255:192</entry></row><row><entry /><entry /><entry /><entry>of 256 bit word</entry></row><row><entry>diu_pcu<sub>—</sub></entry><entry>1</entry><entry>In</entry><entry>Signal from DIU telling PCU</entry></row><row><entry>rvalid</entry><entry /><entry /><entry>that valid read data is on</entry></row><row><entry /><entry /><entry /><entry>the diu_data bus</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 21.7.2 Configuration Registers
2489<tables id="TABLE-US-00206" num="00206"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="294pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 140</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>PCU Configuration Registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="70pt" align="left" /><colspec colname="3" colwidth="28pt" align="center" /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>Address</entry><entry /><entry>#</entry><entry /><entry /></row><row><entry>PCU_base+</entry><entry>register</entry><entry>bits</entry><entry>reset</entry><entry>description</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="294pt" align="left" /><tbody valign="top"><row><entry>Control registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="70pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>0x00</entry><entry>Reset</entry><entry>1</entry><entry>0x1</entry><entry>A write to this register causes</entry></row><row><entry /><entry /><entry /><entry /><entry>a reset of the PCU. This register</entry></row><row><entry /><entry /><entry /><entry /><entry>can be read to indicate the reset</entry></row><row><entry /><entry /><entry /><entry /><entry>state:</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - reset in progress</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - reset not in progress</entry></row><row><entry>0x04</entry><entry>CmdAdr[21:5]</entry><entry>17</entry><entry>0x00 000</entry><entry>The address of the next set of</entry></row><row><entry /><entry>(256-bit aligned</entry><entry /><entry /><entry>commands to retrieve from DRAM.</entry></row><row><entry /><entry>DRAM address)</entry><entry /><entry /><entry>When this register is</entry></row><row><entry /><entry /><entry /><entry /><entry>written to, either by the</entry></row><row><entry /><entry /><entry /><entry /><entry>CPU or DRAM command, 1 is</entry></row><row><entry /><entry /><entry /><entry /><entry>also written to CmdSource</entry></row><row><entry /><entry /><entry /><entry /><entry>to cause the execution of</entry></row><row><entry /><entry /><entry /><entry /><entry>the commands at the specified</entry></row><row><entry /><entry /><entry /><entry /><entry>address.</entry></row><row><entry>0x08</entry><entry>BandSelectMask</entry><entry>3</entry><entry>0x0</entry><entry>Selects which input finishedBand</entry></row><row><entry /><entry>[2:0]</entry><entry /><entry /><entry>flags are to be watched to gene-</entry></row><row><entry /><entry /><entry /><entry /><entry>rate the combined pcu_finishedband</entry></row><row><entry /><entry /><entry /><entry /><entry>signal.</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit0 - lbd_finishedband</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit1 - cdu_finishedband</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit2 - te_finishedband</entry></row><row><entry>0x0C,</entry><entry>NextBandCmdAdr</entry><entry>4 × 17</entry><entry>0x00 000</entry><entry>The address to transfer to CmdAdr</entry></row><row><entry>0x10,</entry><entry>[3:0][21:5]</entry><entry /><entry /><entry>as soon as possible after the next</entry></row><row><entry>0x14,</entry><entry>(256-bit aligned</entry><entry /><entry /><entry>finishedBand[n] signal has been</entry></row><row><entry>0x18</entry><entry>DRAM address)</entry><entry /><entry /><entry>received as long as</entry></row><row><entry /><entry /><entry /><entry /><entry>NextBandCmdEnable[n] is set.</entry></row><row><entry /><entry /><entry /><entry /><entry>A write from the PCU to</entry></row><row><entry /><entry /><entry /><entry /><entry>NextBandCmdAdr[n] with a</entry></row><row><entry /><entry /><entry /><entry /><entry>non-zero value also sets</entry></row><row><entry /><entry /><entry /><entry /><entry>NextBandCmdEnable[n]. A</entry></row><row><entry /><entry /><entry /><entry /><entry>write from the PCU to</entry></row><row><entry /><entry /><entry /><entry /><entry>NextBandCmdAdr[n] with a</entry></row><row><entry /><entry /><entry /><entry /><entry>0 value clears NextBandCmdEnable[n].</entry></row><row><entry>0x1C</entry><entry>NextCmdAdr[21:5]</entry><entry>17</entry><entry>0x00 000</entry><entry>The address to transfer to CmdAdr</entry></row><row><entry /><entry /><entry /><entry /><entry>when the CPU pending bit</entry></row><row><entry /><entry /><entry /><entry /><entry>(CmdPending[4]) get serviced.</entry></row><row><entry /><entry /><entry /><entry /><entry>A write from the PCU to</entry></row><row><entry /><entry /><entry /><entry /><entry>NextCmdAdr[n] with</entry></row><row><entry /><entry /><entry /><entry /><entry>a non-zero value also sets</entry></row><row><entry /><entry /><entry /><entry /><entry>CmdPending[4]. A write</entry></row><row><entry /><entry /><entry /><entry /><entry>from the PCU to NextCmdAdr[n]</entry></row><row><entry /><entry /><entry /><entry /><entry>with a 0 value clears</entry></row><row><entry /><entry /><entry /><entry /><entry>CmdPending[4]</entry></row><row><entry>0x20</entry><entry>CmdSource</entry><entry>1</entry><entry>0x0</entry><entry>0 - commands are taken from the CPU</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - commands are taken from the CPU</entry></row><row><entry /><entry /><entry /><entry /><entry>as well as DRAM at CmdAdr.</entry></row><row><entry>0x24</entry><entry>DebugSelect[15:2]</entry><entry>14</entry><entry>0x00 00</entry><entry>Debug address select. Indicates</entry></row><row><entry /><entry /><entry /><entry /><entry>the address of the register to</entry></row><row><entry /><entry /><entry /><entry /><entry>report on the pcu_cpu_data</entry></row><row><entry /><entry /><entry /><entry /><entry>bus when it is not otherwise being</entry></row><row><entry /><entry /><entry /><entry /><entry>used, and the PEP bus is not being</entry></row><row><entry /><entry /><entry /><entry /><entry>used</entry></row><row><entry /><entry /><entry /><entry /><entry>Bits [15:12] select the unit</entry></row><row><entry /><entry /><entry /><entry /><entry>(see Table )</entry></row><row><entry /><entry /><entry /><entry /><entry>Bits [11:2] select the register</entry></row><row><entry /><entry /><entry /><entry /><entry>within the unit</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="294pt" align="left" /><tbody valign="top"><row><entry>Work registers (read only)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="70pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>0x28</entry><entry>InvalidAddress</entry><entry>19</entry><entry>0</entry><entry>DRAM Address of current 64-bit</entry></row><row><entry /><entry>[21:3] (64-bit</entry><entry /><entry /><entry>command attempting to execute.</entry></row><row><entry /><entry>aligned DRAM)</entry><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x2C</entry><entry>CmdPending</entry><entry>5</entry><entry>0x00</entry><entry>For each bit n, where n is 0 to 3</entry></row><row><entry /><entry /><entry /><entry /><entry>0 -no commands pending for</entry></row><row><entry /><entry /><entry /><entry /><entry>NextBandCmdAdr[n]</entry></row><row><entry /><entry /><entry /><entry /><entry>1 -commands pending for</entry></row><row><entry /><entry /><entry /><entry /><entry>NextBandCmdAdr[n]</entry></row><row><entry /><entry /><entry /><entry /><entry>For bit 4</entry></row><row><entry /><entry /><entry /><entry /><entry>0 -no commands pending for</entry></row><row><entry /><entry /><entry /><entry /><entry>NextCmdAdr[n]</entry></row><row><entry /><entry /><entry /><entry /><entry>1 -commands pending for</entry></row><row><entry /><entry /><entry /><entry /><entry>NextCmdAdr[n]</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x34</entry><entry>FinishedSoFar</entry><entry>3</entry><entry>0x0</entry><entry>The appropriate bit is set when-</entry></row><row><entry /><entry /><entry /><entry /><entry>ever the corresponding input</entry></row><row><entry /><entry /><entry /><entry /><entry>finishedBand flag is set and the</entry></row><row><entry /><entry /><entry /><entry /><entry>corresponding bit in the</entry></row><row><entry /><entry /><entry /><entry /><entry>BandSelectMask bit is also set.</entry></row><row><entry /><entry /><entry /><entry /><entry>If all FinishedSoFar bits</entry></row><row><entry /><entry /><entry /><entry /><entry>are set wherever BandSelect bits</entry></row><row><entry /><entry /><entry /><entry /><entry>are also set, all FinishedSoFar bits</entry></row><row><entry /><entry /><entry /><entry /><entry>are cleared and the output</entry></row><row><entry /><entry /><entry /><entry /><entry>pcu_finishedband signal is given.</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x38</entry><entry>NextBandCmdEnable</entry><entry>4</entry><entry>0x0</entry><entry>This register can be written to</entry></row><row><entry /><entry /><entry /><entry /><entry>indirectly (i.e. the bits are set</entry></row><row><entry /><entry /><entry /><entry /><entry>or cleared via writes to</entry></row><row><entry /><entry /><entry /><entry /><entry>NextBandCmdAdr[n])</entry></row><row><entry /><entry /><entry /><entry /><entry>For each bit:</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - do nothing at the next</entry></row><row><entry /><entry /><entry /><entry /><entry>finishedBand[n] signal.</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - Execute instructions at</entry></row><row><entry /><entry /><entry /><entry /><entry>NextBandCmdAdr[n] as soon</entry></row><row><entry /><entry /><entry /><entry /><entry>as possible after receipt of</entry></row><row><entry /><entry /><entry /><entry /><entry>the next finishedBand[n]</entry></row><row><entry /><entry /><entry /><entry /><entry>signal.</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit0 - lbd_finishedband</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit1 - cdu_finishedband</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit2 - te_finishedband</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit3 - pcu_finishedband</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 21.8 Detailed Description <br /> 21.8.1 PEP Blocks Register Map
2490All PEP accesses are 32-bit register accesses.
2491From Table 140 it can be seen that four bits only are necessary to address each of the sub-blocks within the PEP part of SoPEC. Up to 14 bits may be used to address any configurable 32-bit register within PEP. This gives scope for 1024 configurable registers per sub-block. This address will come either from the CPU or from a command stored in DRAM. The bus is assembled as follows: <ul id="ul0256" list-style="none"><li id="ul0256-0001" num="0000"><ul id="ul0257" list-style="none"><li id="ul0257-0001" num="2492">adr[15:12]=sub-block address</li><li id="ul0257-0002" num="2493">adr[n:2]=32-bit register address within sub-block, only the number of bits required to decode the registers within each sub-block are used.</li></ul></li></ul>
2494<tables id="TABLE-US-00207" num="00207"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 141</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>PEP blocks Register Map</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Block Select</entry></row><row><entry /><entry /><entry>Decode =</entry></row><row><entry /><entry>Block</entry><entry>cpu_adr[15:12]</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>PCU</entry><entry>0x0</entry></row><row><entry /><entry>CDU</entry><entry>0x1</entry></row><row><entry /><entry>CFU</entry><entry>0x2</entry></row><row><entry /><entry>LBD</entry><entry>0x3</entry></row><row><entry /><entry>SFU</entry><entry>0x4</entry></row><row><entry /><entry>TE</entry><entry>0x5</entry></row><row><entry /><entry>TFU</entry><entry>0x6</entry></row><row><entry /><entry>HCU</entry><entry>0x7</entry></row><row><entry /><entry>DNC</entry><entry>0x8</entry></row><row><entry /><entry>DWU</entry><entry>0x9</entry></row><row><entry /><entry>LLU</entry><entry>0xA</entry></row><row><entry /><entry>PHI</entry><entry>0xB</entry></row><row><entry /><entry>Reserved</entry><entry>0xC to 0xF</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 21.8.2 Internal PCU PEP Protocol
2495The PCU performs PEP configuration register accesses via a select signal, pcu_<block>_sel. The read/write sense of the access is communicated via the pcu_rwn signal (1=read, 0=write).
2496Write data is clocked out, and read data clocked in upon receipt of the appropriate select-read/write-address combination.
2497<figref idref="DRAWINGS">FIG. 133</figref> shows a write operation followed by a read operation. The read operation is shown with wait states while the PEP block returns the read data.
2498For access to the PEP blocks a simple bus protocol is used. The PCU first determines which particular PEP block is being addressed so that the appropriate block select signal can be generated. During a write access PCU write data is driven out with the address and block select signals in the first cycle of an access. The addressed PEP block responds by asserting its ready signal indicating that it has registered the write data and the access can complete. The write data bus is common to all PEP blocks.
2499A read access is initiated by driving the address and select signals during the first cycle of an access. The addressed PEP block responds by placing the read data on its bus and asserting its ready signal to indicate to the PCU that the read data is valid. Each block has a separate point-to-point data bus for read accesses to avoid the need for a tri-stateable bus.
2500Consecutive accesses to a PEP block must be separated by at least a single cycle, during which the select signal must be de-asserted.
000021.8.3 PCU DRAM Access Requirements
2501The PCU can execute register programming commands stored in DRAM. These commands can be executed at the start of a print run to initialize all the registers of PEP. The PCU can also execute instructions at the start of a page, and between bands. In the inter-band time, it is critical to have the PCU operate as fast as possible. Therefore in the inter-page and inter-band time the PCU needs to get low latency access to DRAM.
2502A typical band change requires on the order of 4 commands to restart each of the CDU, LBD, and TE, followed by a single command to terminate the DRAM command stream. This is on the order of 5 commands per restart component.
2503The PCU does single 256 bit reads from DRAM. Each PCU command is 64 bits so each 256 bit DRAM read can contain 4 PCU commands. The requested command is read from DRAM together with the next 3 contiguous 64-bits which are cached to avoid unnecessary DRAM reads. Writing zero to CmdSource causes the PCU to flush commands and terminate program access from DRAM for that command stream. The PCU requires a 256-bit buffer to the 4 PCU commands read by each 256-bit DRAM access. When the buffer is empty the PCU can request DRAM access again. Adding a 256-bit double buffer would allow the next set of 4 commands to be fetched from DRAM while the current commands are being executed.
25041024 commands of 64 bits requires 8 kB of DRAM storage.
2505Programs stored in DRAM are referred to as PCU Program Code.
000021.8.4 End of Band Unit
2506The state machine is responsible for watching the various input xx_finishedband signals, setting the FinishedSoFar flags, and outputting the pcu_finishedband flags as specified by the BandSelect register.
2507Each cycle, the end of band unit performs the following tasks:
2508<tables id="TABLE-US-00208" num="00208"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>pcu_finishedband = (FinishedSoFar[0] = = BandSelectMask[0])</entry></row><row><entry>AND</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><colspec colname="2" colwidth="21pt" align="left" /><tbody valign="top"><row><entry /><entry>(FinishedSoFar[1]</entry><entry>= =</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>BandSelectMask[1]) AND</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><colspec colname="2" colwidth="21pt" align="left" /><tbody valign="top"><row><entry /><entry>(FinishedSoFar[2]</entry><entry>= =</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>BandSelectMask[2]) AND</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><colspec colname="2" colwidth="21pt" align="left" /><tbody valign="top"><row><entry /><entry>(BandSelectMask[0]</entry><entry>OR</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>BandSelectMask[1] OR BandSelectMask[2])</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>if (pcu_finishedband = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>FinishedSoFar[0] = 0</entry></row><row><entry /><entry>FinishedSoFar[1] = 0</entry></row><row><entry /><entry>FinishedSoFar[2] = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="28pt" align="left" /><colspec colname="3" colwidth="70pt" align="left" /><colspec colname="4" colwidth="21pt" align="left" /><tbody valign="top"><row><entry /><entry>FinishedSoFar[0]</entry><entry>=</entry><entry>(FinishedSoFar[0]</entry><entry>OR</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>lbdfinishedband) AND BandSelectMask[0]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="28pt" align="left" /><colspec colname="3" colwidth="70pt" align="left" /><colspec colname="4" colwidth="21pt" align="left" /><tbody valign="top"><row><entry /><entry>FinishedSoFar[1]</entry><entry>=</entry><entry>(FinishedSoFar[1]</entry><entry>OR</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>cdu_finishedband) AND BandSelectMask[1]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="28pt" align="left" /><colspec colname="3" colwidth="70pt" align="left" /><colspec colname="4" colwidth="21pt" align="left" /><tbody valign="top"><row><entry /><entry>FinishedSoFar[2]</entry><entry>=</entry><entry>(FinishedSoFar[2]</entry><entry>OR</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>te_finishedband) AND BandSelectMask[2]</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2509Note that it is the responsibility of the microcode at the start of printing a page to ensure that all 3 FinishedSoFar bits are cleared. It is not necessary to clear them between bands since this happens automatically.
2510If a bit of BandSelectMask is cleared, then the corresponding bit of FinishedSoFar has no impact on the generation of pcu_finishedband.
000021.8.5 Executing Commands from DRAM
2511Registers in PEP can be programmed by means of simple 64-bit commands fetched from DRAM. The format of the commands is given in Table 142. Register locations can have a data value of up to 32 bits. Commands are PEP register write commands only.
2512<tables id="TABLE-US-00209" num="00209"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 142</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Register write commands in PEP</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><colspec colname="3" colwidth="42pt" align="left" /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="35pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>bits</entry><entry>bits</entry><entry>bits</entry><entry>bits</entry></row><row><entry /><entry>command</entry><entry>63–32</entry><entry>31–16</entry><entry>15–2</entry><entry>1–0</entry></row><row><entry /><entry namest="offset" nameend="5" align="center" rowsep="1" /></row><row><entry /><entry>Register write</entry><entry>data</entry><entry>zero</entry><entry>32-bit</entry><entry>zero</entry></row><row><entry /><entry /><entry /><entry /><entry>word</entry></row><row><entry /><entry /><entry /><entry /><entry>address</entry></row><row><entry /><entry namest="offset" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2513Due attention must be paid to the endianness of the processor. The LEON processor is a big-endian processor (bit <b>7</b> is the most significant bit).
000021.8.6 General Operation
2514Upon a Reset condition, CmdSource is cleared (to 0), which means that all commands are initially sourced only from the CPU bus interface. Registers and can then be written to or read from one location at a time via the CPU bus interface.
2515If CmdSource is 1, commands are sourced from the DRAM at CmdAdr and from the CPU bus.
2516Writing an address to CmdAdr automatically sets CmdSource to 1, and causes a command stream to be retrieved from DRAM. The PCU will execute commands from the CPU or from the DRAM command stream, giving higher priority to the CPU always.
2517If CmdSource is 0 the DRAM requester examines the CmdPending bits to determine if a new DRAM command stream is pending. If any of CmdPending bits are set, then the appropriate NextBandCmdAdr or NextCmdAdr is copied to CmdAdr (causing CmdSource to get set to 1) and a new command DRAM stream is retrieved from DRAM and executed by the PCU. If there are multiple pending commands the DRAM requestor will service the lowest number pending bit first. Note that a new DRAM command stream only gets retrieved when the current command stream is empty.
2518If there are no DRAM commands pending, and no CPU commands the PCU defaults to an idle state. When idle the PCU address bus defaults to the DebugSelect register value (bits <b>11</b> to <b>2</b> in particular) and the default unit PCU data bus is reflected to the CPU data bus. The default unit is determined by the DebugSelect register bits <b>15</b> to <b>12</b>.
2519In conjunction with this, upon receipt of a finishedBand[n] signal, NextBandCmdEnable[n] is copied to CmdPending[n] and NextBandCmdEnable[n] is cleared. Note, each of the LBD, CDU, and TE (where present) may be re-programmed individually between bands by appropriately setting NextBandCmdAdr[2-0] respectively. However, execution of inter-band commands may be postponed until all blocks specified in the BandSelectMask register have pulsed their finishedband signal. This may be accomplished by only setting NextBandCmdAdr[3] (indirectly causing NextBandCmdEnable[3] to be set) in which case it is the pcu_finishedband signal which causes NextBandCmdEnable[3] to be copied to CmdPending[3].
2520To conveniently update multiple registers, for example at the start of printing a page, a series of Write Register commands can be stored in DRAM. When the start address of the first Write Register command is written to the CmdAdr register (via the CPU), the CmdSource register is automatically set to 1 to actually start the execution at CmdAdr. Alternatively the CPU can write to NextCmdAdr causing the CmdPending[4] bit to get set, which will then get serviced by the DRAM requester in the pending bit arbitration order.
2521The final instruction in the command block stored in DRAM must be a register write of 0 to CmdSource so that no more commands are read from DRAM. Subsequent commands will come from pending programs or can be sent via the CPU bus interface.
000021.8.6.1 Debug Mode
2522Debug mode is implemented by reusing the normal CPU and DRAM access decode logic. When in the Arbitrate state (see state machine A below), the PEP address bus is defaulted to the value in the DebugSelect register. The top bits of the DebugSelect register are used to decode a select to a PEP unit and the remaining bits are reflected on the PEP address bus. The selected units read data bus is reflected on the pcu_cpu_data bus to the RDU in the CPU. The pcu_cpu_debug_valid signal indicates to the RDU that the data on the pcu_cpu_data bus is valid debug data.
2523Normal CPU and DRAM command access will require the PEP bus, and as such will cause the debug data to be invalid during the access, this is indicated to the RDU by setting pcu_cpu_debug_valid to zero.
2524The decode logic is:
2525<tables id="TABLE-US-00210" num="00210"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>// Default Debug decode</entry></row><row><entry>if state = = Arbitrate then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="98pt" align="left" /><colspec colname="2" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry>if (cpu_pcu_sel = =</entry><entry>1 AND cpu_acode /=</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>SUPERVISOR_DATA_MODE) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><colspec colname="3" colwidth="70pt" align="left" /><tbody valign="top"><row><entry /><entry>pcu_cpu_debug_valid</entry><entry> = 0</entry><entry>// bus error</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>condition</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry>pcu_cpu_data</entry><entry>= 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry><unit></entry><entry>= decode(DebugSelect[15:12])</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>if (<unit> = = PCU ) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry>pcu_cpu_data</entry><entry>= Internal PCU register</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry>pcu_cpu_data</entry><entry>= <unit>_pcu_datain[31:0]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry>pcu_adr[11:2]</entry><entry>= DebugSelect[11:2]</entry></row><row><entry /><entry>pcu_cpu_debug_valid</entry><entry>= 1 AFTER 4 clock cycles</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="98pt" align="left" /><colspec colname="2" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry>pcu_cpu_debug_valid</entry><entry>= 0</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 21.8.7 State Machines
2526DRAM command fetching and general command execution is accomplished using two state machines. State machine A evaluates whether a CPU or DRAM command is being executed, and proceeds to execute the command(s). Since the CPU has priority over the DRAM it is permitted to interrupt the execution of a stream of DRAM commands.
2527Machine B decides which address should be used for DRAM access, fetches commands from DRAM and fills a command fifo which A executes. The reason for separating the two functions is to facilitate the execution of CPU or Debug commands while state machine B is performing DRAM reads and filling the command fifo. In the case where state machine A is ready to execute commands (in its Arbitrate state) and it sees both a full DRAM command fifo and an active cpu_pcu_sel then the DRAM commands are executed last.
000021.8.7.1 State Machine A: Arbitration and Execution of Commands
2528The state-machine enters the Reset state when there is an active strobe on either the reset pin, prst_n, or the PCU's soft-reset register. All registers in the PCU are zeroed, unless otherwise specified, on the next rising clock edge. The PCU self-deasserts the soft reset in the pclk cycle after it has been asserted.
2529The state changes from Reset to Arbitrate when prst_n==1 and PCU_softreset==1.
2530The state-machine waits in the Arbitrate state until it detects a request for CPU access to the PEP units (cpu_pcu_sel==1 and cpu_acode==11) or a request to execute DRAM commands CmdSource==1, and DRAM commands are available, CmdFifoFull==1. Note if (cpu_pcu_sel==1 and cpu_acode !=11) the CPU is attempting an illegal access. The PCU ignores this command and strobes the cpu_pcu_berr for one cycle.
2531While in the Arbitrate state the machine assigns the DebugSelect register to the PCU unit decode logic and the remaining bits to the PEP address bus. When in this state the debug data returned from the selected PEP unit is reflected on the CPU bus (pcu_cpu_data bus) and the pcu_cpu_debug valid=1.
2532If a CPU access request is detected (cpu_pcu_sel==1 and cpu_acode==11) then the machine proceeds to the CpuAccess state. In the CpuAccess state the cpu address is decoded and used to determine the PEP unit to select. The remaining address bits are passed through to the PEP address bus. The machine remains in the CpuAccess state until a valid ready from the selected PEP unit is received. When received the machine returns to the arbitrate state, and the ready signal to the CPU is pulsed.
2533<tables id="TABLE-US-00211" num="00211"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="196pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>// decode the logic</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="112pt" align="left" /><tbody valign="top"><row><entry /><entry>pcu_<unit>_sel</entry><entry>= decode(cpu_adr[15:12])</entry></row><row><entry /><entry>pcu_adr[11:2]</entry><entry>= cpu_adr[11:2]</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2534The CPU is prevented from generating an invalid PEP unit address (prevented in the MMU) and so CPU accesses cannot generate an invalid address error.
2535If the state machine detects a request to execute DRAM commands (CmdSource==1), it will wait in the Arbitrate state until commands have been loaded into the command FIFO from DRAM (all controlled by state machine B). When the DRAM commands are available (cmd_fifo_full==1) the state machine will proceed to the DRAMAccess state.
2536When in the DRAMAccess state the commands are executed from the cmd<sub>—</sub>_fifo. A command in the cmd_fifo consists of 64-bits (or which the FIFO holds 4). The decoding of the 64-bits to commands is given in Table. For each command the decode is
2537<tables id="TABLE-US-00212" num="00212"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>// DRAM command decode</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>pcu_<unit>_sel</entry><entry>= decode( cmd_fifo[cmd_count][15:12] )</entry></row><row><entry /><entry>pcu_adr[11:2]</entry><entry>= cmd_fifo[cmd_count][11:2]</entry></row><row><entry /><entry>pcu_dataout</entry><entry>= cmd_fifo[cmd_count][63:32]</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2538When the selected PEP unit returns a ready signal (<unit>_pcu_rdy==1) indicating the command has completed, the state machine will return to the Arbitrate state. If more commands exists (cmd_count !=0) the transition will decrement the command count.
2539When in the DRAMAccess state, if when decoding the DRAM command address bus (cmd_fifo[cmd_count][15.12]), the address selects a reserved address, the state machine proceeds to the AdrError state, and then back to the Arbitrate state. An address error interrupt will be generated and the DRAM command FIFOs will be cleared.
2540A CPU access can pre-empt any pending DRAM commands. After each command is completed the state machine returns to the Arbitrate state. If a CPU access is required and DRAM command stream is executing the CPU access always takes priority. If a CPU or DRAM command sets the CmdSource to 0, all subsequent DRAM commands in the command FIFO are cleared. If the CPU sets the CmdSource to 0 the CmdPending and NextBandCmdEnable work registers are also cleared.
000021.8.7.2 State Machine B: Fetching DRAM Commands
2541A system reset (prst_n==0) or a software reset (pcu_softreset_n==0) will cause the state machine to reset to the Reset state. The state machine remains in the Reset until both reset conditions are removed. When removed the machine proceeds to the Waft state.
2542The state machine waits in the Wait state until it determines that commands are needed from DRAM. Two possible conditions exist that require DRAM access. Either the PCU is processing commands which must be fetched from DRAM (cmd_source==1), and the command FIFO is empty (cmd_fifo_full<sub>—</sub><sub>—</sub>=0), or the cmd_source==0 and the command FIFO is empty and there are some commands pending (cmd_pending !=0). In either of these conditions the machine proceeds to the Ack state and issues a read request to DRAM (pcu_diu_rreq==1), it calculates the address to read from dependent on the transition condition. In the command pending transition condition, the highest priority NextBandCmdAdr (or NextCmdAdr) that is pending is used for the read address (pcu_diu_radr) and is also copied to the CmdAdr register. If multiple pending bits are set the lowest pending bits are serviced first. In the normal PCU processing transition the pcu_diu_radr is the CmdAdr register.
2543When an acknowledge is received from the DRAM the state machine goes to the FillFifo state. In the FillFifo state the machine waits for the DRAM to respond to the read request and transfer data words. On receipt of the first word of data diu_pcu_rvalid==1, the machine stores the 64-bit data word in the command FIFO (cmd_fifo[3]) and transitions to the Data1, Data2, Data3 states each time waiting for a diu_pcu_rvalid==1 and storing the transferred data word to cmd_fifo[2], cmd_fifo[1] and cmd_fifo[0] respectively.
2544When the transfer is complete the machine returns to the Wait state, setting the cmd_count to 3, the cmd_fifo_full is set to 1 and the CmdAdr is incremented.
2545If the CPU sets the CmdSource register low while the PCU is in the middle of a DRAM access, the statemachine returns to the Wait state and the DRAM access is aborted.
000021.8.7.3 PCU_ICU_Address_Invalid Interrupt
2546When the PCU is executing commands from DRAM, addresses decoded from commands which are not PCU mapped addresses (4-bits only) will result in the current command being ignored and the pcu_icu_address_invalid interrupt signal is strobed. When an invalid command occurs all remaining commands already retrieved from DRAM are flushed from the CmdFifo, and the CmdPending, NextBandCmdEnable and CmdSource registers are cleared to zero.
2547The CPU can then interrogate the PCU to find the source of the illegal DRAM command via the InvalidAddress register.
2548The CPU is prevented by the MMU from generating an invalid address command.
000022 Contone Decoder Unit (CDU)
000022.1 Overview
2549The Contone Decoder Unit (CDU) is responsible for performing the optional decompression of the contone data layer.
2550The input to the CDU is up to 4 planes of compressed contone data in JPEG interleaved format. This will typically be 3 planes, representing a CMY contone image, or 4 planes representing a CMYK contone image. The CDU must support a page of A4 length (11.7 inches) and Letter width (8.5 inches) at a resolution of 267 ppi in 4 colors and a print speed of 1 side per 2 seconds.
2551The CDU and the other page expansion units support the notion of page banding. A compressed page is divided into one or more bands, with a number of bands stored in memory. As a band of the page is consumed for printing a new band can be downloaded. The new band may be for the current page or the next page. Band-finish interrupts have been provided to notify the CPU of free buffer space.
2552The compressed contone data is read from the on-chip DRAM. The output of the CDU is the decompressed contone data, separated into planes. The decompressed contone image is written to a circular buffer in DRAM with an expected minimum size of 12 lines and a configurable maximum. The decompressed contone image is subsequently read a line at a time by the CFU, optionally color converted, scaled up to 1600 ppi and then passed on to the HCU for the next stage in the printing pipeline. The CDU also outputs a cdu_finishedband control flag indicating that the CDU has finished reading a band of compressed contone data in DRAM and that area of DRAM is now free. This flag is used by the PCU and is available as an interrupt to the CPU.
000022.2 Storage Requirements for Decompressed Contone Data in DRAM
2553A single SoPEC must support a page of A4 length (11.7 inches) and Letter width (8.5 inches) at a resolution of 267 ppi in 4 colors and a print speed of 1 side per 2 seconds. The printheads specified in the Bi-lithic Printhead Specification [2] have 13824 nozzles per color to provide full bleed printing for A4 and Letter. At 267 ppi, there are 2304 contone pixels<sup>9 </sup>per line represented by 288 JPEG blocks per color. However each of these blocks actually stores data for 8 lines, since a single JPEG block is 8×8 pixels. The CDU produces contone data for 8 lines in parallel, while the HCU processes data linearly across a line on a line by line basis. The contone data is decoded only once and then buffered in DRAM. This means we require two sets of 8 buffer-lines—one set of 8 buffer lines is being consumed by the CFU while the other set of 8 buffer lines is being generated by the CDU. <sup>9</sup>Pixels may be 8, 16, 24 or 32 bits depending on the number of color planes (8-bits per color)
2554The buffer requirement can be reduced by using a 1.5 buffering scheme, where the CDU fills 8 lines while the CFU consumes 4 lines. The buffer space required is a minimum of 12 line stores per color, for a total space of 108 KBytes<sup>10</sup>. A circular buffer scheme is employed whereby the CDU may only begin to write a line of JPEG blocks (equals 8 lines of contone data) when there are 8-lines free in the buffer. Once the full 8 lines have been written by the CDU, the CFU may now begin to read them on a line by line basis. <sup>10 </sup>12 lines×4 colors×2304 bytes (assumes 267 ppi, 4 color, full bleed A4/ Letter)
2555This reduction in buffering comes with the cost of an increased peak bandwidth requirement for the CDU write access to DRAM. The CDU must be able to write the decompressed contone at twice the rate at which the CFU reads the data. To allow for trade-offs to be made between peak bandwidth and amount of storage, the size of the circular buffer is configurable. For example, if the circular buffer is configured to be 16 lines it behaves like a double-buffer scheme where the peak bandwidth requirements of the CDU and CFU are equal. An increase over 16 lines allows the CDU to write ahead of the CFU and provides it with a margin to cope with very poor local compression ratios in the image.
2556SoPEC should also provide support for A3 printing and printing at resolutions above 267 ppi. This increases the storage requirement for the decompressed contone data (buffer) in DRAM. Table 143 gives the storage requirements for the decompressed contone data at some sample contone resolutions for different page sizes. It assumes 4 color planes of contone data and a 1.5 buffering scheme.
2557<tables id="TABLE-US-00213" num="00213"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 143</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Storage requirements for decompressed contone data (buffer)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="49pt" align="center" /><colspec colname="3" colwidth="35pt" align="center" /><colspec colname="4" colwidth="42pt" align="center" /><colspec colname="5" colwidth="49pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Contone</entry><entry /><entry>Pixels</entry><entry>Storage</entry></row><row><entry /><entry>Page</entry><entry>resolution</entry><entry>Scale</entry><entry>per</entry><entry>required</entry></row><row><entry /><entry>size</entry><entry>(ppi)</entry><entry>factor<sup>a</sup></entry><entry>line</entry><entry>(k Bytes)</entry></row><row><entry /><entry namest="offset" nameend="5" align="center" rowsep="1" /></row><row><entry /><entry>A4/</entry><entry>267</entry><entry>6</entry><entry>2304</entry><entry>108<sup>d</sup></entry></row><row><entry /><entry>Letter<sup>b</sup></entry></row><row><entry /><entry /><entry>400</entry><entry>4</entry><entry>3456</entry><entry>162</entry></row><row><entry /><entry /><entry>800</entry><entry>2</entry><entry>6912</entry><entry>324</entry></row><row><entry /><entry>A3<sup>c</sup></entry><entry>267</entry><entry>6</entry><entry>3248</entry><entry>152.25</entry></row><row><entry /><entry /><entry>400</entry><entry>4</entry><entry>4872</entry><entry>228.37</entry></row><row><entry /><entry /><entry>800</entry><entry>2</entry><entry>9744</entry><entry>456.75</entry></row><row><entry /><entry namest="offset" nameend="5" align="center" rowsep="1" /></row><row><entry /><entry namest="offset" nameend="5" align="left" id="FOO-00015"><sup>a</sup>Required for CFU to convert to final output at 1600 dpi</entry></row><row><entry /><entry namest="offset" nameend="5" align="left" id="FOO-00016"><sup>b</sup>Bi-lithic printhead has 13824 nozzles per color providing full bleed printing for A4/Letter</entry></row><row><entry /><entry namest="offset" nameend="5" align="left" id="FOO-00017"><sup>c</sup>Bi-lithic printhead has 19488 nozzles per color providing full bleed printing for A3</entry></row><row><entry /><entry namest="offset" nameend="5" align="left" id="FOO-00018"><sup>d</sup>12 lines × 4 colors × 2304 bytes.</entry></row></tbody></tgroup></table></tables><br /> 22.3 Decompression Performance Requirements
2558The JPEG decoder core can produce a single color pixel every system clock (pclk) cycle, making it capable of decoding at a peak output rate of 8 bits/cycle. SoPEC processes 1 dot (bi-level in 6 colors) per system clock cycle to achieve a print speed of 1 side per 2 seconds for full. bleed A4/Letter printing. The CFU replicates pixels a scale factor (SF) number of times in both the horizontal and vertical directions to convert the final output to 1600 ppi. Thus the CFU consumes a 4 color pixel (32 bits) every SF x SF cycles. The 1.5 buffering scheme described in section 22.2 on page 327 means that the CDU must write the data at twice this rate. With support for 4 colors at 267 ppi, the decompression output bandwidth requirement is 1.78 bits/cycle<sup>11</sup>.
2559The JPEG decoder is fed directly from the main memory via the DRAM interface. The amount of compression determines the input bandwidth requirements for the CDU. As the level of compression increases, the bandwidth decreases, but the quality of the final output image can also decrease. Although the average compression ratio for contone data is expected to be 10:1, the average bandwidth allocated to the CDU allows for a local minimum compression ratio of 5:1 over a single line of JPEG blocks. This equates to a peak input bandwidth requirement of 0.36 bits/cycle for 4 colors at 267 ppi, full bleed A4/Letter printing at 1 side per 2 seconds.
2560Table 144 gives the decompression output bandwidth requirements for different resolutions of contone data to meet a print speed of 1 side per 2 seconds. Higher resolution requires higher bandwidth and larger storage for decompressed contone data in DRAM. A resolution of 400 ppi contone data in 4 colors requires 4 bits/cycle<sup>12</sup>, which is practical using a 1.5 buffering scheme. However, a resolution of 800 ppi would require a double buffering scheme (16 lines) so the CDU only has to match the CFU consumption rate. In this case the decompression output bandwidth requirement is 8 bits/cycle<sup>13</sup>, the limiting factor being the output rate of the JPEG decoder core. <sup>11</sup>2×((4 colors×8 bits)/(6×6 cycles))=1.78 bits/cycle<sup>12</sup>2×((4 colors×8 bits)/(4×4 cycles))=4 bits/cycle<sup>13</sup>(4 colors×8 bits)/(2×2 cycles)=8 bits/cycle
2561<tables id="TABLE-US-00214" num="00214"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 144</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>CDU performance requirements for full bleed</entry></row><row><entry>A4/Letter printing at 1 side per 2 seconds.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="42pt" align="center" /><colspec colname="2" colwidth="70pt" align="center" /><colspec colname="3" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry /><entry>Decompression</entry></row><row><entry /><entry>Contone</entry><entry /><entry>output bandwidth</entry></row><row><entry /><entry>resolution</entry><entry>Scale</entry><entry>requirement</entry></row><row><entry /><entry>(ppi)</entry><entry>factor</entry><entry>(bits/cycle)<sup>a</sup></entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="42pt" align="char" char="." /><colspec colname="2" colwidth="70pt" align="char" char="." /><colspec colname="3" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry>267</entry><entry>6</entry><entry>1.78</entry></row><row><entry /><entry>400</entry><entry>4</entry><entry>4</entry></row><row><entry /><entry>800</entry><entry>2</entry><entry>8<sup>b</sup></entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row><row><entry /><entry namest="offset" nameend="3" align="left" id="FOO-00022"><sup>a</sup>Assumes 4 color pixel contone data and a 12 line buffer.</entry></row><row><entry /><entry namest="offset" nameend="3" align="left" id="FOO-00023"><sup>b</sup>Scale factor 2 requires at least a 16 line buffer.</entry></row></tbody></tgroup></table></tables><br /> 22.4 Data Flow
2562<figref idref="DRAWINGS">FIG. 136</figref> shows the general data flow for contone data—compressed contone planes are read from DRAM by the CDU, and the decompressed contone data is written to the 12-line circular buffer in DRAM. The line buffers are subsequently read by the CFU.
2563The CDU allows the contone data to be passed directly on, which will be the case if the color represented by each color plane in the JPEG image is an available ink. For example, the four colors may be C, M, Y, and K, directly represented by CMYK inks. The four colors may represent gold, metallic green etc. for multi-SoPEC printing with exact colors.
2564However JPEG produces better compression ratios for a given visible quality when luminance and chrominance channels are separated. With CMYK, K can be considered to be luminance, but C, M, and Y each contain luminance information, and so would need to be compressed with appropriate luminance tables. We therefore provide the means by which CMY can be passed to SoPEC as YCrCb. K does not need color conversion. When being JPEG compressed, CMY is typically converted to RGB, then to YCrCb and then finally JPEG compressed. At decompression, the YCrCb data is obtained and written to the decompressed contone store by the CDU. This is read by the CFU where the YCrCb can then be optionally color converted to RGB, and finally back to CMY.
2565The external RIP provides conversion from RGB to YCrCb, specifically to match the actual hardware implementation of the inverse transform within SoPEC, as per CCIR 601–2 [24] except that Y, Cr and Cb are normalized to occupy all 256 levels of an 8-bit binary encoding.
2566The CFU provides the translation to either RGB or CMY. RGB is included since it is a necessary step to produce CMY, and some printers increase their color gamut by including RGB inks as well as CMYK.
000022.5 Implementation
2567A block diagram of the CDU is shown in <figref idref="DRAWINGS">FIG. 137</figref>.
2568All output signals from the CDU (cdu_cfu_wradv8line, cdu_finishedband, cdu_icu_jpegerror, and control signals to the DIU) must always be valid after reset. If the CDU is not currently decoding, cdu_cfu_wradv8line, cdu_finishedband and cdu_icu_jpegerror will always be 0.
2569The read control unit is responsible for keeping the JPEG decoder's input FIFO full by reading compressed contone bytestream from external DRAM via the DIU, and produces the cdu_finishedband signal. The write control unit accepts the output from the JPEG decoder a half JPEG block (32 bytes) at a time, writes it into a double-buffer, and writes the double buffered decompressed half blocks to DRAM via the DIU, interacting with the CFU in order to share DRAM buffers.
000022.5.1 Definitions of I/O
2570<tables id="TABLE-US-00215" num="00215"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 145</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>CDU port list and description</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="105pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>Port name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>Clocks and reset</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="105pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>Pclk</entry><entry>1</entry><entry>In</entry><entry>System clock.</entry></row><row><entry>Jclk</entry><entry>1</entry><entry>In</entry><entry>Gated version of system clock used</entry></row><row><entry /><entry /><entry /><entry>to clock the JPEG decoder core and</entry></row><row><entry /><entry /><entry /><entry>logic at the output of the core.</entry></row><row><entry /><entry /><entry /><entry>Allows for stalling of the JPEG</entry></row><row><entry /><entry /><entry /><entry>core at a pixel sample boundary.</entry></row><row><entry>jclk_enable</entry><entry>1</entry><entry>Out</entry><entry>Gating signal for jclk.</entry></row><row><entry>prst_n</entry><entry>1</entry><entry>In</entry><entry>System reset, synchronous active</entry></row><row><entry /><entry /><entry /><entry>low.</entry></row><row><entry>jrst_n</entry><entry>1</entry><entry>In</entry><entry>Reset for jclk domain, synchronous</entry></row><row><entry /><entry /><entry /><entry>active low.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>PCU interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="105pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>pcu_cdu_sel</entry><entry>1</entry><entry>In</entry><entry>Block select from the PCU. When</entry></row><row><entry /><entry /><entry /><entry>pcu_cdu_sel is high both pcu_adr</entry></row><row><entry /><entry /><entry /><entry>and pcu_dataout are valid.</entry></row><row><entry>pcu_rwn</entry><entry>1</entry><entry>In</entry><entry>Common read/not-write signal from</entry></row><row><entry /><entry /><entry /><entry>the PCU.</entry></row><row><entry>pcu_adr[7:2]</entry><entry>6</entry><entry>In</entry><entry>PCU address bus. Only 6 bits are</entry></row><row><entry /><entry /><entry /><entry>required to decode the address space</entry></row><row><entry /><entry /><entry /><entry>for this block.</entry></row><row><entry>pcu_dataout[31:0]</entry><entry>32</entry><entry>In</entry><entry>Shared write data bus from the</entry></row><row><entry /><entry /><entry /><entry>PCU.</entry></row><row><entry>cdu_pcu_rdy</entry><entry>1</entry><entry>Out</entry><entry>Ready signal to the PCU. When</entry></row><row><entry /><entry /><entry /><entry>cdu_pcu_rdy is high it indicates</entry></row><row><entry /><entry /><entry /><entry>the last cycle of the access.</entry></row><row><entry /><entry /><entry /><entry>For a write cycle this means</entry></row><row><entry /><entry /><entry /><entry>pcu_dataout has been registered</entry></row><row><entry /><entry /><entry /><entry>by the block and for a read cycle</entry></row><row><entry /><entry /><entry /><entry>this means the data on</entry></row><row><entry /><entry /><entry /><entry>cdu_pcu_datain is valid.</entry></row><row><entry>cdu_pcu_datain[31:0]</entry><entry>32</entry><entry>Out</entry><entry>Read data bus to the PCU.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>DIU read interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="105pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>cdu_diu_rreq</entry><entry>1</entry><entry>Out</entry><entry>CDU read request, active high. A</entry></row><row><entry /><entry /><entry /><entry>read request must be accompanied</entry></row><row><entry /><entry /><entry /><entry>by a valid read address.</entry></row><row><entry>diu_cdu_rack</entry><entry>1</entry><entry>In</entry><entry>Acknowledge from DIU, active high.</entry></row><row><entry /><entry /><entry /><entry>Indicates that a read request has</entry></row><row><entry /><entry /><entry /><entry>been accepted and the new read</entry></row><row><entry /><entry /><entry /><entry>address can be placed on the</entry></row><row><entry /><entry /><entry /><entry>address bus, cdu_diu_radr.</entry></row><row><entry>cdu_diu_radr[21:5]</entry><entry>17</entry><entry>Out</entry><entry>CDU read address. 17 bits wide</entry></row><row><entry /><entry /><entry /><entry>(256-bit aligned word).</entry></row><row><entry>diu_cdu_rvalid</entry><entry>1</entry><entry>In</entry><entry>Read data valid, active high.</entry></row><row><entry /><entry /><entry /><entry>Indicates that valid read data is</entry></row><row><entry /><entry /><entry /><entry>now on the read data bus, diu_data.</entry></row><row><entry>diu_data[63:0]</entry><entry>64</entry><entry>In</entry><entry>Read data from DRAM.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>DIU write interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="105pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>cdu_diu_wreq</entry><entry>1</entry><entry>Out</entry><entry>CDU write request, active high. A</entry></row><row><entry /><entry /><entry /><entry>write request must be accompanied</entry></row><row><entry /><entry /><entry /><entry>by a valid write address and valid</entry></row><row><entry /><entry /><entry /><entry>write data.</entry></row><row><entry>diu_cdu_wack</entry><entry>1</entry><entry>In</entry><entry>Acknowledge from DIU, active high.</entry></row><row><entry /><entry /><entry /><entry>Indicates that a write request has</entry></row><row><entry /><entry /><entry /><entry>been accepted and the new write</entry></row><row><entry /><entry /><entry /><entry>address can be placed on the</entry></row><row><entry /><entry /><entry /><entry>address bus, cdu_diu_wadr.</entry></row><row><entry>cdu_diu_wadr[21:3]</entry><entry>19</entry><entry>Out</entry><entry>CDU write address. 19 bits wide</entry></row><row><entry /><entry /><entry /><entry>(64-bit aligned word).</entry></row><row><entry>cdu_diu_wvalid</entry><entry>1</entry><entry>Out</entry><entry>Write data valid, active high.</entry></row><row><entry /><entry /><entry /><entry>Indicates that valid data is now</entry></row><row><entry /><entry /><entry /><entry>on the write data bus,</entry></row><row><entry /><entry /><entry /><entry>cdu_diu_data.</entry></row><row><entry>cdu_diu_data[63:0]</entry><entry>64</entry><entry>Out</entry><entry>Write data bus.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>CFU interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="105pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>cfu_cdu_rdadvline</entry><entry>1</entry><entry>In</entry><entry>Read line pulse, active high.</entry></row><row><entry /><entry /><entry /><entry>Indicates that the CFU has</entry></row><row><entry /><entry /><entry /><entry>finished reading a line of decom-</entry></row><row><entry /><entry /><entry /><entry>pressed contone data to the</entry></row><row><entry /><entry /><entry /><entry>circular buffer in DRAM and that</entry></row><row><entry /><entry /><entry /><entry>line of the buffer is now free.</entry></row><row><entry>cdu_cfu_linestore_rdy</entry><entry>1</entry><entry>Out</entry><entry>Indicates if the contone line</entry></row><row><entry /><entry /><entry /><entry>store has 1 or more lines available</entry></row><row><entry /><entry /><entry /><entry>to read by the CFU.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>TE and LBD interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="105pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>cdu_start_of_bandstore[21:5]</entry><entry>17</entry><entry>Out</entry><entry>Points to the 256-bit word that</entry></row><row><entry /><entry /><entry /><entry>defines the start of the memory</entry></row><row><entry /><entry /><entry /><entry>area allocated for page bands.</entry></row><row><entry>cdu_end_of_bandstore[21:5]</entry><entry>17</entry><entry>Out</entry><entry>Points to the 256-bit word that</entry></row><row><entry /><entry /><entry /><entry>defines the last address of the</entry></row><row><entry /><entry /><entry /><entry>memory area allocated for page</entry></row><row><entry /><entry /><entry /><entry>bands.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>ICU interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="105pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>cdu_finishedband</entry><entry>1</entry><entry>Out</entry><entry>CDU's finishedBand flag, active</entry></row><row><entry /><entry /><entry /><entry>high. Interrupt to the CPU to</entry></row><row><entry /><entry /><entry /><entry>indicate that the CDU has finished</entry></row><row><entry /><entry /><entry /><entry>processing a band of compressed</entry></row><row><entry /><entry /><entry /><entry>contone data in DRAM and that area</entry></row><row><entry /><entry /><entry /><entry>of DRAM is now free. This signal</entry></row><row><entry /><entry /><entry /><entry>goes to both the interrupt con-</entry></row><row><entry /><entry /><entry /><entry>troller and the PCU.</entry></row><row><entry>cdu_icu_jpegerror</entry><entry>1</entry><entry>Out</entry><entry>Active high interrupt indicating</entry></row><row><entry /><entry /><entry /><entry>an error has occurred in the JPEG</entry></row><row><entry /><entry /><entry /><entry>decoding process and decompression</entry></row><row><entry /><entry /><entry /><entry>has stopped. A reset of the CDU</entry></row><row><entry /><entry /><entry /><entry>must be performed to clear this</entry></row><row><entry /><entry /><entry /><entry>interrupt.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 22.5.2 Configuration Registers
2571The configuration registers in the CDU are programmed via the PCU interface. Refer to section 21.8.2 on page 321 for the description of the protocol and timing diagrams for reading and writing registers in the CDU. Note that since addresses in SoPEC are byte aligned and the PCU only supports 32-bit register reads and writes, the lower 2 bits of the PCU address bus are not required to decode the address space for the CDU. When reading a register that is less than 32 bits wide zeros should be returned on the upper unused bit(s) of cdu_pcu_datain.
2572Since the CDU, LBD and TE all access the page band store, they share two registers that enable sequential memory accesses to the page band stores to be circular in nature. Table 146 lists these two registers.
2573<tables id="TABLE-US-00216" num="00216"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 146</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Registers shared between the CDU, LBD, and TE</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="42pt" align="left" /><colspec colname="5" colwidth="70pt" align="left" /><tbody valign="top"><row><entry>Address</entry><entry>Register</entry><entry /><entry>Value on</entry><entry /></row><row><entry>(CDU_base+)</entry><entry>name</entry><entry>#bits</entry><entry>reset</entry><entry>description</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>Setup registers (remain constant during the processing of multiple bands)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="42pt" align="left" /><colspec colname="5" colwidth="70pt" align="left" /><tbody valign="top"><row><entry>0x80</entry><entry>StartOfBandStore[21:5]</entry><entry>17</entry><entry>0x0_0000</entry><entry>Points to the 256-bit</entry></row><row><entry /><entry /><entry /><entry /><entry>word that defines the</entry></row><row><entry /><entry /><entry /><entry /><entry>start of the memory</entry></row><row><entry /><entry /><entry /><entry /><entry>area allocated for</entry></row><row><entry /><entry /><entry /><entry /><entry>page bands. Circular</entry></row><row><entry /><entry /><entry /><entry /><entry>address generation</entry></row><row><entry /><entry /><entry /><entry /><entry>wraps to this start</entry></row><row><entry /><entry /><entry /><entry /><entry>address.</entry></row><row><entry>0x84</entry><entry>EndOfBandStore[21:5]</entry><entry>17</entry><entry>0x1_3FFF</entry><entry>Points to the 256-bit</entry></row><row><entry /><entry /><entry /><entry /><entry>word that defines the</entry></row><row><entry /><entry /><entry /><entry /><entry>last address of the</entry></row><row><entry /><entry /><entry /><entry /><entry>memory area allocated</entry></row><row><entry /><entry /><entry /><entry /><entry>for page bands. If the</entry></row><row><entry /><entry /><entry /><entry /><entry>current read address</entry></row><row><entry /><entry /><entry /><entry /><entry>is from this address,</entry></row><row><entry /><entry /><entry /><entry /><entry>then instead of adding</entry></row><row><entry /><entry /><entry /><entry /><entry>1 to the current</entry></row><row><entry /><entry /><entry /><entry /><entry>address, the current</entry></row><row><entry /><entry /><entry /><entry /><entry>address will be loaded</entry></row><row><entry /><entry /><entry /><entry /><entry>from the</entry></row><row><entry /><entry /><entry /><entry /><entry>StartOfBandStore</entry></row><row><entry /><entry /><entry /><entry /><entry>register.</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2574The software reset logic should include a circuit to ensure that both the pclk and jclk domains are reset regardless of the state of the jclk_enable when the reset is initiated.
2575The CDU contains the following additional registers:
2576<tables id="TABLE-US-00217" num="00217"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="315pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 147</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>CDU registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="98pt" align="left" /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="42pt" align="left" /><colspec colname="5" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>Address</entry><entry>Register</entry><entry /><entry>Value on</entry><entry /></row><row><entry>(CDU_base+)</entry><entry>name</entry><entry>#bits</entry><entry>reset</entry><entry>Description</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="315pt" align="left" /><tbody valign="top"><row><entry>Control registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="98pt" align="left" /><colspec colname="3" colwidth="21pt" align="char" char="." /><colspec colname="4" colwidth="42pt" align="left" /><colspec colname="5" colwidth="98pt" align="left" /><colspec colname="6" colwidth="7pt" align="left" /><tbody valign="top"><row><entry>0x00</entry><entry>Reset</entry><entry>1</entry><entry>0x1</entry><entry>A write to this register</entry><entry /></row><row><entry /><entry /><entry /><entry /><entry>causes a reset of the</entry></row><row><entry /><entry /><entry /><entry /><entry>CDU. This terminates</entry></row><row><entry /><entry /><entry /><entry /><entry>all internal operations</entry></row><row><entry /><entry /><entry /><entry /><entry>within the CS6150. All</entry></row><row><entry /><entry /><entry /><entry /><entry>configuration data</entry></row><row><entry /><entry /><entry /><entry /><entry>previously loaded into</entry></row><row><entry /><entry /><entry /><entry /><entry>the core except for</entry></row><row><entry /><entry /><entry /><entry /><entry>the tables is deleted.</entry></row><row><entry>0x04</entry><entry>Go</entry><entry>1</entry><entry>0x0</entry><entry>Writing 1 to this</entry></row><row><entry /><entry /><entry /><entry /><entry>register starts the CDU.</entry></row><row><entry /><entry /><entry /><entry /><entry>Writing 0 to this</entry></row><row><entry /><entry /><entry /><entry /><entry>register halts the CDU.</entry></row><row><entry /><entry /><entry /><entry /><entry>When Go is deasserted</entry></row><row><entry /><entry /><entry /><entry /><entry>the state-machines go</entry></row><row><entry /><entry /><entry /><entry /><entry>to their idle states</entry></row><row><entry /><entry /><entry /><entry /><entry>but all counters and</entry></row><row><entry /><entry /><entry /><entry /><entry>configuration registers</entry></row><row><entry /><entry /><entry /><entry /><entry>keep their values.</entry></row><row><entry /><entry /><entry /><entry /><entry>When Go is asserted all</entry></row><row><entry /><entry /><entry /><entry /><entry>counters are reset, but</entry></row><row><entry /><entry /><entry /><entry /><entry>configuration registers</entry></row><row><entry /><entry /><entry /><entry /><entry>keep their values (i.e.</entry></row><row><entry /><entry /><entry /><entry /><entry>they don't get reset).</entry></row><row><entry /><entry /><entry /><entry /><entry>NextBandEnable is</entry></row><row><entry /><entry /><entry /><entry /><entry>cleared when Go is</entry></row><row><entry /><entry /><entry /><entry /><entry>asserted. The CFU must</entry></row><row><entry /><entry /><entry /><entry /><entry>be started before the</entry></row><row><entry /><entry /><entry /><entry /><entry>CDU is started. Go must</entry></row><row><entry /><entry /><entry /><entry /><entry>remain low for at least</entry></row><row><entry /><entry /><entry /><entry /><entry>384 jclk cycles after</entry></row><row><entry /><entry /><entry /><entry /><entry>a hardware reset</entry></row><row><entry /><entry /><entry /><entry /><entry>(prst_n = 0) to</entry></row><row><entry /><entry /><entry /><entry /><entry>allow the JPEG core</entry></row><row><entry /><entry /><entry /><entry /><entry>to complete its memory</entry></row><row><entry /><entry /><entry /><entry /><entry>itnitialisation</entry></row><row><entry /><entry /><entry /><entry /><entry>sequence. This register</entry></row><row><entry /><entry /><entry /><entry /><entry>can be read to determine</entry></row><row><entry /><entry /><entry /><entry /><entry>if the CDU is running</entry></row><row><entry /><entry /><entry /><entry /><entry>(1 - running, 0 -</entry></row><row><entry /><entry /><entry /><entry /><entry>stopped).</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="315pt" align="left" /><tbody valign="top"><row><entry>Setup registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="98pt" align="left" /><colspec colname="3" colwidth="21pt" align="char" char="." /><colspec colname="4" colwidth="42pt" align="left" /><colspec colname="5" colwidth="98pt" align="left" /><colspec colname="6" colwidth="7pt" align="left" /><tbody valign="top"><row><entry>0x0C</entry><entry>NumLinesAvail</entry><entry>7</entry><entry>0x0</entry><entry>The number of image</entry><entry /></row><row><entry /><entry /><entry /><entry /><entry>lines of data that there</entry></row><row><entry /><entry /><entry /><entry /><entry>is space available for</entry></row><row><entry /><entry /><entry /><entry /><entry>in the decompressed data</entry></row><row><entry /><entry /><entry /><entry /><entry>buffer in DRAM. If this</entry></row><row><entry /><entry /><entry /><entry /><entry>drops < 8 the CDU will</entry></row><row><entry /><entry /><entry /><entry /><entry>stall. In normal opera-</entry></row><row><entry /><entry /><entry /><entry /><entry>tion this value will</entry></row><row><entry /><entry /><entry /><entry /><entry>start off atNumBuffLines</entry></row><row><entry /><entry /><entry /><entry /><entry>and will be decremented</entry></row><row><entry /><entry /><entry /><entry /><entry>by 8 whenever the CDU</entry></row><row><entry /><entry /><entry /><entry /><entry>writes a line of JPEG</entry></row><row><entry /><entry /><entry /><entry /><entry>blocks (8 lines of data)</entry></row><row><entry /><entry /><entry /><entry /><entry>to DRAM and incremented</entry></row><row><entry /><entry /><entry /><entry /><entry>by 1 whenever the CFU</entry></row><row><entry /><entry /><entry /><entry /><entry>reads a line of data</entry></row><row><entry /><entry /><entry /><entry /><entry>from DRAM. NumLinesAvail</entry></row><row><entry /><entry /><entry /><entry /><entry>can be overwritten by</entry></row><row><entry /><entry /><entry /><entry /><entry>the CPU to prevent the</entry></row><row><entry /><entry /><entry /><entry /><entry>CDU from stalling.</entry></row><row><entry>0x10</entry><entry>MaxPlane</entry><entry>2</entry><entry>0x0</entry><entry>Defines the number of</entry></row><row><entry /><entry /><entry /><entry /><entry>contone planes − 1.</entry></row><row><entry /><entry /><entry /><entry /><entry>For example, this will</entry></row><row><entry /><entry /><entry /><entry /><entry>be 0 for K (greyscale</entry></row><row><entry /><entry /><entry /><entry /><entry>printing), 2 for CMY,</entry></row><row><entry /><entry /><entry /><entry /><entry>and 3 for CMYK.</entry></row><row><entry>0x14</entry><entry>MaxBlock</entry><entry>13</entry><entry>0x000</entry><entry>Number of JPEG MCUs</entry></row><row><entry /><entry /><entry /><entry /><entry>(or JPEG block equiva-</entry></row><row><entry /><entry /><entry /><entry /><entry>lents, i.e. 8 × 8</entry></row><row><entry /><entry /><entry /><entry /><entry>bytes) in a line − 1.</entry></row><row><entry>0x18</entry><entry>BuffStartAdr[21:7]</entry><entry>15</entry><entry>0x0000</entry><entry>Points to the start of</entry></row><row><entry /><entry /><entry /><entry /><entry>the decompressed contone</entry></row><row><entry /><entry /><entry /><entry /><entry>circular buffer in DRAM,</entry></row><row><entry /><entry /><entry /><entry /><entry>aligned to a half JPEG</entry></row><row><entry /><entry /><entry /><entry /><entry>block boundary. A half</entry></row><row><entry /><entry /><entry /><entry /><entry>JPEG block consists of</entry></row><row><entry /><entry /><entry /><entry /><entry>4 words of 256-bits,</entry></row><row><entry /><entry /><entry /><entry /><entry>enough to hold 32 con-</entry></row><row><entry /><entry /><entry /><entry /><entry>tone pixels in 4 colors,</entry></row><row><entry /><entry /><entry /><entry /><entry>i.e. half a JPEG block.</entry></row><row><entry>0x1C</entry><entry>BuffEndAdr[21:7]</entry><entry>15</entry><entry>0x0000</entry><entry>Points to the start of</entry></row><row><entry /><entry /><entry /><entry /><entry>the last half JPEG</entry></row><row><entry /><entry /><entry /><entry /><entry>block at the end of the</entry></row><row><entry /><entry /><entry /><entry /><entry>decompressed contone</entry></row><row><entry /><entry /><entry /><entry /><entry>circular buffer in DRAM,</entry></row><row><entry /><entry /><entry /><entry /><entry>aligned to a half JPEG</entry></row><row><entry /><entry /><entry /><entry /><entry>block boundary. A half</entry></row><row><entry /><entry /><entry /><entry /><entry>JPEG block consists of</entry></row><row><entry /><entry /><entry /><entry /><entry>4 words of 256-bits,</entry></row><row><entry /><entry /><entry /><entry /><entry>enough to hold 32 con-</entry></row><row><entry /><entry /><entry /><entry /><entry>tone pixels in 4 colors,</entry></row><row><entry /><entry /><entry /><entry /><entry>i.e. half a JPEG block.</entry></row><row><entry>0x20</entry><entry>NumBuffLines[6:2]</entry><entry>5</entry><entry>0x03</entry><entry>Defines size of buffer</entry></row><row><entry /><entry /><entry /><entry /><entry>in DRAM in terms of the</entry></row><row><entry /><entry /><entry /><entry /><entry>number of decompressed</entry></row><row><entry /><entry /><entry /><entry /><entry>contone lines. The size</entry></row><row><entry /><entry /><entry /><entry /><entry>of the buffer should be</entry></row><row><entry /><entry /><entry /><entry /><entry>a multiple of 4 lines</entry></row><row><entry /><entry /><entry /><entry /><entry>with a minimum size of</entry></row><row><entry /><entry /><entry /><entry /><entry>8 lines.</entry></row><row><entry>0x24</entry><entry>BypassJpg</entry><entry>1</entry><entry>0x0</entry><entry>Determines whether or</entry></row><row><entry /><entry /><entry /><entry /><entry>not the JPEG decoder</entry></row><row><entry /><entry /><entry /><entry /><entry>will be bypassed (and</entry></row><row><entry /><entry /><entry /><entry /><entry>hence pixels are copied</entry></row><row><entry /><entry /><entry /><entry /><entry>directly from input to</entry></row><row><entry /><entry /><entry /><entry /><entry>output) 0 - don't bypass,</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - bypass</entry></row><row><entry /><entry /><entry /><entry /><entry>Should not be changed</entry></row><row><entry /><entry /><entry /><entry /><entry>between bands.</entry></row><row><entry>0x30</entry><entry>NextBandCurrSourceAdr[21:5]</entry><entry>17</entry><entry>0x0_0000</entry><entry>The 256-bit aligned</entry></row><row><entry /><entry /><entry /><entry /><entry>word address containing</entry></row><row><entry /><entry /><entry /><entry /><entry>the start of the next</entry></row><row><entry /><entry /><entry /><entry /><entry>band of compressed</entry></row><row><entry /><entry /><entry /><entry /><entry>contone data in DRAM.</entry></row><row><entry /><entry /><entry /><entry /><entry>This value is copied</entry></row><row><entry /><entry /><entry /><entry /><entry>to CurrSourceAdr when</entry></row><row><entry /><entry /><entry /><entry /><entry>both DoneBand is 1 and</entry></row><row><entry /><entry /><entry /><entry /><entry>NextBandEnable is 1,</entry></row><row><entry /><entry /><entry /><entry /><entry>or when Go transitions</entry></row><row><entry /><entry /><entry /><entry /><entry>from 0 to 1.</entry></row><row><entry>0x34</entry><entry>NextBandEndSourceAdr[21:3]</entry><entry>19</entry><entry>0x0_0000</entry><entry>The 64-bit aligned</entry></row><row><entry /><entry /><entry /><entry /><entry>word address contain-</entry></row><row><entry /><entry /><entry /><entry /><entry>ing the last bytes of</entry></row><row><entry /><entry /><entry /><entry /><entry>the next band of com-</entry></row><row><entry /><entry /><entry /><entry /><entry>pressed contone data</entry></row><row><entry /><entry /><entry /><entry /><entry>in DRAM. This value is</entry></row><row><entry /><entry /><entry /><entry /><entry>copied to EndSourceAdr</entry></row><row><entry /><entry /><entry /><entry /><entry>when when both DoneBand</entry></row><row><entry /><entry /><entry /><entry /><entry>is 1 and NextBandEnable</entry></row><row><entry /><entry /><entry /><entry /><entry>is 1, or when Go transi-</entry></row><row><entry /><entry /><entry /><entry /><entry>tions from 0 to 1.</entry></row><row><entry>0x38</entry><entry>NextBandValidBytesLastFetch</entry><entry>3</entry><entry>0x0</entry><entry>Indicates the number</entry></row><row><entry /><entry /><entry /><entry /><entry>of valid bytes − 1 in</entry></row><row><entry /><entry /><entry /><entry /><entry>the last 64-bit fetch</entry></row><row><entry /><entry /><entry /><entry /><entry>of the next band of</entry></row><row><entry /><entry /><entry /><entry /><entry>compressed contone data</entry></row><row><entry /><entry /><entry /><entry /><entry>from DRAM. eg 0 implies</entry></row><row><entry /><entry /><entry /><entry /><entry>bits 7:0 are valid, 1</entry></row><row><entry /><entry /><entry /><entry /><entry>implies bits 15:0 are</entry></row><row><entry /><entry /><entry /><entry /><entry>valid, 7 implies all</entry></row><row><entry /><entry /><entry /><entry /><entry>63:0 bits are valid etc.</entry></row><row><entry /><entry /><entry /><entry /><entry>This value is copied</entry></row><row><entry /><entry /><entry /><entry /><entry>to ValidBytesLastFetch</entry></row><row><entry /><entry /><entry /><entry /><entry>when both DoneBand is</entry></row><row><entry /><entry /><entry /><entry /><entry>1 and NextBandEnable is</entry></row><row><entry /><entry /><entry /><entry /><entry>1, or when Go transi-</entry></row><row><entry /><entry /><entry /><entry /><entry>tions from 0 to 1.</entry></row><row><entry>0x3C</entry><entry>NextBandEnable</entry><entry>1</entry><entry>0x0</entry><entry>When NextBandEnable</entry></row><row><entry /><entry /><entry /><entry /><entry>is 1 and DoneBand is 1</entry></row><row><entry /><entry /><entry /><entry /><entry>NextBandCurrSourceAdr</entry></row><row><entry /><entry /><entry /><entry /><entry>is copied to</entry></row><row><entry /><entry /><entry /><entry /><entry>CurrSourceAdr,</entry></row><row><entry /><entry /><entry /><entry /><entry>NextBandEndSourceAdr</entry></row><row><entry /><entry /><entry /><entry /><entry>is copied to</entry></row><row><entry /><entry /><entry /><entry /><entry>EndSourceAdr</entry></row><row><entry /><entry /><entry /><entry /><entry>NextBandValidBytesLastFetch</entry></row><row><entry /><entry /><entry /><entry /><entry>is copied to</entry></row><row><entry /><entry /><entry /><entry /><entry>ValidBytesLastFetch</entry></row><row><entry /><entry /><entry /><entry /><entry>DoneBand is cleared,</entry></row><row><entry /><entry /><entry /><entry /><entry>NextBandEnable is</entry></row><row><entry /><entry /><entry /><entry /><entry>cleared. NextBandEnable</entry></row><row><entry /><entry /><entry /><entry /><entry>is cleared when Go is</entry></row><row><entry /><entry /><entry /><entry /><entry>asserted.</entry></row><row><entry /><entry /><entry /><entry /><entry>Note that DoneBand gets</entry></row><row><entry /><entry /><entry /><entry /><entry>cleared regardless of the</entry></row><row><entry /><entry /><entry /><entry /><entry>state of Go.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="315pt" align="left" /><tbody valign="top"><row><entry>Read-only registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="98pt" align="left" /><colspec colname="3" colwidth="21pt" align="char" char="." /><colspec colname="4" colwidth="42pt" align="left" /><colspec colname="5" colwidth="98pt" align="left" /><colspec colname="6" colwidth="7pt" align="left" /><tbody valign="top"><row><entry>0x40</entry><entry>DoneBand</entry><entry>1</entry><entry>0x0</entry><entry>Specifies whether or not</entry><entry /></row><row><entry /><entry /><entry /><entry /><entry>the current band has</entry></row><row><entry /><entry /><entry /><entry /><entry>finished loading into the</entry></row><row><entry /><entry /><entry /><entry /><entry>local FIFO. It is cleared</entry></row><row><entry /><entry /><entry /><entry /><entry>to 0 when Go transitions</entry></row><row><entry /><entry /><entry /><entry /><entry>from 0 to 1. When the</entry></row><row><entry /><entry /><entry /><entry /><entry>last of the compressed</entry></row><row><entry /><entry /><entry /><entry /><entry>contone data for the band</entry></row><row><entry /><entry /><entry /><entry /><entry>has been loaded into the</entry></row><row><entry /><entry /><entry /><entry /><entry>local FIFO, the</entry></row><row><entry /><entry /><entry /><entry /><entry>cdu_finishedband signal</entry></row><row><entry /><entry /><entry /><entry /><entry>is given out and the</entry></row><row><entry /><entry /><entry /><entry /><entry>DoneBandflag is set.</entry></row><row><entry /><entry /><entry /><entry /><entry>If NextBandEnable is 1</entry></row><row><entry /><entry /><entry /><entry /><entry>at this time then</entry></row><row><entry /><entry /><entry /><entry /><entry>CurrSourceAdr,</entry></row><row><entry /><entry /><entry /><entry /><entry>EndSourceAdr and</entry></row><row><entry /><entry /><entry /><entry /><entry>ValidBytesLastFetch</entry></row><row><entry /><entry /><entry /><entry /><entry>are updated with the</entry></row><row><entry /><entry /><entry /><entry /><entry>values for the next</entry></row><row><entry /><entry /><entry /><entry /><entry>band and DoneBand is</entry></row><row><entry /><entry /><entry /><entry /><entry>cleared. Processing</entry></row><row><entry /><entry /><entry /><entry /><entry>of the next band starts</entry></row><row><entry /><entry /><entry /><entry /><entry>immediately. If</entry></row><row><entry /><entry /><entry /><entry /><entry>NextBandEnable is 0</entry></row><row><entry /><entry /><entry /><entry /><entry>then the remainder of</entry></row><row><entry /><entry /><entry /><entry /><entry>the CDU will continue</entry></row><row><entry /><entry /><entry /><entry /><entry>to run, decompressing</entry></row><row><entry /><entry /><entry /><entry /><entry>the data already loaded,</entry></row><row><entry /><entry /><entry /><entry /><entry>while the read control</entry></row><row><entry /><entry /><entry /><entry /><entry>unit waits for</entry></row><row><entry /><entry /><entry /><entry /><entry>NextBandEnable to be</entry></row><row><entry /><entry /><entry /><entry /><entry>set before it</entry></row><row><entry /><entry /><entry /><entry /><entry>restarts.</entry></row><row><entry>0x44</entry><entry>CurrSourceAdr[21:5]</entry><entry>17</entry><entry>0x0_0000</entry><entry>The current 256-bit</entry></row><row><entry /><entry /><entry /><entry /><entry>aligned word address</entry></row><row><entry /><entry /><entry /><entry /><entry>within the current band</entry></row><row><entry /><entry /><entry /><entry /><entry>of compressed contone</entry></row><row><entry /><entry /><entry /><entry /><entry>data in DRAM.</entry></row><row><entry>0x48</entry><entry>EndSourceAdr[21:3]</entry><entry>19</entry><entry>0x0_0000</entry><entry>The 64-bit aligned</entry></row><row><entry /><entry /><entry /><entry /><entry>word address containing</entry></row><row><entry /><entry /><entry /><entry /><entry>the last bytes of the</entry></row><row><entry /><entry /><entry /><entry /><entry>current band of com-</entry></row><row><entry /><entry /><entry /><entry /><entry>pressed contone data</entry></row><row><entry /><entry /><entry /><entry /><entry>in DRAM.</entry></row><row><entry>0x4C</entry><entry>ValidBytesLastFetch</entry><entry>3</entry><entry>0x00</entry><entry>Indicates the number</entry></row><row><entry /><entry /><entry /><entry /><entry>of valid bytes − 1 in</entry></row><row><entry /><entry /><entry /><entry /><entry>the last 64-bit fetch</entry></row><row><entry /><entry /><entry /><entry /><entry>of the current band of</entry></row><row><entry /><entry /><entry /><entry /><entry>compressed contone data</entry></row><row><entry /><entry /><entry /><entry /><entry>from DRAM. eg 0 implies</entry></row><row><entry /><entry /><entry /><entry /><entry>bits 7:0 are valid, 1</entry></row><row><entry /><entry /><entry /><entry /><entry>implies bits 15:0 are</entry></row><row><entry /><entry /><entry /><entry /><entry>valid, 7 implies all</entry></row><row><entry /><entry /><entry /><entry /><entry>63:0 bits are valid</entry></row><row><entry /><entry /><entry /><entry /><entry>etc.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="315pt" align="left" /><tbody valign="top"><row><entry>JPEG decoder core setup registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="98pt" align="left" /><colspec colname="3" colwidth="21pt" align="char" char="." /><colspec colname="4" colwidth="42pt" align="left" /><colspec colname="5" colwidth="98pt" align="left" /><colspec colname="6" colwidth="7pt" align="left" /><tbody valign="top"><row><entry>0x50</entry><entry>JpgDecMask</entry><entry>5</entry><entry>0x00</entry><entry>As segments are de-</entry><entry /></row><row><entry /><entry /><entry /><entry /><entry>coded they can also</entry></row><row><entry /><entry /><entry /><entry /><entry>be output on the</entry></row><row><entry /><entry /><entry /><entry /><entry>DecJpg (JpgDecHdr)</entry></row><row><entry /><entry /><entry /><entry /><entry>port with the user</entry></row><row><entry /><entry /><entry /><entry /><entry>selecting the segments</entry></row><row><entry /><entry /><entry /><entry /><entry>for output by setting</entry></row><row><entry /><entry /><entry /><entry /><entry>bits in the jpgDecMask</entry></row><row><entry /><entry /><entry /><entry /><entry>port as follows:</entry></row><row><entry /><entry /><entry /><entry /><entry>4 SOF + SOS + DNL</entry></row><row><entry /><entry /><entry /><entry /><entry>3 COM + APP</entry></row><row><entry /><entry /><entry /><entry /><entry>2 DRI</entry></row><row><entry /><entry /><entry /><entry /><entry>1 DQT</entry></row><row><entry /><entry /><entry /><entry /><entry>0 DHT</entry></row><row><entry /><entry /><entry /><entry /><entry>If any one of the bits</entry></row><row><entry /><entry /><entry /><entry /><entry>of jpgDecMask is assert-</entry></row><row><entry /><entry /><entry /><entry /><entry>ed then the SOI and</entry></row><row><entry /><entry /><entry /><entry /><entry>EOI markers are also</entry></row><row><entry /><entry /><entry /><entry /><entry>passed to the DecJpg</entry></row><row><entry /><entry /><entry /><entry /><entry>port.</entry></row><row><entry>0x54</entry><entry>JpgDecTType</entry><entry>1</entry><entry>0x0</entry><entry>Test type selector:</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - DCT coefficients</entry></row><row><entry /><entry /><entry /><entry /><entry>displayed on</entry></row><row><entry /><entry /><entry /><entry /><entry>JpgDecTdata</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - QDCT coefficient</entry></row><row><entry /><entry /><entry /><entry /><entry>displayed on</entry></row><row><entry /><entry /><entry /><entry /><entry>JpgDecTdata</entry></row><row><entry>0x58</entry><entry>JpgDecTestEn</entry><entry>1</entry><entry>0x0</entry><entry>Signal which causes</entry></row><row><entry /><entry /><entry /><entry /><entry>the memories to be</entry></row><row><entry /><entry /><entry /><entry /><entry>bypassed for test</entry></row><row><entry /><entry /><entry /><entry /><entry>purposes.</entry></row><row><entry>0x5C</entry><entry>JpgDecPType</entry><entry>4</entry><entry>0x0</entry><entry>Signal specifying</entry></row><row><entry /><entry /><entry /><entry /><entry>parameters to be</entry></row><row><entry /><entry /><entry /><entry /><entry>placed on port</entry></row><row><entry /><entry /><entry /><entry /><entry>JpgDecPValue (See</entry></row><row><entry /><entry /><entry /><entry /><entry>Table).</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="315pt" align="left" /><tbody valign="top"><row><entry>JPEG decoder core read-only status registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="98pt" align="left" /><colspec colname="3" colwidth="21pt" align="char" char="." /><colspec colname="4" colwidth="42pt" align="left" /><colspec colname="5" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>0x60</entry><entry>JpgDecHdr</entry><entry>8</entry><entry>0x00</entry><entry>Selected header segments</entry></row><row><entry /><entry /><entry /><entry /><entry>from the JPEG stream</entry></row><row><entry /><entry /><entry /><entry /><entry>that is currently being</entry></row><row><entry /><entry /><entry /><entry /><entry>decoded. Segments</entry></row><row><entry /><entry /><entry /><entry /><entry>selected using JpgMask.</entry></row><row><entry>0x64</entry><entry>JpgDecTData</entry><entry>13</entry><entry>0x0000</entry><entry>12 - TSOS output of</entry></row><row><entry /><entry /><entry /><entry /><entry>CS1650, indicates the</entry></row><row><entry /><entry /><entry /><entry /><entry>first output byte of</entry></row><row><entry /><entry /><entry /><entry /><entry>the first 8 × 8 block</entry></row><row><entry /><entry /><entry /><entry /><entry>of the test data.</entry></row><row><entry /><entry /><entry /><entry /><entry>11 - TSOB output of</entry></row><row><entry /><entry /><entry /><entry /><entry>CS1650, indicates the</entry></row><row><entry /><entry /><entry /><entry /><entry>first output byte of</entry></row><row><entry /><entry /><entry /><entry /><entry>each 8 × 8 block of</entry></row><row><entry /><entry /><entry /><entry /><entry>test data.</entry></row><row><entry /><entry /><entry /><entry /><entry>10-0 - 11-bit output</entry></row><row><entry /><entry /><entry /><entry /><entry>test data port - dis-</entry></row><row><entry /><entry /><entry /><entry /><entry>plays DCT coefficients</entry></row><row><entry /><entry /><entry /><entry /><entry>or quantized coefficients</entry></row><row><entry /><entry /><entry /><entry /><entry>depending on value of</entry></row><row><entry /><entry /><entry /><entry /><entry>JpgDecTType.</entry></row><row><entry>0x68</entry><entry>JpgDecPValue</entry><entry>16</entry><entry>0x0000</entry><entry>Decoding parameter bus</entry></row><row><entry /><entry /><entry /><entry /><entry>which enables various</entry></row><row><entry /><entry /><entry /><entry /><entry>parameters used by the</entry></row><row><entry /><entry /><entry /><entry /><entry>core to be read. The</entry></row><row><entry /><entry /><entry /><entry /><entry>data available on the</entry></row><row><entry /><entry /><entry /><entry /><entry>PValue port is for</entry></row><row><entry /><entry /><entry /><entry /><entry>information only, and</entry></row><row><entry /><entry /><entry /><entry /><entry>does not contain</entry></row><row><entry /><entry /><entry /><entry /><entry>control signals for</entry></row><row><entry /><entry /><entry /><entry /><entry>the decoder core.</entry></row><row><entry>0x6C</entry><entry>JpgDecStatus</entry><entry>24</entry><entry>0x00_0000</entry><entry>Bit 23 - jpg_core_stall</entry></row><row><entry /><entry /><entry /><entry /><entry>(if set, indicates that</entry></row><row><entry /><entry /><entry /><entry /><entry>the JPEG core is</entry></row><row><entry /><entry /><entry /><entry /><entry>stalled by gating of</entry></row><row><entry /><entry /><entry /><entry /><entry>jclk as the output</entry></row><row><entry /><entry /><entry /><entry /><entry>JPEG halfblock</entry></row><row><entry /><entry /><entry /><entry /><entry>double-buffers of</entry></row><row><entry /><entry /><entry /><entry /><entry>the CDU are full)</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 22 - pix_out_valid</entry></row><row><entry /><entry /><entry /><entry /><entry>(This signal is an</entry></row><row><entry /><entry /><entry /><entry /><entry>output from the JPEG</entry></row><row><entry /><entry /><entry /><entry /><entry>decoder core and is</entry></row><row><entry /><entry /><entry /><entry /><entry>asserted when a</entry></row><row><entry /><entry /><entry /><entry /><entry>pixel is being output</entry></row><row><entry /><entry /><entry /><entry /><entry>Bits 21–16 -</entry></row><row><entry /><entry /><entry /><entry /><entry>fifo_contents</entry></row><row><entry /><entry /><entry /><entry /><entry>(Number of bytes in</entry></row><row><entry /><entry /><entry /><entry /><entry>compressed contone</entry></row><row><entry /><entry /><entry /><entry /><entry>FIFO at the input of</entry></row><row><entry /><entry /><entry /><entry /><entry>CDU which feeds the</entry></row><row><entry /><entry /><entry /><entry /><entry>JPEG decoder core)</entry></row><row><entry /><entry /><entry /><entry /><entry>Bits 15–0 are JPEG</entry></row><row><entry /><entry /><entry /><entry /><entry>decoder status outputs</entry></row><row><entry /><entry /><entry /><entry /><entry>from the CS6150 (see</entry></row><row><entry /><entry /><entry /><entry /><entry>Table for description</entry></row><row><entry /><entry /><entry /><entry /><entry>of bits).</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 22.5.3 Typical Operation
2577The CDU should only be started after the CFU has been started.
2578For the first band of data, users set up NextBandCurrSourceAdr, NextBandEndSourceAdr, NextBandValidBytesLastFetch, and the various MaxPlane, MaxBlock, BuffStartBlockAdr, BuffEndBlockAdr and NumBuffLines. Users then set the CDU's Go bit to start processing of the band. When the compressed contone data for the band has finished being read in, the cdu_finishedband interrupt will be sent to the PCU and CPU indicating that the memory associated with the first band is now free. Processing can now start on the next band of contone data.
2579In order to process the next band NextBandCurrSourceAdr, NextBandEndSourceAdr and NextBandValidBytesLastFetch need to be updated before finally writing a 1 to NextBandEnable. There are 4 mechanisms for restarting the CDU between bands: <ul id="ul0258" list-style="none"><li id="ul0258-0001" num="2580">a. cdu_finishedband causes an interrupt to the CPU. The CDU will have set its DoneBand bit. The CPU reprograms the NextBandCurrSourceAdr, NextBandEndSourceAdr and NextBandValidBytesLastFetch registers, and sets NextBandEnable to restart the CDU.</li><li id="ul0258-0002" num="2581">b. The CPU programs the CDU's NextBandCurrSourceAdr, NextBandCurrEndAdr and NextBandValidBytesLastFetch registers and sets the NextBandEnable bit before the end of the current band. At the end of the current band the CDU sets DoneBand. As NextBandEnable is already 1, the CDU starts processing the next band immediately.</li><li id="ul0258-0003" num="2582">c. The PCU is programmed so that cdu_finishedband triggers the PCU to execute commands from DRAM to reprogram the NextBandCurrSourceAdr, NextBandEndSourceAdr and NextBandValidBytesLastFetch registers and set the NextBandEnable bit to start the CDU processing the next band. The advantage of this scheme is that the CPU could process band headers in advance and store the band commands in DRAM ready for execution.</li></ul>
2583d. This is a combination of b and c above. The PCU (rather than the CPU in b) programs the CDU's NextBandCurrSourceAdr, NextBandCurrEndAdr and NextBandValidBytesLastFetch registers and sets the NextBandEnable bit before the end of the current band. At the end of the current band the CDU sets DoneBand and pulses cdu_finishedband. As NextBandEnable is already 1, the CDU starts processing the next band immediately. Simultaneously, cdu_finishedband triggers the PCU to fetch commands from DRAM. The CDU will have restarted by the time the PCU has fetched commands from DRAM. The PCU commands program the CDU's next band shadow registers and sets the NextBandEnable bit.
2584If an error occurs in the JPEG stream, the JPEG decoder will suspend its operation, an error bit will be set in the JpgDecStatus register and the core will ignore any input data and await a reset before starting decoding again. An interrupt is sent to the CPU by asserting cdu_icu_jpegerror and the CDU should then be reset by means of a write to its Reset register before a new page can be printed.
000022.5.4 Read Control Unit
2585The read control unit is responsible for reading the compressed contone data and passing it to the JPEG decoder via the FIFO. The compressed contone data is read from DRAM in single 256-bit accesses, receiving the data from the DIU over 4 clock cycles (64-bits per cycle). The protocol and timing for read accesses to DRAM is described in section 20.9.1 on page 240. Read accesses to DRAM are implemented by means of the state machine described in <figref idref="DRAWINGS">FIG. 138</figref>. All counters and flags should be cleared after reset. When Go transitions from 0 to 1 all counters and flags should take their initial value. While the Go bit is set, the state machine relies on the DoneBand bit to tell it whether to attempt to read a band of compressed contone data. When DoneBand is set, the state machine does nothing. When DoneBand is clear, the state machine continues to load data into the JPEG input FIFO up to 256-bits at a time while there is space available in the FIFO. Note that the state machine has no knowledge about numbers of blocks or numbers of color planes—it merely keeps the JPEG input FIFO full by consecutive reads from DRAM. The DIU is responsible for ensuring that DRAM requests are satisfied at least at the peak DRAM read bandwidth of 0.36 bits/cycle (see section 22.3 on page 329).
2586A modulo 4 counter, rd_count, is use to count each of the 64-bits received in a 256-bit read access. It is incremented whenever diu_cdu_rvalid is asserted. As each 64-bit value is returned, indicated by diu_cdu_rvalid being asserted, curr_source_adr is compared to both end_source_adr and end_of_bandstore: <ul id="ul0259" list-style="none"><li id="ul0259-0001" num="0000"><ul id="ul0260" list-style="none"><li id="ul0260-0001" num="2587">If {curr_source_adr rd_count} equals end_source_adr, the end_of_band control signal sent to the FIFO is 1 (to signify the end of the band), the finishedCDUBand signal is output, and the DoneBand bit is set. The remaining 64-bit values in the burst from the DIU are ignored, i.e. they are not written into the FIFO.</li><li id="ul0260-0002" num="2588">If rd_count equals 3 and {curr_source_adr, rd_count} does not equal end_source_adr, then curr_source_adr is updated to be either start_of_bandstore or curr_source_adr+1, depending on whether curr_source_adr also equals end_of_bandstore. The end_of_band control signal sent to the FIFO is 0.</li></ul></li></ul>
2589curr_source_adr is output to the DIU as cdu_diu_radr.
2590A count is kept of the number of 64-bit values in the FIFO. When diu_cdu_rvalid is 1 and ignore_data is 0, data is written to the FIFO by asserting FifoWr, and fifo_contents[3:0] and fifo_wr_adr[2:0] are both incremented.
2591When fifo_contents[3:0] is greater than 0, jpg_in_strb is asserted to indicate that there is data available in the FIFO for the JPEG decoder core. The JPEG decoder core asserts jpg_in_rdy when it is ready to receive data from the FIFO. Note it is also possible to bypass the JPEG decoder core by setting the BypassJpg register to 1. In this case data is sent directly from the FIFO to the half-block double-buffer. While the JPEG decoder is not stalled (jpg_core_stall equal 0), and jpg_in_rdy (or bypass_jpg) and jpg_in_strb are both 1, a byte of data is consumed by the JPEG decoder core. fifo_rd_adr[5:0] is then incremented to select the next byte. The read address is byte aligned, i.e. the upper 3 bits are input as the read address for the FIFO and the lower 3 bits are used to select a byte from the 64 bits. If fifo_rd_adr[2:0]=111 then the next 64-bit value is read from the FIFO by asserting fifo_rd, and fifo_contents[3:0] is decremented.
000022.5.5 Compressed Contone FIFO
2592The compressed contone FIFO conceptually is a 64-bit input, and 8-bit output FIFO to account for the 64-bit data transfers from the DIU, and the 8-bit requirement of the JPEG decoder.
2593In reality, the FIFO is actually 8 entries deep and 65-bits wide (to accommodate two 256-bit accesses), with bits <b>63</b>–<b>0</b> carrying data, and bit <b>64</b> containing a 1-bit end_of_band flag. Whenever 64-bit data is written to the FIFO from the DIU, an end of band flag is also passed in from the read control unit. The end_of_band bit is 1 if this is the last data transfer for the current band, and 0 if it is not the last transfer. When end_of_band=1 during an input, the ValidBytesLastFetch register is also copied to an image version of the same.
2594On the JPEG decoder side of the FIFO, the read address is byte aligned, i.e. the upper 3 bits are input as the read address for the FIFO and the lower 3 bits are used to select a byte from the 64 bits (1st byte corresponds to bits <b>7</b>–<b>0</b>, second byte to bits <b>15</b>–<b>8</b> etc.). If bit <b>64</b> is set on the read, bits <b>63</b>–<b>0</b> contain the end of the bytestream for that band, and only the bytes specified by the image of ValidBytesLastFetch are valid bytes to be read and presented to the JPEG decoder. Note that ValidBytesLastFetch is copied to an image register as it may be possible for the CDU to be reprogrammed for the next band before the previous band's compressed contone data has been read from the FIFO (as an additional effect of this, the CDU has a non-problematic limitation in that each band of contone data must be more than 4×64-bits, or 32 bytes, in length).
000022.5.6 CS6150 JPEG Decoder
2595JPEG decoder functionality is implemented by means of a modified version of the Amphion CS6150 JPEG decoder core. The decoder is run at a nominal clock speed of 160 MHz. (Amphion have stated that the CS6150 JPEG decoder core can run at 185 MHz in 0.13 um technology). The core is clocked by jclk which a gated version of the system clock pclk. Gating the clock provides a mechanism for stalling the JPEG decoder on a single color pixel-by-pixel basis. Control of the flow of output data is also provided by the PixOutEnab input to the JPEG decoder. However, this only allows stalling of the output at a JPEG block boundary and is insufficient for SoPEC. Thus gating of the clock is employed and PixOutEnab is instead tied high.
2596The CS6150 decoder automatically extracts all relevant parameters from the JPEG bytestream and uses them to control the decoding of the image. The JPEG bytestream contains data for the Huffman tables, quantization tables, restart interval definition and frame and scan headers. The decoder parses and checks the JPEG bytestream automatically detecting and processing all the JPEG marker segments. After identifying the JPEG segments the decoder re-directs the data to the appropriate units to be stored or processed as appropriate. Any errors detected in the bytestream, apart from those in the entropy coded segments, are signalled and, if an error is found, the decoder stops reading the JPEG stream and waits to be reset.
2597JPEG images must have their data stored in interleaved format with no subsampling. Images longer than 65536 lines are allowed: these must have an initial imageHeight of 0. If the image has a Define Number Lines (DNL) marker at the end (normally necessary for standard JPEG, but not necessary for SoPEC's version of the CS6150), it must be equal to the total image height mod 64 k or an error will be generated.
2598See the CS6150 Databook [21] for more details on how the core is used, and for timing diagrams of the interfaces. Note that [21] does not describe the use of the DNL marker in images of more than 64 k lines length as this is a modification to the core.
2599The CS6150 decoder can be bypassed by setting the BypassJpg register. If this register is set, then the data read from DRAM must be in the same format as if it was produced by the JPEG decoder: 8×8 blocks of pixels in the correct color order. The data is uncompressed and is therefore lossless.
2600The following subsections describe the means by which the CS6150 internals can be made visible.
000022.5.6.1 JPEG Decoder Reset
2601The JPEG decoder has 2 possible types of reset, an asynchronous reset and a synchronous clear. In SoPEC the asynchronous reset is connected to the hardware synchronous reset of the CDU and can be activated by any hardware reset to SoPEC (either from external pin or from any of the wake-up sources, e.g. USB activity, Wake-up register timeout) or by resetting the PEP section (ResetSection register in the CPR block).
2602The synchronous clear is connected to the software reset of the CDU and can be activated by the low to high transition of the Go register, or a software reset via the Reset register.
2603The 2 types of reset differ, in that the asynchronous reset, resets the JPEG core and causes the core to enter a memory initialization sequence that takes 384 clock cycles to complete after the reset is deasserted. The synchronous clear resets the core, but leaves the memory as is. This has some implications for programming the CDU.
2604In general the CDU should not be started (i.e. setting Go to 1) until at least 384 cycles after a hardware reset. If the CDU is started before then, the memory initialization sequence will be terminated leaving the JPEG core memory in an unknown state. This is allowed if the memory is to be initialized from the incoming JPEG stream.
000022.5.6.2 JPEG Decoder Parameter Bus
2605The decoding parameter bus JpgDecPValue is a 16-bit port used to output various parameters extracted from the input data stream and currently used by the core. The 4-bit selector input (JpgDecPType) determines which internal parameters are displayed on the parameter bus as per Table 148. The data available on the PValue port does not contain control signals used by the CS6150.
2606<tables id="TABLE-US-00218" num="00218"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 148</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Parameter bus definitions</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>PType</entry><entry>Output orientation</entry><entry>PValue</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>0x0</entry><entry>FY[15:0]</entry><entry>FY: number of lines in frame</entry></row><row><entry>0x1</entry><entry>FX[15:0]</entry><entry>FX: number of columns in frame</entry></row><row><entry>0x2</entry><entry>00_YMCU[13:0]</entry><entry>YMCU: number of MCUs in Y</entry></row><row><entry /><entry /><entry>direction of the current scan</entry></row><row><entry>0x3</entry><entry>00_XMCU[13:0]</entry><entry>XMCU: number of MCUs in X</entry></row><row><entry /><entry /><entry>direction of the current scan</entry></row><row><entry>0x4</entry><entry>Cs0[7:0]_Tq0[1:0]<sub>—</sub></entry><entry>Cs0: identifier for the first</entry></row><row><entry /><entry>V0[2:0]_H0[2:0]</entry><entry>scan component</entry></row><row><entry /><entry /><entry>Tq0: quantization table identi-</entry></row><row><entry /><entry /><entry>fier for the first scan compo-</entry></row><row><entry /><entry /><entry>nent</entry></row><row><entry /><entry /><entry>V0: vertical sampling factor</entry></row><row><entry /><entry /><entry>for the first scan component.</entry></row><row><entry /><entry /><entry>Values = 1–4</entry></row><row><entry /><entry /><entry>H0: horizontal sampling factor</entry></row><row><entry /><entry /><entry>for the first scan component.</entry></row><row><entry /><entry /><entry>Values = 1–4</entry></row><row><entry>0x5</entry><entry>Cs1[7:0]_Tq1[1:0]<sub>—</sub></entry><entry>Cs1, Tq1, V1 and H1 for the</entry></row><row><entry /><entry>V1[2:0]_H1[2:0]</entry><entry>second scan component.</entry></row><row><entry /><entry /><entry>V1, H1 undefined if NS < 2</entry></row><row><entry>0x6</entry><entry>Cs2[7:0]_Tq2[1:0]<sub>—</sub></entry><entry>Cs2, Tq2, V2 and H2 for the</entry></row><row><entry /><entry>V2[2:0]_H2[2:0]</entry><entry>second scan component.</entry></row><row><entry /><entry /><entry>V2, H2 undefined if NS < 3</entry></row><row><entry>0x7</entry><entry>Cs3[7:0]_Tq3[1:0]<sub>—</sub></entry><entry>Cs3, Tq3, V3 and H3 for the</entry></row><row><entry /><entry>V3[2:0]_H3[2:0]</entry><entry>second scan component.</entry></row><row><entry /><entry /><entry>V3, H3 undefined if NS < 4</entry></row><row><entry>0x8</entry><entry>CsH[15:0]</entry><entry>CsH: no. of rows in current</entry></row><row><entry /><entry /><entry>scan</entry></row><row><entry>0x9</entry><entry>CsV[15:0]</entry><entry>CsV: no. of columns in</entry></row><row><entry /><entry /><entry>current scan</entry></row><row><entry>0xA</entry><entry>DRI[15:0]</entry><entry>DRI: restart interval</entry></row><row><entry>0xB</entry><entry>000_HMAX[2:0]<sub>—</sub></entry><entry>HMAX: maximal horizontal sampling</entry></row><row><entry /><entry>VMAX[2:0]<sub>—</sub></entry><entry>factor in frame VMAX: maximal</entry></row><row><entry /><entry>MCUBLK[3:0]_NS[2:0]</entry><entry>vertical sampling factor in</entry></row><row><entry /><entry /><entry>frame MCUBLK: number of blocks</entry></row><row><entry /><entry /><entry>per MCU of the current scan,</entry></row><row><entry /><entry /><entry>from 1 to 10 NS: number of</entry></row><row><entry /><entry /><entry>scan components in current</entry></row><row><entry /><entry /><entry>scan, 1–4</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 22.5.6.3 JPEG Decoder Status Register
2607The status register flags indicate the current state of the CS6150 operation. When an error is detected during the decoding process, the decompression process in the JPEG decoder is suspended and an interrupt is sent to the CPU by asserting cdu_icu_jpegerror (generated from DecError). The CPU can check the source of the error by reading the JpgDecStatus register. The CS6150 waits until a reset process is invoked by asserting the hard reset prst_n or by a soft reset of the CDU. The individual bits of JpgDecStatus are set to zero at reset and active high to indicate an error condition as defined in Table 149.
2608Note: A DecHfError will not block the input as the core will try to recover and produce the correct amount of pixel data. The DecHfError is cleared automatically at the start of the next image and so no intervention is required from the user. If any of the other errors occur in the decode mode then, following the error cancellation, the core will discard all input data until the next Start Of Image (SOI) without triggering any more errors.
2609The progress of the decoding can be monitored by observing the values of TbIDef, IDctInProg, DecInProg and JpgInProg.
2610<tables id="TABLE-US-00219" num="00219"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 149</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>JPEG decoder status register definitions</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="35pt" align="center" /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="140pt" align="left" /><tbody valign="top"><row><entry>Bit</entry><entry>Name</entry><entry>Description</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>15–12</entry><entry>TblDef[7:4]</entry><entry>Indicates the number of Huffman tables</entry></row><row><entry /><entry /><entry>defined, 1bit/table.</entry></row><row><entry>11–8 </entry><entry>TblDef[3:0]</entry><entry>Indicates the number of quantization</entry></row><row><entry /><entry /><entry>tables defined, 1bit/table.</entry></row><row><entry>7</entry><entry>DecHfError</entry><entry>Set when an undefined Huffman table</entry></row><row><entry /><entry /><entry>symbol is referenced during decoding.</entry></row><row><entry>6</entry><entry>CtlError</entry><entry>Set when an invalid SOF parameter or</entry></row><row><entry /><entry /><entry>an invalid SOS parameter is detected.</entry></row><row><entry /><entry /><entry>Also set when there is a mismatch</entry></row><row><entry /><entry /><entry>between the DNL segment input to the</entry></row><row><entry /><entry /><entry>core and the number of lines in the</entry></row><row><entry /><entry /><entry>input image which have already been</entry></row><row><entry /><entry /><entry>decoded. Note that SoPEC's implementation</entry></row><row><entry /><entry /><entry>of the CS6150 does not require a final</entry></row><row><entry /><entry /><entry>DNL when the initial setting for</entry></row><row><entry /><entry /><entry>ImageHeight is 0. This is to allow</entry></row><row><entry /><entry /><entry>images longer than 64k lines.</entry></row><row><entry>5</entry><entry>HtError</entry><entry>Set when an invalid DHT segment is</entry></row><row><entry /><entry /><entry>detected.</entry></row><row><entry>4</entry><entry>QtError</entry><entry>Set when an invalid DQT segment is</entry></row><row><entry /><entry /><entry>detected.</entry></row><row><entry>3</entry><entry>DecError</entry><entry>Set when anything other than a JPEG</entry></row><row><entry /><entry /><entry>marker is input.</entry></row><row><entry /><entry /><entry>Set when any of DecFlags[6:4] are set.</entry></row><row><entry /><entry /><entry>Set when any data other than the SOI</entry></row><row><entry /><entry /><entry>marker is detected at the start of a</entry></row><row><entry /><entry /><entry>stream.</entry></row><row><entry /><entry /><entry>Set when any SOF marker is detected</entry></row><row><entry /><entry /><entry>other than SOF0.</entry></row><row><entry /><entry /><entry>Set if incomplete Huffman or quantization</entry></row><row><entry /><entry /><entry>definition is detected.</entry></row><row><entry>2</entry><entry>IDctInProg</entry><entry>Set when IDCT starts processing first</entry></row><row><entry /><entry /><entry>data of a scan. Cleared when IDCT has</entry></row><row><entry /><entry /><entry>processed the last data of a scan.</entry></row><row><entry>1</entry><entry>DecInProg</entry><entry>For each scan this signal is asserted</entry></row><row><entry /><entry /><entry>after the SigSOS (Start of Scan Segment)</entry></row><row><entry /><entry /><entry>signal has been output from the core and</entry></row><row><entry /><entry /><entry>is deasserted when the decoding of a scan</entry></row><row><entry /><entry /><entry>is complete. It indicates that the core</entry></row><row><entry /><entry /><entry>is in the decoding state.</entry></row><row><entry>0</entry><entry>JpgInProg</entry><entry>Set when core starts to process input</entry></row><row><entry /><entry /><entry>data (JpgIn) and de-asserted when</entry></row><row><entry /><entry /><entry>decoding has been completed i.e. when</entry></row><row><entry /><entry /><entry>the last pixel of last block of the</entry></row><row><entry /><entry /><entry>image is output.</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 22.5.7 Half-block Buffer Interface
2611Since the CDU writes 256 bits (4×64 bits) to memory at a time, it requires a double-buffer of 2×256 bits at its output. This is implemented in an 8×64 bit FIFO. It is required to be able to stall the JPEG decoder core at its output on a half JPEG block boundary, i.e. after 32 pixels (8 bits per pixel). We provide a mechanism for stalling the JPEG decoder core by gating the clock to the core (with jclk_enable) when the FIFO is full. The output FIFO is responsible for providing two buffered half JPEG blocks to decouple JPEG decoding (read control unit) from writing those JPEG blocks to DRAM (write control unit). Data coming in is in 8-bit quantities but data going out is in 64-bit quantities for a single color plane.
000022.5.8 Write Control Unit
2612A line of JPEG blocks in 4 colors, or 8 lines of decompressed contone data, is stored in DRAM with the memory arrangement as shown <figref idref="DRAWINGS">FIG. 139</figref>. The arrangement is in order to optimize access for reads by writing the data so that 4 color components are stored together in each 256-bit DRAM word.
2613The CDU writes 8 lines of data in parallel but stores the first 4 lines and second 4 lines separately in DRAM. The write sequence for a single line of JPEG 8×8 blocks in 4 colors, as shown in <figref idref="DRAWINGS">FIG. 139</figref>, is as follows below and corresponds to the order in which pixels are output from the JPEG decoder core:
2614<tables id="TABLE-US-00220" num="00220"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>block 0, color 0, line 0 in word p bits 63–0, line 1 in</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>word p+1 bits 63–0,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>line 2 in word p+2 bits 63–0, line</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>3 in word p+3 bits 63–0,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>block 0, color 0, line 4 in word q bits 63–0, line 5 in</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>word q+1 bits 63–0,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>line 6 in word q+2 bits 63–0, line</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>7 in word q+3 bits 63–0,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>block 0, color 1, line 0 in word p bits 127–64, line 1 in</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>word p+1 bits 127–64,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>line 2 in word p+2 bits 127–64,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>line 3 in word p+3 bits 127–64,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>block 0, color 1, line 4 in word q bits 127–64, line 5 in</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>word q+1 bits 127–64,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>line 6 in word q+2 bits 127–64,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>line 7 in word q+3 bits 127–64,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>repeat for block 0 color 2, block 0 color 3........</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>block 1, color 0, line 0 in word p+4 bits 63–0, line 1 in</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>word p+5 bits 63–0,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>etc...................................................</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>block N, color 3, line 4 in word q+4n bits 255–192, line 5</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>in word q+4n+1 bits 255–192,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>line 6 in word q+4n+2 bits 255−</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>192, line 7 in word q+4n+3 bit 255−192</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2615In SoPEC data is written to DRAM 256 bits at a time. The DIU receives a 64-bit aligned address from the CDU, i.e. the lower 2 bits indicate which 64-bits within a 256-bit location are being written to. With that address the DIU also receives half a JPEG block (4 lines) in a single color, 4×64 bits over 4 cycles. All accesses to DRAM must be padded to 256 bits or the bits which should not be written are masked using the individual bit write inputs of the DRAM. When writing decompressed contone data from the CDU, only 64 bits out of the 256-bit access to DRAM are valid, and the remaining bits of the write are masked by the DIU. This means that the decompressed contone data is written to DRAM in 4 back-to-back 64-bit write masked accesses to 4 consecutive 256-bit DRAM locations/words.
2616Writing of decompressed contone data to DRAM is implemented by the state machine in <figref idref="DRAWINGS">FIG. 140</figref>. The CDU writes the decompressed contone data to DRAM half a JPEG block at a time, 4×64 bits over 4 cycles. All counters and flags should be cleared after reset. When Go transitions from 0 to 1 all counters and flags should take their initial value. While the Go bit is set, the state machine relies on the half_block_ok_to_read and line_store_ok_to_write flags to tell it whether to attempt to write a half JPEG block to DRAM. Once the half-block buffer interface contains a half JPEG block, the state machine requests a write access to DRAM by asserting cdu_diu_wreq and providing the write address, corresponding to the first 64-bit value to be written, on cdu_diu_wadr (only the address the first 64-bit value in each access of 4×64 bits is issued by the CDU. The DIU can generate the addresses for the second, third and fourth 64-bit values). The state machine then waits to receive an acknowledge from the DIU before initiating a read of 4×64-bit values from the half-block buffer interface by asserting rd_adv for 4 cycles. The output cdu_diu_wvalid is asserted in the cycle after rd_adv to indicate to the DIU that valid data is present on the cdu_diu_data bus and should be written to the specified address in DRAM. A rd_adv_half block pulse is then sent to the half-block buffer interface to indicate that the current read buffer has been read and should now be available to be written to again. The state machine then returns to the request state.
2617The pseudocode below shows how the write address is calculated on a per clock cycle basis.
2618Note counters and flags should be cleared after reset. When Go transitions from 0 to 1 all counters and flags should be cleared and lwr_halfblock_adr gets loaded with buff_start_adr and upr_halfblock_adr gets loaded with buff_start_adr+max_block+1.
2619<tables id="TABLE-US-00221" num="00221"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>// assign write address output to DRAM</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="126pt" align="left" /><colspec colname="2" colwidth="119pt" align="left" /><tbody valign="top"><row><entry /><entry>cdu_diu_wadr[6:5] = 00</entry><entry>// corresponds to</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>linenumber, only first address is</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="112pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>// issued for each DRAM</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>access. Thus line is always 0.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="112pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>// The DIU generates these</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>bits of the address.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>cdu_diu_wadr[4:3] = color</entry></row><row><entry /><entry>if (half = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry>cdu_diu_wadr[21:7] = upr_halfblock_adr</entry><entry>// for lines</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>4–7 of JPEG block</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry>cdu_diu_wadr[21:7] = lwr_halfblock_adr</entry><entry>// for lines</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>0–3 of JPEG block</entry></row><row><entry>// update half, color, block and addresses after each DRAM</entry></row><row><entry>write access</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>if (rd_adv_half_block = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>if (half = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>half = 0</entry></row><row><entry /><entry>if (color = = max_plane) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>color = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="112pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry>if (block = = max_block) then</entry><entry>// end of writing</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>a line of JPEG blocks</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>pulse wradv8line</entry></row><row><entry /><entry>block = 0</entry></row><row><entry /><entry>// update half block address for start of next</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>line of JPEG blocks taking</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>// account of address wrapping in circular</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>buffer and 4 line offset</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>if (upr_halfblock_adr = = buff_end_adr) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="98pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>upr_halfblock_adr = buff_start_adr +</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>max_block + 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="84pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (upr_halfblock_adr + max_block + 1 = =</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>buff_end_adr) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="98pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>upr_halfblock_adr = buff_start_adr</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="98pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>upr_halfblock_adr = upr_halfblock_adr +</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>max_block + 2</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>block ++</entry></row><row><entry /><entry>upr_halfblock_adr ++ // move to address</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>for lines 4–7 for next block</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>color ++</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>half = 1</entry></row><row><entry /><entry>if (color = = max_plane) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>if (block = = max_block) then // end of writing a</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>line of JPEG blocks</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>// update half block address for start of next</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>line of JPEG blocks taking</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>// account of address wrapping in circular</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>buffer and 4 line offset</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>if (lwr_halfblock_adr = = buff_end_adr) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="98pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>lwr_halfblock_adr = buff_start_adr +</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>max block + 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (lwr_halfblock_adr + max_block + 1 = =</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>buff_end_adr) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="98pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>lwr_halfblock_adr = buff_start_adr</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="98pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>lwr_halfblock_adr = lwr_halfblock_adr +</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>max_block + 2</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry>lwr_halfblock_adr ++</entry><entry>// move to address</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>for lines 0–3 for next block</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 22.5.9 Contone Line Store Interface
2620The contone line store interface is responsible for providing the control over the shared resource in DRAM. The CDU writes 8 lines of data in up to 4 color planes, and the CFU reads them line-at-a-time. The contone line store interface provides the mechanism for keeping track of the number of lines stored in DRAM, and provides signals so that a given line cannot be read from until the complete line has been written.
2621The CDU writes 8 lines of data in parallel but writes the first 4 lines and second 4 lines to separate areas in DRAM. Thus, when the CFU has read 4 lines from DRAM that area now becomes free for the CDU to write to. Thus the size of the line store in DRAM should be a multiple of 4 lines.
2622The minimum size of the line store interface is 8 lines, providing a single buffer scheme. Typical sizes are 12 lines for a 1.5 buffer scheme while 16 lines provides a double-buffer scheme.
2623The size of the contone line store is defined by num_buff_lines. A count is kept of the number of lines stored in DRAM that are available to be written to. When Go transitions from 0 to 1, NumLinesAvail is set to the value of num_buff_lines. The CDU may only begin to write to DRAM as long as there is space available for 8 lines, indicated when the line_store_ok_to_write bit is set.
2624When the CDU has finished writing 8 lines, the write control unit sends an wradv8line pulse to the contone line store interface, and NumLinesAvail is decremented by 8. The write control unit then waits for line_store_ok_to_write to be set again.
2625If the contone line store is not empty (has one or more lines available in it), the CDU will indicate to the CFU via the cdu_cfu_linestore_rdy signal. The cdu_cfu_linestore_rdy signal is generated by comparing the NumLinesAvail with the programmed num_buff_lines. As the CFU reads a line from the contone line store it will pulse the rdadvline to indicate that it has read a full line from the line store. NumLinesAvail is incremented by 1 on receiving a rdadvline pulse.
2626To enable running the CDU while the CFU is not running the NumLinesAvail register can also be updated via the configuration register interface. In this scenario the CPU polls the value of the NumLinesAvail register and overwrites it to prevent stalling of the CDU (NumLinesAvail<8). The CPU will always have priority in any updating of the NumLinesAvail register.
000023 Contone FIFO Unit (CFU)
000023.1 Overview
2627The Contone FIFO Unit (CFU) is responsible for reading the decompressed contone data layer from the circular buffer in DRAM, performing optional color conversion from YCrCb to RGB followed by optional color inversion in up to 4 color planes, and then feeding the data on to the HCU. Scaling of data is performed in the horizontal and vertical directions by the CFU so that the output to the HCU matches the printer resolution. Non-integer scaling is supported in both the horizontal and vertical directions. Typically, the scale factor will be the same in both directions but may be programmed to be different.
000023.2 Bandwidth Requirements
2628The CFU must read the contone data from DRAM fast enough to match the rate at which the contone data is consumed by the HCU.
2629Pixels of contone data are replicated a X scale factor (SF) number of times in the X direction and Y scale factor (SF) number of times in the Y direction to convert the final output to 1600 dpi. Replication in the X direction is performed at the output of the CFU on a pixel-by-pixel basis while replication in the Y direction is performed by the CFU reading each line a number of times, according to the Y-scale factor, from DRAM. The HCU generates 1 dot (bi-level in 6 colors) per system clock cycle to achieve a print speed of 1 side per 2 seconds for full bleed A4/Letter printing. The CFU output buffer needs to be supplied with a 4 color contone pixel (32 bits) every SF cycles. With support for 4 colors at 267 ppi the CFU must read data from DRAM at 5.33 bits/cycle<sup>14</sup>. <sup>14</sup>32 bits/6 cycles=5.33 bits/cycle
000023.3 Color Space Conversion
2630The CFU allows the contone data to be passed directly on, which will be the case if the color represented by each color plane in the JPEG image is an available ink. For example, the four colors may be C, M, Y, and K, directly represented by CMYK inks. The four colors may represent gold, metallic green etc. for multi-SoPEC printing with exact colors.
2631JPEG produces better compression ratios for a given visible quality when luminance and chrominance channels are separated. With CMYK, K can be considered to be luminance, but C, M and Y each contain luminance information and so would need to be compressed with appropriate luminance tables. We therefore provide the means by which CMY can be passed to SoPEC as YCrCb. K does not need color conversion.
2632When being JPEG compressed, CMY is typically converted to RGB, then to YCrCb and then finally JPEG compressed. At decompression, the YCrCb data is obtained, then color converted to RGB, and finally back to CMY.
2633The external RIP provides conversion from RGB to YCrCb, specifically to match the actual hardware implementation of the inverse transform within SoPEC, as per CCIR 601–2 [24] except that Y, Cr and Cb are normalized to occupy all 256 levels of an 8-bit binary encoding.
2634The CFU provides the translation to either RGB or CMY. RGB is included since it is a necessary step to produce CMY, and some printers increase their color gamut by including RGB inks as well as CMYK.
2635Consequently the JPEG stream in the color space convertor is one of: <ul id="ul0261" list-style="none"><li id="ul0261-0001" num="0000"><ul id="ul0262" list-style="none"><li id="ul0262-0001" num="2636">1 color plane, no color space conversion</li><li id="ul0262-0002" num="2637">2 color planes, no color space conversion</li><li id="ul0262-0003" num="2638">3 color planes, no color space conversion</li><li id="ul0262-0004" num="2639">3 color planes YCrCb, conversion to RGB</li><li id="ul0262-0005" num="2640">4 color planes, no color space conversion</li><li id="ul0262-0006" num="2641">4 color planes YCrCbX, conversion of YCrCb to RGB, no color conversion of X</li></ul></li></ul>
2642The YCrCb to RGB conversion is described in [14]. Note that if the data is non-compressed, there is no specific advantage in performing color conversion (although the CDU and CFU do permit it).
000023.4 Color Space Inversion
2643In addition to performing optional color conversion the CFU also provides for optional bit-wise inversion in up to 4 color planes. This provides the means by which the conversion to CMY may be finalised, or to may be used to provide planar correlation of the dither matrices.
2644The RGB to CMY conversion is given by the relationship: <ul id="ul0263" list-style="none"><li id="ul0263-0001" num="0000"><ul id="ul0264" list-style="none"><li id="ul0264-0001" num="2645">C=255−R</li><li id="ul0264-0002" num="2646">M=255−G</li><li id="ul0264-0003" num="2647">Y=255−B</li></ul></li></ul>
2648These relationships require the page RIP to calculate the RGB from CMY as follows: <ul id="ul0265" list-style="none"><li id="ul0265-0001" num="0000"><ul id="ul0266" list-style="none"><li id="ul0266-0001" num="2649">R=255−C</li><li id="ul0266-0002" num="2650">G=255−M</li><li id="ul0266-0003" num="2651">B=255−Y <br /> 23.5 Scaling </li></ul></li></ul>
2652Scaling of pixel data is performed in the horizontal and vertical directions by the CFU so that the output to the HCU matches the printer resolution. The CFU supports non-integer scaling with the scale factor represented by a numerator and a denominator. Only scaling up of the pixel data is allowed, i.e. the numerator should be greater than or equal to the denominator. For example, to scale up by a factor of two and a half, the numerator is programmed as 5 and the denominator programmed as 2.
2653Scaling is implemented using a counter as described in the pseudocode below. An advance pulse is generated to move to the next dot (x-scaling) or line (y-scaling).
2654<tables id="TABLE-US-00222" num="00222"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>if (count + denominator − numerator >= 0) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>count = count + denominator − numerator</entry></row><row><entry /><entry>advance = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>count = count + denominator</entry></row><row><entry /><entry>advance = 0</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 23.6 Lead-in and Lead-out Clipping
2655The JPEG algorithm encodes data on a block by block basis, each block consists of 64 8-bit pixels (representing 8 rows each of 8 pixels). If the image is not a multiple of 8 pixels in X and Y then padding must be present. This padding (extra pixels) will be present after decoding of the JPEG bytestream.
2656Extra padded lines in the Y direction (which may get scaled up in the CFU) will be ignored in the HCU through the setting of the BottomMargin register.
2657Extra padded pixels in the X direction must also be removed so that the contone layer is clipped to the target page as necessary.
2658In the case of a multi-SoPEC system, 2 SoPECs may be responsible for printing the same side of a page, e.g. SoPEC #1 controls printing of the left side of the page and SoPEC #2 controls printing of the right side of the page and shown in <figref idref="DRAWINGS">FIG. 141</figref>. The division of the contone layer between the 2 SoPECs may not fall on a 8 pixel (JPEG block) boundary. The JPEG block on the boundary of the 2 SoPECs (JPEG block n below) will be the last JPEG block in the line printed by SoPEC #1 and the first JPEG block in the line printed by SoPEC #2. Pixels in this JPEG block not destined for SoPEC #1 are ignored by appropriately setting the LeadOutClipNum. Pixels in this JPEG block not destined for SoPEC #2 must be ignored at the beginning of each line. The number of pixels to be ignored at the start of each line is specified by the LeadInClipNum register. It may also be the case that the CDU writes out more JPEG blocks than is required to be read by the CFU, as shown for SBPEC #2 below. In this case_the value of the MaxBlock register in the CDU is set to correspond to JPEG block m but the value for the MaxBlock register in the CFU is set to correspond to JPEG block m−1. Thus JPEG block m is not read in by the CFU. Additional clipping on contone pixels is required when they are scaled up to the printer's resolution. The scaling of the first valid pixel in the line is controlled by setting the XstartCount register. The HcuLineLength register defines the size of the target page for the contone layer at the printer's resolution and controls the scaling of the last valid pixel in a line sent to the HCU.
000023.7 Implementation
2659<figref idref="DRAWINGS">FIG. 142</figref> shows a block diagram of the CFU.
000023.7.1 Definitions of I/O
2660<tables id="TABLE-US-00223" num="00223"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 150</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>CFU port list and description</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="28pt" align="center" /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>Port Name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>Clocks and reset</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="28pt" align="char" char="." /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>pclk</entry><entry>1</entry><entry>In</entry><entry>System clock</entry></row><row><entry>prst_n</entry><entry>1</entry><entry>In</entry><entry>System reset, synchronous active</entry></row><row><entry /><entry /><entry /><entry>low.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>PCU interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="28pt" align="char" char="." /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>pcu_cfu_sel</entry><entry>1</entry><entry>In</entry><entry>Block select from the PCU. When</entry></row><row><entry /><entry /><entry /><entry>pcu_cfu_sel is high both pcu_adr</entry></row><row><entry /><entry /><entry /><entry>and pcu_dataout are valid.</entry></row><row><entry>pcu_rwn</entry><entry>1</entry><entry>In</entry><entry>Common read/not-write signal from</entry></row><row><entry /><entry /><entry /><entry>the PCU.</entry></row><row><entry>pcu_adr[6:2]</entry><entry>4</entry><entry>In</entry><entry>PCU address bus. Only 5 bits are</entry></row><row><entry /><entry /><entry /><entry>required to decode the address</entry></row><row><entry /><entry /><entry /><entry>space for this block.</entry></row><row><entry>pcu_dataout[31:0]</entry><entry>32</entry><entry>In</entry><entry>Shared write data bus from the</entry></row><row><entry /><entry /><entry /><entry>PCU.</entry></row><row><entry>cfu_pcu_rdy</entry><entry>1</entry><entry>Out</entry><entry>Ready signal to the PCU. When</entry></row><row><entry /><entry /><entry /><entry>cfu_pcu_rdy is high it indicates</entry></row><row><entry /><entry /><entry /><entry>the last cycle of the access. For</entry></row><row><entry /><entry /><entry /><entry>a write cycle this means pcu_dataout</entry></row><row><entry /><entry /><entry /><entry>has been registered by the block</entry></row><row><entry /><entry /><entry /><entry>and for a read cycle this means</entry></row><row><entry /><entry /><entry /><entry>the data on cfu_pcu_datain is valid.</entry></row><row><entry>cfu_pcu_datain[31:0]</entry><entry>32</entry><entry>Out</entry><entry>Read data bus to the PCU.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>DIU interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="28pt" align="char" char="." /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>cfu_diu_rreq</entry><entry>1</entry><entry>Out</entry><entry>CFU read request, active high.</entry></row><row><entry /><entry /><entry /><entry>A read request must be accompanied</entry></row><row><entry /><entry /><entry /><entry>by a valid read address.</entry></row><row><entry>diu_cfu_rack</entry><entry>1</entry><entry>In</entry><entry>Acknowledge from DIU, active high.</entry></row><row><entry /><entry /><entry /><entry>Indicates that a read request has</entry></row><row><entry /><entry /><entry /><entry>been accepted and the new read</entry></row><row><entry /><entry /><entry /><entry>address can be placed on the</entry></row><row><entry /><entry /><entry /><entry>address bus, cfu_diu_radr.</entry></row><row><entry>cfu_diu_radr[21:5]</entry><entry>17</entry><entry>Out</entry><entry>CFU read address. 17 bits wide</entry></row><row><entry /><entry /><entry /><entry>(256-bit aligned word).</entry></row><row><entry>diu_cfu_rvalid</entry><entry>1</entry><entry>In</entry><entry>Read data valid, active high.</entry></row><row><entry /><entry /><entry /><entry>Indicates that valid read data</entry></row><row><entry /><entry /><entry /><entry>is now on the read data bus,</entry></row><row><entry /><entry /><entry /><entry>diu_data.</entry></row><row><entry>diu_data[63:0]</entry><entry>64</entry><entry>In</entry><entry>Read data from DRAM.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>CDU interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="28pt" align="char" char="." /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>cdu_cfu_linestore_rdy</entry><entry>1</entry><entry>In</entry><entry>When high indicates that the</entry></row><row><entry /><entry /><entry /><entry>contone line store has 1 or more</entry></row><row><entry /><entry /><entry /><entry>lines available to be read by</entry></row><row><entry /><entry /><entry /><entry>the CFU.</entry></row><row><entry>cfu_cdu_rdadvline</entry><entry>1</entry><entry>Out</entry><entry>Read line pulse, active high.</entry></row><row><entry /><entry /><entry /><entry>Indicates that the CFU has finished</entry></row><row><entry /><entry /><entry /><entry>reading a line of decompressed</entry></row><row><entry /><entry /><entry /><entry>contone data to the circular buffer</entry></row><row><entry /><entry /><entry /><entry>in DRAM and that line of the buffer</entry></row><row><entry /><entry /><entry /><entry>is now free.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>HCU interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="28pt" align="char" char="." /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>hcu_cfu_advdot</entry><entry>1</entry><entry>In</entry><entry>Informs the CFU that the HCU has</entry></row><row><entry /><entry /><entry /><entry>captured the pixel data on</entry></row><row><entry /><entry /><entry /><entry>cfu_hcu_c[0–3]data lines and the</entry></row><row><entry /><entry /><entry /><entry>CFU can now place the next pixel</entry></row><row><entry /><entry /><entry /><entry>on the data lines.</entry></row><row><entry>cfu_hcu_avail</entry><entry>1</entry><entry>Out</entry><entry>Indicates valid data present on</entry></row><row><entry /><entry /><entry /><entry>cfu_hcu_c[0–3]data lines.</entry></row><row><entry>cfu_hcu_c0data[7:0]</entry><entry>8</entry><entry>Out</entry><entry>Pixel of data in contone plane 0.</entry></row><row><entry>cfu_hcu_c1data[7:0]</entry><entry>8</entry><entry>Out</entry><entry>Pixel of data in contone plane 1.</entry></row><row><entry>cfu_hcu_c2data[7:0]</entry><entry>8</entry><entry>Out</entry><entry>Pixel of data in contone plane 2.</entry></row><row><entry>cfu_hcu_c3data[7:0]</entry><entry>8</entry><entry>Out</entry><entry>Pixel of data in contone plane 3.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 23.7.2 Configuration Registers
2661The configuration registers in the CFU are programmed via the PCU interface. Refer to section 21.8.2 on page 321 for the description of the protocol and timing diagrams for reading and writing registers in the CFU. Note that since addresses in SoPEC are byte aligned and the PCU only supports 32-bit register reads and writes, the lower 2 bits of the PCU address bus are not required to decode the address space for the CFU. When reading a register that is less than 32 bits wide zeros should be returned on the upper unused bit(s) of cfu_pcu_datain. The configuration registers of the CFU are listed in Table 151:
2662<tables id="TABLE-US-00224" num="00224"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 151</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>CFU registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="91pt" align="left" /><tbody valign="top"><row><entry>Address</entry><entry>Register</entry><entry /><entry>Value on</entry><entry /></row><row><entry>(CFU_base +)</entry><entry>Name</entry><entry>#bits</entry><entry>Reset</entry><entry>Description</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>Control registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="21pt" align="char" char="." /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="91pt" align="left" /><tbody valign="top"><row><entry>0x00</entry><entry>Reset</entry><entry>1</entry><entry>0x1</entry><entry>A write to this register</entry></row><row><entry /><entry /><entry /><entry /><entry>causes a reset of the</entry></row><row><entry /><entry /><entry /><entry /><entry>CFU.</entry></row><row><entry>0x04</entry><entry>Go</entry><entry>1</entry><entry>0x0</entry><entry>Writing 1 to this register</entry></row><row><entry /><entry /><entry /><entry /><entry>starts the CFU.</entry></row><row><entry /><entry /><entry /><entry /><entry>Writing 0 to this register</entry></row><row><entry /><entry /><entry /><entry /><entry>halts the CFU.</entry></row><row><entry /><entry /><entry /><entry /><entry>When Go is deasserted</entry></row><row><entry /><entry /><entry /><entry /><entry>the state-machines go</entry></row><row><entry /><entry /><entry /><entry /><entry>to their idle states</entry></row><row><entry /><entry /><entry /><entry /><entry>but all counters and</entry></row><row><entry /><entry /><entry /><entry /><entry>configuration registers</entry></row><row><entry /><entry /><entry /><entry /><entry>keep their values.</entry></row><row><entry /><entry /><entry /><entry /><entry>When Go is asserted all</entry></row><row><entry /><entry /><entry /><entry /><entry>counters are reset, but</entry></row><row><entry /><entry /><entry /><entry /><entry>configuration registers</entry></row><row><entry /><entry /><entry /><entry /><entry>keep their values (i.e.</entry></row><row><entry /><entry /><entry /><entry /><entry>they don't get reset).</entry></row><row><entry /><entry /><entry /><entry /><entry>The CFU must be started</entry></row><row><entry /><entry /><entry /><entry /><entry>before the CDU is</entry></row><row><entry /><entry /><entry /><entry /><entry>started.</entry></row><row><entry /><entry /><entry /><entry /><entry>This register can be</entry></row><row><entry /><entry /><entry /><entry /><entry>read to determine if</entry></row><row><entry /><entry /><entry /><entry /><entry>the CFU is running</entry></row><row><entry /><entry /><entry /><entry /><entry>(1 - running,</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - stopped).</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>Setup registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="21pt" align="char" char="." /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="91pt" align="left" /><tbody valign="top"><row><entry>0x10</entry><entry>MaxBlock</entry><entry>13</entry><entry>0x000</entry><entry>Number of JPEG MCUs</entry></row><row><entry /><entry /><entry /><entry /><entry>(or JPEG block equiva-</entry></row><row><entry /><entry /><entry /><entry /><entry>lents, i.e. 8 × 8</entry></row><row><entry /><entry /><entry /><entry /><entry>bytes) in a line − 1.</entry></row><row><entry>0x14</entry><entry>BuffStartAdr[21:7]</entry><entry>15</entry><entry>0x0000</entry><entry>Points to the start of</entry></row><row><entry /><entry /><entry /><entry /><entry>the decompressed contone</entry></row><row><entry /><entry /><entry /><entry /><entry>circular buffer in DRAM,</entry></row><row><entry /><entry /><entry /><entry /><entry>aligned to a half JPEG</entry></row><row><entry /><entry /><entry /><entry /><entry>block boundary. A half</entry></row><row><entry /><entry /><entry /><entry /><entry>JPEG block consists of</entry></row><row><entry /><entry /><entry /><entry /><entry>4 words of 256-bits,</entry></row><row><entry /><entry /><entry /><entry /><entry>enough to hold 32 contone</entry></row><row><entry /><entry /><entry /><entry /><entry>pixels in 4 colors, i.e.</entry></row><row><entry /><entry /><entry /><entry /><entry>half a JPEG block.</entry></row><row><entry>0x18</entry><entry>BuffEndAdr[21:7]</entry><entry>15</entry><entry>0x0000</entry><entry>Points to the end of the</entry></row><row><entry /><entry /><entry /><entry /><entry>decompressed contone</entry></row><row><entry /><entry /><entry /><entry /><entry>circular buffer in DRAM,</entry></row><row><entry /><entry /><entry /><entry /><entry>aligned to a half JPEG</entry></row><row><entry /><entry /><entry /><entry /><entry>block boundary</entry></row><row><entry /><entry /><entry /><entry /><entry>(address is inclusive).</entry></row><row><entry /><entry /><entry /><entry /><entry>A half JPEG block con-</entry></row><row><entry /><entry /><entry /><entry /><entry>sists of 4 words of</entry></row><row><entry /><entry /><entry /><entry /><entry>256-bits, enough to hold</entry></row><row><entry /><entry /><entry /><entry /><entry>32 contone pixels in</entry></row><row><entry /><entry /><entry /><entry /><entry>4 colors, i.e. half a</entry></row><row><entry /><entry /><entry /><entry /><entry>JPEG block.</entry></row><row><entry>0x1C</entry><entry>4LineOffset</entry><entry>13</entry><entry>0x0000</entry><entry>Defines the offset between</entry></row><row><entry /><entry /><entry /><entry /><entry>the start of one 4 line</entry></row><row><entry /><entry /><entry /><entry /><entry>store to the start of</entry></row><row><entry /><entry /><entry /><entry /><entry>the next 4 line store − 1.</entry></row><row><entry /><entry /><entry /><entry /><entry>In Figure n page 394 on</entry></row><row><entry /><entry /><entry /><entry /><entry>page Error! Bookmark</entry></row><row><entry /><entry /><entry /><entry /><entry>not defined., if</entry></row><row><entry /><entry /><entry /><entry /><entry>BufStartAdr corresponds</entry></row><row><entry /><entry /><entry /><entry /><entry>to line 0 block 0 then</entry></row><row><entry /><entry /><entry /><entry /><entry>BuffStartAdr +</entry></row><row><entry /><entry /><entry /><entry /><entry>4LineOffset corresponds</entry></row><row><entry /><entry /><entry /><entry /><entry>to line 4 block 0.</entry></row><row><entry /><entry /><entry /><entry /><entry>4LineOffset is specified</entry></row><row><entry /><entry /><entry /><entry /><entry>in units of 128 bytes, eg</entry></row><row><entry /><entry /><entry /><entry /><entry>0–128 bytes, 1–256</entry></row><row><entry /><entry /><entry /><entry /><entry>bytes etc.</entry></row><row><entry /><entry /><entry /><entry /><entry>This register is required</entry></row><row><entry /><entry /><entry /><entry /><entry>in addition to MaxBlock</entry></row><row><entry /><entry /><entry /><entry /><entry>as the number of JPEG</entry></row><row><entry /><entry /><entry /><entry /><entry>blocks in a line required</entry></row><row><entry /><entry /><entry /><entry /><entry>by the CFU may be dif-</entry></row><row><entry /><entry /><entry /><entry /><entry>ferent from the number</entry></row><row><entry /><entry /><entry /><entry /><entry>of JPEG blocks in a</entry></row><row><entry /><entry /><entry /><entry /><entry>line written by the CDU.</entry></row><row><entry>0x20</entry><entry>YCrCb2RGB</entry><entry>1</entry><entry>0x0</entry><entry>Set this bit to enable</entry></row><row><entry /><entry /><entry /><entry /><entry>conversion from YCrCb</entry></row><row><entry /><entry /><entry /><entry /><entry>to RGB. Should not be</entry></row><row><entry /><entry /><entry /><entry /><entry>changed between bands.</entry></row><row><entry>0x24</entry><entry>InvertColorPlane</entry><entry>4</entry><entry>0x0</entry><entry>Set these bits to perform</entry></row><row><entry /><entry /><entry /><entry /><entry>bit-wise inversion on a</entry></row><row><entry /><entry /><entry /><entry /><entry>per color plane basis.</entry></row><row><entry /><entry /><entry /><entry /><entry>bit0 - 1 invert color plane 0</entry></row><row><entry /><entry /><entry /><entry /><entry> <sup> </sup> - 0 do not convert</entry></row><row><entry /><entry /><entry /><entry /><entry>bit1 - 1 invert color plane 1</entry></row><row><entry /><entry /><entry /><entry /><entry> <sup> </sup> - 0 do not convert</entry></row><row><entry /><entry /><entry /><entry /><entry>bit2 - 1 invert color plane 2</entry></row><row><entry /><entry /><entry /><entry /><entry> <sup> </sup> - 0 do not convert</entry></row><row><entry /><entry /><entry /><entry /><entry>bit3 - 1 invert color plane 3</entry></row><row><entry /><entry /><entry /><entry /><entry>Should not be changed</entry></row><row><entry /><entry /><entry /><entry /><entry>between bands.</entry></row><row><entry>0x28</entry><entry>HcuLineLength</entry><entry>16</entry><entry>0x0000</entry><entry>Number of contone pixels − 1</entry></row><row><entry /><entry /><entry /><entry /><entry>in a line (after scaling).</entry></row><row><entry /><entry /><entry /><entry /><entry>Equals the number of</entry></row><row><entry /><entry /><entry /><entry /><entry>hcu_cfu_dotadv pulses − 1</entry></row><row><entry /><entry /><entry /><entry /><entry>received from the HCU for</entry></row><row><entry /><entry /><entry /><entry /><entry>each line of contone data.</entry></row><row><entry>0x2C</entry><entry>LeadInClipNum</entry><entry>3</entry><entry>0x0</entry><entry>Number of contone pixels</entry></row><row><entry /><entry /><entry /><entry /><entry>to be ignored at the start</entry></row><row><entry /><entry /><entry /><entry /><entry>of a line (from JPEG block</entry></row><row><entry /><entry /><entry /><entry /><entry>0 in a line). They are not</entry></row><row><entry /><entry /><entry /><entry /><entry>passed to the output buffer</entry></row><row><entry /><entry /><entry /><entry /><entry>to be scaled in the X</entry></row><row><entry /><entry /><entry /><entry /><entry>direction.</entry></row><row><entry>0x30</entry><entry>LeadOutClipNum</entry><entry>3</entry><entry>0x0</entry><entry>Number of contone pixels</entry></row><row><entry /><entry /><entry /><entry /><entry>to be ignored at the end</entry></row><row><entry /><entry /><entry /><entry /><entry>of a line (from JPEG block</entry></row><row><entry /><entry /><entry /><entry /><entry>MaxBlock in a line). They</entry></row><row><entry /><entry /><entry /><entry /><entry>are not passed to the out-</entry></row><row><entry /><entry /><entry /><entry /><entry>put buffer to be scaled in</entry></row><row><entry /><entry /><entry /><entry /><entry>the X direction.</entry></row><row><entry>0x34</entry><entry>XstartCount</entry><entry>8</entry><entry>0x00</entry><entry>Value to be loaded at the</entry></row><row><entry /><entry /><entry /><entry /><entry>start of every line into</entry></row><row><entry /><entry /><entry /><entry /><entry>the counter used for</entry></row><row><entry /><entry /><entry /><entry /><entry>scaling in the X direction.</entry></row><row><entry /><entry /><entry /><entry /><entry>Used to control the</entry></row><row><entry /><entry /><entry /><entry /><entry>scaling of the first pixel</entry></row><row><entry /><entry /><entry /><entry /><entry>in a line to be sent to</entry></row><row><entry /><entry /><entry /><entry /><entry>the HCU. This value will</entry></row><row><entry /><entry /><entry /><entry /><entry>typically be zero,</entry></row><row><entry /><entry /><entry /><entry /><entry>except in the case where a</entry></row><row><entry /><entry /><entry /><entry /><entry>number of dots are clipped</entry></row><row><entry /><entry /><entry /><entry /><entry>on the lead in to a line.</entry></row><row><entry>0x38</entry><entry>XscaleNum</entry><entry>8</entry><entry>0x01</entry><entry>Numerator of contone scale</entry></row><row><entry /><entry /><entry /><entry /><entry>factor in X direction.</entry></row><row><entry>0x3C</entry><entry>XscaleDenom</entry><entry>8</entry><entry>0x01</entry><entry>Denominator of contone</entry></row><row><entry /><entry /><entry /><entry /><entry>scale factor in X</entry></row><row><entry /><entry /><entry /><entry /><entry>direction.</entry></row><row><entry>0x40</entry><entry>YscaleNum</entry><entry>8</entry><entry>0x01</entry><entry>Numerator of contone scale</entry></row><row><entry /><entry /><entry /><entry /><entry>factor in Y direction.</entry></row><row><entry>0x44</entry><entry>YscaleDenom</entry><entry>8</entry><entry>0x01</entry><entry>Denominator of contone</entry></row><row><entry /><entry /><entry /><entry /><entry>scale factor in Y</entry></row><row><entry /><entry /><entry /><entry /><entry>direction.</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 23.7.3 Storage of Decompressed Contone Data in DRAM
2663The CFU reads decompressed contone data from DRAM in single 256-bit accesses. JPEG blocks of decompressed contone data are stored in DRAM with the memory arrangement as shown The arrangement is in order to optimize access for reads by writing the data so that 4 color components are stored together in each 256-bit DRAM word. The means that the CFU reads 64-bits in 4 colors from a single line in each 256-bit DRAM access.
2664The CFU reads data line at a time in 4 colors from DRAM. The read sequence, as shown in <figref idref="DRAWINGS">FIG. 143</figref>, is as follows:
2665<tables id="TABLE-US-00225" num="00225"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>line 0, block 0 in word p of DRAM</entry></row><row><entry /><entry>line 0, block 1 in word p+4 of DRAM</entry></row><row><entry /><entry>.........................................</entry></row><row><entry /><entry>line 0, block n in word p+4n of DRAM</entry></row><row><entry /><entry>(repeat to read line a number of times according to scale</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>factor)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>line 1, block 0 in word p+1 of DRAM</entry></row><row><entry /><entry>line 1, block 1 in word p+5 of DRAM</entry></row><row><entry /><entry>etc......................................</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2666The CFU reads a complete line in up to 4 colors a Y scale factor number of times from DRAM before it moves on to read the next. When the CFU has finished reading 4 lines of contone data that 4 line store becomes available for the CDU to write to.
000023.7.4 Decompressed Contone Buffer
2667Since the CFU reads 256 bits (4 colors x 64 bits) from memory at a time, it requires storage of at least 2×256 bits at its input. To allow for all possible DIU stall conditions the input buffer is increased to 3×256 bits to meet the CFU target bandwidth requirements. The CFU receives the data from the DIU over 4 clock cycles (64-bits of a single color per cycle). It is implemented as 4 buffers. Each buffer conceptually is a 64-bit input and 8-bit output buffer to account for the 64-bit data transfers from the DIU, and the 8-bit output per color plane to the color space converter.
2668On the DRAM side, wr_buff indicates the current buffer within each triple-buffer that writes are to occur to. wr_sel selects which triple-buffer to write the 64 bits of data to when wr_en is asserted. On the color space converter side, rd_buff indicates the current buffer within each triple-buffer that reads are to occur from. When rd_en is asserted a byte is read from each of the triple-buffers in parallel. rd_sel is used to select a byte from the 64 bits (1st byte corresponds to bits <b>7</b>–<b>0</b>, second byte to bits <b>15</b>–<b>8</b> etc.).
2669Due to the limitations of available register arrays in IBM technology, the decompressed contone buffer is implemented as a quadruple buffer. While this offers some benefits for the CFU it is not necessitated by the bandwidth requirements of the CFU.
000023.7.5 Y-scaling Control Unit
2670The Y-scaling control unit is responsible for reading the decompressed contone data and passing it to the color space converter via the decompressed contone buffer. The decompressed contone data is read from DRAM in single 256-bit accesses, receiving the data from the DIU over 4 clock cycles (64-bits per cycle). The protocol and timing for read accesses to DRAM is described in section 20.9.1 on page 240. Read accesses to DRAM are implemented by means of the state machine described in <figref idref="DRAWINGS">FIG. 144</figref>.
2671All counters and flags should be cleared after reset. When Go transitions from 0 to 1 all counters and flags should take their initial value. While the Go bit is set, the state machine relies on the line8_ok_to_read and buff_ok_to_write flags to tell it whether to attempt to read a line of compressed contone data from DRAM. When line8_ok_to_read is 0 the state machine does nothing. When line8_ok_to_read is 1 the state machine continues to load data into the decompressed contone buffer up to 256-bits at a time while there is space available in the buffer. A bit is kept for the status of each 64-bit buffer: buff_avail[0] and buff_avail[1]. It also keeps a single bit (rd_buff) for the current buffer that reads are to occur from, and a single bit (wr_buff) for the current buffer that writes are to occur to. <ul id="ul0267" list-style="none"><li id="ul0267-0001" num="0000"><ul id="ul0268" list-style="none"><li id="ul0268-0001" num="2672">buff ok_to_write equals ˜buff_avail[wr_buff]. When a wr_adv_buff pulse is received, buff_avail[wr_buff] is set, and wr_buff is inverted. Whenever diu_cfu_rvalid is asserted, wr_en is asserted to write the 64-bits of data from DRAM to the buffer selected by wr_sel and wr_buff.</li><li id="ul0268-0002" num="2673">buff ok_to_read equals buff_avail[rd_buff]. If there is data available in the buffer and the output double-buffer has space available (outbuff_ok_to_write equals 1) then data is read from the buffer by asserting rd_en and rd_sel gets incremented to point to the next value. wr_adv is asserted in the following cycle to write the data to the output double-buffer of the CFU. When finished reading the buffer, rd_sel equals b111 and rd_en is asserted, buff_avail[rd_buff] is set, and rd_buff is inverted.</li></ul></li></ul>
2674Each line is read a number of times from DRAM, according to the Y-scale factor, before the CFU moves on to start reading the next line of decompressed contone data. Scaling to the printhead resolution in the Y direction is thus performed.
2675The pseudocode below shows how the read address from DRAM is calculated on a per clock cycle basis. Note all counters and flags should be cleared after reset or when Go is cleared. When a 1 is written to Go, both curr_halfblock and line_start_halfblock get loaded with buff_start_adr, and y_scale_count gets loaded with y_scale_denom. Scaling in the Y direction is implemented by line replication by re-reading lines from DRAM. The algorithm for non-integer scaling is described in the pseudocode below.
2676<tables id="TABLE-US-00226" num="00226"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>// assign read address output to DRAM</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>cdu_diu_wadr[21:7] = curr_halfblock</entry></row><row><entry /><entry>cdu_diu_wadr[6:5] = line[1:0]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>// update block, line, y_scale_count and addresses after</entry></row><row><entry /><entry>each DRAM read access</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>if (wr_adv_buff = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>if (block = = max_block) then // end of reading a line</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>of contone in up to 4 colors</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>block = 0</entry></row><row><entry /><entry>// check whether to advance to next line of contone</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>data in DRAM</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>if (y_scale_count + y_scale_denom −</entry></row><row><entry /><entry>y_scale_num >= 0)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>y_scale_count = y_scale_count + y_scale_denom −</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>y_scale_num</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>pulse RdAdvline</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="112pt" align="left" /><tbody valign="top"><row><entry /><entry>if (line = = 3) then</entry><entry>// end of reading 4 line</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>store of contone data</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="98pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>line = 0</entry></row><row><entry /><entry>// update half block address for start of next</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>line taking account of</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="98pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>// address wrapping in circular buffer and 4</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>line offset</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="98pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>if (curr_halfblock = = buff_end_adr) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="112pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>curr_halfblock = buff_start_adr</entry></row><row><entry /><entry>line_start_adr = buff_start_adr</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="98pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif ((line_start_adr + 4line_offset) = =</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>buff_end_adr)) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="112pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>curr_halfblock = buff_start_adr</entry></row><row><entry /><entry>line_start_adr = buff_start_adr</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="98pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="112pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>curr_halfblock = line_start_adr +</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>4line_offset</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="112pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>line_start_adr = line_start_adr +</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>4line_offset</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="98pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>line ++</entry></row><row><entry /><entry>curr_halfblock = line_start_adr</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>// re-read current line from DRAM</entry></row><row><entry /><entry>y_scale_count = y_scale_count + y_scale_denom</entry></row><row><entry /><entry>curr_halfblock = line_start_adr</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>block ++</entry></row><row><entry /><entry>curr_halfblock ++</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 23.7.6 Contone Line Store Interface
2677The contone line store interface is responsible for providing the control over the shared resource in DRAM. The CDU writes 8 lines of data in up to 4 color planes, and the CFU reads them line-at-a-time. The contone line store interface provides the mechanism for keeping track of the number of lines stored in DRAM, and provides signals so that a given line cannot be read from until the complete line has been written.
2678A count is kept of the number of lines that have been written to DRAM by the CDU and are available to be read by the CFU. At start-up, buff_lines_avail is set to the 0. The CFU may only begin to read from DRAM when the CDU has written 8 complete lines of contone data. When the CDU has finished writing 8 lines, it sends an cdu_cfu_wradv8line pulse to the CFU, and buff_lines_avail is incremented by 8. The CFU may continue reading from DRAM as long as buff_lines_avail is greater than 0. line8_ok_to_read is set while buff_lines_avail is greater than 0. When it has completely finished reading a line of contone data from DRAM, the Y-scaling control unit sends a RdAdvLine signal to contone line store interface and to the CDU to free up the line in the buffer in DRAM. buff_lines_avail is decremented by 1 on receiving a RdAdvline pulse.
000023.7.7 Color Space Converter (CSC)
2679The color space converter consists of 2 stages: optional color conversion from YCrCb to RGB followed by optional bit-wise inversion in up to 4 color planes.
2680The convert YCrCb to RGB block takes 3 8-bit inputs defined as Y, Cr, and Cb and outputs either the same data YCrCb or RGB. The YCrCb2RGB parameter is set to enable the conversion step from YCrCb to RGB. If YCrCb2RGB equals 0, the conversion does not take place, and the input pixels are passed to the second stage. The 4th color plane, if present, bypasses the convert YCrCb to RGB block. Note that the latency of the convert YCrCb to RGB block is 1 cycle. This latency should be equalized for the 4th color plane as it bypasses the block.
2681The second stage involves optional bit-wise inversion on a per color plane basis under the control of invert_color_plane. For example if the input is YCrCbK, then YCrCb2RGB can be set to 1 to convert YCrCb to RGB, and invert_color_plane can be set to 0111 to then convert the RGB to CMY, leaving K unchanged.
2682If YCrCb2RGB equals 0 and invert_color_plane equals 0000, no color conversion or color inversion will take place, so the output pixels will be the same as the input pixels.
2683<figref idref="DRAWINGS">FIG. 145</figref> shows a block diagram of the color space converter.
2684The convert YCrCb to RGB block is an implementation of [14]. Although only 10 bits of coefficients are used (1 sign bit, 1 integer bit, 8 fractional bits), full internal accuracy is maintained with 18 bits. The conversion is implemented as follows: <ul id="ul0269" list-style="none"><li id="ul0269-0001" num="0000"><ul id="ul0270" list-style="none"><li id="ul0270-0001" num="2685">R*=Y+(359/256)(Cr−128)</li><li id="ul0270-0002" num="2686">G*=Y−(183/256)(Cr−128)−(88/256)(Cb−128)</li><li id="ul0270-0003" num="2687">B*=Y+(454/256)(Cb−128)</li></ul></li></ul>
2688R*, G* and B* are rounded to the nearest integer and saturated to the range 0–255 to give R, G and B. Note that, while a Reset results in all-zero output, a zero input gives output RGB=[0<sup>15</sup>, 136<sup>16</sup>, 0<sup>17</sup>]. <sup>15</sup>-179 is saturated to 0<sup>16</sup>135.5, with rounding becomes 136.<sup>17</sup>-227 is saturated to 0
000023.7.8 X-scaling Control Unit
2689The CFU has a 2×32-bit double-buffer at its output between the color space converter and the HCU. The X-scaling control unit performs the scaling of the contone data to the printers output resolution, provides the mechanism for keeping track of the current read and write buffers, and ensures that a buffer cannot be read from until it has been written to.
2690A bit is kept for the status of each 32-bit buffer: buff_avail[0] and buff_avail[1]. It also keeps a single bit (rd_buff) for the current buffer that reads are to occur from, and a single bit (wr_buff) for the current buffer that writes are to occur to.
2691The output value outbuff_ok_to_write equals ˜buff_avail[wr_buff]. Contone pixels are counted as they are received from the Y-scaling control unit, i.e. when wr_adv is 1. Pixels in the lead-in and lead-out areas are ignored, i.e. they are not written to the output buffer. Lead-in and lead-out clipping of pixels is implemented by the following pseudocode that generates the wr_en pulse for the output buffer.
2692<tables id="TABLE-US-00227" num="00227"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>if (wradv = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>if (pixel_count = = {max_block,b111}) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>pixel_count = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>pixel_count ++</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>if ((pixel_count < leadin_clip_num)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>OR (pixel_count > ({max_block,b111} −</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>leadout_clip_num))) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>wr_en = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>wr_en = 1</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2693When a wr_en pulse is sent to the output double-buffer, buff_avail[wr_buff] is set, and wr_buff is inverted.
2694The output cfu_hcu_avail equals buff_avail[rd_buff]. When cfu_hcu_avail equals 1, this indicates to the HCU that data is available to be read from the CFU. The HCU responds by asserting hcu_cfu_advdot to indicate that the HCU has captured the pixel data on cfu_hcu_c[0–3]data lines and the CFU can now place the next pixel on the data lines.
2695The input pixels from the CSC may be scaled a non-integer number of times in the X direction to produce the output pixels for the HCU at the printhead resolution. Scaling is implemented by pixel replication. The algorithm for non-integer scaling is described in the pseudocode below. Note, x_scale_count should be loaded with x_start_count after reset and at the end of each line. This controls the amount by which the first pixel is scaled by. hcu_line_length and hcu_cfu_dotadv control the amount by which the last pixel in a line that is sent to the HCU is scaled by.
2696<tables id="TABLE-US-00228" num="00228"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>if (hcu_cfu_dotadv = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>if (x_scale_count + x_scale_denom − x_scale_num >= 0)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>x_scale_count = x_scale_count + x_scale_denom −</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>x_scale_num</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>rd_en = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>x_scale_count = x_scale_count + x_scale_denom</entry></row><row><entry /><entry>rd_en = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>x_scale_count = x_scale_count</entry></row><row><entry /><entry>rd_en = 0</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2697When a rd_en pulse is received, buff_avail[rd_buff] is cleared, and rd_buff is inverted.
2698A 16-bit counter, dot_adv_count, is used to keep a count of the number of hcu_cfu_dotadv pulses received from the HCU. If the value of dot_adv_count equals hcu_line_length and a hcu_cfu_dotadv pulse is received, then a rd_en pulse is genrated to present the next dot at the output of the CFU, dot_adv_count is reset to 0 and x_scale_count is loaded with x_start_count.
000024 Lossless Bi-level Decoder (LBD)
000024.1 Overview
2699The Lossless Bi-level Decoder (LBD) is responsible for decompressing a single plane of bi-level data. In SoPEC bi-level data is limited to a single spot color (typically black for text and line graphics).
2700The input to the LBD is a single plane of bi-level data, read as a bitstream from DRAM. The LBD is programmed with the start address of the compressed data, the length of the output (decompressed) line, and the number of lines to decompress. Although the requirement for SoPEC is to be able to print text at 10:1 compression, the LBD can cope with any compression ratio if the requested DRAM access is available. A pass-through mode is provided for 1:1 compression. Ten-point plain text compresses with a ratio of about 50:1. Lossless bi-level compression across an average page is about 20:1 with 10:1 possible for pages which compress poorly.
2701The output of the LBD is a single plane of decompressed bi-level data. The decompressed bi-level data is output to the SFU (Spot FIFO Unit), and in turn becomes an input to the HCU (Halftoner/Compositor unit) for the next stage in the printing pipeline. The LBD also outputs a lbd_finishedband control flag that is used by the PCU and is available as an interrupt to the CPU.
000024.2 Main Features OF LBD
2702<figref idref="DRAWINGS">FIG. 147</figref> shows a schematic outline of the LBD and SFU.
2703The LBD is required to support compressed images of up to 800 dpi. If possible we would like to support bi-level images of up to 1600 dpi. The line buffers must therefore be long enough to store a complete line at 1600 dpi.
2704The PEC1 LBD is required to output 2 dots/cycle to the HCU. This throughput capability is retained for SoPEC to minimise changes to the block, although in SoPEC the HCU will only read 1 dot/cycle. The PEC1 LDB outputs 16 bits in parallel to the PEC1 spot buffer. This is also retained for SoPEC. Therefore the LBD in SoPEC can run much faster than is required. This is useful for allowing stalls, e.g. due to band processing latency, to be absorbed.
2705The LBD has a pass through mode to cope with local negative compression. Pass through mode is activated by a special run-length code. Pass through mode continues to either end of line or for a pre-programmed number of bits, whichever is shorter. The special run-length code is always executed as a run-length code, followed by pass through.
2706The LBD outputs decompressed bi-level data to the NextLineFiFO in the Spot FIFO Unit (SFU). This stores the decompressed lines in DRAM, with a typical minimum of 2 lines stored in DRAM, nominally 3 lines up to a programmable number of lines. The SFU's NextLineFIFO can fill while the SFU waits for write access to DRAM. Therefore the LBD must be able to support stalling at its coding process. This is provided by the SFU via it's output during a line.
2707The LBD uses the previous line in the decoding process. This is provided by the SFU via it's PrevLineFIFO. Decoding can stall in the LBD while this FIFO waits to be filled from DRAM.
2708A signal sfu_lbd_rdy indicates that both the SFU's NextLineFIFO and PrevLineFIFO are available for writing and reading, respectively.
2709A configuration register in the LBD controls whether the first line being decoded at the start of a band uses the previous line read from the SFU or uses an all 0's line instead.
2710The line length is stored in DRAM must be programmable to a value greater than 128. An A4 line of 13824 dots requires 1.7 Kbytes of storage. An A3 line of 19488 dots requires 2.4 Kbytes of storage.
2711The compressed spot data can be read at a rate of 1 bit/cycle for pass through mode 1:1 compression.
2712The LBD finished band signal is exported to the PCU and is additionally available to the CPU as an interrupt.
000024.2.1 Bi-level Decoding in the LBD
2713The black bi-level layer is losslessly compressed using Silverbrook Modified Group 4 (SMG4) compression which is a version of Group 4 Facsimile compression [22] without Huffman and with simplified run length encodings. The encoding are listed in Table 152 and Table 153.
2714<tables id="TABLE-US-00229" num="00229"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 152</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Bi-Level group 4 facsimile style compression encodings</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="63pt" align="left" /><colspec colname="1" colwidth="63pt" align="center" /><colspec colname="2" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry>Encoding</entry><entry>Description</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="63pt" align="char" char="." /><colspec colname="3" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry>same as Group</entry><entry>1000</entry><entry>Pass Command: a0 <img file="US7165824B2_D0001.tif" /> b2,</entry></row><row><entry /><entry>4 Facsimile</entry><entry /><entry>skip next two edges</entry></row><row><entry /><entry /><entry>1</entry><entry>Vertical(0): a0 <img file="US7165824B2_D0002.tif" /> b1,</entry></row><row><entry /><entry /><entry /><entry>color = !color</entry></row><row><entry /><entry /><entry>110</entry><entry>Vertical(1): a0 <img file="US7165824B2_D0003.tif" /> b1 +</entry></row><row><entry /><entry /><entry /><entry>1, color = !color</entry></row><row><entry /><entry /><entry>010</entry><entry>Vertical(−1): a0 <img file="US7165824B2_D0004.tif" /> b1 −</entry></row><row><entry /><entry /><entry /><entry>1, color = !color</entry></row><row><entry /><entry /><entry>110000</entry><entry>Vertical(2): a0 <img file="US7165824B2_D0005.tif" /> b1 +</entry></row><row><entry /><entry /><entry /><entry>2, color = !color</entry></row><row><entry /><entry /><entry>010000</entry><entry>Vertical(−2): a0 <img file="US7165824B2_D0006.tif" /> b1 −</entry></row><row><entry /><entry /><entry /><entry>2, color = !color</entry></row><row><entry /><entry>Unique to this</entry><entry>100000</entry><entry>Vertical(3): a0 <img file="US7165824B2_D0007.tif" /> b1 +</entry></row><row><entry /><entry>implementation</entry><entry /><entry>3, color = !color</entry></row><row><entry /><entry /><entry>000000</entry><entry>Vertical(−3): a0 <img file="US7165824B2_D0008.tif" /> b1 −</entry></row><row><entry /><entry /><entry /><entry>3, color = !color</entry></row><row><entry /><entry /><entry><RL><RL>100</entry><entry>Horizontal: a0 <img file="US7165824B2_D0009.tif" /> a0 +</entry></row><row><entry /><entry /><entry /><entry><RL> + <RL></entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2715SMG4 has a pass through mode to cope with local negative compression. Pass through mode is activated by a special run-length code. Pass through mode continues to either end of line or for a pre-programmed number of bits, whichever is shorter. The special run-length code is always executed as a run-length code, followed by pass through. The pass through escape code is a medium length run-length with a run of less than or equal to 31.
2716<tables id="TABLE-US-00230" num="00230"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 153</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Run length (RL) encodings</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry>Encoding</entry><entry>Description</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><colspec colname="3" colwidth="91pt" align="left" /><tbody valign="top"><row><entry>Unique</entry><entry>RRRRR1</entry><entry>Short Black Runlength</entry></row><row><entry>to this</entry><entry /><entry>(5 bits)</entry></row><row><entry>implemen-</entry></row><row><entry>tation</entry></row><row><entry /><entry>RRRRR1</entry><entry>Short White Runlength</entry></row><row><entry /><entry /><entry>(5 bits)</entry></row><row><entry /><entry>RRRRRRRRRR10</entry><entry>Medium Black Runlength</entry></row><row><entry /><entry /><entry>(10 bits)</entry></row><row><entry /><entry>RRRRRRRR10</entry><entry>Medium White Runlength</entry></row><row><entry /><entry /><entry>(8 bits)</entry></row><row><entry /><entry>RRRRRRRRRR10</entry><entry>Medium Black Runlength</entry></row><row><entry /><entry /><entry>with RRRRRRRRRR <= 31,</entry></row><row><entry /><entry /><entry>Enter pass through</entry></row><row><entry /><entry>RRRRRRRR10</entry><entry>Medium White Runlength</entry></row><row><entry /><entry /><entry>with RRRRRRRR <= 31,</entry></row><row><entry /><entry /><entry>Enter pass through</entry></row><row><entry /><entry>RRRRRRRRRRRRRRR00</entry><entry>Long Black Runlength</entry></row><row><entry /><entry /><entry>(15 bits)</entry></row><row><entry /><entry>RRRRRRRRRRRRRRR00</entry><entry>Long White Runlength</entry></row><row><entry /><entry /><entry>(15 bits)</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2717Since the compression is a bitstream, the encodings are read right (least significant bit) to left (most significant bit). The run lengths given as RRRRR in Table 153 are read in the same way (least significant bit at the right to most significant bit at the left).
2718There is an additional enhancement to the G4 fax algorithm, it relates to pass through mode. It is possible for data to compress negatively using the G4 fax algorithm. On occasions like this it would be easier to pass the data to the LBD as un-compressed data. Pass through mode is a new feature that was not implemented in the PEC1 version of the LBD. When the LBD is in pass through mode the least significant bit of the data stream is an un-compressed bit. This bit is used to construct the current line.
2719To enter pass through mode the LBD takes advantage of the way run lengths can be written.
2720Usually if one of the runlength pair is less than or equal to 31 it should be encoded as a short runlength. However under the coding scheme of Table it is still legal to write it as a medium or long runlength. The LBD has been designed so that if a short runlength value is detected in a medium runlength then once the horizontal command containing this runlength is decoded completely this will tell the LBD to enter pass through mode and the bits following the runlength is un-compressed data. The number of bits to pass through is either a programmed number of bits or the end of the line which ever comes first. Once the pass through mode is completed the current color is the same as the color of the last bit of the passed through data.
000024.2.2 DRAM Access Requirements
2721The compressed page store for contone, bi-level and raw tag data is 2 Mbytes. The LBD will access the compressed page store in single 256-bit DRAM reads. The LBD will need a 256-bit double buffer in its interface to the DIU. The LBD's DIU bandwidth requirements are summarized in Table 154
2722<tables id="TABLE-US-00231" num="00231"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 154</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>DRAM bandwidth requirements</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="70pt" align="left" /><colspec colname="3" colwidth="49pt" align="left" /><colspec colname="4" colwidth="49pt" align="left" /><tbody valign="top"><row><entry /><entry>Maximum number</entry><entry /><entry /></row><row><entry /><entry>of cycles between</entry><entry>Peak</entry><entry>Average</entry></row><row><entry /><entry>each 256-bit</entry><entry>Bandwidth</entry><entry>Bandwidth</entry></row><row><entry>Direction</entry><entry>DRAM access</entry><entry>(bits/cycle)</entry><entry>(bits/cycle)</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>Read</entry><entry>2561 (1:1</entry><entry>1 (1:1</entry><entry>0.1 (10:1</entry></row><row><entry /><entry>compression)</entry><entry>compression)</entry><entry>compression)</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
27231: At 1:1 compression the LBD requires 1 bit/cycle or 256 bits every 256 cycles.
000024.3 Implementation
000024.3.1 Definitions of IO
2724<tables id="TABLE-US-00232" num="00232"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 155</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>LBD Port List</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="91pt" align="left" /><tbody valign="top"><row><entry>Port Name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Clocks and Resets</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="91pt" align="left" /><tbody valign="top"><row><entry>Pclk</entry><entry>1</entry><entry>In</entry><entry>SoPEC Functional clock.</entry></row><row><entry>prst_n</entry><entry>1</entry><entry>In</entry><entry>Global reset signal.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Bandstore signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="91pt" align="left" /><tbody valign="top"><row><entry>cdu_endofbandstore[21:5]</entry><entry>17</entry><entry>In</entry><entry>Address of the end of the</entry></row><row><entry /><entry /><entry /><entry>current band of data.</entry></row><row><entry /><entry /><entry /><entry>256-bit word aligned DRAM</entry></row><row><entry /><entry /><entry /><entry>address.</entry></row><row><entry>cdu_startofbandstore[21:5]</entry><entry>17</entry><entry>In</entry><entry>Address of the start of the</entry></row><row><entry /><entry /><entry /><entry>current band of data.</entry></row><row><entry /><entry /><entry /><entry>256-bit word aligned DRAM</entry></row><row><entry /><entry /><entry /><entry>address.</entry></row><row><entry>lbd_finishedband</entry><entry>1</entry><entry>Out</entry><entry>LBD finished band signal to</entry></row><row><entry /><entry /><entry /><entry>PCU and Interrupt Controller.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>DIU Interface signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="91pt" align="left" /><tbody valign="top"><row><entry>lbd_diu_rreq</entry><entry>1</entry><entry>Out</entry><entry>LBD requests DRAM read.</entry></row><row><entry /><entry /><entry /><entry>A read request must be</entry></row><row><entry /><entry /><entry /><entry>accompanied by a valid</entry></row><row><entry /><entry /><entry /><entry>read address.</entry></row><row><entry>lbd_diu_radr[21:5]</entry><entry>17</entry><entry>Out</entry><entry>Read address to DIU</entry></row><row><entry /><entry /><entry /><entry>17 bits wide (256-bit</entry></row><row><entry /><entry /><entry /><entry>aligned word).</entry></row><row><entry>diu_lbd_rack</entry><entry>1</entry><entry>In</entry><entry>Acknowledge from DIU that</entry></row><row><entry /><entry /><entry /><entry>read request has been</entry></row><row><entry /><entry /><entry /><entry>accepted and new read</entry></row><row><entry /><entry /><entry /><entry>address can be placed</entry></row><row><entry /><entry /><entry /><entry>on lbd_diu_radr.</entry></row><row><entry>diu_data[63:0]</entry><entry>64</entry><entry>In</entry><entry>Data from DIU to SoPEC</entry></row><row><entry /><entry /><entry /><entry>Units.</entry></row><row><entry /><entry /><entry /><entry>First 64-bits is bits 63:0</entry></row><row><entry /><entry /><entry /><entry>of 256 bit word.</entry></row><row><entry /><entry /><entry /><entry>Second 64-bits is bits</entry></row><row><entry /><entry /><entry /><entry>127:64 of 256 bit word.</entry></row><row><entry /><entry /><entry /><entry>Third 64-bits is bits</entry></row><row><entry /><entry /><entry /><entry>191:128 of 256 bit word.</entry></row><row><entry /><entry /><entry /><entry>Fourth 64-bits is bits</entry></row><row><entry /><entry /><entry /><entry>255:192 of 256 bit word.</entry></row><row><entry>diu_lbd_rvalid</entry><entry>1</entry><entry>In</entry><entry>Signal from DIU telling</entry></row><row><entry /><entry /><entry /><entry>SoPEC Unit that valid read</entry></row><row><entry /><entry /><entry /><entry>data is on the diu_data</entry></row><row><entry /><entry /><entry /><entry>bus</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>PCU Interface data and control signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="91pt" align="left" /><tbody valign="top"><row><entry>pcu_addr[5:2]</entry><entry>4</entry><entry>In</entry><entry>PCU address bus. Only 4</entry></row><row><entry /><entry /><entry /><entry>bits are required to</entry></row><row><entry /><entry /><entry /><entry>decode the address</entry></row><row><entry /><entry /><entry /><entry>space for this block.</entry></row><row><entry>pcu_dataout[31:0]</entry><entry>32</entry><entry>In</entry><entry>Shared write data bus</entry></row><row><entry /><entry /><entry /><entry>from the PCU.</entry></row><row><entry>lbd_pcu_datain[31:0]</entry><entry>32</entry><entry>Out</entry><entry>Read data bus from the</entry></row><row><entry /><entry /><entry /><entry>LBD to the PCU.</entry></row><row><entry>pcu_rwn</entry><entry>1</entry><entry>In</entry><entry>Common read/not-write</entry></row><row><entry /><entry /><entry /><entry>signal from the PCU.</entry></row><row><entry>pcu_lbd_sel</entry><entry>1</entry><entry>In</entry><entry>Block select from the</entry></row><row><entry /><entry /><entry /><entry>PCU. When pcu_lbd_sel</entry></row><row><entry /><entry /><entry /><entry>is high both pcu_addr</entry></row><row><entry /><entry /><entry /><entry>and pcu_dataout are</entry></row><row><entry /><entry /><entry /><entry>valid.</entry></row><row><entry>lbd_pcu_rdy</entry><entry>1</entry><entry>Out</entry><entry>Ready signal to the PCU.</entry></row><row><entry /><entry /><entry /><entry>When lbd_pcu_rdy is high</entry></row><row><entry /><entry /><entry /><entry>it indicates the last cycle</entry></row><row><entry /><entry /><entry /><entry>of the access. For a write</entry></row><row><entry /><entry /><entry /><entry>cycle this means pcu_dataout</entry></row><row><entry /><entry /><entry /><entry>has been registered by the</entry></row><row><entry /><entry /><entry /><entry>block and for a read cycle</entry></row><row><entry /><entry /><entry /><entry>this means the data on</entry></row><row><entry /><entry /><entry /><entry>lbd_pcu_datain is valid.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>SFU Interface data and control signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="91pt" align="left" /><tbody valign="top"><row><entry>sfu_lbd_rdy</entry><entry>1</entry><entry>In</entry><entry>Ready signal indicating SFU</entry></row><row><entry /><entry /><entry /><entry>has previous line data</entry></row><row><entry /><entry /><entry /><entry>available for reading and</entry></row><row><entry /><entry /><entry /><entry>is also ready to be</entry></row><row><entry /><entry /><entry /><entry>written to.</entry></row><row><entry>lbd_sfu_advline</entry><entry>1</entry><entry>Out</entry><entry>Advance line signal to</entry></row><row><entry /><entry /><entry /><entry>previous and next line</entry></row><row><entry /><entry /><entry /><entry>buffers</entry></row><row><entry>lbd_sfu_pladvword</entry><entry>1</entry><entry>Out</entry><entry>Advance word signal for</entry></row><row><entry /><entry /><entry /><entry>previous line buffer.</entry></row><row><entry>sfu_lbd_pldata[15:0]</entry><entry>16</entry><entry>In</entry><entry>Data from the previous</entry></row><row><entry /><entry /><entry /><entry>line buffer.</entry></row><row><entry>lbd_sfu_wdata[15:0]</entry><entry>16</entry><entry>Out</entry><entry>Write data for next line</entry></row><row><entry /><entry /><entry /><entry>buffer.</entry></row><row><entry>lbd_sfu_wdatavalid</entry><entry>1</entry><entry>Out</entry><entry>Write data valid signal</entry></row><row><entry /><entry /><entry /><entry>for next line buffer</entry></row><row><entry /><entry /><entry /><entry>data.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 24.3.2 Configuration Registers
2725<tables id="TABLE-US-00233" num="00233"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="343pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 156</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>LBD Configuration Registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry /><entry>Value</entry><entry /></row><row><entry>Address</entry><entry /><entry>#</entry><entry>on</entry></row><row><entry>(LBD_base +)</entry><entry>Register Name</entry><entry>Bits</entry><entry>Reset</entry><entry>Description</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="343pt" align="left" /><tbody valign="top"><row><entry>Control registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="21pt" align="char" char="." /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>0x00</entry><entry>Reset</entry><entry>1</entry><entry>0x1</entry><entry>A write to this register causes a reset</entry></row><row><entry /><entry /><entry /><entry /><entry>of the LBD.</entry></row><row><entry /><entry /><entry /><entry /><entry>This register can be read to indicate the</entry></row><row><entry /><entry /><entry /><entry /><entry>reset state:</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - reset in progress</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - reset not in progress</entry></row><row><entry>0x04</entry><entry>Go</entry><entry>1</entry><entry>0x0</entry><entry>Writing 1 to this register starts the LBD.</entry></row><row><entry /><entry /><entry /><entry /><entry>Writing 0 to this register halts the LBD.</entry></row><row><entry /><entry /><entry /><entry /><entry>The Go register is reset to 0 by the LBD</entry></row><row><entry /><entry /><entry /><entry /><entry>when it finishes processing a band.</entry></row><row><entry /><entry /><entry /><entry /><entry>When Go is deasserted the state-machines</entry></row><row><entry /><entry /><entry /><entry /><entry>go to their idle states but all counters and</entry></row><row><entry /><entry /><entry /><entry /><entry>configuration registers keep their values.</entry></row><row><entry /><entry /><entry /><entry /><entry>When Go is asserted all counters are reset,</entry></row><row><entry /><entry /><entry /><entry /><entry>but configuration registers keep their values</entry></row><row><entry /><entry /><entry /><entry /><entry>(i.e. they don't get reset).</entry></row><row><entry /><entry /><entry /><entry /><entry>The LBD should only be started after the</entry></row><row><entry /><entry /><entry /><entry /><entry>SFU is started.</entry></row><row><entry /><entry /><entry /><entry /><entry>This register can be read to determine if</entry></row><row><entry /><entry /><entry /><entry /><entry>the LBD is running</entry></row><row><entry /><entry /><entry /><entry /><entry>(1 - running, 0 - stopped).</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="343pt" align="left" /><tbody valign="top"><row><entry>Setup registers (constant for during processing the page)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="21pt" align="char" char="." /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>0x08</entry><entry>LineLength</entry><entry>16</entry><entry>0x0000</entry><entry>Width of expanded bi-level line (in dots)</entry></row><row><entry /><entry /><entry /><entry /><entry>(must be set greater than 128 bits).</entry></row><row><entry>0x0C</entry><entry>PassThroughEnable</entry><entry>1</entry><entry>0x1</entry><entry>Writing 1 to this register enables</entry></row><row><entry /><entry /><entry /><entry /><entry>passthrough mode.</entry></row><row><entry /><entry /><entry /><entry /><entry>Writing 0 to this register disables</entry></row><row><entry /><entry /><entry /><entry /><entry>pass-through mode thereby making the</entry></row><row><entry /><entry /><entry /><entry /><entry>LBD compatible with PEC1.</entry></row><row><entry>0x10</entry><entry>PassThroughDotLength</entry><entry>16</entry><entry>0x0000</entry><entry>This is the dot length - 1 for which</entry></row><row><entry /><entry /><entry /><entry /><entry>passthrough mode will last. If the end</entry></row><row><entry /><entry /><entry /><entry /><entry>of the line is reached first then</entry></row><row><entry /><entry /><entry /><entry /><entry>pass-through will be disabled. The</entry></row><row><entry /><entry /><entry /><entry /><entry>value written to this register</entry></row><row><entry /><entry /><entry /><entry /><entry>must be a non-zero value.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="343pt" align="left" /><tbody valign="top"><row><entry>Work registers (need to be set up before processing a band)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="21pt" align="char" char="." /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>0x14</entry><entry>NextBandCurrReadAdr[21:5]</entry><entry>17</entry><entry>0x00000</entry><entry>Shadow register which is copied to</entry></row><row><entry /><entry>(256-bit aligned</entry><entry /><entry /><entry>CurrReadAdr when (NextBandEnable = = 1 &</entry></row><row><entry /><entry>DRAM address)</entry><entry /><entry /><entry>Go = = 0).</entry></row><row><entry /><entry /><entry /><entry /><entry>NextBandCurrReadAdr is the address of the</entry></row><row><entry /><entry /><entry /><entry /><entry>start of the next band of compressed</entry></row><row><entry /><entry /><entry /><entry /><entry>bi-level data in DRAM.</entry></row><row><entry>0x18</entry><entry>NextBandLinesRemaining</entry><entry>15</entry><entry>0x0000</entry><entry>Shadow register which is copied to</entry></row><row><entry /><entry /><entry /><entry /><entry>LinesRemaining when (NextBandEnable = = 1 &</entry></row><row><entry /><entry /><entry /><entry /><entry>Go = = 0).</entry></row><row><entry /><entry /><entry /><entry /><entry>NextBandLinesRemaining is the number of</entry></row><row><entry /><entry /><entry /><entry /><entry>lines to be decoded in the next band of</entry></row><row><entry /><entry /><entry /><entry /><entry>compressed bi-level data.</entry></row><row><entry>0x1C</entry><entry>NextBandPrevLineSource</entry><entry>1</entry><entry>0x0</entry><entry>Shadow register which is copied to</entry></row><row><entry /><entry /><entry /><entry /><entry>PrevLineSource when (NextBandEnable = = 1</entry></row><row><entry /><entry /><entry /><entry /><entry>& Go = = 0).</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - use the previous line read from the SFU</entry></row><row><entry /><entry /><entry /><entry /><entry>for decoding the first line at the start</entry></row><row><entry /><entry /><entry /><entry /><entry>of the next band.</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - ignore the previous line read from the</entry></row><row><entry /><entry /><entry /><entry /><entry>SFU for decoding the first line at the start</entry></row><row><entry /><entry /><entry /><entry /><entry>of the next band (an all 0's line is used</entry></row><row><entry /><entry /><entry /><entry /><entry>instead).</entry></row><row><entry>0x20</entry><entry>NextBandEnable</entry><entry>1</entry><entry>0x0</entry><entry>If (NextBandEnable = = 1 & Go = = 0) then</entry></row><row><entry /><entry /><entry /><entry /><entry>NextBandCurrReadAdr is copied to</entry></row><row><entry /><entry /><entry /><entry /><entry>CurrReadAdr,</entry></row><row><entry /><entry /><entry /><entry /><entry>NextBandLinesRemaining is copied</entry></row><row><entry /><entry /><entry /><entry /><entry>to LinesRemaining,</entry></row><row><entry /><entry /><entry /><entry /><entry>NextBandPrevLineSource is copied</entry></row><row><entry /><entry /><entry /><entry /><entry>to PrevLineSource,</entry></row><row><entry /><entry /><entry /><entry /><entry>Go is set,</entry></row><row><entry /><entry /><entry /><entry /><entry>NextBandEnable is cleared.</entry></row><row><entry /><entry /><entry /><entry /><entry>To start LBD processing NextBandEnable</entry></row><row><entry /><entry /><entry /><entry /><entry>should be set.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="343pt" align="left" /><tbody valign="top"><row><entry>Work registers (read only for external access)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="21pt" align="char" char="." /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>0x24</entry><entry>CurrReadAdr[21:5]</entry><entry>17</entry><entry>—</entry><entry>The current 256-bit aligned read address</entry></row><row><entry /><entry>(256-bit aligned DRAM</entry><entry /><entry /><entry>within the compressed bi-level image</entry></row><row><entry /><entry>address)</entry><entry /><entry /><entry>(DRAM address). Read only register.</entry></row><row><entry>0x28</entry><entry>LinesRemaining</entry><entry>15</entry><entry>—</entry><entry>Count of number of lines remaining to be</entry></row><row><entry /><entry /><entry /><entry /><entry>decoded. The band has finished when this</entry></row><row><entry /><entry /><entry /><entry /><entry>number reaches 0. Read only register.</entry></row><row><entry>0x2C</entry><entry>PrevLineSource</entry><entry>1</entry><entry>—</entry><entry>1 - uses the previous line read from the</entry></row><row><entry /><entry /><entry /><entry /><entry>SFU for decoding the first line at the</entry></row><row><entry /><entry /><entry /><entry /><entry>start of the next band.</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - ignores the previous line read from the</entry></row><row><entry /><entry /><entry /><entry /><entry>SFU for decoding the first line at the</entry></row><row><entry /><entry /><entry /><entry /><entry>start of the next band (an all 0's line is</entry></row><row><entry /><entry /><entry /><entry /><entry>used instead).</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only register.</entry></row><row><entry>0x30</entry><entry>CurrWriteAdr</entry><entry>15</entry><entry>—</entry><entry>The current dot position for writing to the</entry></row><row><entry /><entry /><entry /><entry /><entry>SFU. Read only register.</entry></row><row><entry>0x34</entry><entry>FirstLineOfBand</entry><entry>1</entry><entry>—</entry><entry>Indicates whether the current line is</entry></row><row><entry /><entry /><entry /><entry /><entry>considered to be the first line of the</entry></row><row><entry /><entry /><entry /><entry /><entry>band. Read only register.</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 24.3.3 Starting the LBD Between Bands
2726The LBD should be started after the SFU. The LBD is programed with a start address for the compressed bi-level data, a decode line length, the source of the previous line and a count of how many lines to decode. The LBD's NextBandEnable bit should then be set (this will set LBD Go). The LBD decodes a single band and then stops, clearing it's Go bit and issuing a pulse on lbd_finishedband. The LBD can then be restarted for the next band, while the HCU continues to process previously decoded bi-level data from the SFU.
2727There are 4 mechanisms for restarting the LBD between bands: <ul id="ul0271" list-style="none"><li id="ul0271-0001" num="2728">a. lbd_finishedband causes an interrupt to the CPU. The LBD will have stopped and cleared its Go bit. The CPU reprograms the LBD, typically the NextBandCurrReadAdr, NextBandLinesRemaining and NextBandPrevLineSource shadow registers, and sets NextBandEnable to restart the LBD.</li><li id="ul0271-0002" num="2729">b. The CPU programs the LBD's NextBandCurrReadAdr, NextBandLinesRemaining, and NextBandPrevLineSource shadow registers and sets the NextBandEnable flag before the end of the current band. At the end of the band the LBD clears Go, NextBandEnable is already set so the LBD restarts immediately.</li><li id="ul0271-0003" num="2730">c. The PCU is programmed so that lbd_finishedband triggers the PCU to execute commands from DRAM to reprogram the LBD's NextBandCurrReadAdr, NextBandLinesRemaining, and NextBandPrevLineSource shadow registers and set NextBandEnable to restart the LBD. The advantage of this scheme is that the CPU could process band headers in advance and store the band commands in DRAM ready for execution.</li><li id="ul0271-0004" num="2731">d. This is a combination of b and c above. The PCU (rather than the CPU in b) programs the LBD's NextBandCurrReadAdr, NextBandLinesRemaining, and NextBandPrevLineSource shadow registers and sets the NextBandEnable flag before the end of the current band. At the end of the band the LBD clears Go and pulses lbd_finishedband. NextBandEnable is already set so the LBD restarts immediately. Simultaneously, lbd_finishedband triggers the PCU to fetch commands from DRAM. The LBD will have restarted by the time the PCU has fetched commands from DRAM. The PCU commands program the LBD's shadow registers and sets NextBandEnable for the next band. <br /> 24.3.4 Top-level Description </li></ul>
2732A block diagram of the LBD is shown in <figref idref="DRAWINGS">FIG. 148</figref>.
2733The LBD contains the following sub-blocks:
2734<tables id="TABLE-US-00234" num="00234"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 157</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Functional sub-blocks in the LBD</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="35pt" align="left" /><colspec colname="2" colwidth="182pt" align="left" /><tbody valign="top"><row><entry>name</entry><entry>Description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>Registers</entry><entry>PCU interface and configuration registers. Also generates</entry></row><row><entry>and</entry><entry>the Go and the Reset signals for the rest of the LBD</entry></row><row><entry>Resets</entry></row><row><entry>Stream</entry><entry>Accesses the bi-level description from the DRAM through</entry></row><row><entry>Decoder</entry><entry>the DIU interface. It decodes the bit stream into a command</entry></row><row><entry /><entry>with arguments, which it then passes to the command</entry></row><row><entry /><entry>controller.</entry></row><row><entry>Command</entry><entry>Interprets the command from the stream decoder and provide</entry></row><row><entry>Controller</entry><entry>the line fill unit with a limit address and color to fill the</entry></row><row><entry /><entry>SFU Next Line Buffer. It also provides the next edge</entry></row><row><entry /><entry>unit starting address to look for the next edge.</entry></row><row><entry>Next Edge</entry><entry>Scans through the Previous Line Buffer using its current</entry></row><row><entry>Unit</entry><entry>address to find the next edge of a color provided by the</entry></row><row><entry /><entry>command controller. The next edge unit outputs this as the</entry></row><row><entry /><entry>next current address back to the command controller and</entry></row><row><entry /><entry>sets a valid bit when this address is at the next edge.</entry></row><row><entry>Line Fill</entry><entry>Fills the SFU Next Line Buffer with a color from its current</entry></row><row><entry>Unit</entry><entry>address up to a limit address. The color and limit are</entry></row><row><entry /><entry>provided by the command controller.</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2735In the following description the LBD decodes data for its current decode line but writes this data into the SFU's next line buffer.
2736Naming of signals and logical blocks are taken from [22].
2737The LBD is able to stall mid-line should the SFU be unable to supply a previous line or receive a current line frame due to band processing latency.
2738All output control signals from the LBD must always be valid after reset. For example, if the LBD is not currently decoding, lbd_sfu_advline (to the SFU) and lbd_finishedband will always be 0.
000024.3.5 Registers and Resets Sub-block Description
2739Since the CDU, LBD and TE all access the page band store, they share two registers that enable sequential memory accesses to the page band stores to be circular in nature. The CDU chapter lists these two registers. The register descriptions for the LBD are listed in Table.
2740During initialisation of the LBD, the LineLength and the LinesRemaining configuration values are written to the LBD. The ‘Registers and Resets’ sub-block supplies these signals to the other sub-blocks in the LBD. In the case of LinesRemaining, this number is decremented for every line that is completed by the LBD.
2741If pass through is used during a band the PassThroughEnable register needs to be programmed and PassThroughDotLength programmed with the length of the compressed bits in pass through mode.
2742PrevLineSource is programmed during the initialisation of a band, if the previous line supplied for the first line is a valid previous line, a 1 is written to PrevLineSource so that the data is used. If a 0 is written the LBD ignores the previous line information supplied and acts as if it is receiving all zeros for the previous line regardless of what the out of the SFU is.
2743The ‘Registers and Resets’ sub-block also generates the resets used by the rest of the LBD and the Go bit which tells the LBD that it can start requesting data from the DIU and commence decoding of the compressed data stream.
000024.3.6 Stream Decoder Sub-block Description
2744The Stream Decoder reads the compressed bi-level image from the DRAM via the DIU (single accesses of 256-bits) into a double 256-bit FIFO. The barrel shift register uses the 64-bit word from the FIFO to fill up the empty space created by the barrel shift register as it is shifting it's contents. The bit stream is decoded into a command/arguments pair, which in turn is passed to the command controller.
2745A dataflow block diagram of the stream decoder is shown in <figref idref="DRAWINGS">FIG. 149</figref>.
000024.3.6.1 DecodeC—Decode Command
2746The DecodeC logic encodes the command from bits <b>6</b> . . . <b>0</b> of the bit stream to output one of three commands: SKIP, VERTICAL and RUNLENGTH. It also provides an output to indicate how many bits were consumed, which feeds back to the barrel shift register.
2747There is a fourth command, PASS_THROUGH, which is not encoded in bits <b>6</b> . . . <b>0</b>, instead it is inferred in a special runlength. If the stream decoder detects a short runlength value, i.e. a number less than 31, encoded as a medium runlength this tell the Stream Decoder that once the horizontal command containing this runlength is decoded completely the LBD enters PASS_THROUGH mode. Following the runlength there will be a number of bits that represent un-compressed data. The LBD will stay in PASS_THROUGH mode until all these bits have been decoded successfully, this will occur once a programmed number of bits is reached or the line ends, which ever comes first.
000024.3.6.2 DecodeD—Decode Delta
2748The DecodeD logic decodes the run length from bits <b>20</b> . . . <b>3</b> of the bit stream. If DecodeC is decoding a vertical command, it will cause DecodeD to put constants of −3 through 3 on its output. The output delta is a 15 bit number, which is generally considered to be positive, but since it needs to only address to 13824 dots for an A4 page and 19488 dots for an A3 page (of 32,768), a 2's complement representation of −3, −2, −1 will work correctly for the data pipeline that follows. This unit also outputs how many bits were consumed.
2749In the case of PASS_THROUGH mode, DecodeD parses the bits that represent the un-compressed data and this is used by the Line Fill Unit to construct the current line frame.
2750DecodeD parses the bits at one bit per clock cycle and passes the bit in the less significant bit location of delta to the line fill unit.
2751DecodeD currently requires to know the color of the run length to decode it correctly as black and white runs are encoded differently. The stream decoder keeps track of the next color based on the current color and the current command.
000024.3.6.3 State-machine
2752This state machine continuously fetches consecutive DRAM data whenever there is enough free space in the FIFO, thereby keeping the barrel shift register full so it can continually decode commands for the command controller. Note in <figref idref="DRAWINGS">FIG. 149</figref> that each read cycle curr_read_addr is compared to end_of_band_store. If the two are equal, curr_read_addr is loaded with start_of_band_store (circular memory addressing). Otherwise curr_read_addr is simply incremented. start_of_band_store and end_of_band_store need to be programed so that the distance between them is a multiple of the 256-bit DRAM word size.
2753When the state machine decodes a SKIP command, the state machine provides two SKIP instructions to the command controller.
2754The RUNLENGTH command has two different run lengths. The two run lengths are passed to the command controller as separate RUNLENGTH instructions. In the first instruction fetch, the first run length is passed, and the state machine selects the DecodeD shift value for the barrel shift. In the second instruction fetch from the command controller another RUNLENGTH instruction is generated and the respective shift value is decoded. This is achieved by forcing DecodeC to output a second RUNLENGTH instruction and the respective shift value is decoded.
2755For PASS_THROUGH mode, the PASS THROUGH command is issued every time the command controller requests a new command. It does this until all the un-compressed bits have been processed.
000024.3.7 Command Controller Sub-block Description
2756The Command Controller interprets the command from the Stream Decoder and provides the line fill unit with a limit address and color to fill the SFU Next Line Buffer. It provides the next edge unit with a starting address to look for the next edge and is responsible for detecting the end of line and generating the eob_cc signal that is passed to the line fill unit.
2757A dataflow block diagram of the command controller is shown in <figref idref="DRAWINGS">FIG. 150</figref>. Note that data names such as a0 and b1p are taken from [22], and they denote the reference or starting changing element on the coding line and the first changing element on the reference line to the right of a0 and of the opposite color to a0 respectively.
000024.3.7.1 State Machine
2758The following is an explanation of all the states that the state machine utilizes.
0000i Start
2759This is the state that the Command Controller enters when a hard or soft reset occurs or when Go has been de-asserted. This state cannot be left until the reset has been removed, Go has been asserted and the NEU (Next Edge Unit), the SD (Stream Decoder) and the SFU are ready.
0000ii AWAIT_BUFFER
2760The NEU contains a buffer memory for the data it receives from the SFU. When the command controller enters this state the NEU detects this and starts buffering data, the command controller is able to leave this state when the state machine in the NEU has entered the NEU_RUNNING state. Once this occurs the command controller can proceed to the PARSE state.
0000iii PAUSE_CC
2761During the decode of a line it is possible for the FIFO in the stream decoder to get starved of data if the DRAM is not able to supply replacement data fast enough. Additionally the SFU can also stall mid-line due to band processing latency. If either of these cases occurs the LBD needs to pause until the stream decoder gets more of the compressed data stream from the DRAM or the SFU can receive or deliver new frames. All of the remaining states check if sdvalid goes to zero (this denotes a starving of the stream decoder) or if sfu_lbd_rdy goes to zero and that the LBD needs to pause. PAUSE_CC is the state that the command controller enters to achieve this and it does not leave this state until sdvalid and sfu_lbd_rdy are both asserted and the LBD can recommence decompressing.
0000iv PARSE
2762Once the command controller enters the PARSE state it uses the information that is supplied by the stream decoder. The first clock cycle of the state sees the sdack signal getting asserted informing the stream decoder that the current register information is being used so that it can fetch the next command.
2763When in this state the command controller can receive one of four valid commands:
0000a) Runlength or Horizontal
2764For this command the value given as delta is an integer that denotes the number of bits of the current color that must be added to the current line.
2765Should the current line position, a0, be added to the delta and the result be greater than the final position of the current frame being processed by the Line Fill Unit (only 16 bits at a time), it is necessary for the command controller to wait for the Line Fill Unit (LFU) to process up to that point. The command controller changes into the WAIT_FOR_RUNLENGTH state while this occurs.
2766When the current line position, a1, and the delta together equal or exceed the LINE_LENGTH, which is programmed during initialisation, then this denotes that it is the end of the current line. The command controller signals this to the rest of the LBD and then returns to the STAR<sub>T </sub>state.
0000b) Vertical
2767When this command is received, it tells the command controller that, in the previous line, it needs to find a change from the current color to opposite of the current color, i.e. if the current color is white it looks from the current position in the previous line for the next time where there is a change in color from white to black. It is important to note that if a black to white change occurs first it is ignored.
2768Once this edge has been detected, the delta will denote which of the vertical commands to use, refer to Table. The delta will denote where the changing element in the current line is relative to the changing element on the previous line, for a Vertical(2) the new changing element position in the current line will correspond to the two bits extra from changing element position in the previous line.
2769Should the next edge not be detected in the current frame under review in the NEU, then the command controller enters the WAIT_FOR_NE state and waits there until the next edge is found.
0000c) Skip
2770A skip follow the same functionality as to Vertical(0) commands but the color in the current line is not changed as it is been filled out. The stream decoder supplies what looks like two separate skip commands that the command controller treats the same a two Vertical(0) commands and has been coded not to change the current color in this case.
0000d) Pass Through
2771When in pass through mode the stream decoder supplies one bit per clock cycle that is uses to construct the current frame. Once pass through mode is completed, which is controlled in the stream decoder, the LBD can recommence normal decompression again. The current color after pass through mode is the same color as the last bit in un-compressed data stream. Pass through mode does not need an extra state in the command controller as each pass through command received from the stream decoder can always be processed in one clock cycle.
0000v WAIT_FOR_RUNLENGTH
2772As some RUNLENGTH's can carry over more than one 16-bit frame, this means that the Line Fill Unit needs longer than one clock cycle to write out all the bits represented by the RUNLENGTH.
2773After the first clock cycle the command controller enters into the WAIT_FOR_RUNLENGTH state until all the RUNLENGTH data has been consumed. Once finished and provided it is not the end of the line the command controller will return to the PARSE state.
0000vi WAIT_FOR_NE
2774Similar to the RUNLENGTH commands the vertical commands can sometimes not find an edge in the current 16-bit frame. After the first clock cycle the command controller enters the WAIT_FOR_NE state and remains here until the edge is detected. Provided it is not the end of the line the command controller will return to the PARSE state.
0000vii FINISH_LINE
2775At the end of a line the command controller needs to hold its data for the SFU before going back to the STAR<sub>T </sub>state. Command controller remains in the FINISH_LINE state for one clock cycle to achieve this.
000024.3.8 Next Edge Unit Sub-block Description
2776The Next Edge Unit (NEU) is responsible for detecting color changes, or edges, in the previous line based on the current address and color supplied by the Command Controller. The NEU is the interface to the SFU and it buffers the previous line for detecting an edge. For an edge detect operation the Command Controller supplies the current address, this typically was the location of the last edge, but it could also be the end of a run length. With the current address a color is also supplied and using these two values the NEU will search the previous line for the next edge. If an edge is found the NEU returns this location to the Command Controller as the next address in the current line and it sets a valid bit to tell the Command Controller that the edge has been detected. The Line Fill Unit uses this result to construct the current line. The NEU operates on 16-bit words and it is possible that there is no edge in the current 16 bits in the NEU. In this case the NEU will request more words from the SFU and will keep searching for an edge. It will continue doing this until it finds an edge or reaches the end of the previous line, which is based on the LINE_LENGTH. A dataflow block diagram of the Next Edge unit is shown in <figref idref="DRAWINGS">FIG. 152</figref>.
000024.3.8.1 NEU Buffer
2777The algorithm being employed for decompression is based on the whole previous line and is not delineated during the line. However the Next Edge Unit, NEU, can only receive 16 bits at a time from the SFU. This presents a problem for vertical commands if the edge occurs in the successive frame, but refers to a changing element in the current frame.
2778To accommodate this the NEU works on two frames at the same time, the current frame and the first 3 bits from the successive frame. This allows for the information that is needed from the previous line to construct the current frame of the current line.
2779In addition to this buffering there is also buffering right after the data is received from the SFU as the SFU output is not registered. The current implementation of the SFU takes two clock cycles from when a request for a current line is received until it is returned and registered. However when NEU requests a new frame it needs it on the next clock cycle to maintain a decoded rate of 2 bits per clock cycle. A more detailed diagram of the buffer in the NEU is shown in <figref idref="DRAWINGS">FIG. 153</figref>.
2780The output of the buffer are two 16-bit vectors, use_prev_line_a and use_prev_line_b, that are used to detect an edge that is relevant to the current line being put together in the Line Fill Unit.
000024.3.8.2 NEU Edge Detect
2781The NEU Edge Detect block takes the two 16 bit vectors supplied by the buffer and based on the current line position in the current line, a0, and the current color, sd_color, it will detect if there is an edge relevant to the current frame. If the edge is found it supplies the current line position, b1p, to the command controller and the line fill unit. The configuration of the edge detect is shown in <figref idref="DRAWINGS">FIG. 154</figref>.
2782The two vectors from the buffer, use_prev_line_a and use_prev_line_b, pass into two sub-blocks, transition_wtob and transition_btow. transition_wtob detects if any white to black transitions occur in the 19 bit vector supplied and outputs a 19-bit vector displaying the transitions. transition_wtob is functionally the same as transition_btow, but it detects white to black transitions.
2783The two 19-bit vectors produced enter into a multiplexer and the output of the multiplexer is controlled by color_neu. color_neu is the current edge transition color that the edge detect is searching for.
2784The output of the multiplexer is masked against a 19-bit vector, the mask is comprised of three parts concatenated together: decode_b_ext, decode_b and FIRST_FLU_WRITE.
2785The output of transition_wtob (and it complement transition_btow) are all the transitions in the 16 bit word that is under review. The decode_b is a mask generated from a0. In bit-wise terms all the bits above and including a0 are 1's and all bits below a0 are 0's. When they are gated together it means that all the transitions below a0 are ignored and the first transition after a0 is picked out as the next edge.
2786The decode_b block decodes the 4 lsb of the current address (a0) into 16-bit mask bits that control which of the data bits are examined. Table 158 shows the truth table for this block.
2787<tables id="TABLE-US-00235" num="00235"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 158</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Decode_b truth table</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry>input</entry><entry>output</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>0000</entry><entry>1111111111111111</entry></row><row><entry /><entry>0001</entry><entry>1111111111111110</entry></row><row><entry /><entry>0010</entry><entry>1111111111111100</entry></row><row><entry /><entry>0011</entry><entry>1111111111111000</entry></row><row><entry /><entry>0100</entry><entry>1111111111110000</entry></row><row><entry /><entry>0101</entry><entry>1111111111100000</entry></row><row><entry /><entry>0110</entry><entry>1111111111000000</entry></row><row><entry /><entry>0111</entry><entry>1111111110000000</entry></row><row><entry /><entry>1000</entry><entry>1111111100000000</entry></row><row><entry /><entry>1001</entry><entry>1111111000000000</entry></row><row><entry /><entry>1010</entry><entry>1111110000000000</entry></row><row><entry /><entry>1011</entry><entry>1111100000000000</entry></row><row><entry /><entry>1100</entry><entry>1111000000000000</entry></row><row><entry /><entry>1101</entry><entry>1110000000000000</entry></row><row><entry /><entry>1110</entry><entry>1100000000000000</entry></row><row><entry /><entry>1111</entry><entry>1000000000000000</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2788For cases when there is a negative vertical command from the stream decoder it is possible that the edge is in the three lower significant bits of the next frame. The decode_b_ext block supplies the mask so that the necessary bits can be used by the NEU to detect an edge if present, Table 159 shows the truth table of this block.
2789<tables id="TABLE-US-00236" num="00236"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 159</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Decode_b_ext truth table</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><tbody valign="top"><row><entry /><entry>delta</entry><entry>output</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>Vertical(−3)</entry><entry>111</entry></row><row><entry /><entry>Vertical(−2)</entry><entry>111</entry></row><row><entry /><entry>Vertical(−1)</entry><entry>011</entry></row><row><entry /><entry>OTHERS</entry><entry>001</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2790FIRST_FLU_WRITE is only used in the first frame of the current line. 2.2.5 a) in [22] refers to “Processing the first picture element”, in which it states that “The first starting picture element, a0, on each coding line is imaginarily set at a position just before the first picture element, and is regarded as a white picture element”. transition_wtob and transition_btow are set up produce this case for every single frame. However it is only used by the NEU if it is not masked out. This occurs when FIRST_FLU_WRITE is ‘1’ which is only asserted at the beginning of a line. 2.2.5 b) in [22] covers the case of “Processing the last picture element”, this case states that “The coding of the coding line continues until the position of the imaginary changing element situated after the last actual element is coded”. This means that no matter what the current color is the NEU needs to always find an edge at the end of a line. This feature is used with negative vertical commands.
2791The vector, end_frame, is a “one-hot” vector that is asserted during the last frame. It asserts a bit in the end of line position, as determined by LineLength, and this simulates an edge in this location which is ORed with the transition's vector. The output of this, masked_data, is sent into the encodeB_one_hot block
000024.3.8.3 Encode_b_one_hot
2792The encode_b_one_hot block is the first stage of a two stage process that encodes the data to determine the address of the 0 to 1 transition. Table 160 lists the truth table outlining the functionally required by this block.
2793<tables id="TABLE-US-00237" num="00237"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 160</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Encode_b_one_hot Truth Table</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="112pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry>Input</entry><entry>output</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>XXXXXXXXXXXXXXXXXX1</entry><entry>0000000000000000001</entry></row><row><entry /><entry>XXXXXXXXXXXXXXXXX10</entry><entry>0000000000000000010</entry></row><row><entry /><entry>XXXXXXXXXXXXXXXX100</entry><entry>0000000000000000100</entry></row><row><entry /><entry>XXXXXXXXXXXXXXX1000</entry><entry>0000000000000001000</entry></row><row><entry /><entry>XXXXXXXXXXXXXX10000</entry><entry>0000000000000010000</entry></row><row><entry /><entry>XXXXXXXXXXXXX100000</entry><entry>0000000000000100000</entry></row><row><entry /><entry>XXXXXXXXXXXX1000000</entry><entry>0000000000001000000</entry></row><row><entry /><entry>XXXXXXXXXXX10000000</entry><entry>0000000000010000000</entry></row><row><entry /><entry>XXXXXXXXXX100000000</entry><entry>0000000000100000000</entry></row><row><entry /><entry>XXXXXXXXX1000000000</entry><entry>0000000001000000000</entry></row><row><entry /><entry>XXXXXXXX10000000000</entry><entry>0000000010000000000</entry></row><row><entry /><entry>XXXXXXX100000000000</entry><entry>0000000100000000000</entry></row><row><entry /><entry>XXXXXX1000000000000</entry><entry>0000001000000000000</entry></row><row><entry /><entry>XXXXX10000000000000</entry><entry>0000010000000000000</entry></row><row><entry /><entry>XXXX100000000000000</entry><entry>0000100000000000000</entry></row><row><entry /><entry>XXX1000000000000000</entry><entry>0001000000000000000</entry></row><row><entry /><entry>XX10000000000000000</entry><entry>0010000000000000000</entry></row><row><entry /><entry>X100000000000000000</entry><entry>0100000000000000000</entry></row><row><entry /><entry>1000000000000000000</entry><entry>1000000000000000000</entry></row><row><entry /><entry>0000000000000000000</entry><entry>0000000000000000000</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2794The output of encode_b_one-hot is a “one-hot” vector that will denote where that edge transition is located. In cases of multiple edges, only the first one will be picked.
000024.3.8.4 Encode_b<sub>—</sub>4 Bit
2795Encode_b<sub>—</sub>4 bit is the second stage of the two stage process that encodes the data to determine the address of the 0 to 1 transition.
2796Encode_b<sub>—</sub>4 bit receives the “one-hot” vector from encode_b_one_hot and determines the bit location that is asserted. If there is none present this means that there was no edge present in this frame. If there is a bit asserted the bit location in the vector is converted to a number, for example if bit <b>0</b> is asserted then the number is one, if bit one is asserted then the number is one, etc. The delta supplied to the NEU determines what vertical command is being processed. The formula that is implemented to return b1p to the command controller is:
2797<tables id="TABLE-US-00238" num="00238"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>for V(n) b1p = x + n modulus16</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>where x is the number that was extracted from the “one-hot”</entry></row><row><entry /><entry>vector and n is the vertical command.</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 24.3.8.5 State Machine
2798The following is an explanation of all the states that the NEU state machine utilizes.
0000i NEU_START
2799This is the state that NEU enters when a hard or soft reset occurs or when Go has been de-asserted. This state can not left until the reset has been removed, Go has been asserted and it detects that the command controller has entered it's AWAIT_BUFF state. When this occurs the NEU enters the NEU_FILL_BUFF state.
0000ii NEU_FILL_BUFF
2800Before any compressed data can be decoded the NEU needs to fill up its buffer with new data from the SFU. The rest of the LBD waits while the NEU retrieves the first four frames from the previous line. Once completed it enters the NEU_HOLD state.
0000iii NEU_HOLD
2801The NEU waits in this state for one clock cycle while data requested from the SFU on the last access returns.
0000iv NEU_RUNNING
2802NEU_RUNNING controls the requesting of data from the SFU for the remainder of the line by pulsing lbd_sfu_pladvword when the LBD needs a new frame from the SFU. When the NEU has received all the word it needs for the current line, as denoted by the LineLength, the NEU enters the NEU_EMPTY state.
0000v NEU_EMPTY
2803NEU waits in this state while the rest of the LBD finishes outputting the completed line to the SFU. The NEU leaves this state when Go gets deasserted. This occurs when the end_of_line signal is detected from the LBD.
000024.3.9 Line Fill Unit Sub-block Description
2804The Line Fill Unit, LFU, is responsible for filling the next line buffer in the SFU. The SFU receives the data in blocks of sixteen bits. The LFU uses the color and a0 provided by the Command Controller and when it has put together a complete 16-bit frame, it is written out to the SFU. The LBD signals to the SFU that the data is valid by strobing the lbd_sfu_wdatavalid signal.
2805When the LFU is at the end of the line for the current line data it strobes lbd_sfu_advline to indicate to the SFU that the end of the line has occurred.
2806A dataflow block diagram of the line fill unit is shown in <figref idref="DRAWINGS">FIG. 154</figref>.
2807The dataflow above has the following blocks:
000024.3.9.1 State Machine
2808The following is an explanation of all the states that the LFU state machine utilizes.
0000i LFU_START
2809This is the state that the LFU enters when a hard or soft reset occurs or when Go has been de-asserted. This state can not left until the reset has been removed, Go has been asserted and it detects that a0 is no longer zero, this only occurs once the command controller start processing data from the Next Edge Unit, NEU.
0000ii LFU_NEW REG
2810LFU_NEW_REG is only entered at the beginning of a new frame. It can remain in this state on subsequent cycles if a whole frame is completed in one clock cycle. If the frame is completed the LFU will output the data to the SFU with the write enable signal. However if a frame is not completed in one clock cycle the state machine will change to the LFU_COMPLETE_REG state to complete the remainder of the frame. LFU_NEW_REG handles all the lbd_sfu_wdata writes and asserts lbd_sfu_wdatavalid as necessary.
0000iii LFU_COMPLETE_REG
2811LFU_COMPLETE_REG fills out all the remaining parts of the frame that were not completed in the first clock cycle. The command controller supplies the a0 value and the color and the state machine uses these to derive the limit and color_sel<sub>—</sub>16 bit_If which the line_fill_data block needs to construct a frame. Limit is the four lower significant bits of a0 and color_sel<sub>—</sub>16 bit_If is a 16-bit wide mask of sd_dolor. The state machine also maintains a check on the upper eleven bits of a0. If these increment from one clock cycle to the next that means that a frame is completed and the data can be written to the SFU. In the case of the LineLength being reached the Line Fill Unit fills out the remaining part of the frame with the color of the last bit in the line that was decoded.
000024.3.9.2 line_fill_data
2812line_fill_data takes the limit value and the color_sel<sub>—</sub>16 bit_If values and constructs the current frame that the command controller and the next edge unit are decoding. The following pseudo code illustrate the logic followed by the line_fill_data. work_sfu_wdata is exported by the LBD to the SFU as lbd_sfu_wdata.
2813<tables id="TABLE-US-00239" num="00239"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>if (lfu_state = = LFU_START) OR (lfu_state = =</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>LFU_NEW_REG) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>work_sfu_wdata = color_sel_16bit_lf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>work_sfu_wdata[(15 − limit) downto limit] =</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>color_sel_16bit_lf[(15 − limit) downto limit]</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 25 Spot FIFO Unit (SFU) <br /> 25.1 Overview
2814The Spot FIFO Unit (SFU) provides the means by which data is transferred between the LBD and the HCU. By abstracting the buffering mechanism and controls from both units, the interface is clean between the data user and the data generator. The amount of buffering can also be increased or decreased without affecting either the LBD or HCU. Scaling of data is performed in the horizontal and vertical directions by the SFU so that the output to the HCU matches the printer resolution. Non-integer scaling is supported in both the horizontal and vertical directions. Typically, the scale factor will be the same in both directions but may be programmed to be different.
000025.2 Main Features of the SFU
2815The SFU replaces the Spot Line Buffer Interface (SLBI) in PEC1. The spot line store is now located in DRAM.
2816The SFU outputs the previous line to the LBD, stores the next line produced by the LBD and outputs the HCU read line. Each interface to DRAM is via a feeder FIFO. The LBD interfaces to the SFU with a data width of 16 bits. The SFU interfaces to the HCU with a data width of 1 bit. Since the DRAM word width is 256-bits but the LBD line length is a multiple of 16 bits, a capability to flush the last multiples of 16-bits at the end of a line into a 256-bit DRAM word size is required. Therefore, SFU reads of DRAM words at the end of a line, which do not fill the DRAM word, will already be padded.
2817A signal sfu_lbd_rdy to the LBD indicates that the SFU is available for writing and reading. For the first LBD line after SFU Go has been asserted, previous line data is not supplied until after the first lbd_sfu_advline strobe from the LBD (zero data is supplied instead), and sfu_lbd_rdy to the LBD indicates that the SFU is available for writing. lbd_sfu_advline tells the SFU to advance to the next line. lbd_sfu_pladvword tells the SFU to supply the next 16-bits of previous line data. Until the number of lbd_sfu_pladvword strobes received is equivalent to the LBD line length, sfu_lbd_rdy indicates that the SFU is available for both reading and writing. Thereafter it indicates the SFU is available for writing. The LBD should not generate lbd_sfu_pladvword or lbd_sfu_advline strobes until sfu_lbd_rdy is asserted.
2818A signal sfu_hcu_avail indicates that the SFU has data to supply to the HCU. Another signal hcu_sfu_advdot, from the HCU, tells the SFU to supply the next dot. The HCU should not generate the hcu_sfu_advdot signal until sfu_hcu_avail is true. The HCU can therefore stall waiting for the sfu_hcu_avail signal.
2819X and Y non-integer scaling of the bi-level dot data is performed in the SFU.
2820At 1600 dpi the SFU requires 1 dot per cycle for all DRAM channels, 3 dots per cycle in total (read+read+write). Therefore the SFU requires two 256 bit read DRAM access per 256 cycles, 1 write access every 256 cycles. A single DIU read interface will be shared for reading the current and previous lines from DRAM.
000025.3 Bi-level Dram Memory Buffer Between LBD, SFU and HCU
2821<figref idref="DRAWINGS">FIG. 158</figref> shows a bi-level buffer store in DRAM. <figref idref="DRAWINGS">FIG. 158(</figref><i>a</i>) shows the LBD previous line address reading after the HCU read line address in DRAM. <figref idref="DRAWINGS">FIG. 158(</figref><i>b</i>) shows the LBD previous line address reading before the HCU read line address in DRAM.
2822Although the LBD and HCU read and write complete lines of data, the bi-level DRAM buffer is not line based. The buffering between the LBD, SFU and HCU is a FIFO of programmable size. The only line based concept is that the line the HCU is currently reading cannot be over-written because it may need to be re-read for scaling purposes.
2823The SFU interfaces to DRAM via three FIFOs: <ul id="ul0272" list-style="none"><li id="ul0272-0001" num="2824">a. The HCUReadLineFIFO which supplies dot data to the HCU.</li><li id="ul0272-0002" num="2825">b. The LBDNextLineFIFO which writes decompressed bi-level data from the LBD.</li><li id="ul0272-0003" num="2826">c. The LBDPrevLineFIFO which reads previous decompressed bi-level data for the LBD.</li></ul>
2827There are four address pointers used to manage the bi-level DRAM buffer: <ul id="ul0273" list-style="none"><li id="ul0273-0001" num="2828">a. hcu_readline_rd_adr[21:5] is the read address in DRAM for the HCUReadLineFIFO.</li><li id="ul0273-0002" num="2829">b. hcu_startreadline_adr[21:5] is the start address in DRAM for the current line being read by the HCUReadLineFIFO.</li><li id="ul0273-0003" num="2830">c. lbd_nextline_wr_adr[21:5] is the write address in DRAM for the LBDNextLineFIFO.</li><li id="ul0273-0004" num="2831">d. lbd_prevline_rd_adr[21:5] is the read address in DRAM for the LBDPrevLineFIFO.</li></ul>
2832The address pointers must obey certain rules which indicate whether they are valid: <ul id="ul0274" list-style="none"><li id="ul0274-0001" num="2833">a. hcu_readline_rd_adr is only valid if it is reading earlier in the line than lbd_nextline_wr_adr is writing i.e. the fifo is not empty</li><li id="ul0274-0002" num="2834">b. The SFU (lbd_nextline_wr_adr) cannot overwrite the current line that the HCU is reading from (hcu_startreadline_adr) i.e. the fifo is not full, when compared with the HCU read line pointer</li><li id="ul0274-0003" num="2835">c. The LBDNextLineFIFO (lbd_nextline_wr_adr) must be writing earlier in the line than LBDPrevLineFIFO (lbd_prevline_rd_adr) is reading and must not overwrite the current line that the HCU is reading from i.e. the fifo is not full when compared to the PrevLineFifo read pointer</li><li id="ul0274-0004" num="2836">d. The LBDPrevLineFIFO (lbd_prevline_rd_adr) can read right up to the address that LBDNextLineFIFO (lbd_nextline_wr_adr) is writing i.e the fifo is not empty.</li><li id="ul0274-0005" num="2837">e. At startup i.e. when sfu_go is asserted, the pointers are reset to start_sfu_adr[21:5].</li><li id="ul0274-0006" num="2838">f. The address pointers can wrap around the SFU bi-level store area in DRAM.</li></ul>
2839As a guideline, the typical FIFO size should be a minimum of 2 lines stored in DRAM, nominally 3 lines, up to a programmable number of lines. A larger buffer allows lines to be decompressed in advance. This can be useful for absorbing local complexities in compressed bi-level images.
000025.4 DRAM Access Requirements
2840The SFU has 1 read interface to the DIU and 1 write interface. The read interface is shared between the previous and current line read FIFOs.
2841The spot line store requires 5.1 Kbytes of DRAM to store 3 A4 lines. The SFU will read and write the spot line store in single 256-bit DRAM accesses. The SFU will need 256-bit double buffers for each of its previous, current and next line interfaces.
2842The SFU's DIU bandwidth requirements are summarized in Table 161.
2843<tables id="TABLE-US-00240" num="00240"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 161</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>DRAM bandwidth requirements</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="70pt" align="center" /><colspec colname="3" colwidth="63pt" align="center" /><colspec colname="4" colwidth="42pt" align="center" /><tbody valign="top"><row><entry /><entry>Maximum number of</entry><entry>Peak Bandwidth</entry><entry /></row><row><entry /><entry>cycles between</entry><entry>required to be</entry><entry>Average</entry></row><row><entry /><entry>each 256-bit</entry><entry>supported by</entry><entry>Bandwidth</entry></row><row><entry>Direction</entry><entry>DRAM access</entry><entry>DIU (bits/cycle)</entry><entry>(bits/cycle)</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>Read</entry><entry>1281</entry><entry>2</entry><entry>2</entry></row><row><entry>Write</entry><entry>2562</entry><entry>1</entry><entry>1</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry namest="1" nameend="4" align="left" id="FOO-00028">1: Two separate reads of 1 bit/cycle.</entry></row><row><entry namest="1" nameend="4" align="left" id="FOO-00029">2: Write at 1 bit/cycle.</entry></row></tbody></tgroup></table></tables><br /> 25.5 Scaling
2844Scaling of bi-level data is performed in both the horizontal and vertical directions by the SFU so that the output to the HCU matches the printer resolution. The SFU supports non-integer scaling with the scale factor represented by a numerator and a denominator. Only scaling up of the bi-level data is allowed, i.e. the numerator should be greater than or equal to the denominator. Scaling is implemented using a counter as described in the pseudocode below. An advance pulse is generated to move to the next dot (x-scaling) or line (y-scaling).
2845<tables id="TABLE-US-00241" num="00241"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>if (count + denominator >= numerator) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>count = (count + denominator) − numerator</entry></row><row><entry /><entry>advance = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>count = count + denominator</entry></row><row><entry /><entry>advance = 0</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2846X scaling controls whether the SFU supplies the next dot or a copy of the current dot when the HCU asserts hcu_sfu_advdot. The SFU counts the number of hcu_sfu_advdot signals from the HCU. When the SFU has supplied an entire HCU line of data, the SFU will either re-read the current line from DRAM or advance to the next line of HCU read data depending on the programmed Y scale factor.
2847An example of scaling for numerator=7 and denominator=3 is given in Table 162. The signal advance if asserted causes the next input dot to be output on the next cycle, otherwise the same input dot is output
2848<tables id="TABLE-US-00242" num="00242"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 162</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Non-integer scaling example for scaleNum = 7, scaleDenom = 3</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="98pt" align="center" /><colspec colname="2" colwidth="28pt" align="center" /><colspec colname="3" colwidth="91pt" align="center" /><tbody valign="top"><row><entry>count</entry><entry>advance</entry><entry>dot</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>0</entry><entry>0</entry><entry>1</entry></row><row><entry>3</entry><entry>0</entry><entry>1</entry></row><row><entry>6</entry><entry>1</entry><entry>1</entry></row><row><entry>2</entry><entry>0</entry><entry>2</entry></row><row><entry>5</entry><entry>1</entry><entry>2</entry></row><row><entry>1</entry><entry>0</entry><entry>3</entry></row><row><entry>4</entry><entry>1</entry><entry>3</entry></row><row><entry>0</entry><entry>0</entry><entry>4</entry></row><row><entry>3</entry><entry>0</entry><entry>4</entry></row><row><entry>6</entry><entry>1</entry><entry>4</entry></row><row><entry>2</entry><entry>0</entry><entry>5</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 25.6 Lead-in and Lead-out Clipping
2849To account for the case where there may be two SoPEC devices, each generating its own portion of a dot-line, the first dot in a line may not be replicated the total scale-factor number of times by an individual SoPEC. The dot will ultimately be scaled-up correctly with both devices doing part of the scaling, one on its lead-out and the other on its lead in. Scaled up dots on the lead-out, i.e. which go beyond the HCU linelength, will be ignored. Scaling on the lead-in, i.e. of the first valid dot in the line, is controlled by setting the XstartCount register.
2850At the start of each line count in the pseudo-code above is set to XstartCount. If there is no lead-in, XstartCount is set to 0 i.e. the first value of count in Table. If there is lead-in then XstartCount needs to be set to the appropriate value of count in the sequence above.
000025.7 Interfaces Between LDB, SFU and HCU
000025.7.1 LDB-SFU Interfaces
2851The LBD has two interfaces to the SFU. The LBD writes the next line to the SFU and reads the previous line from the SFU.
000025.7.1.1 LBDNextLineFIFO Interface
2852The LBDNextLineFIFO interface from the LBD to the SFU comprises the following signals: <ul id="ul0275" list-style="none"><li id="ul0275-0001" num="0000"><ul id="ul0276" list-style="none"><li id="ul0276-0001" num="2853">lbd_sfu_wdata, 16-bit write data.</li><li id="ul0276-0002" num="2854">lbd_sfu_wdatavalid, write data valid.</li><li id="ul0276-0003" num="2855">lbd_sfu_advline, signal indicating LDB has advanced to the next line.</li></ul></li></ul>
2856The LBD should not write to the SFU until sfu_lbd_rdy is true. The LBD can therefore stall waiting for the sfu_lbd_rdy signal.
000025.7.1.2 LBDPrevLineFIFO Interface
2857The LBDPrevLineFIFO interface from the SFU to the LBD comprises the following signals: <ul id="ul0277" list-style="none"><li id="ul0277-0001" num="0000"><ul id="ul0278" list-style="none"><li id="ul0278-0001" num="2858">sfu_lbd_pldata, 16-bit data.</li></ul></li></ul>
2859The previous line read buffer interface from the LBD to the SDU comprises the following signals: <ul id="ul0279" list-style="none"><li id="ul0279-0001" num="0000"><ul id="ul0280" list-style="none"><li id="ul0280-0001" num="2860">lbd_sfu_pladvword, signal indicating to the SFU to supply the next 16-bit word.</li></ul></li></ul>
2861lbd_sfu_advline, signal indicating LDB has advanced to the next line.
2862Previous line data is not supplied until after the first lbd_sfu_advline strobe from the LBD (zero data is supplied instead). The LBD should not assert lbd_sfu_pladvword unless sfu_lbd_rdy is asserted.
000025.7.1.3 Common Control Signals
2863sfu_lbd_rdy indicates to the LBD that the SFU is available for writing. After the first lbd_sfu_advline and before the number of lbd_sfu_pladvword strobes received is equivalent to the LBD line length, sfu_lbd_rdy indicates that the SFU is available for both reading and writing.
2864Thereafter it indicates the SFU is available for writing.
2865The LBD should not generate lbd_sfu_pladvword or lbd_sfu_advline strobes until sfu_lbd_rdy is asserted.
000025.7.2 SFU-HCU Current Line FIFO Interface
2866The interface from the SFU to the HCU comprises the following signals: <ul id="ul0281" list-style="none"><li id="ul0281-0001" num="0000"><ul id="ul0282" list-style="none"><li id="ul0282-0001" num="2867">sfu_hcu_sdata, 1-bit data.</li><li id="ul0282-0002" num="2868">sfu_hcu_avail, data valid signal indicating that there is data available in the SFU HCUReadLineFIFO.</li></ul></li></ul>
2869The interface from HCU to SFU comprises the following signals: <ul id="ul0283" list-style="none"><li id="ul0283-0001" num="0000"><ul id="ul0284" list-style="none"><li id="ul0284-0001" num="2870">hcu_sfu_advdot, indicating to the SFU to supply the next dot.</li></ul></li></ul>
2871The HCU should not generate the hcu_sfu_advdot signal until sfu_hcu_avail is true. The HCU can therefore stall waiting for the sfu_hcu_avail signal.
000025.8 Implementation
000025.8.1 Definitions of IO
2872<tables id="TABLE-US-00243" num="00243"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 163</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>SFU Port List</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="28pt" align="center" /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="84pt" align="left" /><tbody valign="top"><row><entry>Port Name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Clocks and Resets</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="28pt" align="char" char="." /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="84pt" align="left" /><tbody valign="top"><row><entry>Pclk</entry><entry>1</entry><entry>In</entry><entry>SoPEC Functional clock.</entry></row><row><entry>prst_n</entry><entry>1</entry><entry>In</entry><entry>Global reset signal.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>DIU Read Interface signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="28pt" align="char" char="." /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="84pt" align="left" /><tbody valign="top"><row><entry>sfu_diu_rreq</entry><entry>1</entry><entry>Out</entry><entry>SFU requests DRAM read.</entry></row><row><entry /><entry /><entry /><entry>A read request must be</entry></row><row><entry /><entry /><entry /><entry>accompanied by a valid</entry></row><row><entry /><entry /><entry /><entry>read address.</entry></row><row><entry>sfu_diu_radr[21:5]</entry><entry>17</entry><entry>Out</entry><entry>Read address to DIU</entry></row><row><entry /><entry /><entry /><entry>17 bits wide (256-bit</entry></row><row><entry /><entry /><entry /><entry>aligned word).</entry></row><row><entry>diu_sfu_rack</entry><entry>1</entry><entry>In</entry><entry>Acknowledge from DIU</entry></row><row><entry /><entry /><entry /><entry>that read request has</entry></row><row><entry /><entry /><entry /><entry>been accepted and new</entry></row><row><entry /><entry /><entry /><entry>read address can be</entry></row><row><entry /><entry /><entry /><entry>placed on sfu_diu_radr.</entry></row><row><entry>diu_data[63:0]</entry><entry>64</entry><entry>In</entry><entry>Data from DIU to SoPEC</entry></row><row><entry /><entry /><entry /><entry>Units.</entry></row><row><entry /><entry /><entry /><entry>First 64-bits are bits</entry></row><row><entry /><entry /><entry /><entry>63:0 of 256 bit word.</entry></row><row><entry /><entry /><entry /><entry>Second 64-bits are bits</entry></row><row><entry /><entry /><entry /><entry>127:64 of 256 bit word.</entry></row><row><entry /><entry /><entry /><entry>Third 64-bits are bits</entry></row><row><entry /><entry /><entry /><entry>191:128 of 256 bit word.</entry></row><row><entry /><entry /><entry /><entry>Fourth 64-bits are bits</entry></row><row><entry /><entry /><entry /><entry>255:192 of 256 bit word.</entry></row><row><entry>diu_sfu_rvalid</entry><entry>1</entry><entry>In</entry><entry>Signal from DIU telling</entry></row><row><entry /><entry /><entry /><entry>SoPEC Unit that valid</entry></row><row><entry /><entry /><entry /><entry>read data is on the</entry></row><row><entry /><entry /><entry /><entry>diu_data bus.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>DIU Write Interface signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="28pt" align="char" char="." /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="84pt" align="left" /><tbody valign="top"><row><entry>sfu_diu_wreq</entry><entry>1</entry><entry>Out</entry><entry>SFU requests DRAM write.</entry></row><row><entry /><entry /><entry /><entry>A write request must be</entry></row><row><entry /><entry /><entry /><entry>accompanied by a valid</entry></row><row><entry /><entry /><entry /><entry>write address together</entry></row><row><entry /><entry /><entry /><entry>with valid write data</entry></row><row><entry /><entry /><entry /><entry>and a write valid.</entry></row><row><entry>sfu_diu_wadr[21:5]</entry><entry>17</entry><entry>Out</entry><entry>Write address to DIU</entry></row><row><entry /><entry /><entry /><entry>17 bits wide (256-bit</entry></row><row><entry /><entry /><entry /><entry>aligned word).</entry></row><row><entry>diu_sfu_wack</entry><entry>1</entry><entry>In</entry><entry>Acknowledge from DIU</entry></row><row><entry /><entry /><entry /><entry>that write request has</entry></row><row><entry /><entry /><entry /><entry>been accepted and new</entry></row><row><entry /><entry /><entry /><entry>write address can be</entry></row><row><entry /><entry /><entry /><entry>placed on sfu_diu_wadr.</entry></row><row><entry>sfu_diu_data[63:0]</entry><entry>64</entry><entry>Out</entry><entry>Data from SFU to DIU.</entry></row><row><entry /><entry /><entry /><entry>First 64-bits are bits</entry></row><row><entry /><entry /><entry /><entry>63:0 of 256 bit word.</entry></row><row><entry /><entry /><entry /><entry>Second 64-bits are bits</entry></row><row><entry /><entry /><entry /><entry>127:64 of 256 bit word.</entry></row><row><entry /><entry /><entry /><entry>Third 64-bits are bits</entry></row><row><entry /><entry /><entry /><entry>191:128 of 256 bit word.</entry></row><row><entry /><entry /><entry /><entry>Fourth 64-bits are bits</entry></row><row><entry /><entry /><entry /><entry>255:192 of 256 bit word.</entry></row><row><entry>sfu_diu_wvalid</entry><entry>1</entry><entry>Out</entry><entry>Signal from PEP Unit</entry></row><row><entry /><entry /><entry /><entry>indicating that data on</entry></row><row><entry /><entry /><entry /><entry>sfu_diu_data is valid.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>PCU Interface data and control signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="28pt" align="char" char="." /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="84pt" align="left" /><tbody valign="top"><row><entry>pcu_adr[5:2]</entry><entry>4</entry><entry>In</entry><entry>PCU address bus. Only 4</entry></row><row><entry /><entry /><entry /><entry>bits are required to</entry></row><row><entry /><entry /><entry /><entry>decode the address space</entry></row><row><entry /><entry /><entry /><entry>for this block</entry></row><row><entry>pcu_dataout[31:0]</entry><entry>32</entry><entry>In</entry><entry>Shared write data bus</entry></row><row><entry /><entry /><entry /><entry>from the PCU</entry></row><row><entry>sfu_pcu_datain[31:0]</entry><entry>32</entry><entry>Out</entry><entry>Read data bus from the</entry></row><row><entry /><entry /><entry /><entry>SFU to the PCU</entry></row><row><entry>pcu_rwn</entry><entry>1</entry><entry>In</entry><entry>Common read/not-write</entry></row><row><entry /><entry /><entry /><entry>signal from the PCU</entry></row><row><entry>pcu_sfu_sel</entry><entry>1</entry><entry>In</entry><entry>Block select from the</entry></row><row><entry /><entry /><entry /><entry>PCU. When pcu_sfu_sel</entry></row><row><entry /><entry /><entry /><entry>is high both pcu_adr</entry></row><row><entry /><entry /><entry /><entry>and pcu_dataout are</entry></row><row><entry /><entry /><entry /><entry>valid</entry></row><row><entry>sfu_pcu_rdy</entry><entry>1</entry><entry>Out</entry><entry>Ready signal to the PCU.</entry></row><row><entry /><entry /><entry /><entry>When sfu_pcu_rdy is high</entry></row><row><entry /><entry /><entry /><entry>it indicates the last</entry></row><row><entry /><entry /><entry /><entry>cycle of the access. For</entry></row><row><entry /><entry /><entry /><entry>a write cycle this means</entry></row><row><entry /><entry /><entry /><entry>pcu_dataout has been</entry></row><row><entry /><entry /><entry /><entry>registered by the block</entry></row><row><entry /><entry /><entry /><entry>and for a read cycle this</entry></row><row><entry /><entry /><entry /><entry>means the data on</entry></row><row><entry /><entry /><entry /><entry>sfu_pcu_datain is valid.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>LBD Interface Data and Control Signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="28pt" align="char" char="." /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="84pt" align="left" /><tbody valign="top"><row><entry>sfu_lbd_rdy</entry><entry>1</entry><entry>Out</entry><entry>Signal indication that</entry></row><row><entry /><entry /><entry /><entry>SFU has previous line</entry></row><row><entry /><entry /><entry /><entry>data available and is</entry></row><row><entry /><entry /><entry /><entry>ready to be written to.</entry></row><row><entry>lbd_sfu_advline</entry><entry>1</entry><entry>In</entry><entry>Line advance signal for</entry></row><row><entry /><entry /><entry /><entry>both next and previous</entry></row><row><entry /><entry /><entry /><entry>lines.</entry></row><row><entry>lbd_sfu_pladvword</entry><entry>1</entry><entry>In</entry><entry>Advance word signal for</entry></row><row><entry /><entry /><entry /><entry>previous line buffer.</entry></row><row><entry>sfu_lbd_pldata[15:0]</entry><entry>16</entry><entry>Out</entry><entry>Data from the previous</entry></row><row><entry /><entry /><entry /><entry>line buffer.</entry></row><row><entry>lbd_sfu_wdata[15:0]</entry><entry>16</entry><entry>In</entry><entry>Write data for next line</entry></row><row><entry /><entry /><entry /><entry>buffer.</entry></row><row><entry>lbd_sfu_wdatavalid</entry><entry>1</entry><entry>In</entry><entry>Write data valid signal</entry></row><row><entry /><entry /><entry /><entry>for next line buffer data.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>HCU Interface Data and Control Signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="28pt" align="char" char="." /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="84pt" align="left" /><tbody valign="top"><row><entry>hcu_sfu_advdot</entry><entry>1</entry><entry>In</entry><entry>Signal indicating to the</entry></row><row><entry /><entry /><entry /><entry>SFU that the HCU is ready</entry></row><row><entry /><entry /><entry /><entry>to accept the next dot of</entry></row><row><entry /><entry /><entry /><entry>data from SFU.</entry></row><row><entry>sfu_hcu_sdata</entry><entry>1</entry><entry>Out</entry><entry>Bi-level dot data.</entry></row><row><entry>sfu_hcu_avail</entry><entry>1</entry><entry>Out</entry><entry>Signal indicating valid</entry></row><row><entry /><entry /><entry /><entry>bi-level dot data on</entry></row><row><entry /><entry /><entry /><entry>sfu_hcu_sdata.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 25.8.2 Configuration Registers
2873<tables id="TABLE-US-00244" num="00244"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="315pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 164</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>SFU Configuration Registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>Address</entry><entry /><entry>#</entry><entry>value on</entry><entry /></row><row><entry>(SFU_base +)</entry><entry>register name</entry><entry>bits</entry><entry>reset</entry><entry>description</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="315pt" align="left" /><tbody valign="top"><row><entry>Control registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="21pt" align="char" char="." /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>0x00</entry><entry>Reset</entry><entry>1</entry><entry>0x1</entry><entry>A write to this register causes a reset</entry></row><row><entry /><entry /><entry /><entry /><entry>of the SFU.</entry></row><row><entry /><entry /><entry /><entry /><entry>This register can be read to indicate</entry></row><row><entry /><entry /><entry /><entry /><entry>the reset state:</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - reset in progress</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - reset not in progress</entry></row><row><entry>0x04</entry><entry>Go</entry><entry>1</entry><entry>0x0</entry><entry>Writing 1 to this register starts the</entry></row><row><entry /><entry /><entry /><entry /><entry>SFU. Writing 0 to this register halts</entry></row><row><entry /><entry /><entry /><entry /><entry>the SFU.</entry></row><row><entry /><entry /><entry /><entry /><entry>When Go is deasserted the state-</entry></row><row><entry /><entry /><entry /><entry /><entry>machines go to their idle states but all</entry></row><row><entry /><entry /><entry /><entry /><entry>counters and configuration registers</entry></row><row><entry /><entry /><entry /><entry /><entry>keep their values.</entry></row><row><entry /><entry /><entry /><entry /><entry>When Go is asserted all counters are</entry></row><row><entry /><entry /><entry /><entry /><entry>reset, but configuration registers keep</entry></row><row><entry /><entry /><entry /><entry /><entry>their values (i.e. they don't get reset).</entry></row><row><entry /><entry /><entry /><entry /><entry>The SFU must be started before the</entry></row><row><entry /><entry /><entry /><entry /><entry>LBD is started.</entry></row><row><entry /><entry /><entry /><entry /><entry>This register can be read to determine</entry></row><row><entry /><entry /><entry /><entry /><entry>if the SFU is running</entry></row><row><entry /><entry /><entry /><entry /><entry>(1 - running, 0 - stopped).</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="315pt" align="left" /><tbody valign="top"><row><entry>Setup registers (constant for during processing the page)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="21pt" align="char" char="." /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>0x08</entry><entry>HCUNumDots</entry><entry>16</entry><entry>0x0000</entry><entry>Width of HCU line (in dots).</entry></row><row><entry>0x0C</entry><entry>HCUDRAMWords</entry><entry>8</entry><entry>0x00</entry><entry>Number of 256-bit DRAM words in a</entry></row><row><entry /><entry /><entry /><entry /><entry>HCU line − 1.</entry></row><row><entry>0x10</entry><entry>LBDDRAMWords</entry><entry>8</entry><entry>0x00</entry><entry>Number of 256-bit words in a LBD</entry></row><row><entry /><entry /><entry /><entry /><entry>line − 1.</entry></row><row><entry /><entry /><entry /><entry /><entry>(LBD line length must be at least 128</entry></row><row><entry /><entry /><entry /><entry /><entry>bits).</entry></row><row><entry>0x14</entry><entry>StartSfuAdr[21:5]</entry><entry>17</entry><entry>0x0000 0</entry><entry>First SFU location in memory.</entry></row><row><entry /><entry>(256-bit aligned</entry></row><row><entry /><entry>DRAM address)</entry></row><row><entry>0x18</entry><entry>EndSfuAdr[21:5]</entry><entry>17</entry><entry>0x0000 0</entry><entry>Last SFU location in memory.</entry></row><row><entry /><entry>(256-bit aligned</entry></row><row><entry /><entry>DRAM address)</entry></row><row><entry>0x1C</entry><entry>XstartCount</entry><entry>8</entry><entry>0x00</entry><entry>Value to be loaded at the start of</entry></row><row><entry /><entry /><entry /><entry /><entry>every line into the counter used for</entry></row><row><entry /><entry /><entry /><entry /><entry>scaling in the X direction. Used to</entry></row><row><entry /><entry /><entry /><entry /><entry>control the scaling of the first dot in a</entry></row><row><entry /><entry /><entry /><entry /><entry>line.</entry></row><row><entry /><entry /><entry /><entry /><entry>This value will typically equal zero,</entry></row><row><entry /><entry /><entry /><entry /><entry>except in the case where a number of</entry></row><row><entry /><entry /><entry /><entry /><entry>dots are clipped on the lead in to a</entry></row><row><entry /><entry /><entry /><entry /><entry>line. XstartCount must be programmed</entry></row><row><entry /><entry /><entry /><entry /><entry>to be less than the XscaleNum value.</entry></row><row><entry>0x20</entry><entry>XscaleNum</entry><entry>8</entry><entry>0x01</entry><entry>Numerator of spot data scale factor in</entry></row><row><entry /><entry /><entry /><entry /><entry>X direction.</entry></row><row><entry>0x24</entry><entry>XscaleDenom</entry><entry>8</entry><entry>0x01</entry><entry>Denominator of spot data scale factor</entry></row><row><entry /><entry /><entry /><entry /><entry>in X direction.</entry></row><row><entry>0x28</entry><entry>YscaleNum</entry><entry>8</entry><entry>0x01</entry><entry>Numerator of spot data scale factor in</entry></row><row><entry /><entry /><entry /><entry /><entry>Y direction.</entry></row><row><entry>0x2C</entry><entry>YscaleDenom</entry><entry>8</entry><entry>0x01</entry><entry>Denominator of spot data scale factor</entry></row><row><entry /><entry /><entry /><entry /><entry>in Y direction.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="315pt" align="left" /><tbody valign="top"><row><entry>Work registers (PCU has read-only access)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="21pt" align="char" char="." /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>0x30</entry><entry>HCUReadLineAdr[21:5]</entry><entry>17</entry><entry>—</entry><entry>Current address pointer in DRAM to</entry></row><row><entry /><entry>(256-bit aligned</entry><entry /><entry /><entry>HCU read data. Read only register.</entry></row><row><entry /><entry>DRAM address)</entry></row><row><entry>0x34</entry><entry>HCUStartReadLineAdr[21:5]</entry><entry>17</entry><entry>—</entry><entry>Start address in DRAM of line being</entry></row><row><entry /><entry>(256-bit aligned</entry><entry /><entry /><entry>read by HCU buffer in DRAM. Read</entry></row><row><entry /><entry>DRAM address)</entry><entry /><entry /><entry>only register.</entry></row><row><entry>0x38</entry><entry>LBDNextLineAdr[21:5]</entry><entry>17</entry><entry>—</entry><entry>Current address pointer in DRAM to</entry></row><row><entry /><entry>(256-bit aligned</entry><entry /><entry /><entry>LBD write data. Read only register</entry></row><row><entry /><entry>DRAM address)</entry></row><row><entry>0x3C</entry><entry>LBDPrevLineAdr[21:5]</entry><entry>17</entry><entry>—</entry><entry>Current address pointer in DRAM to</entry></row><row><entry /><entry>(256-bit aligned</entry><entry /><entry /><entry>LBD read data. Read only register</entry></row><row><entry /><entry>DRAM address)</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 25.8.3 SFU Sub-block Partition
2874The SFU contains a number of sub-blocks:
2875<tables id="TABLE-US-00245" num="00245"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="147pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>Name</entry><entry>description</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>PCU</entry><entry>PCU interface, configuration and status</entry></row><row><entry /><entry>Interface</entry><entry>registers. Also generates the Go and the</entry></row><row><entry /><entry /><entry>Reset signals for the rest of the SFU</entry></row><row><entry /><entry>LBD</entry><entry>Contains FIFO which is read by the LBD</entry></row><row><entry /><entry>Previous</entry><entry>previous line interface.</entry></row><row><entry /><entry>Line FIFO</entry></row><row><entry /><entry>LBD Next</entry><entry>Contains FIFO which is written by the LBD</entry></row><row><entry /><entry>Line FIFO</entry><entry>next line interface.</entry></row><row><entry /><entry>HCU Read</entry><entry>Contains FIFO which is read by the HCU</entry></row><row><entry /><entry>Line FIFO</entry><entry>interface.</entry></row><row><entry /><entry>DIU</entry><entry>Contains DIU read interface and DIU write</entry></row><row><entry /><entry>Interface</entry><entry>interface. Manages the address pointers for</entry></row><row><entry /><entry>and Address</entry><entry>the bi-level DRAM buffer. Contains X and Y</entry></row><row><entry /><entry>Generator</entry><entry>scaling logic.</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2876The various FIFO sub-blocks have no knowledge of where in DRAM their read or write data is stored. In this sense the FIFO sub-blocks are completely de-coupled from the bi-level DRAM buffer. All DRAM address management_is centralised in the DIU Interface and Address Generation sub-block. DRAM access is pre-emptive i.e. after a FIFO unit has made an access then as soon as the FIFO has space to read or data to write a DIU access will be requested immediately. This ensures there are no unnecessary stalls introduced e.g. at the end of an LBD or HCU line.
2877There now follows a description of the SFU sub-blocks.
000025.8.4 PCU Interface Sub-block
2878The PCU interface sub-block provides for the CPU to access SFU specific registers by reading or writing to the SFU address space.
000025.8.5 LBDPrevLineFIFO Sub-block
2879<tables id="TABLE-US-00246" num="00246"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 165</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>LBDPrevLineFIFO Additional IO Definitions</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>Port Name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Internal Output</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>plf_rdy</entry><entry>1</entry><entry>Out</entry><entry>Signal indicating LBDPrevLineFIFO</entry></row><row><entry /><entry /><entry /><entry>is ready to be read from. Until the</entry></row><row><entry /><entry /><entry /><entry>first lbd_sfu_advline for a band</entry></row><row><entry /><entry /><entry /><entry>has been received and after the number</entry></row><row><entry /><entry /><entry /><entry>of reads from DRAM for a line is</entry></row><row><entry /><entry /><entry /><entry>received is equal to LBDDRAMWords,</entry></row><row><entry /><entry /><entry /><entry>plf_rdy is always asserted. During</entry></row><row><entry /><entry /><entry /><entry>the second and subsequent lines</entry></row><row><entry /><entry /><entry /><entry>plf_rdy is deasserted whenever the</entry></row><row><entry /><entry /><entry /><entry>LBDPrevLineFIFO has one word left</entry></row><row><entry /><entry /><entry /><entry>in the FIFO..</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>DIU and Address Generation sub-block Signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>plf_diurreq</entry><entry>1</entry><entry>Out</entry><entry>Signal indicating the LBDPrevLineFIFO</entry></row><row><entry /><entry /><entry /><entry>has 256-bits of data free.</entry></row><row><entry>plf_diurack</entry><entry>1</entry><entry>In</entry><entry>Acknowledge that read request has</entry></row><row><entry /><entry /><entry /><entry>been accepted and plf_diurreq should</entry></row><row><entry /><entry /><entry /><entry>be de-asserted.</entry></row><row><entry>plf_diurdata</entry><entry>1</entry><entry>In</entry><entry>Data from the DIU to LBDPrevLineFIFO.</entry></row><row><entry /><entry /><entry /><entry>First 64-bits are bits 63:0 of 256</entry></row><row><entry /><entry /><entry /><entry>bit word.</entry></row><row><entry /><entry /><entry /><entry>Second 64-bits are bits 127:64 of</entry></row><row><entry /><entry /><entry /><entry>256 bit word.</entry></row><row><entry /><entry /><entry /><entry>Third 64-bits are bits 191:128 of</entry></row><row><entry /><entry /><entry /><entry>256 bit word.</entry></row><row><entry /><entry /><entry /><entry>Fourth 64-bits is are 255:192 of</entry></row><row><entry /><entry /><entry /><entry>256 bit word.</entry></row><row><entry>plf_diurrvalid</entry><entry>1</entry><entry>In</entry><entry>Signal indicating data on</entry></row><row><entry /><entry /><entry /><entry>plf_diurdata is valid.</entry></row><row><entry>plf_diuidle</entry><entry>1</entry><entry>Out</entry><entry>Signal indicating DIU state-machine</entry></row><row><entry /><entry /><entry /><entry>is in the IDLE state.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 25.8.5.1 General Description
2880The LBDPrevLineFIFO sub-block comprises a double 256-bit buffer between the LBD and the DIU Interface and Address Generator sub-block. The FIFO is implemented as 8 times 64-bit words. The FIFO is written by the DIU Interface and Address Generator sub-block and read by the LBD.
2881Whenever 4 locations in the FIFO are free the FIFO will request 256-bits of data from the DIU Interface and Address Generation sub-block by asserting plf_diurreq. A signal plf_diurack indicates that the request has been accepted and plf_diurreq should be de-asserted.
2882The data is written to the FIFO as 64-bits on plf_diurdata[63:0] over 4 clock cycles. The signal plf_diurvalid indicates that the data returned on plf_diurdata[63:0] is valid. plf_diurvalid is used to generate the FIFO write enable, write_en, and to increment the FIFO write address, write_adr[2:0]. If the LBDPrevLineFIFO still has 256-bits free then plf_diurreq should be asserted again.
2883The DIU Interface and Address Generation sub-block handles all address pointer management and DIU interfacing and decides whether to acknowledge a request for data from the FIFO.
2884The state diagram of the LBDPrevLineFIFO DIU Interface is shown in <figref idref="DRAWINGS">FIG. 163</figref>. If sfu_go is deasserted then the state-machine returns to its idle state.
2885The LBD reads 16-bit wide data from the LBDPrevLineFIFO on sfu_lbd_pldata[15:0]. lbd_sfu_pladvword from the LBD tells the LBDPrevLineFIFO to supply the next 16-bit word. The FIFO control logic generates a signal word_select which selects the next 16-bits of the 64-bit FIFO word to output on sfu_lbd_pldata[15:0]. When the entire current 64-bit FIFO word has been read by the LBD lbd_sfu_pladvword will cause the next word to be popped from the FIFO. Previous line data is not supplied until after the first lbd_sfu_advline strobe from the LBD after sfu_go is asserted (zero data is supplied instead). Until the first lbd_sfu_advline strobe after sfu_go lbd_sfu_pladvword strobes are ignored.
2886The LBDPrevLineFIFO control logic uses a counter, pl_count[7:0], to counts the number of DRAM read accesses for the line. When the pl_count counter is equal to the LBDDRAMWords, a complete line of data has been read by the LBD the plf_rdy is set high, and the counter is reset. It remains high until the next lbd_sfu_advline strobe from the LBD. On receipt of the lbd_sfu_advline strobe the remaining data in the 256-bit word in the FIFO is ignored, and the FIFO read_adr is rounded up if required.
2887The LBDPrevLineFIFO generates a signal plf_rdy to indicate that it has data available. Until the first lbd_sfu_advline for a band has been received and after the number of DRAM reads for a line is equal to LBDDRAMWords, plf_rdy is always asserted. During the second and subsequent lines plf_rdy is deasserted whenever the LBDPrevLineFIFO has one word left.
2888The last 256-bit word for a line read from DRAM can contain extra padding which should not be output to the LBD. This is because the number of 16-bit words per line may not fit exactly into a 256-bit DRAM word. When the count of the number of DRAM reads for a line is equal to lbd_dram_words the LBDPrevLineFIFO must adjust the FIFO write address to point to the next 256-bit word boundary in the FIFO for the next line of data. At the end of a line the read address must round up the nearest 256-bit word boundary and ignore the remaining 16-bit words. This can be achieved by considering the FIFO read address, read adr[2:0], will require 3 bits to address 8 locations of 64-bits. The next 256-bit aligned address is calculated by inverting the MSB of the read_adr and setting all other bits to 0. <ul id="ul0285" list-style="none"><li id="ul0285-0001" num="0000"><ul id="ul0286" list-style="none"><li id="ul0286-0001" num="2889">if (read_adr[1:0] /= b00 AND lbd_sfu_advline == 1)then <ul id="ul0287" list-style="none"><li id="ul0287-0001" num="2890">read_adr[1:0] = b00</li><li id="ul0287-0002" num="2891">read_adr[2] = ˜read_adr[2] <br /> 25.8.6 LBDNextLineFIFO Sub-block </li></ul></li></ul></li></ul>
2892<tables id="TABLE-US-00247" num="00247"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 166</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>LBDNextLineFIFO Additional IO Definition</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>Port Name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>LBDNextLineFIFO Interface Signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>nlf_rdy</entry><entry>1</entry><entry>Out</entry><entry>Signal indicating LBDNextLineFIFO is</entry></row><row><entry /><entry /><entry /><entry>ready to be written to i.e. there is</entry></row><row><entry /><entry /><entry /><entry>space in the FIFO.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>DIU and Address Generation sub-block Signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>nlf_diuwreq</entry><entry>1</entry><entry>Out</entry><entry>Signal indicating the LBDNextLineFIFO</entry></row><row><entry /><entry /><entry /><entry>has 256-bits of data for writing to</entry></row><row><entry /><entry /><entry /><entry>the DIU.</entry></row><row><entry>nlf_diuwack</entry><entry>1</entry><entry>In</entry><entry>Acknowledge from DIU that write</entry></row><row><entry /><entry /><entry /><entry>request has been accepted and write</entry></row><row><entry /><entry /><entry /><entry>data can be output on nlf_diuwdata</entry></row><row><entry /><entry /><entry /><entry>together with nlf_diuwvalid.</entry></row><row><entry>nlf_diuwdata</entry><entry>1</entry><entry>Out</entry><entry>Data from LBDNextLineFIFO to DIU</entry></row><row><entry /><entry /><entry /><entry>Interface.</entry></row><row><entry /><entry /><entry /><entry>First 64-bits is bits 63:0 of 256</entry></row><row><entry /><entry /><entry /><entry>bit word</entry></row><row><entry /><entry /><entry /><entry>Second 64-bits is bits 127:64 of</entry></row><row><entry /><entry /><entry /><entry>256 bit word</entry></row><row><entry /><entry /><entry /><entry>Third 64-bits is bits 191:128 of</entry></row><row><entry /><entry /><entry /><entry>256 bit word</entry></row><row><entry /><entry /><entry /><entry>Fourth 64-bits is bits 255:192 of</entry></row><row><entry /><entry /><entry /><entry>256 bit word</entry></row><row><entry>nlf_diuwvalid</entry><entry>1</entry><entry>In</entry><entry>Signal indicating that data on</entry></row><row><entry /><entry /><entry /><entry>wlf_diuwdata is valid.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 25.8.6.1 General Description
2893The LBDNextLineFIFO sub-block comprises a double 256-bit buffer between the LBD and the DIU Interface and Address Generator sub-block. The FIFO is implemented as 8 times 64-bit words. The FIFO is written by the LBD and read by the DIU Interface and Address Generator. Whenever 4 locations in the FIFO are full the FIFO will request 256-bits of data to be written to the DIU Interface and Address Generator by asserting nlf_diuwreq. A signal nlf_diuwack indicates that the request has been accepted and nlf_diuwreq should be de-asserted. On receipt of nlf_diuwack, the data is sent to the DIU Interface as 64-bits on nlf_diuwdata[63:0] over 4 clock cycles. The signal nlf_diuwvalid indicates that the data on nlf_diuwdata[63:0] is valid. nlf_diuwvalid should be asserted with the smallest latency after nlf_diuwack. If the LBDNextLineFIFO still has 256-bits more to transfer then nlf_diuwreq should be asserted again. The state diagram of the LBDNextLineFIFO DIU Interface is shown in <figref idref="DRAWINGS">FIG. 166</figref>. If sfu_go is deasserted then the state-machine returns to its Idle state.
2894The signal nlf_rdy indicates that the LBDNextLineFIFO has space for writing by the LBD. The LBD writes 16-bit wide data supplied on lbd_sfu_wdata[15:0]. lbd_sfu_wvalid indicates that the data is valid.
2895The LBDNextLineFIFO control logic counts the number of lbd_sfu_wvalid signals and is used to correctly address into the next line FIFO. The lbd_sfu_wvalid counter is rounded up to the nearest 256-bit word when a lbd_sfu_advline strobe is received from the LBD. Any data remaining in the FIFO is flushed to DRAM with padding being added to fill a complete 256-bit word.
000025.8.7 sfu_lbd_rdy Generation
2896The signal sfu_lbd_rdy is generated by ANDing plf_rdy from the LBDPrevLineFIFO and nlf_rdy from the LBDNextLineFIFO.
2897sfu_lbd_rdy indicates to the LBD that the SFU is available for writing i.e. there is space available in the LBDNextLineFIFO. After the first ibd_sfu_advline and before the number of lbd_sfu_pladvword strobes received is equivalent to the line length, sfu_lbd_rdy indicates that the SFU is available for both reading, i.e. there is data in the LBDPrevLineFIFO, and writing.
2898Thereafter it indicates the SFU is available for writing.
000025.8.8 LBD-SFU Interfaces Timing Waveform Description
2899In <figref idref="DRAWINGS">FIG. 167</figref> and <figref idref="DRAWINGS">FIG. 168</figref>, shows the timing of the data valid and ready signals between the SFU and LBD. A diagram and pseudocode is given for both read and write interfaces between the SFU and LBD.
000025.8.8.1 LBD-SFU Write Interface Timing
2900The main points to note from <figref idref="DRAWINGS">FIG. 167</figref> are: <ul id="ul0288" list-style="none"><li id="ul0288-0001" num="0000"><ul id="ul0289" list-style="none"><li id="ul0289-0001" num="2901">In clock cycle 1 sfu_lbd_rdy detects that it has only space to receive 2 more 16 bit words from the LBD after the current clock cycle.</li><li id="ul0289-0002" num="2902">The data on lbd_sfu_wdata is valid and this is indicated by lbd_sfu_wdatavalid being asserted.</li><li id="ul0289-0003" num="2903">In clock cycle 2 sfu_lbd_rdy is deasserted however the LBD can not react to this signal until clock cycle 3. So in clock cycle 3 there is also valid data from the LBD which consumes the last available location available in the FIFO in the SFU (FIFO free level is zero).</li><li id="ul0289-0004" num="2904">In clock cycle 4 and 5 the FIFO is read and 2 words become free in the FIFO.</li><li id="ul0289-0005" num="2905">In cycle 4 the SFU determines that the FIFO has more room and asserts the ready signal on the next cycle.</li><li id="ul0289-0006" num="2906">The LBD has entered a pause mode and waits for sfu_lbd_rdy to be asserted again, in cycle 5 the LBD sees the asserted ready signal and responds by writing one unit into the FIFO, in cycle 6.</li><li id="ul0289-0007" num="2907">The SFU detects it has 2 spaces left in the FIFO and the current cycle is an active write (same as in cycle 1), and deasserts the ready on the next cycle.</li><li id="ul0289-0008" num="2908">In cycle 7 the LBD did not have data to write into the FIFO, and so the FIFO remains with one space left</li><li id="ul0289-0009" num="2909">The SFU toggles the ready signal every second cycle, this allows the LBD to write one unit at a time to the FIFO.</li><li id="ul0289-0010" num="2910">In cycle 9 the LBD responds to the single ready pulse by writing into the FIFO and consuming the last remaining unit free.</li></ul></li></ul>
2911The write interface pseudocode for generating the ready is.
2912<tables id="TABLE-US-00248" num="00248"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>// ready generation pseudocode</entry></row><row><entry /><entry>if (fifo_free_level > 2) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>nlf_rdy = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (fifo_free_level = = 2) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>if (lbd_sfu_wdatavalid = = 1)then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>nlf_rdy = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>nlf_rdy = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (fifo_free_level = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>if (lbd_sfu_wdatavalid = = 1)then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>nlf_rdy = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>nlf_rdy = NOT(sfu_lbd_rdy)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="119pt" align="left" /><tbody valign="top"><row><entry /><entry>nlf_rdy</entry><entry>= 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>sfu_lbd_rdy = (nlf_rdy AND plf_rdy)</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 25.8.8.2 SFU-LBD Read Interface
2913The read interface is similar to the write interface except that read data (sfu_lbd_pldata) takes an extra cycle to respond to the data advance signal (lbd_sfu_pladvword signal).
2914It is not possible to read the FIFO totally empty during the processing of a line, one word must always remain in the FIFO. At the end of a line the fifo can be read to totally empty. This functionality is controlled by the SFU with the generation of the plf_signal.
2915There is an apparent corner case on the read side which should be highlighted. On examination this turns out to not be an issue.
0000Scenario 1:
0000<ul id="ul0290" list-style="none"><li id="ul0290-0001" num="0000"><ul id="ul0291" list-style="none"><li id="ul0291-0001" num="2916">sfu_lbd_rdy will go low when there is still is still 2 pieces of data in the FIFO. If there is a lbd_sfu_pladvword pulse in the next cycle the data will appear on sfu_lbd_pldata[15:0]. <br /> Scenario 2: </li><li id="ul0291-0002" num="2917">sfu_lbd_rdy will go low when there is still 2 pieces of data in the FIFO. If there is no lbd_sfu_pladvword pulse in the next cycle and it is not the end of the page then the SFU will read the data for the next line from DRAM and the read FIFO will fill more, sfu_lbd_rdy will assert again, and so the data will appear on sfu_lbd_pldata[15:0]. If it happens that the next line of data is not available yet the sfu_lbd_pldata bus will go invalid until the next lines data is available. The LBD does not sample the sfu_lbd_pldata bus at this time (i.e. after the end of a line) and it is safe to have invalid data on the bus. <br /> Scenario 3: </li><li id="ul0291-0003" num="2918">sfu_lbd_rdy will go low when there is still 2 pieces of data in the FIFO. If there is no lbd_sfu_pladvword pulse in the next cycle and it is the end of the page then the SFU will do no more reads from DRAM, sfu_lbd_rdy will remain de-asserted, and the data will not be read out from the FIFO. However last line of data on the page is not needed for decoding in the LBD and will not be read by the LBD. So scenario 3 will never apply.</li></ul></li></ul>
2919The pseudocode for the read FIFO ready generation
2920<tables id="TABLE-US-00249" num="00249"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>// ready generation pseudocode</entry></row><row><entry /><entry>if (pl_count = = lbd_dram_words) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>plf_rdy = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (fifo_fill_level > 3)then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>plf_rdy = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (fifo_fill_level = = 3) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>if (lbd_sfu_pladvword = = 1)then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>plf_rdy = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>plf_rdy = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (fifo_fill_level = = 2) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>if (lbd_sfu_pladvword = = 1)then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>plf_rdy = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>plf_rdy = NOT(sfu_lbd_rdy)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>plf_rdy = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>sfu_lbd_rdy = (plf_rdy AND nlf_rdy)</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 25.8.9 HCUReadLineFIFO Sub-block
2921<tables id="TABLE-US-00250" num="00250"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 167</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>HCUReadLineFIFO Additional IO Definition</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="98pt" align="left" /><tbody valign="top"><row><entry>Port Name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>DIU and Address Generation sub-block Signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="98pt" align="left" /><tbody valign="top"><row><entry>hrf_xadvance</entry><entry>1</entry><entry>In</entry><entry>Signal from horizontal</entry></row><row><entry /><entry /><entry /><entry>scaling unit</entry></row><row><entry /><entry /><entry /><entry>1 - supply the next dot</entry></row><row><entry /><entry /><entry /><entry>1 - supply the current dot</entry></row><row><entry>hrf_hcu_endofline</entry><entry>1</entry><entry>Out</entry><entry>Signal lasting 1 cycle</entry></row><row><entry /><entry /><entry /><entry>indicating then end of the</entry></row><row><entry /><entry /><entry /><entry>HCU read line.</entry></row><row><entry>hrf_diurreq</entry><entry>1</entry><entry>Out</entry><entry>Signal indicating the</entry></row><row><entry /><entry /><entry /><entry>HCUReadLineFIFO has space</entry></row><row><entry /><entry /><entry /><entry>for 256-bits of DIU data.</entry></row><row><entry>hrf_diurack</entry><entry>1</entry><entry>In</entry><entry>Acknowledge that read</entry></row><row><entry /><entry /><entry /><entry>request has been accepted</entry></row><row><entry /><entry /><entry /><entry>and hrf_diurreq should be</entry></row><row><entry /><entry /><entry /><entry>de-asserted.</entry></row><row><entry>hrf_diurdata</entry><entry>1</entry><entry>In</entry><entry>Data from HCUReadLineFIFO</entry></row><row><entry /><entry /><entry /><entry>to DIU.</entry></row><row><entry /><entry /><entry /><entry>First 64-bits are bits</entry></row><row><entry /><entry /><entry /><entry>63:0 of 256 bit word.</entry></row><row><entry /><entry /><entry /><entry>Second 64-bits are bits</entry></row><row><entry /><entry /><entry /><entry>127:64 of 256 bit word.</entry></row><row><entry /><entry /><entry /><entry>Third 64-bits are bits</entry></row><row><entry /><entry /><entry /><entry>191:128 of 256 bit word.</entry></row><row><entry /><entry /><entry /><entry>Fourth 64-bits are bits</entry></row><row><entry /><entry /><entry /><entry>255:192 of 256 bit word.</entry></row><row><entry>hrf_diurvalid</entry><entry>1</entry><entry>In</entry><entry>Signal indicating data on</entry></row><row><entry /><entry /><entry /><entry>hrf_diurdata is valid.</entry></row><row><entry>hrf_diuidle</entry><entry>1</entry><entry>Out</entry><entry>Signal indicating DIU</entry></row><row><entry /><entry /><entry /><entry>state-machine is in the</entry></row><row><entry /><entry /><entry /><entry>IDLE state.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 25.8.9.1 General Description
2922The HCUReadLineFIFO sub-block comprises a double 256-bit buffer between the HCU and the DIU Interface and Address Generator sub-block. The FIFO is implemented as 8 times 64-bit words. The FIFO is written by the DIU Interface and Address Generator sub-block and read by the HCU.
2923The DIU Interface and Address Generation (DAG) sub-block interface of the HCUReadLineFIFO is identical to the LBDPrevLineFIFO DIU interface.
2924Whenever 4 locations in the FIFO are free the FIFO will request 256-bits of data from the DAG sub-block by asserting hrf_diurreq. A signal hrf_diurack indicates that the request has been accepted and hrf_diurreq should be de-asserted.
2925The data is written to the FIFO as 64-bits on hrf_diurdata[63:0] over 4 clock cycles. The signal hrf_diurvalid indicates that the data returned on hrf_diurdata[63:0] is valid. hrf_diurvalid is used to generate the FIFO write enable, write_en, and to increment the FIFO write address, write_adr[2:0]. If the HCUReadLineFIFO still has 256-bits free then hrf_diurreq should be asserted again.
2926The HCUReadLineFIFO generates a signal sfu_hcu_avail to indicate that it has data available for the HCU. The HCU reads single-bit data supplied on sfu_hcu_sdata. The FIFO control logic generates a signal bit select which selects the next bit of the 64-bit FIFO word to output on sfu_hcu_sdata. The signal hcu_sfu_advdot tells the HCUReadLineFIFO to supply the next dot (hrf_xadvance=1) or the current dot (hrf_xadvance=0) on sfu_hcu_sdata according to the hrf_xadvance signal from the scaling control unit in the DAG sub-block. The HCU should not generate the hcu_sfu_advdot signal until sfu_hcu_avail is true. The HCU can therefore stall waiting for the sfu_hcu_avail signal.
2927When the entire current 64-bit FIFO word has been read by the HCU hcu_sfu_advdot will cause the next word to be popped from the FIFO.
2928The last 256-bit word for a line read from DRAM and written into the HCUReadLineFIFO can contain dots or extra padding which should not be output to the HCU. A counter in the HCUReadLineFIFO, hcuadvdot_count[15:0], counts the number of hcu_sfu_advdot strobes received from the HCU. When the count equals hcu_num_dots[15:0] the HCUReadLineFIFO must adjust the FIFO read address to point to the next 256-bit word boundary in the FIFO. This can be achieved by considering the FIFO read address, read adr[2:0], will require 3 bits to address 8 locations of 64-bits. The next 256-bit aligned address is calculated by inverting the MSB of the read_adr and setting all other bits to 0.
2929<tables id="TABLE-US-00251" num="00251"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>If (hcuadvdot_count = = hcu_num_dots) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>read_adr[1:0] = b00</entry></row><row><entry /><entry>read_adr[2] = ~read_adr[2]</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2930The DIU Interface and Address Generator sub-block scaling unit also needs to know when hcuadvdot_count equals hcu_num_dots. This condition is exported from the HCUReadLineFIFO as the signal hrf_hcu_endofline. When the hrf_hcu_endofline is asserted the scaling unit will decide based on vertical scaling whether to go back to the start of the current line or go onto the next line.
000025.8.9.2 DRAM Access Limitation
2931The SFU must output 1 bit/cycle to the HCU. Since HCUNumDots may not be a multiple of 256 bits the last 256-bit DRAM word on the line can contain extra zeros. In this case, the SFU may not be able to provide 1 bit/cycle to the HCU. This could lead to a stall by the SFU. This stall could then propagate if the margins being used by the HCU are not sufficient to hide it. The maximum stall can be estimated by the calculation: DRAM service period—X scale factor * dots used from last DRAM read for HCU line.
25.8.10 DIU
2932Interface and Address Generator Sub-block
2933<tables id="TABLE-US-00252" num="00252"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 168</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>DIU Interface and Address Generator Additional IO Description</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="98pt" align="left" /><tbody valign="top"><row><entry>Port name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Internal LBDPrevLineFIFO Inputs</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="98pt" align="left" /><tbody valign="top"><row><entry>plf_diurreq</entry><entry>1</entry><entry>In</entry><entry>Signal indicating the</entry></row><row><entry /><entry /><entry /><entry>LBDPrevLineFIFO has</entry></row><row><entry /><entry /><entry /><entry>256-bits of data free.</entry></row><row><entry>plf_diurack</entry><entry>1</entry><entry>Out</entry><entry>Acknowledge that read</entry></row><row><entry /><entry /><entry /><entry>request has been accepted</entry></row><row><entry /><entry /><entry /><entry>and plf_diurreq should</entry></row><row><entry /><entry /><entry /><entry>be de-asserted.</entry></row><row><entry>plf_diurdata</entry><entry>1</entry><entry>Out</entry><entry>Data from the DIU to</entry></row><row><entry /><entry /><entry /><entry>LBDPrevLineFIFO.</entry></row><row><entry /><entry /><entry /><entry>First 64-bits are bits</entry></row><row><entry /><entry /><entry /><entry>63:0 of 256 bit word</entry></row><row><entry /><entry /><entry /><entry>Second 64-bits are bits</entry></row><row><entry /><entry /><entry /><entry>127:64 of 256 bit word</entry></row><row><entry /><entry /><entry /><entry>Third 64-bits are bits</entry></row><row><entry /><entry /><entry /><entry>191:128 of 256 bit word</entry></row><row><entry /><entry /><entry /><entry>Fourth 64-bits are bits</entry></row><row><entry /><entry /><entry /><entry>255:192 of 256 bit word</entry></row><row><entry>plf_diurrvalid</entry><entry>1</entry><entry>Out</entry><entry>Signal indicating data on</entry></row><row><entry /><entry /><entry /><entry>plf_diurdata is valid.</entry></row><row><entry>plf_diuidle</entry><entry>1</entry><entry>In</entry><entry>Signal indicating DIU</entry></row><row><entry /><entry /><entry /><entry>state-machine is in the</entry></row><row><entry /><entry /><entry /><entry>IDLE state.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Internal LBDNextLineFIFO Inputs</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="98pt" align="left" /><tbody valign="top"><row><entry>nlf_diuwreq</entry><entry>1</entry><entry>In</entry><entry>Signal indicating the</entry></row><row><entry /><entry /><entry /><entry>LBDNextLineFIFO has</entry></row><row><entry /><entry /><entry /><entry>256-bits of data for</entry></row><row><entry /><entry /><entry /><entry>writing to the DIU.</entry></row><row><entry>nlf_diuwack</entry><entry>1</entry><entry>Out</entry><entry>Acknowledge from DIU</entry></row><row><entry /><entry /><entry /><entry>that write request has</entry></row><row><entry /><entry /><entry /><entry>been accepted and write</entry></row><row><entry /><entry /><entry /><entry>data can be output on</entry></row><row><entry /><entry /><entry /><entry>nlf_diuwdata together</entry></row><row><entry /><entry /><entry /><entry>with nlf_diuwvalid.</entry></row><row><entry>nlf_diuwdata</entry><entry>1</entry><entry>In</entry><entry>Data from LBDNextLineFIFO</entry></row><row><entry /><entry /><entry /><entry>to DIU Interface.</entry></row><row><entry /><entry /><entry /><entry>First 64-bits are bits</entry></row><row><entry /><entry /><entry /><entry>63:0 of 256 bit word</entry></row><row><entry /><entry /><entry /><entry>Second 64-bits are bits</entry></row><row><entry /><entry /><entry /><entry>127:64 of 256 bit word</entry></row><row><entry /><entry /><entry /><entry>Third 64-bits are bits</entry></row><row><entry /><entry /><entry /><entry>191:128 of 256 bit word</entry></row><row><entry /><entry /><entry /><entry>Fourth 64-bits are bits</entry></row><row><entry /><entry /><entry /><entry>255:192 of 256 bit word</entry></row><row><entry>nlf_diuwvalid</entry><entry>1</entry><entry>In</entry><entry>Signal indicating that data</entry></row><row><entry /><entry /><entry /><entry>on wlf_diuwdata is valid.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Internal HCUReadLineFIFO Inputs</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="98pt" align="left" /><tbody valign="top"><row><entry>hrf_hcu_endofline</entry><entry>1</entry><entry>In</entry><entry>Signal lasting 1 cycle</entry></row><row><entry /><entry /><entry /><entry>indicating then end of the</entry></row><row><entry /><entry /><entry /><entry>HCU read line.</entry></row><row><entry>hrf_xadvance</entry><entry>1</entry><entry>Out</entry><entry>Signal from horizontal</entry></row><row><entry /><entry /><entry /><entry>scaling unit</entry></row><row><entry /><entry /><entry /><entry>1 - supply the next dot</entry></row><row><entry /><entry /><entry /><entry>1 - supply the current dot</entry></row><row><entry>hrf_diurreq</entry><entry>1</entry><entry>In</entry><entry>Signal indicating the</entry></row><row><entry /><entry /><entry /><entry>HCUReadLineFIFO has space</entry></row><row><entry /><entry /><entry /><entry>for 256-bits of DIU data.</entry></row><row><entry>hrf_diurack</entry><entry>1</entry><entry>Out</entry><entry>Acknowledge that read</entry></row><row><entry /><entry /><entry /><entry>request has been accepted</entry></row><row><entry /><entry /><entry /><entry>and hrf_diurreq should be</entry></row><row><entry /><entry /><entry /><entry>de-asserted.</entry></row><row><entry>hrf_diurdata</entry><entry>1</entry><entry>Out</entry><entry>Data from HCUReadLineFIFO</entry></row><row><entry /><entry /><entry /><entry>to DIU.</entry></row><row><entry /><entry /><entry /><entry>First 64-bits are bits</entry></row><row><entry /><entry /><entry /><entry>63:0 of 256 bit word</entry></row><row><entry /><entry /><entry /><entry>Second 64-bits are bits</entry></row><row><entry /><entry /><entry /><entry>127:64 of 256 bit word</entry></row><row><entry /><entry /><entry /><entry>Third 64-bits are bits</entry></row><row><entry /><entry /><entry /><entry>191:128 of 256 bit word</entry></row><row><entry /><entry /><entry /><entry>Fourth 64-bits are bits</entry></row><row><entry /><entry /><entry /><entry>255:192 of 256 bit word</entry></row><row><entry>hrf_diurvalid</entry><entry>1</entry><entry>Out</entry><entry>Signal indicating data on</entry></row><row><entry /><entry /><entry /><entry>plf_diurdata is valid.</entry></row><row><entry>hrf_diuidle</entry><entry>1</entry><entry>In</entry><entry>Signal indicating DIU</entry></row><row><entry /><entry /><entry /><entry>state-machine is in the</entry></row><row><entry /><entry /><entry /><entry>IDLE state.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 25.8.10.1 General Description
2934The DIU Interface and Address Generator (DAG) sub-block manages the bi-level buffer in DRAM. It has a DIU Write Interface for the LBDNextLineFIFO and a DIU Read Interface shared between the HCUReadLineFIFO and LBDPrevLineFIFO.
2935All DRAM address management is centralised in the DAG. DRAM access is pre-emptive i.e. after a FIFO unit has made an access then as soon as the FIFO has space to read or data to write a DIU access will be requested immediately. This ensures there are no unnecessary stalls introduced e.g. at the end of an LBD or HCU line.
2936The control logic for horizontal and vertical non-integer scaling logic is completely contained in the DAG sub-block. The scaling control unit exports the hlf_xadvance signal to the HCUReadLineFIFO which indicates whether to replicate the current dot or supply the next dot for horizontal scaling.
000025.8.10.2 DIU Write Interface
2937The LBDNextLineFIFO generates all the DIU write interface signals directly except for sfu_diu_wadr[21:5] which is generated by the Address Generation logic The DIU request from the LBDNextLineFIFO will be negated if its respective address pointer in DRAM is invalid i.e. nlf_adrvalid=0. The implementation must ensure that no erroneous requests occur on sfu_diu_wreq.
000025.8.10.3 DIU Read Interface
2938Both HCUReadLineFIFO and LBDPrevLineFIFO share the read interface. If both sources request simultaneously, then the arbitration logic implements a round-robin sharing of read accesses between the HCUReadLineFIFO and LBDPrevLineFIFO.
2939The DIU read request arbitration logic generates a signal, select_hrfplf, which indicates whether the DIU access is from the HCUReadLineFIFO or LBDPrevLineFIFO (0=HCUReadLineFIFO, 1=LBDPrevLineFIFO). <figref idref="DRAWINGS">FIG. 171</figref> shows select_hrfplf multiplexing the returned DIU acknowledge and read data to either the HCUReadLineFIFO or LBDPrevLineFIFO.
2940The DIU read request arbitration logic is shown in <figref idref="DRAWINGS">FIG. 172</figref>. The arbitration logic will select a DIU read request on hrf_diurreq or plf_diurreq and assert sfu_diu_rreq which goes to the DIU. The accompanying DIU read address is generated by the Address Generation Logic. The select signal select_hrfplf will be set according to the arbitration winner (0=HCUReadLineFIFO, 1=LBDPrevLineFIFO). sfu_diu_rreq is cleared when the DIU acknowledges the request on diu_sfu_rack. Arbitration cannot take place again until the DIU state-machine of the arbitration winner is in the idle state, indicated by diu_idle. This is necessary to ensure that the DIU read data is multiplexed back to the FIFO that requested it.
2941The DIU read requests from the HCUReadLineFIFO and LBDPrevLineFIFO will be negated if their respective addresses in DRAM are invalid, hrf_adrvalid=0 or plf_adrvalid=0. The implementation must ensure that no erroneous requests occur on sfu_diu_rreq.
2942If the HCUReadLineFIFO and LBDPrevLineFIFO request simultaneously, then if the request is not following immediately another DIU read port access, the arbitration logic will choose the HCUReadLineFIFO by default. If there are back to back requests to the DIU read port then the arbitration logic implements a round-robin sharing of read accesses between the HCUReadLineFIFO and LBDPrevLineFIFO.
2943A pseudo-code description of the DIU read arbitration is given below.
2944<tables id="TABLE-US-00253" num="00253"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>// history is of type {none, hrf, plf}, hrf is</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>HCUReadLineFIFO, plf is LBDPrevLineFIFO</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// initialisation on reset</entry></row><row><entry /><entry>select_hrfplf = 0 // default choose hrf</entry></row><row><entry /><entry>history = none // no DIU read access immediately preceding</entry></row><row><entry /><entry>// state-machine is busy between asserting sfu_diu_rreq</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>and diu_idle = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// if DIU read requester state-machine is in idle state</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>then de-assert busy</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>if (diu_idle = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>busy = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>//if acknowledge received from DIU then de-assert DIU</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>request</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>if (diu_sfu_rack = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>//de-assert request in response to acknowledge</entry></row><row><entry /><entry>sfu_diu_rreq = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// if not busy then arbitrate between incoming requests</entry></row><row><entry /><entry>// if request detected then assert busy</entry></row><row><entry /><entry>if (busy = = 0) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>//if there is no request</entry></row><row><entry /><entry>if (hrf_diurreq = = 0) AND (plf_diurreq = = 0) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>sfu_diu_rreq = 0</entry></row><row><entry /><entry>history = none</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>// else there is a request</entry></row><row><entry /><entry>else {</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>// assert busy and request DIU read access</entry></row><row><entry /><entry>busy = 1</entry></row><row><entry /><entry>sfu_diu_rreq = 1</entry></row><row><entry /><entry>// arbitrate in round-robin fashion between</entry></row><row><entry /><entry>the</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>requestors</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>// if only HCUReadLineFIFO requesting choose</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>HCUReadLineFIFO</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>if (hrf_diurreq = = 1) AND (plf_diurreq = = 0) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>history = hrf</entry></row><row><entry /><entry>select_hrfplf = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>// if only LBDPrevLineFIFO requesting choose</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>LBDPrevLineFIFO</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>if (hrf_diurreq = = 0) AND (plf_diurreq = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>history = plf</entry></row><row><entry /><entry>select_hrfplf = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>//if both HCUReadLineFIFO and LBDPrevLineFIFO</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>requesting</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>if (hrf_diurreq = = 1) AND (plf_diurreq = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>// no immediately preceding request</entry></row><row><entry /><entry>choose</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>HCUReadLineFIFO</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>if (history = = none) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="84pt" align="left" /><colspec colname="1" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>history = hrf</entry></row><row><entry /><entry>select_hrfplf = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>// if previous winner was</entry></row><row><entry /><entry>HCUReadLineFIFO choose</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>LBDPrevLineFIFO</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (history = = hrf) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="84pt" align="left" /><colspec colname="1" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>history = plf</entry></row><row><entry /><entry>select_hrfplf = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>// if previous winner was</entry></row><row><entry /><entry>LBDPrevLineFIFO choose</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>HCUReadLineFIFO</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (history = = plf) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="84pt" align="left" /><colspec colname="1" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>history = hrf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>select_hrfplf = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>// end there is a request</entry></row><row><entry /><entry>}</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 25.8.10.4 Address Generation Logic
2945The DIU interface generates the DRAM addresses of data read and written by the SFU's FIFOs.
2946A write request from the LBDNextLineFIFO on nlf_diuwreq causes a write request from the DIU Write Interface. The Address Generator supplies the DRAM write address on sfu_diu_wadr[21:5]A winning read request from the DIU read request arbitration logic causes a read request from the DIU Read Interface. The Address Generator supplies the DRAM read address on sfu_diu_radr[21:5].
2947The address generator is configured with the number of DRAM words to read in a HCU line, hcu_dram_words, the first DRAM address of the SFU area, start_sfu_adr[21:5], and the last DRAM address of the SFU area, end_sfu_adr[21:5].
2948Note hcu_dram_words configuration register specifies the the number of DRAM words consumed per line in the HCU, while lbd_dram_words specifies the number of DRAM words generated per line by the LBD. These values are not required to be the same.
2949For example the LBD may store 10 DRAM words per line (lbd_dram_words=10), but the HCU may consume 5 DRAM words per line. In such case the hcu_dram_words would be set to 5 and the HCU Read Line FIFO would trigger a new line after it had consumed 5 DRAM words (via hrf_hcu_endofline).
0000Address Generation
2950There are four address pointers used to manage the bi-level DRAM buffer: <ul id="ul0292" list-style="none"><li id="ul0292-0001" num="2951">a. hcu_readline_rd_adr is the read address in DRAM for the HCUReadLineFIFO.</li><li id="ul0292-0002" num="2952">b. hcu_startreadline_adr is the start address in DRAM for the current line being read by the HCUReadLineFIFO.</li><li id="ul0292-0003" num="2953">c. lbd_nextline_wr_adr is the write address in DRAM for the LBDNextLineFIFO.</li><li id="ul0292-0004" num="2954">d. lbd_prevline_rd_adr is the read address in DRAM for the LBDPrevLineFIFO.</li></ul>
2955The current value of these address pointers are readable by the CPU.
2956Four corresponding address valid flags are required to indicate whether the address pointers are valid, based on whether the FIFOs are full or empty. <ul id="ul0293" list-style="none"><li id="ul0293-0001" num="2957">a. hlf_adrvalid, derived from hrf_nlf_fifo_emp</li><li id="ul0293-0002" num="2958">b. hlf_start_adrvalid, derived from start_hrd_nlf_fifo_emp</li><li id="ul0293-0003" num="2959">c. nlf_adrvalid. derived from nlf_plf_fifo_full and nlf_hrf_fifo_full</li><li id="ul0293-0004" num="2960">d. plf_adrvalid. derived from plf_nlf_fifo_emp</li></ul>
2961DRAM requests from the FIFOs will not be issued to the DIU until the appropriate address flag is valid.
2962Once a request has been acknowledged, the address generation logic can calculate the address of the next 256-bit word in DRAM, ready for the next request.
0000Rules for Address Pointers
2963The address pointers must obey certain rules which indicate whether they are valid: <ul id="ul0294" list-style="none"><li id="ul0294-0001" num="2964">a. hcu_readline_rd_adr is only valid if it is reading earlier in the line than lbd_nextline_wr_adr is writing i.e. the fifo is not empty</li><li id="ul0294-0002" num="2965">b. The SFU (lbd_nextline_wr_adr) cannot overwrite the current line that the HCU is reading from (hcu_startreadline_adr) i.e. the fifo is not full, when compared with the HCU read line pointer</li><li id="ul0294-0003" num="2966">c. The LBDNextLineFIFO (lbd_nextline_wr_adr) must be writing earlier in the line than LBD-PrevLineFIFO (lbd_prevline_rd_adr) is reading and must not overwrite the current line that the HCU is reading from i.e. the fifo is not full when compared to the PrevLineFifo read pointer</li><li id="ul0294-0004" num="2967">d. The LBDPrevLineFIFO (lbd_prevline_rd_adr) can read right up to the address that LBDNextLineFIFO (lbd_nextline_wr_adr) is writing i.e the fifo is not empty.</li><li id="ul0294-0005" num="2968">e. At startup i.e. when sfu_go is asserted, the pointers are reset to start_sfu_adr[21:5].</li><li id="ul0294-0006" num="2969">f. The address pointers can wrap around the SFU bi-level store area in DRAM. <br /> Address Generator Pseudo-code: </li></ul>
2970Initialization:
2971<tables id="TABLE-US-00254" num="00254"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>if (sfu_go rising edge) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>//initialise address pointers to start of SFU address</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>space</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="98pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><tbody valign="top"><row><entry /><entry>lbd_prevline_rd_adr</entry><entry>= start_sfu_adr[21:5]</entry></row><row><entry /><entry>lbd_nextline_wr_adr</entry><entry>= start_sfu_adr[21:5]</entry></row><row><entry /><entry>hcu_readline_rd_adr</entry><entry>= start_sfu_adr[21:5]</entry></row><row><entry /><entry>hcu_startreadline_adr</entry><entry>= start_sfu_adr[21:5]</entry></row><row><entry /><entry>lbd_nextline_wr_wrap</entry><entry>= 0</entry></row><row><entry /><entry>lbd_prevline_rd_wrap</entry><entry>= 0</entry></row><row><entry /><entry>hcu_startreadline_wrap</entry><entry>= 0</entry></row><row><entry /><entry>hcu_readline_rd_wrap</entry><entry>= 0</entry></row><row><entry /><entry>}</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2972Determine FIFO fill and empty status:
2973<tables id="TABLE-US-00255" num="00255"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>// calculate which FIFOs are full and empty</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="28pt" align="left" /><colspec colname="3" colwidth="77pt" align="left" /><colspec colname="4" colwidth="35pt" align="left" /><tbody valign="top"><row><entry>plf_nlf_fifo_emp</entry><entry>=</entry><entry>(lbd_prevline_rd_adr</entry><entry>= =</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>lbd_nextline_wr_adr) AND</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="126pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><tbody valign="top"><row><entry /><entry>(lbd_prevline_rd_wrap</entry><entry>= =</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>lbd_nextline_wr_wrap)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="28pt" align="left" /><colspec colname="3" colwidth="84pt" align="left" /><colspec colname="4" colwidth="35pt" align="left" /><tbody valign="top"><row><entry>nlf_plf_fifo_full</entry><entry>=</entry><entry>(lbd_nextline_wr_adr</entry><entry>= =</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>lbd_prevline_rd_adr) AND</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="126pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><tbody valign="top"><row><entry /><entry>(lbd_prevline_rd_wrap</entry><entry>!=</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>lbd_nextline_wr_wrap)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="28pt" align="left" /><colspec colname="3" colwidth="77pt" align="left" /><colspec colname="4" colwidth="35pt" align="left" /><tbody valign="top"><row><entry>nlf_hrf_fifo_full</entry><entry>=</entry><entry>(lbd_nextline_wr_adr</entry><entry>= =</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>hcu_startreadline_adr) AND</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="126pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><tbody valign="top"><row><entry /><entry>(hcu_startreadline_wrap</entry><entry>!=</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>lbd_nextline_wr_wrap)</entry></row><row><entry>// hcu start address can jump addresses and so needs</entry></row><row><entry>comparitor</entry></row><row><entry>if (hcu_startreadline_wrap = = lbd_nextline_wr_wrap) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="105pt" align="left" /><colspec colname="2" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry>start_hrf_nlf_fifo_emp =</entry><entry>(hcu_startreadline_adr</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>>=lbd_nextline_wr_adr)</entry></row><row><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="112pt" align="left" /><tbody valign="top"><row><entry /><entry>start_hrf_nlf_fifo_emp</entry><entry>= NOT(hcu_startreadline_adr</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>>=lbd_nextline_wr_adr)</entry></row><row><entry>// hcu read address can jump addresses and so needs</entry></row><row><entry>comparitor</entry></row><row><entry>if (hcu_readline_rd_wrap = = lbd_nextline_wr_wrap) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="98pt" align="left" /><colspec colname="2" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry>hrf_nlf_fifo_emp =</entry><entry>(hcu_readline_rd_adr</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>>=lbd_nextline_wr_adr)</entry></row><row><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="28pt" align="left" /><colspec colname="3" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry>hrf_nlf_fifo_emp</entry><entry>=</entry><entry>NOT(hcu_readline_rd_adr</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>>=lbd_nextline_wr_adr)</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2974Address pointer updating:
2975<tables id="TABLE-US-00256" num="00256"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>// LBD Next line FIFO</entry></row><row><entry>// if DIU write acknowledge and LBDNextLineFIFO is not full</entry></row><row><entry>with reference to PLF and HRF</entry></row><row><entry>if (diu_sfu_wack == 1 AND nlf_plf_fifo_full != 1 AND</entry></row><row><entry>nlf_hrf_fifo_full !=1 ) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>if (lbd_nextline_wr_adr == end sfu adr) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>// if end of SFU address range</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><colspec colname="2" colwidth="14pt" align="left" /><tbody valign="top"><row><entry /><entry>lbd_nextline_wr_adr = start_sfu_adr</entry><entry>//</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>go to start of SFU address range</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><colspec colname="2" colwidth="14pt" align="left" /><tbody valign="top"><row><entry /><entry>lbd_nextline_wr_wrap= NOT (lbd_nextline_wr_wrap)</entry><entry>//</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>invert the wrap bit</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><colspec colname="2" colwidth="14pt" align="left" /><tbody valign="top"><row><entry /><entry>lbd_nextline_wr_adr++</entry><entry>//</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>increment address pointer</entry></row><row><entry>// LBD PrevLine FIFO</entry></row><row><entry>//if DIU read acknowledge and LBDPrevLineFIFO is not empty</entry></row><row><entry>if (diu_sfu_rack == 1 AND select_hrfplf == 1 AND</entry></row><row><entry>plf_nlf_fifo_emp !=1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>if (lbd_prevline_rd_adr == end_sfu_adr) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><colspec colname="2" colwidth="14pt" align="left" /><tbody valign="top"><row><entry /><entry>lbd_prevline_rd_adr = start_sfu_adr</entry><entry>//</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>go to start of SFU address range</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><colspec colname="2" colwidth="14pt" align="left" /><tbody valign="top"><row><entry /><entry>lbd_prevline_rd_wrap= NOT (lbd_prevline_rd_wrap)</entry><entry>//</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>invert the wrap bit</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><colspec colname="2" colwidth="14pt" align="left" /><tbody valign="top"><row><entry /><entry>lbd_prevline_rd_adr++</entry><entry>//</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>increment address pointer</entry></row><row><entry>// HCU ReadLine FIFO</entry></row><row><entry>// if DIU read acknowledge and HCUReadLineFIFO fifo is not</entry></row><row><entry>empty</entry></row><row><entry>if (diu_sfu_rack == 1 AND select_hrfplf == 0 AND</entry></row><row><entry>hrf_nlf_fifo_emp != 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// going to update hcu read line address</entry></row><row><entry /><entry>if (hrf_hcu_endofline == 1) AND (hrf_yadvance == 1) then {</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>// read the next line from DRAM</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>// advance to start of next HCU line in DRAM</entry></row><row><entry /><entry>hcu_startreadline_adr = hcu_startreadline_adr +</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>lbd_dram_words</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>offset = hcu_startreadline_adr − end_sfu_adr − 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>// allow for address wraparound</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>if (offset >= 0) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>hcu_startreadline_adr = start_sfu_adr + offset</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>hcu_startreadline_wrap=</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>NOT (hcu_startreadline_wrap)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>hcu_readline_rd_adr = hcu_startreadline_adr</entry></row><row><entry /><entry>hcu_readline_rd_wrap= hcu_startreadline_wrap</entry></row><row><entry /><entry>}</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (hrf_hcu_endofline == 1) AND (hrf_yadvance == 0)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><colspec colname="2" colwidth="14pt" align="left" /><tbody valign="top"><row><entry /><entry>hcu_readline_rd_adr = hcu_startreadline_adr</entry><entry>//</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>restart and re-use the same line</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>hcu_readline_rd_wrap= hcu_startreadline_wrap</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (hcu readline rd adr == end sfu adr) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>// check if the FIFO needs to wrap space</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><colspec colname="2" colwidth="14pt" align="left" /><tbody valign="top"><row><entry /><entry>hcu_readline_rd_adr = start_sfu_adr</entry><entry>//</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>go to start of SFU address space</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>hcu_readline_rd_wrap= NOT (hcu_readline_rd_wrap)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><colspec colname="2" colwidth="14pt" align="left" /><tbody valign="top"><row><entry /><entry>hcu_readline_rd_adr ++</entry><entry>//</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>increment address pointer</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 25.8.10.4.1 X Scaling of Data for HCUReadLineFIFO
2976The signal hcu_sfu_advdot tells the HCUReadLineFIFO to supply the next dot or the current dot on sfu_hcu_sdata according to the hrf_xadvance signal from the scaling control unit. When hrf_xadvance is 1 the HCUReadLineFIFO should supply the next dot. When hrf_xadvance is 0 the HCUReadLineFIFO should supply the current dot.
2977The algorithm for non-integer scaling is described in the pseudocode below. Note, x_scale_count should be loaded with x_start_count after reset and at the end of each line. The end of the line is indicated by hrf_hcu_endofline from the HCUReadLineFIFO.
2978<tables id="TABLE-US-00257" num="00257"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>if (hcu_sfu_advdot = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>if (x_scale_count + x_scale_denom − x_scale_num >= 0)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>x_scale_count = x_scale_count + x_scale_denom −</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>x_scale_num</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>hrf_xadvance = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>x_scale_count = x_scale_count + x_scale_denom</entry></row><row><entry /><entry>hrf_xadvance = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>x_scale_count = x_scale_count</entry></row><row><entry /><entry>hrf_xadvance = 0</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 25.8.10.4.2 Y Scaling of Data for HCUReadLineFIFO
2979The HCUReadLineFIFO counts the number of hcu_sfu_advdot strobes received from the HCU. When the count equals hcu_num_dots the HCUReadLineFIFO will assert hrf_hcu_endofline for a cycle.
2980The algorithm for non-integer scaling is described in the pseudocode below. Note, y_scale_count should be loaded with zero after reset.
2981<tables id="TABLE-US-00258" num="00258"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>if (hrf_hcu_endofline = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>if (y_scale_count + y_scale_denom − y_scale_num >= 0)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>y_scale_count = y_scale_count + y_scale_denom −</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>y_scale_num</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>hrf_yadvance = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>y_scale_count = y_scale_count + y_scale_denom</entry></row><row><entry /><entry>hrf_yadvance = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>y_scale_count = y_scale_count</entry></row><row><entry /><entry>hrf_yadvance = 0</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
2982When the hrf_hcu_endofline is asserted the Y scaling unit will decide whether to go back to the start of the current line, by setting hrf_yadvance=0, or go onto the next line, by setting hrf_yadvance=1.
2983<figref idref="DRAWINGS">FIG. 176</figref> shows an overview of X and Y scaling for HCU data.
000026 Tag Encoder (TE)
000026.1 Overview
2984The Tag Encoder (TE) provides functionality for Netpage-enabled applications, and typically requires the presence of IR ink (although K ink can be used for tags in limited circumstances). The TE encodes fixed data for the page being printed, together with specific tag data values into an error-correctable encoded tag which is subsequently printed in infrared or black ink on the page. The TE places tags on a triangular grID, and can be programmed for both landscape and portrait orientations.
2985Basic tag structures are normally rendered at 1600 dpi, while tag data is encoded into an arbitrary number of printed dots. The TE supports integer scaling in the Y-direction while the TFU supports integer scaling in the X-direction. Thus, the TE can render tags at resolutions less than 1600 dpi which can be subsequently scaled up to 1600 dpi.
2986The output from the TE is buffered in the Tag FIFO Unit (TFU) which is in turn used as input by the HCU. In addition, a te_finishedband signal is output to the end of band unit once the input tag data has been loaded from DRAM. The high level data path is shown by the block diagram in <figref idref="DRAWINGS">FIG. 177</figref>.
2987After passing through the HCU, the tag plane is subsequently printed with an infrared-absorptive ink that can be read by a Netpage sensing device. Since black ink can be IR absorptive, limited functionality can be provided on offset-printed pages using black ink on otherwise blank areas of the page—for example to encode buttons. Alternatively an invisible infrared ink can be used to print the position tags over the top of a regular page. However, if invisible IR ink is used, care must be taken to ensure that any other printed information on the page is printed in infrared-transparent CMY ink, as black ink will obscure the infrared tags. The monochromatic scheme was chosen to maximize dynamic range in blurry reading environments.
2988When multiple SoPEC chips are used for printing the same side of a page, it is possible that a single tag will be produced by two SoPEC chips. This implies that the TE must be able to print partial tags.
2989The throughput requirement for the SoPEC TE is to produce tags at half the rate of the PEC1 TE.
2990Since the TE is reused from PEC1, the SoPEC TE over-produces by a factor of 2.
2991In PEC1, in order to keep up with the HCU which processes 2 dots per cycle, the tag data interface has been designed to be capable of encoding a tag in 63 cycles. This is actually accomplished in approximately 52 cycles within PEC1. If the SoPEC TE were to be modified from two dots production per cycle to a nominal one dot per cycle it should not lose the 63/52 cycle performance edge attained in the PEC1 TE.
000026.2 What are Tags?
2992The first barcode was described in the late 1940's by Woodland and Silver, and finally patented in 1952 (U.S. Pat. No. 2,612,994) when electronic parts were scarce and very expensive. Now however, with the advent of cheap and readily available computer technology, nearly every item purchased from a shop contains a barcode of some description on the packaging. From books to CDs, to grocery items, the barcode provides a convenient way of identifying an object by a product number. The exact interpretation of the product number depends on the type of barcode. Warehouse inventory tracking systems let users define their own product number ranges, while inventory in shops must be more universally encoded so that products from one company don't overlap with products from another company. Universal Product Codes (UPC) were introduced in the mid 1970's at the request of the National Association of Food Chains for this very reason. Barcodes themselves have been specified in a large number of formats. The older barcode formats contain characters that are displayed in the form of lines. The combination of black and white lines describe the information the barcodes contains. Often there are two types of lines to form the complete barcode: the characters (the information itself) and lines to separate blocks for better optical recognition. While the information may change from barcode to barcode, the lines to separate blocks stays constant. The lines to separate blocks can therefore be thought of as part of the constant structural components of the barcode.
2993Barcodes are read with specialized reading devices that then pass the extracted data onto the computer for further processing. For example, a point-of-sale scanning device allows the sales assistant to add the scanned item to the current sale, places the name of the item and the price on a display device for verification etc. Light-pens, gun readers, scanners, slot readers, and cameras are among the many devices used to read the barcodes.
2994To help ensure that the data extracted was read correctly, checksums were introduced as a crude form of error detection. More recent barcode formats, such as the Aztec 2D barcode developed by Andy Longacre in 1995 (U.S. Pat. No. 5,591,956), but now released to the public domain, use redundancy encoding schemes such as Reed-Solomon. Reed Solomon encoding is adequately discussed in [28], [30] and [34]. The reader is advised to refer to these sources for background information. Very often the degree of redundancy encoding is user selectable.
2995More recently there has also been a move from the simple one dimensional barcodes (line based) to two dimensional barcodes. Instead of storing the information as a series of lines, where the data can be extracted from a single dimension, the information is encoded in two dimensions. Just as with the original barcodes, the 2D barcode contains both information and structural components for better optical recognition. <figref idref="DRAWINGS">FIG. 178</figref> shows an example of a QR Code (Quick Response Code), developed by Denso of Japan (U.S. Pat. No. 5,726,435). Note the barcode cell is comprised of two areas: a data area (depends on the data being stored in the barcode), and a constant position detection pattern. The constant position detection pattern is used by the reader to help locate the cell itself, then to locate the cell boundaries, to allow the reader to determine the original orientation of the cell (orientation can be determined by the fact that there is no 4th corner pattern).
2996The number of barcode encoding schemes grows daily. Yet very often the hardware for producing these barcodes is specific to the particular barcode format. As printers become more and more embedded, there is an increasing desire for real-time printing of these barcodes. In particular, Netpage enabled applications require the printing of 2D barcodes (or tags) over the page, preferably in infra-red ink. The tag encoder in SoPEC uses a generic barcode format encoding scheme which is particularly suited to real-time printing. Since the barcode encoding format is generic, the same rendering hardware engine can be used to produce a wide variety of barcode formats.
2997Unfortunately the term “barcode” is interpreted in different ways by different people. Sometimes it refers only to the data area component, and does not include the constant position detection pattern. In other cases it refers to both data and constant position detection pattern.
2998We therefore use the term tag to refer to the combination of data and any other components (such as position detection pattern, blank space etc. surround) that must be rendered to help hold or locate/read the data. A tag therefore contains the following components: <ul id="ul0295" list-style="none"><li id="ul0295-0001" num="0000"><ul id="ul0296" list-style="none"><li id="ul0296-0001" num="2999">data area(s). The data area is the whole reason that the tag exists. The tag data area(s) contains the encoded data (optionally redundancy-encoded, perhaps simply checksummed) where the bits of the data are placed within the data area at locations specified by the tag encoding scheme.</li><li id="ul0296-0002" num="3000">constant background patterns, which typically includes a constant position detection pattern. These help the tag reader to locate the tag. They include components that are easy to locate and may contain orientation and perspective information in the case of 2D tags. Constant background patterns may also include such patterns as a blank area surrounding the data area or position detection pattern. These blank patterns can aid in the decoding of the data by ensuring that there is no interference between tags or data areas.</li></ul></li></ul>
3001In most tag encoding schemes there is at least some constant background pattern, but it is not necessarily required by all. For example, if the tag data area is enclosed by a physical space and the reading means uses a non-optical location mechanism (e.g. physical alignment of surface to data reader) then a position detection pattern is not required.
3002Different tag encoding schemes have different sized tags, and have different allocation of physical tag area to constant position detection pattern and data area. For example, the QR code has 3 fixed blocks at the edges of the tag for position detection pattern (see <figref idref="DRAWINGS">FIG. 178</figref>) and a data area in the remainder. By contrast, the Netpage tag structure (see <figref idref="DRAWINGS">FIGS. 179 and 180</figref>) contains a circular locator component, an orientation feature, and several data areas. <figref idref="DRAWINGS">FIG. 179(</figref><i>a</i>) shows the Netpage tag constant background pattern in a resolution independent form. <figref idref="DRAWINGS">FIG. 179(</figref><i>b</i>) is the same as <figref idref="DRAWINGS">FIG. 179(</figref><i>a</i>), but with the addition of the data areas to the Netpage tag. <figref idref="DRAWINGS">FIG. 180</figref> is an example of dot placement and rendering to 1600 dpi for a Netpage tag. Note that in <figref idref="DRAWINGS">FIG. 180</figref> a single bit of data is represented by many physical output dots to form a block within the data area.
000026.2.1 Contents of the Data Area
3003The data area contains the data for the tag.
3004Depending on the tag's encoding format, a single bit of data may be represented by a number of physical printed dots. The exact number of dots will depend on the output resolution and the target reading/scanning resolution. For example, in the QR code (see <figref idref="DRAWINGS">FIG. 178</figref>), a single bit is represented by a dark module or a light module, where the exact number of dots in the dark module or light module depends on the rendering resolution and target reading/scanning resolution. For example, a dark module may be represented by a square block of printed dots (all on for binary 1, or all off for binary 0), as shown in <figref idref="DRAWINGS">FIG. 181</figref>.
3005The point to note here is that a single bit of data may be represented in the printed tag by an arbitrary printed shape. The smallest shape is a single printed dot, while the largest shape is theoretically the whole tag itself, for example a giant macrodot comprised of many printed dots in both dimensions.
3006An ideal generic tag definition structure allows the generation of an arbitrary printed shape from each bit of data.
000026.2.2 What do the Bits Represent?
3007Given an original number of bits of data, and the desire to place those bits into a printed tag for subsequent retrieval via a reading/scanning mechanism, the original number of bits can either be placed directly into the tag, or they can be redundancy-encoded in some way. The exact form of redundancy encoding will depend on the tag format.
3008The placement of data bits within the data area of the tag is directly related to the redundancy mechanism employed in the encoding scheme. The idea is generally to place data bits together in 2D so that burst errors are averaged out over the tag data, thus typically being correctable. For example, all the bits of Reed-Solomon codeword would be spread out over the entire tag data area so to minimize being affected by a burst error.
3009Since the data encoding scheme and shape and size of the tag data area are closely linked, it is desirable to have a generic tag format structure. This allows the same data structure and rendering embodiment to be used to render a variety of tag formats.
000026.2.2.1 Fixed and Variable Data Components
3010In many cases, the tag data can be reasonably divided into fixed and variable components. For example, if a tag holds N bits of data, some of these bits may be fixed for all tags while some may vary from tag to tag.
3011For example, the Universal product code allows a country code and a company code. Since these bits don't change from tag to tag, these bits can be defined as fixed, and don't need to be provided to the tag encoder each time, thereby reducing the bandwidth when producing many tags.
3012Another example is Netpage tags. A single printed page contains a number of Netpage tags. The page-id will be constant across all the tags, even though the remainder of the data within each tag may be different for each tag. By reducing the amount of variable data being passed to SoPEC's tag encoder for each tag, the overall bandwidth can be reduced.
3013Depending on the embodiment of the tag encoder, these parameters will be either implicit or explicit, and may limit the size of tags renderable by the system. For example, a software tag encoder may be completely variable, while a hardware tag encoder such as SoPEC's tag encoder may have a maximum number of tag data bits.
000026.2.2.2 Redundancy-encode the Tag Data within the Tag Encoder
3014Instead of accepting the complete number of TagData bits encoded by an external encoder, the tag encoder accepts the basic non-redundancy-encoded data bits and encodes them as required for each tag. This leads to significant savings of bandwidth and on-chip storage.
3015In SoPEC's case for Netpage tags, only 120 bits of original data are provided per tag, and the tag encoder encodes these 120 bits into 360 bits. By having the redundancy encoder on board the tag encoder the effective bandwidth and internal storage required is reduced to only 33% of what would be required if the encoded data was read directly.
000026.3 Placement of Tags on a Page
3016The TE places tags on the page in a triangular grid arrangement as shown in <figref idref="DRAWINGS">FIG. 182</figref>.
3017The triangular mesh of tags combined with the restriction of no overlap of columns or rows of tags means that the process of tag placement is greatly simplified. For a given line of dots, all the tags on that line correspond to the same part of the general tag structure. The triangular placement can be considered as alternative lines of tags, where one line of tags is inset by one amount in the dot dimension, and the other line of dots is inset by a different amount. The dot inter-tag gap is the same in both lines of tag, and is different from the line inter-tag gap.
3018Note also that as long as the tags themselves can be rotated, portrait and landscape printing are essentially the same—the placement parameters of line and dot are swapped, but the placement mechanism is the same.
3019The general case for placement of tags therefore relies on a number of parameters, as shown in <figref idref="DRAWINGS">FIG. 183</figref>.
3020The parameters are more formally described in Table 169. Note that these are placement parameters and not registers.
3021<tables id="TABLE-US-00259" num="00259"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 169</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Tag placement parameters</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="56pt" align="left" /><tbody valign="top"><row><entry>parameter</entry><entry>description</entry><entry>restrictions</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>Tag height</entry><entry>The number of dot lines in</entry><entry>minimum 1</entry></row><row><entry /><entry>a tag's bounding box</entry></row><row><entry>Tag width</entry><entry>The number of dots in a</entry><entry>minimum 1</entry></row><row><entry /><entry>single line of the tag's</entry></row><row><entry /><entry>bounding box. The number of</entry></row><row><entry /><entry>dots in the tag itself may</entry></row><row><entry /><entry>vary depending on the shape</entry></row><row><entry /><entry>of the tag, but the number</entry></row><row><entry /><entry>of dots in the bounding box</entry></row><row><entry /><entry>will be constant (by</entry></row><row><entry /><entry>definition).</entry></row><row><entry>Dot inter-</entry><entry>The number of dots from the</entry><entry>minimum = 0</entry></row><row><entry>tag gap</entry><entry>edge of one tag's bounding</entry></row><row><entry /><entry>box to the start of the next</entry></row><row><entry /><entry>tag's bounding box, in the</entry></row><row><entry /><entry>dot direction.</entry></row><row><entry>Line inter-</entry><entry>The number of dot lines</entry><entry>minimum = 0</entry></row><row><entry>tag gap</entry><entry>from the edge of one tag's</entry></row><row><entry /><entry>bounding box to the start</entry></row><row><entry /><entry>of the next tag's bounding</entry></row><row><entry /><entry>box, in the line direction.</entry></row><row><entry>Start</entry><entry>Defines the status of the</entry><entry>—</entry></row><row><entry>Position</entry><entry>top left dot on the page -</entry></row><row><entry /><entry>is an offset in dot & row</entry></row><row><entry /><entry>within the tag or the</entry></row><row><entry /><entry>inter-tag gap.</entry></row><row><entry>AltTagLinePosition</entry><entry>Defines the status for the</entry><entry>—</entry></row><row><entry /><entry>start of the alternate row</entry></row><row><entry /><entry>of tags. Is an offset in</entry></row><row><entry /><entry>dot within the tag or within</entry></row><row><entry /><entry>the dot inter-tag gap</entry></row><row><entry /><entry>(the row position is</entry></row><row><entry /><entry>always 0).</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 26.4 Basic Tag Encoding Parameters
3022SoPEC's tag encoder imposes range restrictions on tag encoding parameters as a direct result of on-chip buffer sizes. Table 170 lists the basic encoding parameters as well as range restrictions where appropriate. Although the restrictions were chosen to take the most likely encoding scenarios into account, it is a simple matter to adjust the buffer sizes and corresponding addressing to allow arbitrary encoding parameters in future implementations.
3023<tables id="TABLE-US-00260" num="00260"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 170</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Encoding parameters</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><colspec colname="3" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>name</entry><entry>definition</entry><entry>maximum value imposed by TE</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>W</entry><entry>page width</entry><entry>2<sup>14 </sup>dotpairs or 20.48 inches</entry></row><row><entry /><entry /><entry>at 1600 dpi</entry></row><row><entry>S</entry><entry>tag size</entry><entry>typical tag size is 2 mm × 2 mm</entry></row><row><entry /><entry /><entry>maximum tag size is</entry></row><row><entry /><entry /><entry>384 dots × 384 dots before</entry></row><row><entry /><entry /><entry>scaling i.e. 6 mm × 6 mm</entry></row><row><entry /><entry /><entry>at 1600 dpi</entry></row><row><entry>N</entry><entry>number of dots in each</entry><entry>384 dots before scaling</entry></row><row><entry /><entry>dimension of the tag</entry></row><row><entry>E</entry><entry>redundancy encoding for</entry><entry>Reed-Solomon GF(2<sup>4</sup>) at</entry></row><row><entry /><entry>tag data</entry><entry>5:10 or 7:8</entry></row><row><entry>D<sub>F</sub></entry><entry>size of fixed data</entry><entry>40 or 56 bits</entry></row><row><entry /><entry>(unencoded)</entry></row><row><entry>R<sub>F</sub></entry><entry>size of redundancy-</entry><entry>120 bits</entry></row><row><entry /><entry>encoded fixed data</entry></row><row><entry>D<sub>V</sub></entry><entry>size of variable data</entry><entry>120 or 112 bits</entry></row><row><entry /><entry>(unencoded)</entry></row><row><entry>R<sub>V</sub></entry><entry>size of redundancy-</entry><entry>360 or 240 bits</entry></row><row><entry /><entry>encoded variable data</entry></row><row><entry>T</entry><entry>tags per page width</entry><entry>256</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3024The fixed data for the tags on a page need only be supplied to the TE once. It can be supplied as 40 or 56 bits of unencoded data and encoded within the TE as described in Section 26.4.1. Alternatively it can be supplied as 120 bits of pre-encoded data (encoded arbitrarily).
3025The variable data for the tags on a page are those 112 or 120 data bits that are variable for each tag. Variable tag data is supplied as part of the band data, and is always encoded by the TE as described in Section 26.4.1, but may itself be arbitrarily pre-encoded.
000026.4.1 Redundancy Encoding
3026The mapping of data bits (both fixed and variable) to redundancy encoded bits relies heavily on the method of redundancy encoding employed. Reed-Solomon encoding was chosen for its ability to deal with burst errors and effectively detect and correct errors using a minimum of redundancy. Reed Solomon encoding is adequately discussed in [28], [30] and [34]. The reader is advised to refer to these sources for background information.
3027In this implementation of the TE we use Reed-Solomon encoding over the Galois Field GF(2<sup>4</sup>). Symbol size is 4 bits. Each codeword contains 15 4-bit symbols for a codeword length of 60 bits.
3028The primitive polynomial is p(x)=x<sup>4</sup>+x+1, and the generator polynomial is g(x)=(x+α)(x+α<sup>2</sup>) . . . (x+α<sup>2t</sup>), where t=the number of symbols that can be corrected.
3029Of the 15 symbols, there are two possibilities for encoding: <ul id="ul0297" list-style="none"><li id="ul0297-0001" num="0000"><ul id="ul0298" list-style="none"><li id="ul0298-0001" num="3030">RS(15, 5): 5 symbols original data (20 bits), and 10 redundancy symbols (40 bits). The 10 redundancy symbols mean that we can correct up to 5 symbols in error. The generator polynomial is therefore g(x)=(x+α)(x+α<sup>2</sup>) . . . (x+α<sup>10</sup>).</li><li id="ul0298-0002" num="3031">RS(15, 7): 7 symbols original data (28 bits), and 8 redundancy symbols (32 bits). The 8 redundancy symbols mean that we can correct up to 4 symbols in error. The generator polynomial is g(x)=(x+α)(x+α<sup>2</sup>) . . . (x+α<sup>8</sup>).</li></ul></li></ul>
3032In the first case, with 5 symbols of original data, the total amount of original data per tag is 160 bits (40 fixed, 120 variable). This is redundancy encoded to give a total amount of 480 bits (120 fixed, 360 variable) as follows: <ul id="ul0299" list-style="none"><li id="ul0299-0001" num="0000"><ul id="ul0300" list-style="none"><li id="ul0300-0001" num="3033">Each tag contains up to 40 bits of fixed original data. Therefore 2 codewords are required for the fixed data, giving a total encoded data size of 120 bits. Note that this fixed data only needs to be encoded once per page.</li><li id="ul0300-0002" num="3034">Each tag contains up to 120 bits of variable original data. Therefore 6 codewords are required for the variable data, giving a total encoded data size of 360 bits.</li></ul></li></ul>
3035In the second case, with 7 symbols of original data, the total amount of original data per tag is 168 bits (56 fixed, 112 variable). This is redundancy encoded to give a total amount of 360 bits (120 fixed, 240 variable) as follows: <ul id="ul0301" list-style="none"><li id="ul0301-0001" num="0000"><ul id="ul0302" list-style="none"><li id="ul0302-0001" num="3036">Each tag contains up to 56 bits of fixed original data. Therefore 2 codewords are required for the fixed data, giving a total encoded data size of 120 bits. Note that this fixed data only needs to be encoded once per page.</li><li id="ul0302-0002" num="3037">Each tag contains up to 112 bits of variable original data. Therefore 4 codewords are required for the variable data, giving a total encoded data size of 240 bits.</li></ul></li></ul>
3038The choice of data to redundancy ratio depends on the application.
000026.5 Data Structures Used by Tag Encoder
000026.5.1 Tag Format Structure
3039The Tag Format Structure (TFS) is the template used to render tags, optimized so that the tag can be rendered in real time. The TFS contains an entry for each dot position within the tag's bounding box. Each entry specifies whether the dot is part of the constant background pattern or part of the tag's data component (both fixed and variable).
3040The TFS is very similar to a bitmap in that it contains one entry for each dot position of the tag's bounding box. The TFS therefore has TagHeight×TagWidth entries, where TagHeight matches the height of the bounding box for the tag in the line dimension, and TagWidth matches the width of the bounding box for the tag in the dot dimension. A single line of TFS entries for a tag is known as a tag line structure.
3041The TFS consists of TagHeight number of tag line structures, one for each 1600 dpi line in the tag's bounding box. Each tag line structure contains three contiguous tables, known as tables A, B, and C. Table A contains 384 2-bit entries, one entry for each of the maximum number of dots in a single line of a tag (see Table). The actual number of entries used should match the size of the bounding box for the tag in the dot dimension, but all 384 entries must be present. Table B contains 32 9-bit data addresses that refer to (in order of appearance) the data dots present in the particular line. All 32 entries must be present, even if fewer are used. Table C contains two 5-bit pointers into table B, and therefore comprises 10 bits. Padding of 214 bits is added. The total length of each tag line structure is therefore 5×256-bit DRAM words. Thus a TFS containing TagHeight tag line structures requires a TagHeight*160 bytes. The structure of a TFS is shown in <figref idref="DRAWINGS">FIG. 184</figref>.
3042A full description of the interpretation and usage of Tables A, B and C is given in section 26.8.3 on page 444.
000026.5.1.1 Scaling a Tag
3043If the size of the printed dots is too small, then the tag can be scaled in one of several ways. Either the tag itself can be scaled by N dots in each dimension, which increases the number of entries in the TFS. As an alternative, the output from the TE can be scaled up by pixel replication via a scale factor greater than 1 in the both the TE and TFU.
3044For example, if the original TFS was 21×21 entries, and the scaling were a simple 2×2 dots for each of the original dots, we could increase the TFS to be 42×42. To generate the new TFS from the old, we would repeat each entry across each line of the TFS, and then we would repeat each line of the TFS. The net number of entries in the TFS would be increased fourfold (2×2).
3045The TFS allows the creation of macrodots instead of simple scaling. Looking at <figref idref="DRAWINGS">FIG. 185</figref> for a simple example of a 3×3 dot tag, we may want to produce a physically large printed form of the tag, where each of the original dots was represented by 7×7 printed dots. If we simply performed replication by 7 in each dimension of the original TFS, either by increasing the size of the TFS by 7 in each dimension or putting a scale-up on the output of the tag generator output, then we would have 9 sets of 7×7 square blocks. Instead, we can replace each of the original dots in the TFS by a 7×7 dot definition of a rounded dot. <figref idref="DRAWINGS">FIG. 186</figref> shows the results.
3046Consequently, the higher the resolution of the TFS the more printed dots can be printed for each macrodot, where a macrodot represents a single data bit of the tag. The more dots that are available to produce a macrodot, the more complex the pattern of the macrodot can be. As an example, Figure n page 461 on page Error! Bookmark not defined. shows the Netpage tag structure rendered such that the data bits are represented by an average of 8 dots×8 dots (at 1600 dpi), but the actual shape structure of a dot is not square. This allows the printed Netpage tag to be subsequently read at any orientation.
000026.5.2 Raw Tag Data
3047The TE requires a band of unencoded variable tag data if variable data is to be included in the tag bit-plane. A band of unencoded variable tag data is a set of contiguous unencoded tag data records, in order of encounter top left of printed band from top left to lower right.
3048An unencoded tag data record is 128 bits arranged as follows: bits <b>0</b>–<b>111</b> or <b>0</b>–<b>119</b> are the bits of raw tag data, bit <b>120</b> is a flag used by the TE (TagIsPrinted), and the remaining 7 bits are reserved (and should be 0). Having a record size of 128 bits simplifies the tag data access since the data of two tags fits into a 256-bit DRAM word. It also means that the flags can be stored apart from the tag data, thus keeping the raw tag data completely unrestricted. If there is an odd number of tags in line then the last DRAM read will contain a tag in the first 128 bits and padding in the final 128 bits.
3049The TagIsPrinted flag allows the effective specification of a tag resolution mask over the page. For each tag position the TagIsPrinted flag determines whether any of the tag is printed or not. This allows arbitrary placement of tags on the page. For example, tags may only be printed over particular active areas of a page. The TagIsPrinted flag allows only those tags to be printed. TagIsPrinted is a 1 bit flag with values as shown in Table 171.
3050<tables id="TABLE-US-00261" num="00261"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 171</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>TagIsPrinted values</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>Value</entry><entry>description</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>0</entry><entry>Don't print the tag in this tag position.</entry></row><row><entry /><entry /><entry>Output 0 for each dot within the tag</entry></row><row><entry /><entry /><entry>bounding box.</entry></row><row><entry /><entry>1</entry><entry>Print the tag as specified by the various</entry></row><row><entry /><entry /><entry>tag structures.</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 26.5.3 DRAM Storage Requirements
3051The total DRAM storage required by a single band of raw tag data depends on the number of tags present in that band. Each tag requires 128 bits. Consequently if there are N tags in the band, the size in DRAM is 16N bytes.
3052The maximum size of a line of tags is 163×128 bits. When maximally packed, a row of tags contains 163 tags (see Table) and extends over a minimum of 126 print lines. This equates to 282 KBytes over a Letter page.
3053The total DRAM storage required by a single TFS is TagHeight/7 KBytes (including padding). Since the likely maximum value for TagHeight is 384 (given that SoPEC restricts TagWidth to 384), the maximum size in DRAM for a TFS is 55 KBytes.
000026.5.4 DRAM Access Requirements
3054The TE has two separate read interfaces to DRAM for raw tag data, TD, and tag format structure, TFS.
3055The memory usage requirements are shown in Table 172. Raw tag data is stored in the compressed page store
3056<tables id="TABLE-US-00262" num="00262"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 172</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Memory usage requirements</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="56pt" align="left" /><colspec colname="3" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>Block</entry><entry>Size</entry><entry>Description</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>Compressed</entry><entry>2048 Kbytes</entry><entry>Compressed data page store for</entry></row><row><entry>page</entry><entry /><entry>Bi-level, contone and raw tag</entry></row><row><entry>store</entry><entry /><entry>data.</entry></row><row><entry>Tag Format</entry><entry>55 Kbyte (384</entry><entry>55 kB in PEC1 for 384 dot line</entry></row><row><entry>Structure</entry><entry>dot line</entry><entry>tags (the benchmark) at 1600 dpi</entry></row><row><entry /><entry>tags @</entry><entry>2.5 mm tags</entry></row><row><entry /><entry>1600 dpi)</entry><entry>( 1/10th inch) @ 1600 dpi</entry></row><row><entry /><entry /><entry>require 160 dot lines =</entry></row><row><entry /><entry /><entry>160/384 × 55 or 23 kB</entry></row><row><entry /><entry /><entry>2.5 mm tags @ 800 dpi</entry></row><row><entry /><entry /><entry>require 80/384 × 55 = 12 kB</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3057The TD interface will read 256-bits from DRAM at a time. Each 256-bit read returns 2 times 128-bit tags. The TD interface to the DIU will be a 256-bit double buffer. If there is an odd number of tags in line then the last DRAM read will contain a tag in the first 128 bits and padding in the final 128 bits.
3058The TFS interface will also read 256-bits from DRAM at a time. The TFS required for a line is 136 bytes. A total of 5 times 256-bit DRAM reads is required to read the TFS for a line with 192 unused bits in the fifth 256-bit word. A 136-byte double-line buffer will be implemented to store the TFS data.
3059The TE's DIU bandwidth requirements are summarized in Table 173.
3060<tables id="TABLE-US-00263" num="00263"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 173</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>DRAM bandwidth requirements</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><colspec colname="3" colwidth="77pt" align="left" /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry /><entry>Peak</entry><entry>Average</entry></row><row><entry /><entry /><entry>Maximum number of</entry><entry>Bandwidth</entry><entry>Bandwidth</entry></row><row><entry>Block</entry><entry /><entry>cycles between each</entry><entry>(bits/</entry><entry>(bits/</entry></row><row><entry>Name</entry><entry>Direction</entry><entry>256-bit DRAM access</entry><entry>cycle)</entry><entry>cycle)</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row><row><entry>TD</entry><entry>Read</entry><entry>Single 256 bit reads 1.</entry><entry>1.02</entry><entry>1.02</entry></row><row><entry>TFS</entry><entry>Read</entry><entry>Single 256 bit reads 2.</entry><entry>0.093</entry><entry>0.093</entry></row><row><entry /><entry /><entry>TFS is 136 bytes. This</entry></row><row><entry /><entry /><entry>means there is unused</entry></row><row><entry /><entry /><entry>data in the fifth 256</entry></row><row><entry /><entry /><entry>bit read. A total of</entry></row><row><entry /><entry /><entry>5 reads is required.</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 1: Each 2 mm tag lasts 126 dot cycles and requires 128 bits. This is a rate of 256 bits every 252 cycles. <br /> 2: 17×64 bit reads per line in PEC1 is 5×256 bit reads per line in SoPEC with unused bits in the last 256-bit read. <br /> 26.5.5 TD and TFS Bandstore Wrapping
3061<tables id="TABLE-US-00264" num="00264"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 174</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Bandstore Inputs from CDU</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="28pt" align="center" /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="77pt" align="left" /><tbody valign="top"><row><entry>Port Name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>cdu_endofbandstore[21:5]</entry><entry>17</entry><entry>In</entry><entry>Address of the end of</entry></row><row><entry /><entry /><entry /><entry>the current band of data.</entry></row><row><entry /><entry /><entry /><entry>256-bit word aligned</entry></row><row><entry /><entry /><entry /><entry>DRAM address.</entry></row><row><entry>cdu_startofbandstore[21:5]</entry><entry>17</entry><entry>In</entry><entry>Address of the start of</entry></row><row><entry /><entry /><entry /><entry>the current band of data.</entry></row><row><entry /><entry /><entry /><entry>256-bit word aligned</entry></row><row><entry /><entry /><entry /><entry>DRAM address.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3062Both TD and TFS storage in DRAM can wrap around the bandstore area. The bounds of the band store are described by inputs from the CDU shown in Table 174. The TD and TFS DRAM interfaces therefore support bandstore wrapping. If the TD or TFS DRAM interface increments an address it is checked to see if it matches the end of bandstore address. If so, then the address is mapped to the start of the bandstore.
000026.5.6 Tag Sizes
3063SoPEC allows for tags to be between 0 to 384 dots. A typical 2 mm tag requires 126 dots. Short tags do not change the internal bandwidth or throughput behaviours at all. Tag height is specified so as to allow the DRAM storage for raw tag data to be specified. Minimum tag width is a condition imposed by throughput limitations, so if the width is too small TE cannot consistently produce 2 dots per cycle across several tags (also there are raw tag data bandwidth implications). Thinner tags still work, they just take longer and/or need scaling.
000026.6 Implementation
000026.6.1 Tag Encoder Architecture
3064A block diagram of the TE can be seen below.
3065The TE writes lines of bi-level tag plane data to the TFU for later reading by the HCU. The TE is responsible for merging the encoded tag data with the tag structure (interpreted from the TFS). Y-integer scaling of tags is performed in the TE with X-integer scaling of the tags performed in the TFU. The encoded tag layer is generated 2 bits at a time and output to the TFU at this rate. The HCU however only consumes 1 bit per cycle from the TFU. The TE must provide support for 126 dot Tags (2 mm densely packed) with 108 Tags per line with 128 bits per tag.
3066The tag encoder consists of a TFS interface that loads and decodes TFS entries, a tag data interface that loads tag raw data, encodes it, and provides bit values on request, and a state machine to generate appropriate addressing and control signals. The TE has two separate read interfaces to DRAM for raw tag data, TD, and tag format structure, TFS.
3067It is possible that the raw tag data interface, the TD, to the DIU could be replaced by a hardware state machine at a later stage. This would allow flexibility in the generation of tags. Support for Y scaling needs to be added to the PEC1 TE. The PEC1 TE already allows stalling at its output during a line when tfu_te_oktowrite is deasserted.
000026.6.2 Y-scaling Output Lines
3068In order to support scaling in the Y direction the following modifications to the PEC1 TE are suggested to the Tag Data Interface, Tag Format Structure Interface and TE Top Level: <ul id="ul0303" list-style="none"><li id="ul0303-0001" num="0000"><ul id="ul0304" list-style="none"><li id="ul0304-0001" num="3069">for Tag Data Interface: program the configuration registers of Table, firstTagLineHeight and tagMaxLine with true value i.e. not multiplied up by the scale factor YScale. Within the Tag Data interface there are two counters, countx and county that have a direct bearing on the rawTagDataAddr generation. countx decrements as tags are read from DRAM. It is reset to NumTags[RtdTagSense] at start of each line of tags. county is decremented as each line of tags is completely read from DRAM i.e. countx=0. Scaling may be performed by counting the number of times countx reaches zero and only decrementing county when this number reaches YScale. This will cause the TagData Interface to read each line of tag data NumTags[RtdTagSense]* YScale times.</li><li id="ul0304-0002" num="3070">for Tag Format Structure Interface: The implication of Y-scaling for the TFS is that each Tag Line Structure is used YScale times. This may be accomplished in either of two ways:</li><li id="ul0304-0003" num="3071">For each Tag Line Structure read it once from DRAM and reuse YScale times. This involves gating the control of TFS buffer flipping with YScale. Because of the way in which this advTfsLine and advTagLine related functionality is coded in the PEC1 TFS this solution is judged to be error-prone.</li><li id="ul0304-0004" num="3072">Fetch each TagLineStructure YScale times. This solution involves controlling the activity of currTfsAddr with YScale. <ul id="ul0305" list-style="none"><li id="ul0305-0001" num="3073">In SoPEC the TFS must supply five addresses to the DIU to read each individual Tag Line Structure. The DIU returns 4*64-bit words for each of the 5 accesses. This is different from the behaviour in PEC1, where one address is given and 17 data-words were returned by the DIU.</li><li id="ul0305-0002" num="3074">Since the behaviour of the currTfsAddr must be changed to meet the requirements of the SoPEC DIU it makes sense to include the Y-Scaling into this change i.e. a count of the number of completed sets of 5 accesses to the DIU is compared to YScale. Only when this count equals YScale can currTfsAddr be loaded with the base address of the next lines Tag Line Structure in DRAM, otherwise it is re-loaded with the base address of the current lines Tag Line Structure in DRAM.</li></ul></li><li id="ul0304-0005" num="3075">For Top Level: The Top Level of the TE has a counter, LinePos, which is used to count the number of completed output lines when in a tag gap or in a line of tags. At the start (i.e. top-left hand dot-pair) of a gap or tag LinePos is loaded with either TagGapLine or TagMaxLine. The value of LinePos is decremented at last dot-pair in line. Y-Scaling may be accomplished by gating the decrement of LinePos based on YScale value <br /> 26.6.3 TE Physical Hierarchy </li></ul></li></ul>
3076<figref idref="DRAWINGS">FIG. 188</figref> above illustrates the structural hierarchy of the TE. The top level contains the Tag Data Interface (TDI), Tag Format Structure (TFS), and an FSM to control the generation of dot pairs along with a clocked process to carry out the PCU read/write decoding. There is also some additional logic for muxing the output data and generating other control signals.
3077At the highest level, the TE state machine processes the output lines of a page one line at a time, with the starting position either in an inter-tag gap or in a tag (a SoPEC may be only printing part of a tag due to multiple SoPECs printing a single line).
3078If the current position is within an inter-tag gap, an output of 0 is generated. If the current position is within a tag, the tag format structure is used to determine the value of the output dot, using the appropriate encoded data bit from the fixed or variable data buffers as necessary. The TE then advances along the line of dots, moving through tags and inter-tag gaps according to the tag placement parameters.
000026.6.4 IO Definitions
3079<tables id="TABLE-US-00265" num="00265"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 175</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>TE Port List</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="84pt" align="left" /><tbody valign="top"><row><entry>Port Name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Clocks and Resets</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="84pt" align="left" /><tbody valign="top"><row><entry>Pclk</entry><entry>1</entry><entry>In</entry><entry>SoPEC Functional clock.</entry></row><row><entry>prst_n</entry><entry>1</entry><entry>In</entry><entry>Global reset signal.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Bandstore Signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="84pt" align="left" /><tbody valign="top"><row><entry>cdu_endofbandstore[21:5]</entry><entry>17</entry><entry>In</entry><entry>Address of the end of</entry></row><row><entry /><entry /><entry /><entry>the current band of</entry></row><row><entry /><entry /><entry /><entry>data. 256-bit word</entry></row><row><entry /><entry /><entry /><entry>aligned DRAM address.</entry></row><row><entry>cdu_startofbandstore[21:5]</entry><entry>17</entry><entry>In</entry><entry>Address of the start</entry></row><row><entry /><entry /><entry /><entry>of the current band</entry></row><row><entry /><entry /><entry /><entry>of data. 256-bit word</entry></row><row><entry /><entry /><entry /><entry>aligned DRAM address.</entry></row><row><entry>te_finishedband</entry><entry>1</entry><entry>Out</entry><entry>TE finished band sig-</entry></row><row><entry /><entry /><entry /><entry>nal to PCU and ICU.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>PCU Interface data and control signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="84pt" align="left" /><tbody valign="top"><row><entry>pcu_addr[8:2]</entry><entry>7</entry><entry>In</entry><entry>PCU address bus. 7</entry></row><row><entry /><entry /><entry /><entry>bits are required</entry></row><row><entry /><entry /><entry /><entry>to decode the address</entry></row><row><entry /><entry /><entry /><entry>space for this block.</entry></row><row><entry>pcu_dataout[31:0]</entry><entry>32</entry><entry>In</entry><entry>Shared write data bus</entry></row><row><entry /><entry /><entry /><entry>from the PCU.</entry></row><row><entry>te_pcu_datain[31:0]</entry><entry>32</entry><entry>Out</entry><entry>Read data bus from</entry></row><row><entry /><entry /><entry /><entry>the TE to the PCU.</entry></row><row><entry>pcu_rwn</entry><entry>1</entry><entry>In</entry><entry>Common read/not-write</entry></row><row><entry /><entry /><entry /><entry>signal from the PCU.</entry></row><row><entry>pcu_te_sel</entry><entry>1</entry><entry>In</entry><entry>Block select from the</entry></row><row><entry /><entry /><entry /><entry>PCU. When pcu_te_sel is</entry></row><row><entry /><entry /><entry /><entry>high both pcu_addr and</entry></row><row><entry /><entry /><entry /><entry>pcu_dataout are valid.</entry></row><row><entry>te_pcu_rdy</entry><entry>1</entry><entry>Out</entry><entry>Ready signal to the PCU.</entry></row><row><entry /><entry /><entry /><entry>When te_pcu_rdy is high</entry></row><row><entry /><entry /><entry /><entry>it indicates the last</entry></row><row><entry /><entry /><entry /><entry>cycle of the access. For</entry></row><row><entry /><entry /><entry /><entry>a write cycle this means</entry></row><row><entry /><entry /><entry /><entry>pcu_dataout has been</entry></row><row><entry /><entry /><entry /><entry>registered by the block</entry></row><row><entry /><entry /><entry /><entry>and for a read cycle this</entry></row><row><entry /><entry /><entry /><entry>means the data on</entry></row><row><entry /><entry /><entry /><entry>te_pcu_datain is valid.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>TD (raw Tag Data) DIU Read Interface signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="84pt" align="left" /><tbody valign="top"><row><entry>td_diu_rreq</entry><entry>1</entry><entry>Out</entry><entry>TD requests DRAM read.</entry></row><row><entry /><entry /><entry /><entry>A read request must be</entry></row><row><entry /><entry /><entry /><entry>accompanied by a valid</entry></row><row><entry /><entry /><entry /><entry>read address.</entry></row><row><entry>td_diu_radr[21:5]</entry><entry>17</entry><entry>Out</entry><entry>TD read address to DIU.</entry></row><row><entry /><entry /><entry /><entry>17 bits wide (256-bit</entry></row><row><entry /><entry /><entry /><entry>aligned word).</entry></row><row><entry>diu_td_rack</entry><entry>1</entry><entry>In</entry><entry>Acknowledge from DIU</entry></row><row><entry /><entry /><entry /><entry>that TD read request</entry></row><row><entry /><entry /><entry /><entry>has been accepted and</entry></row><row><entry /><entry /><entry /><entry>new read address can be</entry></row><row><entry /><entry /><entry /><entry>placed on te_diu_radr.</entry></row><row><entry>diu_data[63:0]</entry><entry>64</entry><entry>In</entry><entry>Data from DIU to TE.</entry></row><row><entry /><entry /><entry /><entry>First 64-bits are bits</entry></row><row><entry /><entry /><entry /><entry>63:0 of 256 bit word;</entry></row><row><entry /><entry /><entry /><entry>Second 64-bits are bits</entry></row><row><entry /><entry /><entry /><entry>127:64 of 256 bit word;</entry></row><row><entry /><entry /><entry /><entry>Third 64-bits are bits</entry></row><row><entry /><entry /><entry /><entry>191:128 of 256 bit word;</entry></row><row><entry /><entry /><entry /><entry>Fourth 64-bits are bits</entry></row><row><entry /><entry /><entry /><entry>255:192 of 256 bit word.</entry></row><row><entry>diu_td_rvalid</entry><entry>1</entry><entry>In</entry><entry>Signal from DIU telling</entry></row><row><entry /><entry /><entry /><entry>TD that valid read data</entry></row><row><entry /><entry /><entry /><entry>is on the diu_data bus.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>TFS (Tag Format Structure) DIU Read Interface signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="84pt" align="left" /><tbody valign="top"><row><entry>tfs_diu_rreq</entry><entry>1</entry><entry>Out</entry><entry>TFS requests DRAM read.</entry></row><row><entry /><entry /><entry /><entry>A read request must be</entry></row><row><entry /><entry /><entry /><entry>accompanied by a valid</entry></row><row><entry /><entry /><entry /><entry>read address.</entry></row><row><entry>tfs_diu_radr[21:5]</entry><entry>17</entry><entry>Out</entry><entry>TFS Read address to DIU</entry></row><row><entry /><entry /><entry /><entry>17 bits wide (256-bit</entry></row><row><entry /><entry /><entry /><entry>aligned word).</entry></row><row><entry>diu_tfs_rack</entry><entry>1</entry><entry>In</entry><entry>Acknowledge from DIU</entry></row><row><entry /><entry /><entry /><entry>that TFS read request</entry></row><row><entry /><entry /><entry /><entry>has been accepted and</entry></row><row><entry /><entry /><entry /><entry>new read address can be</entry></row><row><entry /><entry /><entry /><entry>placed on tfs_diu_radr.</entry></row><row><entry>diu_data[63:0]</entry><entry>64</entry><entry>In</entry><entry>Data from DIU to TE.</entry></row><row><entry /><entry /><entry /><entry>First 64-bits are bits</entry></row><row><entry /><entry /><entry /><entry>63:0 of 256 bit word;</entry></row><row><entry /><entry /><entry /><entry>Second 64-bits are bits</entry></row><row><entry /><entry /><entry /><entry>127:64 of 256 bit word;</entry></row><row><entry /><entry /><entry /><entry>Third 64-bits are bits</entry></row><row><entry /><entry /><entry /><entry>191:128 of 256 bit word;</entry></row><row><entry /><entry /><entry /><entry>Fourth 64-bits are bits</entry></row><row><entry /><entry /><entry /><entry>255:192 of 256 bit word.</entry></row><row><entry>diu_tfs_rvalid</entry><entry>1</entry><entry>In</entry><entry>Signal from DIU telling</entry></row><row><entry /><entry /><entry /><entry>TFS that valid read data</entry></row><row><entry /><entry /><entry /><entry>is on the diu_data bus.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>TFU Interface data and control signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="84pt" align="left" /><tbody valign="top"><row><entry>tfu_te_oktowrite</entry><entry>1</entry><entry>In</entry><entry>Ready signal indicating</entry></row><row><entry /><entry /><entry /><entry>TFU has space available</entry></row><row><entry /><entry /><entry /><entry>and is ready to be written</entry></row><row><entry /><entry /><entry /><entry>to. Also asserted from the</entry></row><row><entry /><entry /><entry /><entry>point that the TFU has</entry></row><row><entry /><entry /><entry /><entry>recieved its expected</entry></row><row><entry /><entry /><entry /><entry>number of bytes for a</entry></row><row><entry /><entry /><entry /><entry>line until the next</entry></row><row><entry /><entry /><entry /><entry>te_tfu_wradvline</entry></row><row><entry>te_tfu_wdata[7:0]</entry><entry>8</entry><entry>Out</entry><entry>Write data for TFU.</entry></row><row><entry>te_tfu_wdatavalid</entry><entry>1</entry><entry>Out</entry><entry>Write data valid signal.</entry></row><row><entry /><entry /><entry /><entry>This signal remains</entry></row><row><entry /><entry /><entry /><entry>high whenever there is</entry></row><row><entry /><entry /><entry /><entry>valid output data on</entry></row><row><entry /><entry /><entry /><entry>te_tfu_wdata</entry></row><row><entry>te_tfu_wradvline</entry><entry>1</entry><entry>Out</entry><entry>Advance line signal</entry></row><row><entry /><entry /><entry /><entry>strobed when the last</entry></row><row><entry /><entry /><entry /><entry>byte in a line is placed</entry></row><row><entry /><entry /><entry /><entry>on te_tfu_wdata</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 26.6.5 Configuration Registers
3080The configuration registers in the TE are programmed via the PCU interface. Refer to section 21.8.2 on page 321 for the description of the protocol and timing diagrams for reading and writing registers in the TE. Note that since addresses in SoPEC are byte aligned and the PCU only supports 32-bit register reads and writes the lower 2 bits of the PCU address bus are not required to decode the address space for the TE. Table 176 lists the configuration registers in the TE. Registers which address DRAM are 64-bit DRAM word aligned as this is the case for the PEC1 TE. SoPEC assumes a 256-bit DRAM word size. If the TE can be easily modified then the DRAM word addressing should be modified to 256-bit word aligned addressing. Otherwise, software should program these the 64-bit word aligned addresses on a 256-bit DRAM word boundary.
3081<tables id="TABLE-US-00266" num="00266"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="273pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 176</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>TE Configuration Registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="28pt" align="center" /><colspec colname="4" colwidth="21pt" align="center" /><colspec colname="5" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry /><entry>value</entry><entry /></row><row><entry>Address</entry><entry>register</entry><entry /><entry>on</entry></row><row><entry>TE_base +</entry><entry>name</entry><entry>#bits</entry><entry>reset</entry><entry>description</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="273pt" align="left" /><tbody valign="top"><row><entry>Control registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="21pt" align="char" char="." /><colspec colname="5" colwidth="91pt" align="left" /><tbody valign="top"><row><entry>0x00</entry><entry>Reset</entry><entry>1</entry><entry>1</entry><entry>A write to this reg-</entry></row><row><entry /><entry /><entry /><entry /><entry>ister causes a reset</entry></row><row><entry /><entry /><entry /><entry /><entry>of the TE.</entry></row><row><entry /><entry /><entry /><entry /><entry>This register can be</entry></row><row><entry /><entry /><entry /><entry /><entry>read to indicate the</entry></row><row><entry /><entry /><entry /><entry /><entry>reset state:</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - reset in progress</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - reset not in</entry></row><row><entry /><entry /><entry /><entry /><entry>progress</entry></row><row><entry>0x04</entry><entry>Go</entry><entry>1</entry><entry>0</entry><entry>Writing 1 to this reg-</entry></row><row><entry /><entry /><entry /><entry /><entry>ister starts the TE.</entry></row><row><entry /><entry /><entry /><entry /><entry>Writing 0 to this reg-</entry></row><row><entry /><entry /><entry /><entry /><entry>ister halts the TE.</entry></row><row><entry /><entry /><entry /><entry /><entry>When Go is deasserted</entry></row><row><entry /><entry /><entry /><entry /><entry>the state-machines go</entry></row><row><entry /><entry /><entry /><entry /><entry>to their idle states</entry></row><row><entry /><entry /><entry /><entry /><entry>but all counters and</entry></row><row><entry /><entry /><entry /><entry /><entry>configuration registers</entry></row><row><entry /><entry /><entry /><entry /><entry>keep their values.</entry></row><row><entry /><entry /><entry /><entry /><entry>When Go is asserted all</entry></row><row><entry /><entry /><entry /><entry /><entry>counters are reset, but</entry></row><row><entry /><entry /><entry /><entry /><entry>configuration registers</entry></row><row><entry /><entry /><entry /><entry /><entry>keep their values (i.e.</entry></row><row><entry /><entry /><entry /><entry /><entry>they don't get reset).</entry></row><row><entry /><entry /><entry /><entry /><entry>NextBandEnable is</entry></row><row><entry /><entry /><entry /><entry /><entry>cleared when Go is</entry></row><row><entry /><entry /><entry /><entry /><entry>asserted. The TFU must</entry></row><row><entry /><entry /><entry /><entry /><entry>be started before the</entry></row><row><entry /><entry /><entry /><entry /><entry>TE is started. This</entry></row><row><entry /><entry /><entry /><entry /><entry>register can be read</entry></row><row><entry /><entry /><entry /><entry /><entry>to determine if the TE</entry></row><row><entry /><entry /><entry /><entry /><entry>is running [1 = running,</entry></row><row><entry /><entry /><entry /><entry /><entry>0 = stopped).</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="273pt" align="left" /><tbody valign="top"><row><entry>Setup registers</entry></row><row><entry>constant for</entry></row><row><entry>processing of a</entry></row><row><entry>page)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="21pt" align="char" char="." /><colspec colname="5" colwidth="91pt" align="left" /><tbody valign="top"><row><entry>0x40</entry><entry>TfsStartAdr</entry><entry>19</entry><entry>0</entry><entry>Points to the first</entry></row><row><entry /><entry>(64-bit aligned</entry><entry /><entry /><entry>word of the first TFS</entry></row><row><entry /><entry>DRAM address -</entry><entry /><entry /><entry>line in DRAM.</entry></row><row><entry /><entry>should start at</entry></row><row><entry /><entry>a 256-bit</entry></row><row><entry /><entry>aligned location)</entry></row><row><entry>0x44</entry><entry>TfsEndAdr</entry><entry>19</entry><entry>0</entry><entry>Points to the first</entry></row><row><entry /><entry>(64-bit aligned</entry><entry /><entry /><entry>word of the last</entry></row><row><entry /><entry>DRAM address -</entry><entry /><entry /><entry>TFS line in DRAM.</entry></row><row><entry /><entry>should start at</entry></row><row><entry /><entry>a 256-bit</entry></row><row><entry /><entry>aligned location)</entry></row><row><entry>0x48</entry><entry>TfsFirstLineAdr</entry><entry>19</entry><entry>0</entry><entry>Points to the first</entry></row><row><entry /><entry>(64-bit aligned</entry><entry /><entry /><entry>word of the first TFS</entry></row><row><entry /><entry>DRAM address)</entry><entry /><entry /><entry>line to be encountered</entry></row><row><entry /><entry /><entry /><entry /><entry>on the page. If the</entry></row><row><entry /><entry /><entry /><entry /><entry>start of the page is in</entry></row><row><entry /><entry /><entry /><entry /><entry>an inter-tag gap, then</entry></row><row><entry /><entry /><entry /><entry /><entry>this value will be the</entry></row><row><entry /><entry /><entry /><entry /><entry>same as TFSStartAdr</entry></row><row><entry /><entry /><entry /><entry /><entry>since the first tag</entry></row><row><entry /><entry /><entry /><entry /><entry>line reached will be</entry></row><row><entry /><entry /><entry /><entry /><entry>the top line of a tag.</entry></row><row><entry>0x4C</entry><entry>DataRedun</entry><entry>1</entry><entry>0</entry><entry>Defines the data to</entry></row><row><entry /><entry /><entry /><entry /><entry>redundancy ratio for</entry></row><row><entry /><entry /><entry /><entry /><entry>the Reed Solomon en-</entry></row><row><entry /><entry /><entry /><entry /><entry>coder. Symbol size is</entry></row><row><entry /><entry /><entry /><entry /><entry>always 4 bits, Code-</entry></row><row><entry /><entry /><entry /><entry /><entry>word size is always 15</entry></row><row><entry /><entry /><entry /><entry /><entry>symbols (60 bits).</entry></row><row><entry /><entry /><entry /><entry /><entry>0–5 data symbols</entry></row><row><entry /><entry /><entry /><entry /><entry>(20 bits), 10 redun-</entry></row><row><entry /><entry /><entry /><entry /><entry>dancy symbols (40 bits)</entry></row><row><entry /><entry /><entry /><entry /><entry>1–7 data symbols</entry></row><row><entry /><entry /><entry /><entry /><entry>(28 bits), 8 redundancy</entry></row><row><entry /><entry /><entry /><entry /><entry>symbols (32 bits)</entry></row><row><entry>0x50</entry><entry>Decode2DEn</entry><entry>1</entry><entry>0</entry><entry>Determines whether or</entry></row><row><entry /><entry /><entry /><entry /><entry>not the data bits are</entry></row><row><entry /><entry /><entry /><entry /><entry>to be 2D decoded rather</entry></row><row><entry /><entry /><entry /><entry /><entry>than redundancy encoded</entry></row><row><entry /><entry /><entry /><entry /><entry>(each 2 bits of the</entry></row><row><entry /><entry /><entry /><entry /><entry>data bits becomes</entry></row><row><entry /><entry /><entry /><entry /><entry>4 output data bits).</entry></row><row><entry /><entry /><entry /><entry /><entry>0 = redundancy encode</entry></row><row><entry /><entry /><entry /><entry /><entry>data</entry></row><row><entry /><entry /><entry /><entry /><entry>1 = decode each 2 bits</entry></row><row><entry /><entry /><entry /><entry /><entry>of data into 4 bits</entry></row><row><entry>0x54</entry><entry>VariableDataPresent</entry><entry>1</entry><entry>0</entry><entry>Defines whether or not</entry></row><row><entry /><entry /><entry /><entry /><entry>there is variable data</entry></row><row><entry /><entry /><entry /><entry /><entry>in the tags. If there</entry></row><row><entry /><entry /><entry /><entry /><entry>is none, no attempt is</entry></row><row><entry /><entry /><entry /><entry /><entry>made to read tag data,</entry></row><row><entry /><entry /><entry /><entry /><entry>and tag encoding should</entry></row><row><entry /><entry /><entry /><entry /><entry>only reference fixed</entry></row><row><entry /><entry /><entry /><entry /><entry>tag data.</entry></row><row><entry>0x58</entry><entry>EncodeFixed</entry><entry>1</entry><entry>0</entry><entry>Determines whether or</entry></row><row><entry /><entry /><entry /><entry /><entry>not the lower 40 (or 56)</entry></row><row><entry /><entry /><entry /><entry /><entry>bits of fixed data</entry></row><row><entry /><entry /><entry /><entry /><entry>should be encoded into</entry></row><row><entry /><entry /><entry /><entry /><entry>120 bits or simply used</entry></row><row><entry /><entry /><entry /><entry /><entry>as is.</entry></row><row><entry>0x5C</entry><entry>TagMaxDotpairs</entry><entry>8</entry><entry>0</entry><entry>The width of a tag in</entry></row><row><entry /><entry /><entry /><entry /><entry>dot-pairs, minus 1.</entry></row><row><entry /><entry /><entry /><entry /><entry>Minimum 0, Maximum =</entry></row><row><entry /><entry /><entry /><entry /><entry>191.</entry></row><row><entry>0x60</entry><entry>TagMaxLine</entry><entry>9</entry><entry>0</entry><entry>The number of lines in</entry></row><row><entry /><entry /><entry /><entry /><entry>a tag, minus 1.</entry></row><row><entry /><entry /><entry /><entry /><entry>Minimum 0, Maximum =</entry></row><row><entry /><entry /><entry /><entry /><entry>383.</entry></row><row><entry>0x64</entry><entry>TagGapDot</entry><entry>14</entry><entry>0</entry><entry>The number of dot pairs</entry></row><row><entry /><entry /><entry /><entry /><entry>between tags in the dot</entry></row><row><entry /><entry /><entry /><entry /><entry>dimension minus 1.</entry></row><row><entry /><entry /><entry /><entry /><entry>Only valid if</entry></row><row><entry /><entry /><entry /><entry /><entry>TagGapPresent[bit 0] =</entry></row><row><entry /><entry /><entry /><entry /><entry>1.</entry></row><row><entry>0x68</entry><entry>TagGapLine</entry><entry>14</entry><entry>0</entry><entry>Defines the number of</entry></row><row><entry /><entry /><entry /><entry /><entry>dotlines between tags</entry></row><row><entry /><entry /><entry /><entry /><entry>in the line dimension</entry></row><row><entry /><entry /><entry /><entry /><entry>minus 1.</entry></row><row><entry /><entry /><entry /><entry /><entry>Only valid if</entry></row><row><entry /><entry /><entry /><entry /><entry>TagGapPresent[bit1] =</entry></row><row><entry /><entry /><entry /><entry /><entry>1.</entry></row><row><entry>0x6C</entry><entry>DotPairsPerLine</entry><entry>14</entry><entry>0</entry><entry>Number of output dot pairs</entry></row><row><entry /><entry /><entry /><entry /><entry>to generate per tag line.</entry></row><row><entry>0x70</entry><entry>DotStartTagSense</entry><entry>2</entry><entry>0</entry><entry>Determines for the first/</entry></row><row><entry /><entry /><entry /><entry /><entry>(even bit 0) and second/odd</entry></row><row><entry /><entry /><entry /><entry /><entry>(bit 1) rows of tags</entry></row><row><entry /><entry /><entry /><entry /><entry>whether or not the first</entry></row><row><entry /><entry /><entry /><entry /><entry>dot position of the line</entry></row><row><entry /><entry /><entry /><entry /><entry>is in a tag.</entry></row><row><entry /><entry /><entry /><entry /><entry>1 = in a tag, 0 =</entry></row><row><entry /><entry /><entry /><entry /><entry>in an inter-tag gap.</entry></row><row><entry>0x74</entry><entry>TagGapPresent</entry><entry>2</entry><entry>0</entry><entry>Bit 0 is 1 if there is</entry></row><row><entry /><entry /><entry /><entry /><entry>an inter-tag gap in the</entry></row><row><entry /><entry /><entry /><entry /><entry>dot dimension, and 0 if</entry></row><row><entry /><entry /><entry /><entry /><entry>tags are tightly packed.</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 1 is 1 if there is</entry></row><row><entry /><entry /><entry /><entry /><entry>an inter-tag gap in the</entry></row><row><entry /><entry /><entry /><entry /><entry>line dimension, and 0 if</entry></row><row><entry /><entry /><entry /><entry /><entry>tags are tightly packed.</entry></row><row><entry>0x78</entry><entry>YScale</entry><entry>8</entry><entry>1</entry><entry>Tag scale factor in Y</entry></row><row><entry /><entry /><entry /><entry /><entry>direction. Output lines</entry></row><row><entry /><entry /><entry /><entry /><entry>to the TFU will be gen-</entry></row><row><entry /><entry /><entry /><entry /><entry>erated YScale times.</entry></row><row><entry>0x80 to</entry><entry>DotStartPos</entry><entry>2 × 14</entry><entry>0</entry><entry>Determines for the first/</entry></row><row><entry>0x84</entry><entry /><entry /><entry /><entry>even (0) and second/odd</entry></row><row><entry /><entry /><entry /><entry /><entry>(1) rows of tags the</entry></row><row><entry /><entry /><entry /><entry /><entry>number of dotpairs</entry></row><row><entry /><entry /><entry /><entry /><entry>remaining minus 1, in</entry></row><row><entry /><entry /><entry /><entry /><entry>either the tag or inter-</entry></row><row><entry /><entry /><entry /><entry /><entry>tag gap at the start of</entry></row><row><entry /><entry /><entry /><entry /><entry>the line.</entry></row><row><entry>0x88 to</entry><entry>NumTags</entry><entry>2 × 8 </entry><entry>0</entry><entry>Determines for the first/</entry></row><row><entry>0x8C</entry><entry /><entry /><entry /><entry>even and second/odd rows</entry></row><row><entry /><entry /><entry /><entry /><entry>of tags how many tags</entry></row><row><entry /><entry /><entry /><entry /><entry>are present in a line</entry></row><row><entry /><entry /><entry /><entry /><entry>(equals number of tags</entry></row><row><entry /><entry /><entry /><entry /><entry>minus 1).</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="273pt" align="left" /><tbody valign="top"><row><entry>Setup band</entry></row><row><entry>related registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="21pt" align="char" char="." /><colspec colname="5" colwidth="91pt" align="left" /><tbody valign="top"><row><entry>0xC0</entry><entry>NextBandStartTagDataAdr</entry><entry /><entry /><entry>Holds the value of</entry></row><row><entry /><entry>(64-bit aligned</entry><entry /><entry /><entry>StartTagDataAdr for the</entry></row><row><entry /><entry>DRAM address -</entry><entry /><entry /><entry>next band. This value is</entry></row><row><entry /><entry>should start at</entry><entry /><entry /><entry>copied to StartTagDataAdr</entry></row><row><entry /><entry>a 256-bit</entry><entry /><entry /><entry>when DoneBand is 1 and</entry></row><row><entry /><entry>aligned location)</entry><entry /><entry /><entry>NextBandEnable is 1, or</entry></row><row><entry /><entry /><entry /><entry /><entry>when Go transitions from</entry></row><row><entry /><entry /><entry /><entry /><entry>0 to 1.</entry></row><row><entry>0xC4</entry><entry>NextBandEndOfTagData</entry><entry /><entry /><entry>Holds the value of</entry></row><row><entry /><entry>(64-bit aligned</entry><entry /><entry /><entry>EndOfTagData for the</entry></row><row><entry /><entry>DRAM address)</entry><entry /><entry /><entry>next band. This value is</entry></row><row><entry /><entry /><entry /><entry /><entry>copied to EndOfTagData</entry></row><row><entry /><entry /><entry /><entry /><entry>when DoneBand is 1 and</entry></row><row><entry /><entry /><entry /><entry /><entry>NextBandEnable is 1, or</entry></row><row><entry /><entry /><entry /><entry /><entry>when Go transitions from</entry></row><row><entry /><entry /><entry /><entry /><entry>0 to 1.</entry></row><row><entry>0xC8</entry><entry>NextBandFirstTagLineHeight</entry><entry>9</entry><entry>0</entry><entry>Holds the value of</entry></row><row><entry /><entry /><entry /><entry /><entry>FirstTagLineHeight for</entry></row><row><entry /><entry /><entry /><entry /><entry>the next band. This</entry></row><row><entry /><entry /><entry /><entry /><entry>value is copied to</entry></row><row><entry /><entry /><entry /><entry /><entry>FirstTagLineHeight when</entry></row><row><entry /><entry /><entry /><entry /><entry>DoneBand gets is 1 and</entry></row><row><entry /><entry /><entry /><entry /><entry>NextBandEnable is 1, or</entry></row><row><entry /><entry /><entry /><entry /><entry>when Go transitions from</entry></row><row><entry /><entry /><entry /><entry /><entry>0 to 1.</entry></row><row><entry>0xCC</entry><entry>NextBandEnable</entry><entry /><entry /><entry>When NextBandEnable is 1</entry></row><row><entry /><entry /><entry /><entry /><entry>and DoneBand is 1, then</entry></row><row><entry /><entry /><entry /><entry /><entry>when te_finishedband is</entry></row><row><entry /><entry /><entry /><entry /><entry>set at the end of a band:</entry></row><row><entry /><entry /><entry /><entry /><entry>NextBandStartTagDataAdr</entry></row><row><entry /><entry /><entry /><entry /><entry>is copied to</entry></row><row><entry /><entry /><entry /><entry /><entry>StartTagDataAdr</entry></row><row><entry /><entry /><entry /><entry /><entry>NextBandEndOfTagData is</entry></row><row><entry /><entry /><entry /><entry /><entry>copied to EndOfTagData</entry></row><row><entry /><entry /><entry /><entry /><entry>NextBandFirstTagLineHeight</entry></row><row><entry /><entry /><entry /><entry /><entry>is copied to</entry></row><row><entry /><entry /><entry /><entry /><entry>FirstTagLineHeight</entry></row><row><entry /><entry /><entry /><entry /><entry>DoneBand is cleared</entry></row><row><entry /><entry /><entry /><entry /><entry>NextBandEnable is cleared.</entry></row><row><entry /><entry /><entry /><entry /><entry>NextBandEnable is cleared</entry></row><row><entry /><entry /><entry /><entry /><entry>when Go is asserted.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="273pt" align="left" /><tbody valign="top"><row><entry>Read-only band</entry></row><row><entry>related registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="21pt" align="char" char="." /><colspec colname="5" colwidth="91pt" align="left" /><tbody valign="top"><row><entry>0xD0</entry><entry>DoneBand</entry><entry>1</entry><entry>0</entry><entry>Specifies whether the tag</entry></row><row><entry /><entry /><entry /><entry /><entry>data interface has finished</entry></row><row><entry /><entry /><entry /><entry /><entry>loading all the tag data</entry></row><row><entry /><entry /><entry /><entry /><entry>for the band.</entry></row><row><entry /><entry /><entry /><entry /><entry>It is cleared to 0 when Go</entry></row><row><entry /><entry /><entry /><entry /><entry>transitions from 0 to 1.</entry></row><row><entry /><entry /><entry /><entry /><entry>When the tag data interface</entry></row><row><entry /><entry /><entry /><entry /><entry>has finished loading all</entry></row><row><entry /><entry /><entry /><entry /><entry>the tag data for the band,</entry></row><row><entry /><entry /><entry /><entry /><entry>the te_finishedband signal</entry></row><row><entry /><entry /><entry /><entry /><entry>is given out and the</entry></row><row><entry /><entry /><entry /><entry /><entry>DoneBand flag is set.</entry></row><row><entry /><entry /><entry /><entry /><entry>If NextBandEnable is 1 at</entry></row><row><entry /><entry /><entry /><entry /><entry>this time then</entry></row><row><entry /><entry /><entry /><entry /><entry>startTagDataAdr,</entry></row><row><entry /><entry /><entry /><entry /><entry>endOfTagData and</entry></row><row><entry /><entry /><entry /><entry /><entry>firstTaglineHeight are</entry></row><row><entry /><entry /><entry /><entry /><entry>updated with the values</entry></row><row><entry /><entry /><entry /><entry /><entry>for the next band and</entry></row><row><entry /><entry /><entry /><entry /><entry>DoneBand is cleared.</entry></row><row><entry /><entry /><entry /><entry /><entry>Processing of the next</entry></row><row><entry /><entry /><entry /><entry /><entry>band starts immediately.</entry></row><row><entry /><entry /><entry /><entry /><entry>If NextBandEnable is 0</entry></row><row><entry /><entry /><entry /><entry /><entry>then the remainder of the</entry></row><row><entry /><entry /><entry /><entry /><entry>TE will continue to run,,</entry></row><row><entry /><entry /><entry /><entry /><entry>while the read control</entry></row><row><entry /><entry /><entry /><entry /><entry>unit waits for</entry></row><row><entry /><entry /><entry /><entry /><entry>NextBandEnable to be set</entry></row><row><entry /><entry /><entry /><entry /><entry>before it restarts. Read</entry></row><row><entry /><entry /><entry /><entry /><entry>only.</entry></row><row><entry>0xD4</entry><entry>StartTagDataAdr</entry><entry>19</entry><entry>0</entry><entry>The start address of the</entry></row><row><entry /><entry>(64-bit aligned</entry><entry /><entry /><entry>current row of raw tag</entry></row><row><entry /><entry>DRAM address -</entry><entry /><entry /><entry>data. This is initially</entry></row><row><entry /><entry>should start at</entry><entry /><entry /><entry>points to the first word</entry></row><row><entry /><entry>a 256-bit</entry><entry /><entry /><entry>of the band's tag data,</entry></row><row><entry /><entry>aligned location)</entry><entry /><entry /><entry>which should be aligned</entry></row><row><entry /><entry /><entry /><entry /><entry>to a 128-bit boundary (i.e.</entry></row><row><entry /><entry /><entry /><entry /><entry>the lower bit of this</entry></row><row><entry /><entry /><entry /><entry /><entry>address should be 0).</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only.</entry></row><row><entry>0xD8</entry><entry>EndOfTagData</entry><entry>19</entry><entry>0</entry><entry>Points to the address of</entry></row><row><entry /><entry>(64-bit aligned</entry><entry /><entry /><entry>the final tag for the band.</entry></row><row><entry /><entry>DRAM address)</entry><entry /><entry /><entry>When all the tag data up</entry></row><row><entry /><entry /><entry /><entry /><entry>to and including address</entry></row><row><entry /><entry /><entry /><entry /><entry>endOfTagData has been read</entry></row><row><entry /><entry /><entry /><entry /><entry>in, the te_finishedband</entry></row><row><entry /><entry /><entry /><entry /><entry>signal is given and the</entry></row><row><entry /><entry /><entry /><entry /><entry>doneBand flag is set. Read</entry></row><row><entry /><entry /><entry /><entry /><entry>only.</entry></row><row><entry>0xDC</entry><entry>FirstTagLineHeight</entry><entry>9</entry><entry>0</entry><entry>The number of lines minus</entry></row><row><entry /><entry /><entry /><entry /><entry>1 in the first tag en-</entry></row><row><entry /><entry /><entry /><entry /><entry>countered in this band.</entry></row><row><entry /><entry /><entry /><entry /><entry>This will be equal to</entry></row><row><entry /><entry /><entry /><entry /><entry>TagMaxLine if the band</entry></row><row><entry /><entry /><entry /><entry /><entry>starts at a tag boundary.</entry></row><row><entry /><entry /><entry /><entry /><entry>Read only.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="273pt" align="left" /><tbody valign="top"><row><entry>Work registers (set</entry></row><row><entry>before starting the</entry></row><row><entry>TE and must not</entry></row><row><entry>be touched</entry></row><row><entry>between bands)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="21pt" align="char" char="." /><colspec colname="5" colwidth="91pt" align="left" /><tbody valign="top"><row><entry>0x100</entry><entry>LineInTag</entry><entry>1</entry><entry>0</entry><entry>Determines whether or not</entry></row><row><entry /><entry /><entry /><entry /><entry>the first line of the page</entry></row><row><entry /><entry /><entry /><entry /><entry>is in a line of tags or in</entry></row><row><entry /><entry /><entry /><entry /><entry>an inter-tag gap.</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - in a tag, 0 - in an</entry></row><row><entry /><entry /><entry /><entry /><entry>inter-tag gap.</entry></row><row><entry>0x104</entry><entry>LinePos</entry><entry>14</entry><entry>0</entry><entry>The number of lines</entry></row><row><entry /><entry /><entry /><entry /><entry>remaining minus 1, in</entry></row><row><entry /><entry /><entry /><entry /><entry>either the tag or the</entry></row><row><entry /><entry /><entry /><entry /><entry>inter-tag gap in at the</entry></row><row><entry /><entry /><entry /><entry /><entry>start of the page.</entry></row><row><entry>0x110 to</entry><entry>TagData</entry><entry>4 × 32</entry><entry>0</entry><entry>This 128 bit register must</entry></row><row><entry>0x11C</entry><entry /><entry /><entry /><entry>be set up initially with</entry></row><row><entry /><entry /><entry /><entry /><entry>the fixed data record for</entry></row><row><entry /><entry /><entry /><entry /><entry>the page. This is either</entry></row><row><entry /><entry /><entry /><entry /><entry>the lower 40 (or 56) bits</entry></row><row><entry /><entry /><entry /><entry /><entry>(and the encodeFixed reg-</entry></row><row><entry /><entry /><entry /><entry /><entry>ister should be set), or</entry></row><row><entry /><entry /><entry /><entry /><entry>the lower 120 bits (and</entry></row><row><entry /><entry /><entry /><entry /><entry>encodedFixed should be</entry></row><row><entry /><entry /><entry /><entry /><entry>clear). The tagData[0]</entry></row><row><entry /><entry /><entry /><entry /><entry>register contains the lower</entry></row><row><entry /><entry /><entry /><entry /><entry>32 bits and the tagData[3]</entry></row><row><entry /><entry /><entry /><entry /><entry>register contains the upper</entry></row><row><entry /><entry /><entry /><entry /><entry>32 bits. This register is</entry></row><row><entry /><entry /><entry /><entry /><entry>used throughout the tag</entry></row><row><entry /><entry /><entry /><entry /><entry>encoding process to hold</entry></row><row><entry /><entry /><entry /><entry /><entry>the next tag's variable</entry></row><row><entry /><entry /><entry /><entry /><entry>data.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="273pt" align="left" /><tbody valign="top"><row><entry>Work registers (set</entry></row><row><entry>internally)</entry></row><row><entry>Read-only from</entry></row><row><entry>the point of view of</entry></row><row><entry>PCU register</entry></row><row><entry>access</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="21pt" align="char" char="." /><colspec colname="5" colwidth="91pt" align="left" /><tbody valign="top"><row><entry>0x140</entry><entry>DotPos</entry><entry>14</entry><entry>0</entry><entry>Defines the number of</entry></row><row><entry /><entry /><entry /><entry /><entry>dotpairs remaining in</entry></row><row><entry /><entry /><entry /><entry /><entry>either the tag or inter-</entry></row><row><entry /><entry /><entry /><entry /><entry>tag gap. Does not need to</entry></row><row><entry /><entry /><entry /><entry /><entry>be setup.</entry></row><row><entry>0x144</entry><entry>CurrTagPlaneAdr</entry><entry>14</entry><entry>0</entry><entry>The dot-pair number being</entry></row><row><entry /><entry /><entry /><entry /><entry>generated.</entry></row><row><entry>0x148</entry><entry>DotsInTag</entry><entry>1</entry><entry>0</entry><entry>Determines whether the</entry></row><row><entry /><entry /><entry /><entry /><entry>current dot pair is in a</entry></row><row><entry /><entry /><entry /><entry /><entry>tag or not</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - in a tag, 0 - in an</entry></row><row><entry /><entry /><entry /><entry /><entry>inter-tag gap.</entry></row><row><entry>0x14C</entry><entry>TagAltSense</entry><entry>1</entry><entry>0</entry><entry>Determines whether the</entry></row><row><entry /><entry /><entry /><entry /><entry>production of output dots</entry></row><row><entry /><entry /><entry /><entry /><entry>is for the first (and sub-</entry></row><row><entry /><entry /><entry /><entry /><entry>sequent even) or second</entry></row><row><entry /><entry /><entry /><entry /><entry>(and subsequent odd) row</entry></row><row><entry /><entry /><entry /><entry /><entry>of tags.</entry></row><row><entry>0x154</entry><entry>CurrTFSAdr</entry><entry>19</entry><entry>0</entry><entry>Points to the start next</entry></row><row><entry /><entry>(64-bit aligned</entry><entry /><entry /><entry>line of the TFS to be</entry></row><row><entry /><entry>DRAM address)</entry><entry /><entry /><entry>read in.</entry></row><row><entry>0x158</entry><entry>ReadsRemaining</entry><entry>4</entry><entry>0</entry><entry>Number of reads remaining</entry></row><row><entry /><entry /><entry /><entry /><entry>in the current burst from</entry></row><row><entry /><entry /><entry /><entry /><entry>the raw tag data interface</entry></row><row><entry>0x15C</entry><entry>CountX</entry><entry>8</entry><entry>0</entry><entry>The number of tags remain-</entry></row><row><entry /><entry /><entry /><entry /><entry>ing to be read (minus 1)</entry></row><row><entry /><entry /><entry /><entry /><entry>by the raw tag data inter-</entry></row><row><entry /><entry /><entry /><entry /><entry>face for the current line.</entry></row><row><entry>0x160</entry><entry>CountY</entry><entry>9</entry><entry>0</entry><entry>The number of times (minus</entry></row><row><entry /><entry /><entry /><entry /><entry>1) the tag data for the</entry></row><row><entry /><entry /><entry /><entry /><entry>current line of tags needs</entry></row><row><entry /><entry /><entry /><entry /><entry>to be read in by the raw</entry></row><row><entry /><entry /><entry /><entry /><entry>tag data interface.</entry></row><row><entry>0x164</entry><entry>RtdTagSense</entry><entry>1</entry><entry>0</entry><entry>Determines whether the raw</entry></row><row><entry /><entry /><entry /><entry /><entry>tag data interface is</entry></row><row><entry /><entry /><entry /><entry /><entry>currently reading even</entry></row><row><entry /><entry /><entry /><entry /><entry>rows of tags (=0) or</entry></row><row><entry /><entry /><entry /><entry /><entry>odd rows of tags (=1)</entry></row><row><entry /><entry /><entry /><entry /><entry>with respect to the start</entry></row><row><entry /><entry /><entry /><entry /><entry>of the page. Note that</entry></row><row><entry /><entry /><entry /><entry /><entry>this can be different from</entry></row><row><entry /><entry /><entry /><entry /><entry>tagAltSense since the raw</entry></row><row><entry /><entry /><entry /><entry /><entry>tag data interface is</entry></row><row><entry /><entry /><entry /><entry /><entry>reading ahead of the</entry></row><row><entry /><entry /><entry /><entry /><entry>production of dots.</entry></row><row><entry>0x168</entry><entry>RawTagDataAdr</entry><entry>19</entry><entry>0</entry><entry>The current read address</entry></row><row><entry /><entry>(64-bit aligned</entry><entry /><entry /><entry>within the unencoded raw</entry></row><row><entry /><entry>DRAM address)</entry><entry /><entry /><entry>tag data.</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3082The PCU accessible registers are divided amongst the TE top level and the TE sub-blocks. This is achieved by including write decoders in the sub-blocks as well as the top level, see <figref idref="DRAWINGS">FIG. 189</figref>. In order to perform reads the sub-block registers are fed to the top level where the read decode is carried out on all the PCU accessible TE registers.
000026.6.5.1 Starting the TE and Restarting the TE Between Bands
3083The TE must be started after the TFU.
3084For the first band of data, users set up NextBandStartTagDataAdr, NextBandEndTagData and NextBandFirstTagLineHeight as well as other TE configuration registers. Users then set the TE's Go bit to start processing of the band. When the tag data for the band has finished being decoded, the te_finishedband interrupt will be sent to the PCU and ICU indicating that the memory associated with the first band is now free. Processing can now start on the next band of tag data.
3085In order to process the next band NextBandStartTagDataAdr, NextBandEndTagData and NextBandFirstTagLineHeight need to be updated before writing a 1 to NextBandEnable. There are 4 mechanisms for restarting the TE between bands: <ul id="ul0306" list-style="none"><li id="ul0306-0001" num="3086">a. te_finishedband causes an interrupt to the CPU. The TE will have set its DoneBand bit. The CPU reprograms the NextBandStartTagDataAdr, NextBandEndTagData and NextBandFirstTagLineHeight registers, and sets NextBandEnable to restart the TE.</li><li id="ul0306-0002" num="3087">b. The CPU programs the TE's NextBandStartTagDataAdr, NextBandEndTagData and NextBandFirstTagLineHeight registers and sets the NextBandEnable flag before the end of the current band. At the end of the current band the TE sets DoneBand. As NextBandEnable is already 1, the TE starts processing the next band immediately.</li><li id="ul0306-0003" num="3088">c. The PCU is programmed so that te_finishedband triggers the PCU to execute commands from DRAM to reprogram the NextBandStaifTagDataAdr, NextBandEndTagData and NextBandFirstTagLineHeight registers and set the NextBandEnable bit to start the TE processing the next band. The advantage of this scheme is that the CPU could process band headers in advance and store the band commands in DRAM ready for execution.</li><li id="ul0306-0004" num="3089">d. This is a combination of b and c above. The PCU (rather than the CPU in b) programs the TE's NextBandStartTagDataAdr, NextBandEndTagData and NextBandFirstTagLineHeight registers and sets the NextBandEnable bit before the end of the current band. At the end of the current band the TE sets DoneBand and pulses te_finishedband. As NextBandEnable is already 1, the TE starts processing the next band immediately. Simultaneously, te_finishedband triggers the PCU to fetch commands from DRAM. The TE will have restarted by the time the PCU has fetched commands from DRAM. The PCU commands program the TE next band shadow registers and sets the NextBandEnable bit.</li></ul>
3090After the first tag on the page, all bands have their first tag start at the top i.e. NextBandFirstTagLineHeight=TagMaxLine. Therefore the same value of NextBandFirstTagLineHeight will normally be used for all bands. Certainly, NextBandFirstTagLineHeight should not need to change after the second time it is programmed.
000026.6.6 TE Top Level FSM
3091The following diagram illustrates the states in the FSM.
3092At the highest level, the TE state machine steps through the output lines of a page one line at a time, with the starting position either in an inter-tag gap (signal dotsintag=0) or in a tag (signals tfsvalid and tdvalid and lineintag=1) (a SoPEC may be only printing part of a tag due to multiple SoPECs printing a single line).
3093If the current position is within an inter-tag gap, an output of 0 is generated. If the current position is within a tag, the tag format structure is used to determine the value of the output dot, using the appropriate encoded data bit from the fixed or variable data buffers as necessary. The TE then advances along the line of dots, moving through tags and inter-tag gaps according to the tag placement parameters.
3094Table 177 highlights the signals used within the FSM.
3095<tables id="TABLE-US-00267" num="00267"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 177</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Signals used within TE top level FSM</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>Signal Name</entry><entry>Function</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>pclk</entry><entry>Sync clock used to register all data</entry></row><row><entry /><entry /><entry>within the FSM</entry></row><row><entry /><entry>prst_n, te_reset</entry><entry>Reset signals</entry></row><row><entry /><entry>advtagline</entry><entry>1 cycles pulse indicating to TDI and</entry></row><row><entry /><entry /><entry>TFS sub-blocks to move onto the next</entry></row><row><entry /><entry /><entry>line of Tag data</entry></row><row><entry /><entry>currdotlineadr[13:0]</entry><entry>Address counter starting 2 pclk ahead</entry></row><row><entry /><entry /><entry>of currtagplaneadr to generate the</entry></row><row><entry /><entry /><entry>correct dotpair for the current line</entry></row><row><entry /><entry>dotpos</entry><entry>Counter to identify how many dotpairs</entry></row><row><entry /><entry /><entry>wide the tag/gap is</entry></row><row><entry /><entry>dotsintag</entry><entry>Signal identifying whether the dotpair</entry></row><row><entry /><entry /><entry>are in a tag(1)/gap(0)</entry></row><row><entry /><entry>lineintag_temp</entry><entry>Identical to lineintag but generated</entry></row><row><entry /><entry /><entry>1 pclk earlier</entry></row><row><entry /><entry>linepos_shadow</entry><entry>Shadow register for linepos due to</entry></row><row><entry /><entry /><entry>linepos being written to by 2</entry></row><row><entry /><entry /><entry>different processes</entry></row><row><entry /><entry>talaltsense</entry><entry>Flag which alternates between tag/gap</entry></row><row><entry /><entry /><entry>lines</entry></row><row><entry /><entry>te_state</entry><entry>FSM state variable</entry></row><row><entry /><entry>teplanebuf</entry><entry>6-bit shift register used to format</entry></row><row><entry /><entry /><entry>dotpairs into a byte for the TFU</entry></row><row><entry /><entry>wradvline</entry><entry>Advance line signal strobed when the</entry></row><row><entry /><entry /><entry>last byte in a line is placed on</entry></row><row><entry /><entry /><entry>te_tfu_wdata</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3096Due to the 2 system clock delay in the TFS (both Table A and Table B outputs are registered) the TE FSM is working 2 system clock cycles AHEAD of the logic generating the write data for the TFU. As a result the following control signals had to be single/double registered on the system clock.
3097The tag_dot_line state can be broken down into 3 different stages.
3098Stage1:—The state tag_dot_line is entered due to the go signal becoming active. This state controls the writing of dotbytes to the TFU. As long as the tag line buffer address is not equal to the dotpairsperline register value and tfu_te_oktowrite is active, and there is valid TFS and TD available or taggaps, dotpairs are buffered into bytes and written to the TFU. The tag line buffer address is used internally but not supplied to the TFU since the TFU is a FIFO rather than the line store used in PEC1.
3099While generating the dotline of a tag/gap line (lineintag flag=1) the dot position counter dotpos is decremented/reloaded (with tagmaxdotpairs or taggapdot) as the TE moves between tags/gaps. The dotsintag flag is toggled between tags/gaps (0 for a gap, 1 for a tag). This pattern continues until the end of a dotline approaches (currdotlineadr==dotpairsperline).
31002 system clock cycles before the end of the dotline the lineintag and tagaltsense signals must be prepared for the next dotline be it in a tag/gap dotline or a purely gap dotline.
3101Stage2:—At this point the end of a dot line is reached so it is time to decrement the linepos counter if still in a tag/gap row or reload the linepos register, dotpos counter and reprogram the dotsintag flag if going onto another tag/gap or pure gap row. Any signal with the _temp extension means this register is updated a cycle early in order for the real register to get its correct value while switching between dot lines and tag rows when dotpos and linepos counters reach zero i.e when dotpos=0 the end of a tag/gap has been reached, when linepos=0 the end of a tag row is reached. This stage uses the signals lineintag temp and tagaltsense which were generated one system clock cycle earlier in Stage 1.
3102Stage3:—This stage implements the writing of dotpairs to the correct part of the 6-bit shift register based on the LSBs of currtagplaneadr and also implements the counter for the currtagplaneadr. The currtagplaneadr is reset on reaching currtagplaneadr=(dotpairsperline−1). All the qualifier signals e.g dotsintag for this stage are delayed by 2 system clock cycles i.e. the currtagplaneadr (which is the internal write address not needed by the TFU) cannot be incremented until the dotpairs are available which is always 2 system clock cycles later than when currdotlineadr is incremented.
3103The wradvline and advtagline pulses are generated using the same logic (currently separated in the PEC1 Tag Encoder VHDL for clarity). Both of these pulses used to update further registers hence the reason they do not use the delayed by 2 system clock cycle qualifiers.
000026.6.7 Combinational Logic
3104The TDI is responsible for providing the information data for a tag while the TFSI is responsible for deciding whether a particular dot on the tag should be printed as background pattern or tag information. Every dot within a tag's boundary is either an information dot or part of the background pattern.
3105The resulting lines of dots are stored in the TFU.
3106The TFSI reads one Tag Line Structure (TLS) from the DIU for every dot line of tags. Depending on the current printing position within the tag (indicated by the signal tagdotnum), the TFS interface outputs dot information for two dots and if necessary the corresponding read addresses for encoded tag data. The read address are supplied to the TDI which outputs the corresponding data values.
3107These data values (tdi_etd0 and tdi_etd1) are then combined with the dot information (tfsi_ta_dot0 and tfsi_ta_dot1) to produce the dot values that will actually be printed on the page (dots), see <figref idref="DRAWINGS">FIG. 192</figref>.
3108The signal lastdotintag is generated by checking that the dots are in a tag (dotsintag=1) and that the dotposition counter dotpos is equal to zero. It is also used by the TFS to load the index address register with zeros at the end of a tag as this is always the starting index when going from one tag to the next. lastdotintag is gated with advtagline in the TFSi (Table C) where adv_tfs_line pulse is used to update the Table C address reg for the new tag line—this is because lastdotintag occurs a cycle earlier than adv_tfs_line which would result in the wrong Table C value for the last dotpair. lastdotintag is also used in the TDi FSM (etd_switch state) to pulse the etd_advtag signal hence switching buffers in the ETDi for the next tag.
3109The signal lastdotintag1 is identical to lastdotintag except it is combinatorially generated (1 cycle earlier than lastdotintag, except at the end of a tagline). lastdotintag1 signal is only used in the TDi to reset the tdvalid signal on the cycle when dotpos=0. Note the UNSIGNED(currdotlineadr)=UNSIGNED(dotpairsperline)−1 not UNSIGNED(currdotlineadr)=UNSIGNED(dotpairsperline)−2 as in the lastdotintag_gen process as this is an combinatorial process.
3110The dotposvalid signal is created based on being in a tag line (lineintag1=1), dots being in a tag (dotsintag1=1), having a valid tag format structure available (tfsvalid1=1) and having encoded tag data available (tdvalid1=1). Note that each of the qualifier signals are delayed by 1 pclk cycle due to the registering of Table A output data into Table C where dotposvalid is used. The dotposvalid signal is used as an enable to load the Table C address register with the next index into Table B which in turn provides the 2 addresses to make 2 dots available.
3111The signal te_tfu_wdatavalid can only be active if in a taggap or if valid tag data is available (tdvalid2 and tfsvalid2) and the currtagpplaneadr(1:0) equal 11 i.e. a byte of data has been generated by combining four dotpairs.
3112The signal tagdotnum tells the TFS how many dotpairs remain in a tag/gap. It is calculated by subtracting the value in the dotpos counter from the value programmed in the tagmaxdotpairs register.
000026.7 Tag Data Interface (TDI)
000026.7.1 I/O Specification
3113<tables id="TABLE-US-00268" num="00268"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 178</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>TDI Port List</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="21pt" align="left" /><colspec colname="3" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>signal name</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Clocks and Resets</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="21pt" align="left" /><colspec colname="3" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>pclk</entry><entry>In</entry><entry>SoPEC system clock</entry></row><row><entry>prst_n</entry><entry>In</entry><entry>Active-low, synchronous</entry></row><row><entry /><entry /><entry>reset in pclk domain.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>DIU Read Interface Signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="21pt" align="left" /><colspec colname="3" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>diu_data[63:0]</entry><entry>In</entry><entry>Data from DRAM.</entry></row><row><entry>td_diu_rreq</entry><entry>Out</entry><entry>Data request to DRAM.</entry></row><row><entry>td_diu_radr[21:5]</entry><entry>Out</entry><entry>Read address to DRAM.</entry></row><row><entry>diu_td_rack</entry><entry>In</entry><entry>Data acknowledge from DRAM.</entry></row><row><entry>diu_td_rvalid</entry><entry>In</entry><entry>Data valid signal from DRAM.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>PCU Interface Data, Control Signals and</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="21pt" align="left" /><colspec colname="3" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>pcu_dataout[31:0]</entry><entry>In</entry><entry>PCU writes this data.</entry></row><row><entry>pcu_addr[8:2]</entry><entry>In</entry><entry>PCU accesses this address.</entry></row><row><entry>pcu_rwn</entry><entry>In</entry><entry>Global read/write-not signal</entry></row><row><entry /><entry /><entry>from PCU.</entry></row><row><entry>pcu_te_sel</entry><entry>In</entry><entry>PCU selects TE for r/w access.</entry></row><row><entry>pcu_te_reset</entry><entry>In</entry><entry>PCU reset.</entry></row><row><entry>td_te_doneband</entry><entry>Out</entry><entry>PCU readable registers.</entry></row><row><entry>td_te_dataredun</entry></row><row><entry>td_te_decode2den</entry></row><row><entry>td_te_variabledatapresent</entry></row><row><entry>td_te_encodefixed</entry></row><row><entry>td_te_numtags0</entry></row><row><entry>td_te_numtags1</entry></row><row><entry>td_te_starttagdataadr</entry></row><row><entry>td_te_rawtagdataadr</entry></row><row><entry>td_te_endoftagdata</entry></row><row><entry>td_te_firsttaglineheight</entry></row><row><entry>td_te_tagdata0</entry></row><row><entry>td_te_tagdata1</entry></row><row><entry>td_te_tagdata2</entry></row><row><entry>td_te_tagdata3</entry></row><row><entry>td_te_countx</entry></row><row><entry>td_te_county</entry></row><row><entry>td_te_rtdtagsense</entry></row><row><entry>td_te_readsremaining</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>TFS (Tag Format Structure)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="21pt" align="left" /><colspec colname="3" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>tfsi_adr0[8:0]</entry><entry>In</entry><entry>Read address for dot0</entry></row><row><entry>tfsi_adr1[8:0]</entry><entry>In</entry><entry>Read address for dot1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Bandstore Signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="21pt" align="left" /><colspec colname="3" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>cdu_startofbandstore[24:0]</entry><entry>In</entry><entry>Start memory area allocated</entry></row><row><entry /><entry /><entry>for page bands</entry></row><row><entry>cdu_endofbandstore[24:0]</entry><entry>In</entry><entry>Last address of the memory</entry></row><row><entry /><entry /><entry>allocated for page bands</entry></row><row><entry>te_finishedband</entry><entry>Out</entry><entry>Tag encoder band finished</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 26.7.2 Introduction
3114The tag data interface is responsible for obtaining the raw tag data and encoding it as required by the tag encoder. The smallest typical tag placement is 2 mm×2 mm, which means a tag is at least 126 1600 dpi dots wide.
3115In PEC1, in order to keep up with the HCU which processes 2 dots per cycle, the tag data interface has been designed to be capable of encoding a tag in 63 cycles. This is actually accomplished in approximately 52 cycles within PEC1. For SoPEC the TE need only produce one dot per cycle; it should be able to produce tags in no more than twice the time taken by the PEC1 TE. Moreover, any change in implementation from two dots to one dot per cycle should not lose the 63/52 cycle performance edge attained in the PEC1 TE.
3116As shown in <figref idref="DRAWINGS">FIG. 198</figref>, the tag data interface contains a raw tag data interface FSM that fetches tag data from DRAM, two symbol-at-a-time GF(2<sup>4</sup>) Reed-Solomon encoders, an encoded data interface and a state machine for controlling the encoding process. It also contains a tagData register that needs to be set up to hold the fixed tag data for the page.
3117The type of encoding used depends on the registers TE_encodefixed, TE_dataredun and TE_decode2den the options being, <ul id="ul0307" list-style="none"><li id="ul0307-0001" num="0000"><ul id="ul0308" list-style="none"><li id="ul0308-0001" num="3118">(15,5) RS coding, where every 5 input symbols are used to produce 15 output symbols, so the output is 3 times the size of the input. This can be performed on fixed and variable tag data.</li><li id="ul0308-0002" num="3119">(15,7) RS coding, where every 7 input symbols are used to produce 15 output symbols, so for the same number of input symbols, the output is not as large as the (15,5) code (for more details see section 26.7.6 on page 435). This can be performed on fixed and variable tag data.</li><li id="ul0308-0003" num="3120">2D decoding, where each 2 input bits are used to produce 4 output bits. This can be performed on fixed and variable tag data.</li><li id="ul0308-0004" num="3121">no coding, where the data is simply passed into the Encoded Data Interface. This can be performed on fixed data only.</li></ul></li></ul>
3122Each tag is made up of fixed tag data (i.e. this data is the same for each tag on the page) and variable tag data (i.e. different for each tag on the page).
3123Fixed tag data is either stored in DRAM as 120-bits when it is already coded (or no coding is required), 40-bits when (15,5) coding is required or 56-bits when (15,7) coding is required. Once the fixed tag data is coded it is 120-bits long. It is then stored in the Encoded Tag Data Interface. The variable tag data is stored in the DRAM in uncoded form. When (15,5) coding is required, the 120-bits stored in DRAM are encoded into 360-bits. When (15,7) coding is required, the 112-bits stored in DRAM are encoded into 240-bits. When 2D decoding is required the 120-bits stored in DRAM are converted into 240-bits. In each case the encoded bits are stored in the Encoded Tag Data Interface.
3124The encoded fixed and variable tag data are eventually used to print the tag.
3125The fixed tag data is loaded in once from the DRAM at the start of a page. It is encoded as necessary and is then stored in one of the 8×15-bits registers/RAMs in the Encoded Tag Data Interface. This data remains unchanged in the registers/RAMs until the next page is ready to be processed.
3126The 120-bits of unencoded variable tag data for each tag is stored in four 32-bit words. The TE re-reads the variable tag data, for a particular tag from DRAM, every time it produces that tag. The variable tag data FIFO which reads from DRAM has enough space to store 4 tags.
000026.7.2.1 Bandstore Wrapping
3127Both TD and TFS storage in DRAM can wrap around the bandstore area. The bounds of the band store are described by inputs from the CDU shown in Table. The TD and TFS DRAM interfaces therefore support bandstore wrapping. If the TD or TFS DRAM interface increments an address it is checked to see if it matches the end of bandstore address. If so, then the address is mapped to the start of the bandstore.
000026.7.3 Data Flow
3128An overview of the dataflow through the TDI can be seen in <figref idref="DRAWINGS">FIG. 198</figref> below.
3129The TD interface consists of the following main sections: <ul id="ul0309" list-style="none"><li id="ul0309-0001" num="0000"><ul id="ul0310" list-style="none"><li id="ul0310-0001" num="3130">the Raw Tag Data Interface—fetches tag data from DRAM;</li><li id="ul0310-0002" num="3131">the tag data register;</li><li id="ul0310-0003" num="3132">2 Reed Solomon encoders—each encodes one 4-bit symbol at a time;</li><li id="ul0310-0004" num="3133">the Encoded Tag Data Interface—supplies encoded tag data for output;</li><li id="ul0310-0005" num="3134">Two 2D decoders.</li></ul></li></ul>
3135The main performance specification for PEC1 is that the TE must be able to output data at a continuous rate of 2 dots per cycle.
000026.7.4 Raw Tag Data Interface
3136The raw tag data interface (RTDI) provides a simple means of accessing raw tag data in DRAM. The RTDI passes tag data into a FIFO where it can be subsequently read as required. The 64-bit output from the FIFO can be read directly, with the value of the wr_rd_counter being used to set/reset as the enable signal (rtdAvail). The FIFO is clocked out with receipt of an rtdRd signal from the TS FSM.
3137<figref idref="DRAWINGS">FIG. 199</figref> shows a block diagram of the raw tag data interface.
26.7.4.1 RTDI FSM
3138The RTDI state machine is responsible for keeping the raw tag FIFO full. The state machine reads the line of tag data once for each printline that uses the tag. This means a given line of tag data will be read TagHeight times. Typically this will be 126 times or more, based on an approximately 2 mm tag. Note that the first line of tag data may be read fewer times since the start of the page may be within a tag. In addition odd and even rows of tags may contain different numbers of tags. Section 26.6.5.1 outlines how to start the TE and restart it between bands. Users must set the NextBandStartTagDataAdr, NextBandEndOfTagData, NextBandFirstTagLineHeight and numTags[0], numTags[1] registers before starting the TE by asserting Go.
3139To restart the tag encoder for second and subsequent bands of a page, the NextBandStartTagDataAdr, NextBandEndOfTagData and NextBandFirstTagLineHeight registers need to be updated (typically numTags[0] and numTags[1] will be the same if the previous band contains an even number of tag rows) and NextBandEnable set. See Section 26.6.5.1 for a full description of the four ways of reprogramming the TE between bands.
3140The tag data is read once for every printline containing tags. When maximally packed, a row of tags contains 163 tags (see Table n page465 on page 408).
3141The RTDI State Flow diagram is shown in <figref idref="DRAWINGS">FIG. 200</figref>. An explanation of the states follows: idle state:—Stay in the idle state if there is no variable data present. If there is variable data present and there are at least 4 spaces left in the FIFO then request a burst of 2 tags from the DRAM (1*256 bits). Counter countx is assigned the number of tags in a even/odd line which depends on the value of register rtdtagsense. Down-counter county is assigned the number of dot lines high a tag will be (min 126). Initially it must be set the firsttaglineheight value as the TE may be between pages (i.e. a partial tag). For normal tag generation county will take the value of tagmaxline register.
3142diu_access:—The diu_access state will generate a request to the DRAM if there are at least 4 spaces in the FIFO. This is indicated by the counter wr_rd_counter which is incremented/decremented on writes/reads of the FIFO. As long as wr_rd_counter is less than 4 (FIFO is 8 high) there must be 4 locations free. A control signal called td_diu_radrvalid is generated for the duration of the DRAM burst access. Addresses are sent in bursts of 1. The counter burst_count controls this signal, (will involve modification to existing TE code.) If there is an odd number of tags in line then the last DRAM read will contain a tag in the first 128 bits and padding in the final 128 bits.
3143fifo_load:—This state controls the addressing to the DRAM. Counters countx and county are used to monitor whether the TE is processing a line of dots within a row of tags. When countx is zero it means all tag dots for this row are complete. When county is zero it means the TE is on the last line of dots (prior to Y scaling) for this row of tags. When a row of tags is complete the sense of rtdtagsense is inverted (odd/even). The rawtagdataadr is compared to the te_endoftagdata address. If rawtagdataadr=endoftagdata the doneband signal is set, the finishedband signal is pulsed, and the FSM enters the rtd_stall state until the doneband signal is reset to zero by the PCU by which time the rawtagdata, endoftagedata and firsttaglineheight registers are setup with new values to restart the TE. This state is used to count the 64-bit reads from the DIU. Each time diu_td_rvalid is high rtd_data_count is incremented by 1. The compare of rtd_data_count=rtd_num is necessary to find out when either all 4*64-bit data has been received or n*64-bit data (depending on a match of rawtagdataadr=endoftagdata in the middle of a set of 4*64-bit values being returned by the DIU.
3144rtd_stall:—This state waits for the the doneband signal to be reset (see page 426 for a description of how this occurs). Once reset the FSM returns to the idle state. This states also performs the same count on the diu_data read as above in the case where diu_td_rvalid has not gone high by the time the addressing is complete and the end of band data has been reached i.e. rawtagdataadr=endoftagdata
000026.7.5 TDI State Machine
3145The tag data state machine has two processing phases. The first processing phase is to encode the fixed tag data stored in the 128-bit (2×64-bit) tag data register. The second is to encode tag data as it is required by the tag encoder.
3146When the Tag Encoder is started up, the fixed tag data is already preloaded in the 128 bit tag data record. If encodeFixed is set, then the 2 codewords stored in the lower bits of the tag data record need to be encoded: 40 bits if dataRedun=0, and 56 bits if dataRedun=1. If encodeFixed is clear, then the lower 120 bits of the tag data record must be passed to the encoded tag data interface without being encoded.
3147When encodeFixed is set, the symbols derived from codeword 0 are written to codeword 6 and the symbols derived from codeword 1 are written to codeword 7. The data symbols are stored first and then the remaining redundancy symbols are stored afterwards, for a total of 15 symbols. Thus, when dataRedun=0, the 5 symbols derived from bits <b>0</b>–<b>19</b> are written to symbols 0–4, and the redundancy symbols are written to symbols 5–14. When dataRedun=1, the 7 symbols derived from bits <b>0</b>–<b>27</b> are written to symbols 0–6, and the redundancy symbols are written to symbols 7–14.
3148When encodeFixed is clear, the 120 bits of fixed data is copied directly to codewords 6 and 7. The TDI State Flow diagram is shown in <figref idref="DRAWINGS">FIG. 202</figref>. An explanation of the states follows.
3149idle:—In the idle state wait for the tag encoder go signal—top_go=1. The first task is to either store or encode the Fixed data. Once the Fixed data is stored or encoded/stored the donefixed flag is set. If there is no variable data the FSM returns to the idle state hence the reason to check the donefixed flag before advancing i.e. only store/encode the fixed data once.
3150fixed_data:—In the fixed_data state the FSM must decode whether to directly store the fixed data in the ETDi or if the fixed data needs to be either (15:5) (40-bits) or (15:7) (56-bits) RS encoded or 2D decoded. The values stored in registers encodefixed and dataredun and decode2den determine what the next state should be.
3151bypass to etdi:—The bypass_to_etdi takes 120-bits of fixed data(pre-encoded) from the tag_data(127:0) register and stores it in the 15*8 (by 2 for simultaneous reads) buffers. The data is passed from the tag data register through 3 levels of muxing (level1, level2, level3) where it enters the RS0/RS1 encoders (which are now in a straight through mode (i.e. control<sub>—</sub>5 and control<sub>—</sub>7 are zero hence the data passes straight from the input to the output). The MSBs of the etd_wr_adr must be high to store this data as codewords 6,7.
3152etd_buf_switch:—This state is used to set the tdvalid signal and pulse the etd_adv_tag signal which in turn is used to switch the read write sense of the ETDi buffers (wrsb0). The firsttime signal is used to identify the first time a tag is encoded. If zero it means read the tag data from the RTDi FIFO and encode. Once encoded and stored the FSM returns to this state where it evaluates the sense of tdvalid. First time around it will be zero so this sets tdvalid and returns to the readtagdata state to fill the 2nd ETDi buffer. After this the FSM returns to this state and waits for the lastdotintag signal to arrive. In between tags when the lastdotingtag signal is received the etd_adv_tag is pulsed and the FSM goes to the readtagdata state. However if the lastdotintag signal arrives at the end of a line there is an extra 1 cycle delay introduced in generating the etd_adv_tag pulse (via etd_adv_tag_endofline) due to the pipelining in the TFS. This allows all the previous tag to be read from the correct buffer and seamless transfer to the other buffer for the next line.
3153readtagdata:—The readtagdata state waits to receive a rtdavail signal from the raw tag data interface which indicates there is raw tag data available. The tag_data register is 128-bits so it takes 2 pulses of the rtdrd signal to get the 2*64-bits into the tag_data register. If the rtdavail signal is set rtdrd is pulsed for 1 cycle and the FSM steps onto the loadtagdata state. Initially the flag first64 bits will be zero. The 64-bits of rtd are assigned to the tag_data[63:0] and the flag first64 bits is set to indicate the first raw tag data read is complete. The FSM then steps back to the read_tagdata state where it generates the second rtdrd pulse. The FSM then steps onto the loadtagdata state for where the second 64-bits of rawtag data are assigned to tag_data[128:64]. loadtagdata:—The loadtagdata state writes the raw tag data into the tag_data register from the RTDi FIFO. The first64 bits flag is reset to zero as the tag_data register now contains 120/112 bits of variable data. A decode of whether to (15:5) or (15:7) RS encode or 2D decode this data decides the next state.
3154rs<sub>—</sub>15<sub>—</sub>5:—The rs<sub>—</sub>15<sub>—</sub>5 (Reed Solomon (15:5) mode) state either encodes 40-bit Fixed data or 120-bit Variable data and provides the encoded tag data write address and write enable (etd_wr_adr and etdwe respectively). Once the fixed tag data is encoded the donefixed flag is set as this only needs to be done once per page. The variabledatapresent register is then polled to see if there is variable data in the tags. If there is variable data present then this data must be read from the RTDi and loaded into the tag_data register. Else the tdvalid flag must be set and FSM returns to the idle state. control<sub>—</sub>5 is a control bit for the RS Encoder and controls feedforward and feedback muxes that enable (15:5) encoding.
3155The rs<sub>—</sub>15<sub>—</sub>5 state also generates the control signals for passing 120-bits of variable tag data to the RS encoder in 4-bit symbols per clock cycle. rs_counter is used both to control the level1_mux and act as the 15-cycle counter of the RS Encoder. This logic cycles for a total of 3*15 cycles to encode the 120-bits.
3156rs<sub>—</sub>15<sub>—</sub>7:—The rs<sub>—</sub>15<sub>—</sub>7 state is similar to the rs<sub>—</sub>15<sub>—</sub>5 state except the level1_mux has to select 7 4-bit symbols instead of 5.
3157decode<sub>—</sub>2d 15<sub>—</sub>5, decode<sub>—</sub>2d<sub>—</sub>15<sub>—</sub>7:—The decode<sub>—</sub>2d states provides the control signals for passing the 120-bit variable data to the 2D decoder. The 2 lsbs are decoded to create 4 bits. The 4 bits from each decoder are combined and stored in the ETDi. Next the 2 MSBs are decoded to create 4 bits. Again the 4 bits from each decoder are combined and stored in the ETDi.
3158As can be seen from Figure n page 488 on page Error! Bookmark not defined. there are 3 stages of muxing between the Tag Data register and the RS encoders or 2D decoders. Levels 1–2 are controlled by level1_mux and level2_mux which are generated within the TDi FSM as is the write address to the ETDi buffers (etd_wr_adr)
3159<figref idref="DRAWINGS">FIGS. 203 through 208</figref> illustrate the mappings used to store the encoded fixed and variable tag data in the ETDI buffers.
000026.7.6 Reed Solomon (RS) Encoder
000026.7.7 Introduction
3160A Reed Solomon code is a non binary, block code. If a symbol consists of m bits then there are q=2<sup>m </sup>possible symbols defining the code alphabet. In the TE, m=4 so the number of possible symbols is q=16.
3161An (n,k) RS code is a block code with k information symbols and n code-word symbols. RS codes have the property that the code word n is limited to at most q+1 symbols in length.
3162In the case of the TE, both (15,5) and (15,7) RS codes can be used. This means that up to 5 and 4 symbols respectively can be corrected.
3163Only one type of RS coder is used at any particular time. The RS coder to be used is determined by the registers TE_dataredun and TE_decode2den: <ul id="ul0311" list-style="none"><li id="ul0311-0001" num="0000"><ul id="ul0312" list-style="none"><li id="ul0312-0001" num="3164">TE_dataredun=0 and TE_decode2den=0, then use the (15,5) RS coder</li><li id="ul0312-0002" num="3165">TE_dataredun=1 and TE_decode2den=0, then use the (15,7) RS coder</li></ul></li></ul>
3166For a (15,k) RS code with m=4, k 4-bit information symbols applied to the coder produce 15 4-bit codeword symbols at the output. In the TE, the code is systematic so the first k codeword symbols are the same the as the k input information symbols.
3167A simple block diagram can be seen in.
000026.7.8 I/O Specification
3168A I/O diagram of the RS encoder can be seen in.
000026.7.9 Proposed Implementation
3169In the case of the TE, (15,5) and (15,7) codes are to be used with 4-bits per symbol.
3170The primitive polynomial is p(x)=x<sup>4</sup>x+x+1
3171In the case of the (15,5) code, this gives a generator polynomial of <br /><i>g</i>(<i>x</i>)=(<i>x+a</i>)(<i>x+a</i><sup>2</sup>)(<i>x+a</i><sup>3</sup>)(<i>x+a</i><sup>4</sup>)(<i>x+a</i><sup>5</sup>)(<i>x+a</i><sup>6</sup>)(<i>x+a</i><sup>7</sup>)(<i>x+a</i><sup>8</sup>)(<i>x+a</i><sup>9</sup>)(<i>x+a</i><sup>10</sup>)<br /><i>g</i>(<i>x</i>)=<i>x</i><sup>10</sup><i>+a</i><sup>2</sup><i>x</i><sup>9</sup><i>+a</i><sup>3</sup><i>x</i><sup>8</sup><i>+a</i><sup>9</sup><i>x</i><sup>7</sup><i>+a</i><sup>6</sup><i>x</i><sup>6</sup><i>+a</i><sup>14</sup><i>x</i><sup>5</sup><i>+a</i><sup>2</sup><i>x</i><sup>4</sup><i>+ax</i><sup>3</sup><i>+a</i><sup>6</sup><i>x</i><sup>2</sup><i>+ax+a</i><sup>10</sup><br /><i>g</i>(<i>x</i>)=<i>x</i><sup>10</sup><i>+g</i><sub>9</sub><i>x</i><sup>9</sup><i>+g</i><sub>8</sub><i>x</i><sup>8</sup><i>+g</i><sub>7</sub><i>x</i><sup>7</sup><i>+g</i><sub>6</sub><i>x</i><sup>6</sup><i>+g</i><sub>5</sub><i>x</i><sup>5</sup><i>+g</i><sub>4</sub><i>x</i><sup>4</sup><i>+g</i><sub>3</sub><i>x</i><sup>3</sup><i>+g</i><sub>2</sub><i>x</i><sup>2</sup><i>+g</i><sub>1</sub><i>x+g</i><sub>0</sub>
3172In the case of the (15,7) code, this gives a generator polynomial of <br /><i>h</i>(<i>x</i>)=(<i>x+a</i>)(<i>x+a</i><sup>2</sup>)(<i>x+a</i><sup>3</sup>)(<i>x+a</i><sup>4</sup>)(<i>x+a</i><sup>5</sup>)(<i>x+a</i><sup>6</sup>)(<i>x+a</i><sup>7</sup>)(<i>x+a</i><sup>8</sup>)<br /><i>h</i>(<i>x</i>)=<i>x</i><sup>8</sup><i>+a</i><sup>14</sup><i>x</i><sup>7</sup><i>+a</i><sup>2</sup><i>x</i><sup>6</sup><i>+a</i><sup>4</sup><i>x</i><sup>5</sup><i>+a</i><sup>2</sup><i>x</i><sup>4</sup><i>+a</i><sup>13</sup><i>x</i><sup>3</sup><i>+a</i><sup>5</sup><i>x</i><sup>2</sup><i>+a</i><sup>11</sup><i>x+a</i><sup>6</sup><br /><i>h</i>(<i>x</i>)=<i>x</i><sup>8</sup><i>+h</i><sub>7</sub><i>x</i><sup>7</sup><i>+h</i><sub>6</sub><i>x</i><sup>6</sup><i>+h</i><sub>5</sub><i>x</i><sup>5</sup><i>+h</i><sub>4</sub><i>x</i><sup>4</sup><i>+h</i><sub>3</sub><i>x</i><sup>3</sup><i>+h</i><sub>2</sub><i>x</i><sup>2</sup><i>+h</i><sub>1</sub><i>x+h</i><sub>0</sub>
3173The output code words are produced by dividing the generator polynomial into a polynomial made up from the input symbols.
3174This division is accomplished using the circuit shown in <figref idref="DRAWINGS">FIG. 211</figref>.
3175The data in the circuit are Galois Field elements so addition and multiplication are performed using special circuitry. These are explained in the next sections.
3176The RS coder can operate either in (15,5) or (15,7) mode. The selection is made by the registers TE_dataredun and TE_decode2den.
3177When operating in (15,5) mode control<sub>—</sub>7 is always zero and when operating in (15,7) mode control<sub>—</sub>5 is always zero.
3178Firstly consider (15,5) mode i.e. TE_dataredun is set to zero.
3179For each new set of 5 input symbols, processing is as follows:
3180The 4-bits of the first symbol d<sub>0 </sub>are fed to the input port rs_data_in(3:0) and control<sub>—</sub>5 is set to 0. mux2 is set so as to use the output as feedback. control<sub>—</sub>5 is zero so mux4 selects the input (rs_data_in) as the output (rs_data_out). Once the data has settled (<<1 cycle), the shift registers are clocked. The next symbol d<sub>1 </sub>is then applied to the input, and again after the data has settled the shift registers are clocked again. This is repeated for the next 3 symbols d<sub>2</sub>, d<sub>3 </sub>and d<sub>4</sub>. As a result, the first 5 outputs are the same as the inputs. After 5 cycles, the shift registers now contain the next 10 required outputs. control<sub>—</sub>5 is set to 1 for the next 10 cycles so that zeros are fed back by mux2 and the shift register values are fed to the output by mux3 and mux4 by simply clocking the registers.
3181A timing diagram is shown below.
3182Secondly consider (15,7) mode i.e. TE_dataredun is set to one.
3183In this case processing is similar to above except that control<sub>—</sub>7 stays low while 7 symbols (d<sub>0</sub>, d<sub>1 </sub>. . . d<sub>6</sub>) are fed in. As well as being fed back into the circuit, these symbols are fed to the output.
3184After these 7 cycles, control<sub>—</sub>7 is set to 1 and the contents of the shift registers are fed to the output.
3185A timing diagram is shown below.
3186The enable signal can be used to start/reset the counter and the shift registers.
3187The RS encoders can be designed so that encoding starts on a rising enable edge. After 15 symbols have been output, the encoder stops until a rising enable edge is detected. As a result there will be a delay between each codeword.
3188Alternatively, once the enable goes high the shift registers are reset and encoding will proceed until it is told to stop. rs_data_in must be supplied at the correct time. Using this method, data can be continuously output at a rate of 1 symbol per cycle, even over a few codewords.
3189Alternatively, the RS encoder can request data as it requires.
3190The performance criterion that must be met is that the following must be carried out within 63 cycles <ul id="ul0313" list-style="none"><li id="ul0313-0001" num="0000"><ul id="ul0314" list-style="none"><li id="ul0314-0001" num="3191">load one tag's raw data into TE_tagdata</li><li id="ul0314-0002" num="3192">encode the raw tag data</li><li id="ul0314-0003" num="3193">store the encoded tag data in the Encoded Tag Data Interface</li></ul></li></ul>
3194In the case of the raw fixed tag data at the start of a page, there is no definite performance criterion except that it should be encoded and stored as fast as possible.
000026.7.10 Galois Field Elements and Their Representation
3195A Galois Field is a set of elements in which we can do addition, subtraction, multiplication and division without leaving the set.
3196The TE uses RS encoding over the Galois Field GF(2<sup>4</sup>). There are 2<sup>4 </sup>elements in GF(2<sup>4</sup>) and they are generated using the primitive polynomial p(x)=x<sup>4</sup>+x+1.
3197The 16 elements of GF(2<sup>4</sup>) can be represented in a number of different ways. Table 179 shows three possible representations—the power, polynomial and 4-tuple representation.
3198<tables id="TABLE-US-00269" num="00269"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 179</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>GF(2<sup>4</sup>) representations</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="70pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry /><entry>4-tuple</entry></row><row><entry /><entry>power</entry><entry>Polynomial</entry><entry>representation</entry></row><row><entry /><entry>representation</entry><entry>Representation</entry><entry>(a0 a1 a2 a3)</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row><row><entry /><entry>0</entry><entry>0</entry><entry>(0 0 0 0)</entry></row><row><entry /><entry>1</entry><entry>1</entry><entry>(1 0 0 0)</entry></row><row><entry /><entry>A</entry><entry>x</entry><entry>(0 1 0 0)</entry></row><row><entry /><entry>α<sup>2</sup></entry><entry><img file="US7165824B2_D0010.tif" /> x<sup>2</sup></entry><entry>(0 0 1 0)</entry></row><row><entry /><entry>α<sup>3</sup></entry><entry>x<sup>3</sup></entry><entry>(0 0 0 1)</entry></row><row><entry /><entry>α<sup>4</sup></entry><entry>1 + x</entry><entry>(1 1 0 0)</entry></row><row><entry /><entry>α<sup>5</sup></entry><entry>x + x<sup>2</sup></entry><entry>(0 1 1 0)</entry></row><row><entry /><entry>a<sup>6</sup></entry><entry>x<sup>2 </sup>+ x<sup>3</sup></entry><entry>(0 0 1 1)</entry></row><row><entry /><entry>α<sup>7</sup></entry><entry>1 + x <img file="US7165824B2_D0011.tif" /> + x<sup>3</sup></entry><entry>(1 1 0 1)</entry></row><row><entry /><entry>α<sup>8</sup></entry><entry>1 + x<sup>2</sup></entry><entry>(1 0 1 0)</entry></row><row><entry /><entry>α<sup>9</sup></entry><entry /><entry>(0 1 0 1)</entry></row><row><entry /><entry /><entry>x <img file="US7165824B2_D0012.tif" /> + x<sup>3</sup></entry></row><row><entry /><entry>α<sup>10</sup></entry><entry>1 + x + x<sup>2</sup></entry><entry>(1 1 1 0)</entry></row><row><entry /><entry>α<sup>11</sup></entry><entry>x + x<sup>2 </sup>+ x<sup>3</sup></entry><entry>(0 1 1 1)</entry></row><row><entry /><entry>α<sup>12</sup></entry><entry>1 + x + x<sup>2 </sup>+ x<sup>3</sup></entry><entry>(1 1 1 1)</entry></row><row><entry /><entry>α<sup>13</sup></entry><entry>1 + x<sup>2 </sup>+ x<sup>3</sup></entry><entry>(1 0 1 1)</entry></row><row><entry /><entry>α<sup>14</sup></entry><entry>1 + x<sup>3</sup></entry><entry>(1 0 0 1)</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 26.7.11 Multiplication of GF(2<sup>4</sup>) Elements
3199The multiplication of two field elements α<sup>a </sup>and α<sup>b </sup>is defined as <br />α<sup>c</sup>=α<sup>a</sup>.α<sup>b</sup>=α<sup>(a+b)modulo 15</sup><br /> Thus <br />α<sup>1</sup>.α<sup>2</sup>=α<sup>3</sup><br />α<sup>5</sup>.α<sup>10</sup>=α<sup>15</sup><br />α<sup>6</sup>.α<sup>12</sup>=α<sup>3</sup>
3200So if we have the elements in exponential form, multiplication is simply a matter of modulo 15 addition.
3201If the elements are in polynomial/tuple form, the polynomials must be multiplied and reduced mod x<sup>4</sup>+x+1.
3202Suppose we wish to multiply the two field elements in GF(2<sup>4</sup>): <br />α<sup>a</sup><i>=a</i><sub>3</sub><i>x</i><sup>3</sup><i>+a</i><sub>2</sub><i>x</i><sup>2</sup><i>+a</i><sub>1</sub><i>x</i><sup>1</sup><i>+a</i><sub>0</sub><br />α<sup>b</sup><i>=b</i><sub>3</sub><i>x</i><sup>3</sup><i>+b</i><sub>2</sub><i>x</i><sup>2</sup><i>+b</i><sub>1</sub><i>x</i><sup>1</sup><i>+b</i><sub>0</sub><ul id="ul0315" list-style="none"><li id="ul0315-0001" num="0000"><ul id="ul0316" list-style="none"><li id="ul0316-0001" num="3203">where a<sub>1</sub>, b<sub>i </sub>are in the field (0,1) (i.e. modulo 2 arithmetic)</li></ul></li></ul>
3204Multiplying these out and using x<sup>4</sup>+x+1=0 we get:
3205<maths id="MATH-US-00001" num="00001"><math overflow="scroll"><mtable><mtr><mtd><mtable><mtr><mtd><mrow><msup><mi>α</mi><mrow><mi>a</mi><mo>+</mo><mi>b</mi></mrow></msup><mo>=</mo><mi /><mo></mo><mrow><mrow><mrow><mo>[</mo><mrow><mrow><mo>(</mo><mrow><mrow><msub><mi>a</mi><mn>0</mn></msub><mo></mo><msub><mi>b</mi><mn>3</mn></msub></mrow><mo>+</mo><mrow><msub><mi>a</mi><mn>1</mn></msub><mo></mo><msub><mi>b</mi><mn>2</mn></msub></mrow><mo>+</mo><mrow><msub><mi>a</mi><mn>2</mn></msub><mo></mo><msub><mi>b</mi><mn>1</mn></msub></mrow><mo>+</mo><mrow><msub><mi>a</mi><mn>3</mn></msub><mo></mo><msub><mi>b</mi><mn>0</mn></msub></mrow></mrow><mo>)</mo></mrow><mo>+</mo><mrow><msub><mi>a</mi><mn>3</mn></msub><mo></mo><msub><mi>b</mi><mn>3</mn></msub></mrow></mrow><mo>]</mo></mrow><mo></mo><msup><mi>x</mi><mn>3</mn></msup></mrow><mo>+</mo></mrow></mrow></mtd></mtr><mtr><mtd><mrow><mi /><mo></mo><mrow><mrow><mrow><mo>[</mo><mrow><mrow><mo>(</mo><mrow><mrow><msub><mi>a</mi><mn>0</mn></msub><mo></mo><msub><mi>b</mi><mn>2</mn></msub></mrow><mo>+</mo><mrow><msub><mi>a</mi><mn>1</mn></msub><mo></mo><msub><mi>b</mi><mn>1</mn></msub></mrow><mo>+</mo><mrow><msub><mi>a</mi><mn>2</mn></msub><mo></mo><msub><mi>b</mi><mn>0</mn></msub></mrow></mrow><mo>)</mo></mrow><mo>+</mo><mrow><msub><mi>a</mi><mn>3</mn></msub><mo></mo><msub><mi>b</mi><mn>3</mn></msub></mrow><mo>+</mo><mrow><mo>(</mo><mrow><mrow><msub><mi>a</mi><mn>3</mn></msub><mo></mo><msub><mi>b</mi><mn>2</mn></msub></mrow><mo>+</mo><mrow><msub><mi>a</mi><mn>2</mn></msub><mo></mo><msub><mi>b</mi><mn>3</mn></msub></mrow></mrow><mo>)</mo></mrow></mrow><mo>]</mo></mrow><mo></mo><msup><mi>x</mi><mn>2</mn></msup></mrow><mo>+</mo></mrow></mrow></mtd></mtr><mtr><mtd><mrow><mi /><mo></mo><mrow><mrow><mrow><mo>[</mo><mrow><mrow><mo>(</mo><mrow><mrow><msub><mi>a</mi><mn>0</mn></msub><mo></mo><msub><mi>b</mi><mn>1</mn></msub></mrow><mo>+</mo><mrow><msub><mi>a</mi><mn>1</mn></msub><mo></mo><msub><mi>b</mi><mn>0</mn></msub></mrow></mrow><mo>)</mo></mrow><mo>+</mo><mrow><mo>(</mo><mrow><mrow><msub><mi>a</mi><mn>3</mn></msub><mo></mo><msub><mi>b</mi><mn>2</mn></msub></mrow><mo>+</mo><mrow><msub><mi>a</mi><mn>2</mn></msub><mo></mo><msub><mi>b</mi><mn>3</mn></msub></mrow></mrow><mo>)</mo></mrow><mo>+</mo><mrow><mo>(</mo><mrow><mrow><msub><mi>a</mi><mn>1</mn></msub><mo></mo><msub><mi>b</mi><mn>3</mn></msub></mrow><mo>+</mo><mrow><msub><mi>a</mi><mn>2</mn></msub><mo></mo><msub><mi>b</mi><mn>2</mn></msub></mrow><mo>+</mo><mrow><msub><mi>a</mi><mn>3</mn></msub><mo></mo><msub><mi>b</mi><mn>1</mn></msub></mrow></mrow><mo>)</mo></mrow></mrow><mo>]</mo></mrow><mo></mo><mi>x</mi></mrow><mo>+</mo></mrow></mrow></mtd></mtr><mtr><mtd><mrow><mi /><mo></mo><mrow><mo>[</mo><mrow><mo>(</mo><mrow><mrow><msub><mi>a</mi><mn>0</mn></msub><mo></mo><msub><mi>b</mi><mn>0</mn></msub></mrow><mo>+</mo><mrow><msub><mi>a</mi><mn>1</mn></msub><mo></mo><msub><mi>b</mi><mn>3</mn></msub></mrow><mo>+</mo><mrow><msub><mi>a</mi><mn>2</mn></msub><mo></mo><msub><mi>b</mi><mn>2</mn></msub></mrow><mo>+</mo><mrow><msub><mi>a</mi><mn>3</mn></msub><mo></mo><msub><mi>b</mi><mn>1</mn></msub></mrow></mrow><mo>)</mo></mrow><mo>]</mo></mrow></mrow></mtd></mtr></mtable></mtd></mtr><mtr><mtd><mtable><mtr><mtd><mrow><msup><mi>α</mi><mrow><mi>a</mi><mo>+</mo><mi>b</mi></mrow></msup><mo>=</mo><mi /><mo></mo><mrow><mrow><mrow><mo>[</mo><mrow><mrow><msub><mi>a</mi><mn>0</mn></msub><mo></mo><msub><mi>b</mi><mn>3</mn></msub></mrow><mo>+</mo><mrow><msub><mi>a</mi><mn>1</mn></msub><mo></mo><msub><mi>b</mi><mn>2</mn></msub></mrow><mo>+</mo><mrow><msub><mi>a</mi><mn>2</mn></msub><mo></mo><msub><mi>b</mi><mn>1</mn></msub></mrow><mo>+</mo><mrow><msub><mi>a</mi><mn>3</mn></msub><mo></mo><mrow><mo>(</mo><mrow><msub><mi>b</mi><mn>0</mn></msub><mo>+</mo><msub><mi>b</mi><mn>3</mn></msub></mrow><mo>)</mo></mrow></mrow></mrow><mo>]</mo></mrow><mo></mo><msup><mi>x</mi><mn>3</mn></msup></mrow><mo>+</mo></mrow></mrow></mtd></mtr><mtr><mtd><mrow><mi /><mo></mo><mrow><mrow><mrow><mo>[</mo><mrow><mrow><msub><mi>a</mi><mn>0</mn></msub><mo></mo><msub><mi>b</mi><mn>2</mn></msub></mrow><mo>+</mo><mrow><msub><mi>a</mi><mn>1</mn></msub><mo></mo><msub><mi>b</mi><mn>1</mn></msub></mrow><mo>+</mo><mrow><msub><mi>a</mi><mn>2</mn></msub><mo></mo><mrow><mo>(</mo><mrow><msub><mi>b</mi><mn>0</mn></msub><mo>+</mo><msub><mi>b</mi><mn>3</mn></msub></mrow><mo>)</mo></mrow></mrow><mo>+</mo><mrow><msub><mi>a</mi><mn>3</mn></msub><mo></mo><mrow><mo>(</mo><mrow><msub><mi>b</mi><mn>2</mn></msub><mo>+</mo><msub><mi>b</mi><mn>3</mn></msub></mrow><mo>)</mo></mrow></mrow></mrow><mo>]</mo></mrow><mo></mo><msup><mi>x</mi><mn>2</mn></msup></mrow><mo>+</mo></mrow></mrow></mtd></mtr><mtr><mtd><mrow><mi /><mo></mo><mrow><mrow><mrow><mo>[</mo><mrow><mrow><msub><mi>a</mi><mn>0</mn></msub><mo></mo><msub><mi>b</mi><mn>1</mn></msub></mrow><mo>+</mo><mrow><msub><mi>a</mi><mn>1</mn></msub><mo></mo><mrow><mo>(</mo><mrow><msub><mi>b</mi><mn>0</mn></msub><mo>+</mo><msub><mi>b</mi><mn>3</mn></msub></mrow><mo>)</mo></mrow></mrow><mo>+</mo><mrow><msub><mi>a</mi><mn>2</mn></msub><mo></mo><mrow><mo>(</mo><mrow><msub><mi>b</mi><mn>2</mn></msub><mo>+</mo><msub><mi>b</mi><mn>3</mn></msub></mrow><mo>)</mo></mrow></mrow><mo>+</mo><mrow><msub><mi>a</mi><mn>3</mn></msub><mo></mo><mrow><mo>(</mo><mrow><msub><mi>b</mi><mn>1</mn></msub><mo>+</mo><msub><mi>b</mi><mn>2</mn></msub></mrow><mo>)</mo></mrow></mrow></mrow><mo>]</mo></mrow><mo></mo><mi>x</mi></mrow><mo>+</mo></mrow></mrow></mtd></mtr><mtr><mtd><mrow><mi /><mo></mo><mrow><mo>[</mo><mrow><mrow><msub><mi>a</mi><mn>0</mn></msub><mo></mo><msub><mi>b</mi><mn>0</mn></msub></mrow><mo>+</mo><mrow><msub><mi>a</mi><mn>1</mn></msub><mo></mo><msub><mi>b</mi><mn>3</mn></msub></mrow><mo>+</mo><mrow><msub><mi>a</mi><mn>2</mn></msub><mo></mo><msub><mi>b</mi><mn>2</mn></msub></mrow><mo>+</mo><mrow><msub><mi>a</mi><mn>3</mn></msub><mo></mo><msub><mi>b</mi><mn>1</mn></msub></mrow></mrow><mo>]</mo></mrow></mrow></mtd></mtr></mtable></mtd></mtr></mtable></math></maths>
3206If we wish to multiply an arbitrary field element by a fixed field element we get a more simple form. Suppose we wish to multiply α<sup>b </sup>by α<sup>3</sup>.
3207In this case α<sup>3</sup>=x<sup>3 </sup>so (a0 a1 a2 a3)=(0001). Substituting this into the above equation gives <br />α<sup>c</sup>=(<i>b</i><sub>0</sub><i>+b</i><sub>3</sub>)<i>x</i><sup>3</sup>+(<i>b</i><sub>2</sub><i>+b</i><sub>3</sub>)<i>x</i><sup>2</sup>+(<i>b</i><sub>1</sub><i>+b</i><sub>2</sub>)<i>x+b</i><sub>1</sub>
3208This can be implemented using simple XOR gates as shown in <figref idref="DRAWINGS">FIG. 214</figref>
000026.7.12 Addition of GF(2<sup>4</sup>) Elements
3209If the elements are in their polynomial/tuple form, polynomials are simply added.
3210Suppose we wish to add the two field elements in GF(2<sup>4</sup>): <br />α<sup>a</sup><i>=a</i><sub>3</sub><i>x</i><sup>3</sup><i>+a</i><sub>2</sub><i>x</i><sup>2</sup><i>+a</i><sub>1</sub><i>x+a</i><sub>0</sub><br />α<sup>b</sup><i>=b</i><sub>3</sub><i>x</i><sup>3</sup><i>+b</i><sub>2</sub><i>z</i><sup>2</sup><i>+b</i><sub>1</sub><i>x+b</i><sub>0</sub><ul id="ul0317" list-style="none"><li id="ul0317-0001" num="0000"><ul id="ul0318" list-style="none"><li id="ul0318-0001" num="3211">where a<sub>i</sub>, b<sub>i </sub>are in the field (0,1) (i.e. modulo 2 arithmetic) <br />α<sup>c</sup>=α<sup>a</sup>+α<sup>b</sup>=(<i>a</i><sub>3</sub><i>+b</i><sub>3</sub>)<i>x</i><sup>3</sup>+(<i>a</i><sub>2</sub><i>+b</i><sub>2</sub>)<i>x</i>2+(<i>a</i><sub>1</sub><i>+b</i><sub>1</sub>)<i>x</i>+(<i>a</i><sub>0</sub><i>+b</i><sub>0</sub>)</li></ul></li></ul>
3212Again this can be implemented using simple XOR gates as shown in <figref idref="DRAWINGS">FIG. 215</figref>
000026.7.13 Reed Solomon Implementation
3213The designer can decide to create the relevant addition and multiplication circuits and instantiate them where necessary. Alternatively the feedback multiplications can be combined as follows.
3214Consider the multiplication <br />α<sup>a</sup>.α<sup>b</sup>=α<sup>c</sup><ul id="ul0319" list-style="none"><li id="ul0319-0001" num="0000"><ul id="ul0320" list-style="none"><li id="ul0320-0001" num="3215">or in terms of polynomials <br />(<i>a</i><sub>3</sub><i>x</i><sup>3</sup><i>+a</i><sub>2</sub><i>x</i><sup>2</sup><i>+a</i><sub>1</sub><i>x+a</i><sub>0</sub>).(<i>b</i><sub>3</sub><i>x</i><sup>3</sup><i>+b</i><sub>2</sub><i>x</i><sup>2</sup><i>+b</i><sub>1</sub><i>x+b</i><sub>0</sub>)=(<i>c</i><sub>3</sub><i>x</i><sup>3</sup><i>+c</i><sub>2</sub><i>x</i><sup>2</sup><i>+c</i><sub>1</sub><i>x+c</i><sub>0</sub>)</li></ul></li></ul>
3216If we substitute all of the possible field elements in for α<sup>a </sup>and express α<sup>c </sup>in terms of α<sup>b</sup>, we get the table of results shown in Table 180.
3217<tables id="TABLE-US-00270" num="00270"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="343pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 180</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>α<sup>c </sup>multiplied by all field elements, expressed in terms of α<sup>b</sup></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="91pt" align="center" /><colspec colname="2" colwidth="252pt" align="center" /><tbody valign="top"><row><entry>αa = a3x3 + a2x2 + a1x + a0</entry><entry /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="343pt" align="left" /><tbody valign="top"><row><entry>fixed</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="252pt" align="center" /><tbody valign="top"><row><entry>field</entry><entry>c3x3 + c2x2 + c1x + c0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="49pt" align="left" /><colspec colname="3" colwidth="63pt" align="left" /><colspec colname="4" colwidth="63pt" align="left" /><colspec colname="5" colwidth="63pt" align="left" /><colspec colname="6" colwidth="63pt" align="left" /><tbody valign="top"><row><entry>element</entry><entry>(a0 a1 a2 a3)</entry><entry>c0</entry><entry>c1</entry><entry>c2</entry><entry>c3</entry></row><row><entry namest="1" nameend="6" align="center" rowsep="1" /></row><row><entry>0</entry><entry>(0 0 0 0)</entry><entry /><entry /><entry /><entry /></row><row><entry>1</entry><entry>(1 0 0 0)</entry><entry>b<sub>0</sub></entry><entry>b<sub>1</sub></entry><entry>b<sub>2</sub></entry><entry>b<sub>3</sub></entry></row><row><entry>a</entry><entry>(0 1 0 0)</entry><entry>b<sub>3</sub></entry><entry>b<sub>0 </sub>+ b<sub>3</sub></entry><entry>b<sub>1</sub></entry><entry>b<sub>2</sub></entry></row><row><entry>α<sup>2</sup></entry><entry>(0 0 1 0)</entry><entry>b<sub>2</sub></entry><entry>b<sub>2 </sub>+ b<sub>3</sub></entry><entry>b<sub>0 </sub>+ b<sub>3</sub></entry><entry>b<sub>1</sub></entry></row><row><entry>α<sup>3</sup></entry><entry>(0 0 0 1)</entry><entry>b<sub>1</sub></entry><entry>b<sub>1 </sub>+ b<sub>2</sub></entry><entry>b<sub>2 </sub>+ b<sub>3</sub></entry><entry>b<sub>0 </sub>+ b<sub>3</sub></entry></row><row><entry>α<sup>4</sup></entry><entry>(1 1 0 0)</entry><entry>b<sub>0 </sub>+ b<sub>3</sub></entry><entry>b<sub>0 </sub>+ b<sub>1 </sub>+ b<sub>3</sub></entry><entry>b<sub>1 </sub>+ b<sub>2</sub></entry><entry>b<sub>2 </sub>+ b<sub>3</sub></entry></row><row><entry>α<sup>5</sup></entry><entry>(0 1 1 0)</entry><entry>b<sub>2 </sub>+ b<sub>3</sub></entry><entry>b<sub>0 </sub>+ b<sub>2</sub></entry><entry>b<sub>0 </sub>+ b<sub>1 </sub>+ b<sub>3</sub></entry><entry>b<sub>1 </sub>+ b<sub>2</sub></entry></row><row><entry>a<sup>6</sup></entry><entry>(0 0 1 1)</entry><entry>b<sub>1 </sub>+ b<sub>2</sub></entry><entry>b<sub>1 </sub>+ b<sub>3</sub></entry><entry>b<sub>0 </sub>+ b<sub>2</sub></entry><entry>b<sub>0 </sub>+ b<sub>1 </sub>+ b<sub>3</sub></entry></row><row><entry>α<sup>7</sup></entry><entry>(1 1 0 1)</entry><entry>b<sub>0 </sub>+ b<sub>1 </sub>+ b<sub>3</sub></entry><entry>b<sub>0 </sub>+ b<sub>2 </sub>+ b<sub>3</sub></entry><entry>b<sub>1 </sub>+ b<sub>3</sub></entry><entry>b<sub>0 </sub>+ b<sub>2</sub></entry></row><row><entry>α<sup>8</sup></entry><entry>(1 0 1 0)</entry><entry>b<sub>0 </sub>+ b<sub>2</sub></entry><entry>b<sub>1 </sub>+ b<sub>2 </sub>+ b<sub>3</sub></entry><entry>b<sub>0 </sub>+ b<sub>2 </sub>+ b<sub>3</sub></entry><entry>b<sub>1 </sub>+ b<sub>3</sub></entry></row><row><entry>α<sup>9</sup></entry><entry>(0 1 0 1)</entry><entry>b<sub>1 </sub>+ b<sub>3</sub></entry><entry>b<sub>0 </sub>+ b<sub>1 </sub>+ b<sub>2 </sub>+ b<sub>3</sub></entry><entry>b<sub>1 </sub>+ b<sub>2 </sub>+ b<sub>3</sub></entry><entry>b<sub>0 </sub>+ b<sub>2 </sub>+ b<sub>3</sub></entry></row><row><entry>α<sup>10</sup></entry><entry>(1 1 1 0)</entry><entry>b<sub>0 </sub>+ b<sub>2 </sub>+ b<sub>3</sub></entry><entry>b<sub>0 </sub>+ b<sub>1 </sub>+ b<sub>2</sub></entry><entry>b<sub>0 </sub>+ b<sub>1 </sub>+ b<sub>2 </sub>+ b<sub>3</sub></entry><entry>b<sub>1 </sub>+ b<sub>2 </sub>+ b<sub>3</sub></entry></row><row><entry>α<sup>11</sup></entry><entry>(0 1 1 1)</entry><entry>b<sub>1 </sub>+ b<sub>2 </sub>+ b<sub>3</sub></entry><entry>b<sub>0 </sub>+ b<sub>1</sub></entry><entry>b<sub>0 </sub>+ b<sub>1 </sub>+ b<sub>2</sub></entry><entry>b<sub>0 </sub>+ b<sub>1 </sub>+ b<sub>2 </sub>+ b<sub>3</sub></entry></row><row><entry>α<sup>12</sup></entry><entry>(1 1 1 1)</entry><entry>b<sub>0 </sub>+ b<sub>1 </sub>+ b<sub>2 </sub>+ b<sub>3</sub></entry><entry>b<sub>0</sub></entry><entry>b<sub>0 </sub>+ b<sub>1</sub></entry><entry>b<sub>0 </sub>+ b<sub>1 </sub>+ b<sub>2</sub></entry></row><row><entry>α<sup>13</sup></entry><entry>(1 0 1 1)</entry><entry>b<sub>0 </sub>+ b<sub>1 </sub>+ b<sub>2</sub></entry><entry>b<sub>3</sub></entry><entry>b<sub>0</sub></entry><entry>b<sub>0 </sub>+ b<sub>1</sub></entry></row><row><entry>α<sup>14</sup></entry><entry>(1 0 0 1)</entry><entry>b<sub>0 </sub>+ b<sub>1</sub></entry><entry>b<sub>2</sub></entry><entry>b<sub>3</sub></entry><entry>b<sub>0</sub></entry></row><row><entry namest="1" nameend="6" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> the following signals are required: <ul id="ul0321" list-style="none"><li id="ul0321-0001" num="0000"><ul id="ul0322" list-style="none"><li id="ul0322-0001" num="3218">b<sub>0</sub>, b<sub>1</sub>, b<sub>2</sub>, b<sub>3</sub>,</li><li id="ul0322-0002" num="3219">(b<sub>0</sub>+b<sub>1</sub>), (b<sub>0</sub>+b<sub>2</sub>), (b<sub>0</sub>+b<sub>3</sub>), (b<sub>1</sub>+b<sub>2</sub>), (b<sub>1</sub>+b<sub>3</sub>), (b<sub>2</sub>+b<sub>3</sub>),</li><li id="ul0322-0003" num="3220">(b<sub>0</sub>+b<sub>1</sub>+b<sub>2</sub>), (b<sub>0</sub>+b<sub>1</sub>+b<sub>3</sub>), (b<sub>0</sub>+b<sub>2</sub>+b<sub>3</sub>), (b<sub>1</sub>+b<sub>2</sub>+b<sub>3</sub>),</li><li id="ul0322-0004" num="3221">(b<sub>0</sub>+b<sub>1</sub>+b<sub>2</sub>+b<sub>3</sub>)</li></ul></li></ul>
3222The implementation of the circuit can be seen in Figure. The main components are XOR gates, 4-bit shift registers and multiplexers.
3223The RS encoder has 4 input lines labelled <b>0</b>, <b>1</b>, <b>2</b> & <b>3</b> and 4 output lines labelled <b>0</b>, <b>1</b>, <b>2</b> & <b>3</b>. This labelling corresponds to the subscripts of the polynomial/4-tuple representation. The mapping of 4-bit symbols from the TE tagdata register into the RS is as follows: <ul id="ul0323" list-style="none"><li id="ul0323-0001" num="0000"><ul id="ul0324" list-style="none"><li id="ul0324-0001" num="3224">the LSB in the TE_tagdata is fed into line<b>0</b></li><li id="ul0324-0002" num="3225">the next most significant LSB is fed into line<b>1</b></li><li id="ul0324-0003" num="3226">the next most significant LSB is fed into line<b>2</b></li><li id="ul0324-0004" num="3227">the MSB is fed into line<b>3</b></li></ul></li></ul>
3228The RS output mapping to the Encoded tag data interface is similiar. Two encoded symbols are stored in an 8-bit address. Within these 8 bits: <ul id="ul0325" list-style="none"><li id="ul0325-0001" num="0000"><ul id="ul0326" list-style="none"><li id="ul0326-0001" num="3229">line<b>0</b> is fed into the LSB (bit <b>0</b>/<b>4</b>)</li><li id="ul0326-0002" num="3230">line<b>1</b> is fed into the next most significant LSB (bit <b>1</b>/<b>5</b>)</li><li id="ul0326-0003" num="3231">line<b>2</b> is fed into the next most significant LSB (bit <b>2</b>/<b>6</b>)</li><li id="ul0326-0004" num="3232">line<b>3</b> is fed into the MSB (bit <b>3</b>/<b>7</b>) <br /> 267.14 2D Decoder </li></ul></li></ul>
3233The 2D decoder is selected when TE_decode2den=1. It operates on variable tag data only. its function is to convert 2-bits into 4-bits according to Table 181.
3234<tables id="TABLE-US-00271" num="00271"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 181</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Operation of 2D decoder</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="21pt" align="center" /><colspec colname="2" colwidth="140pt" align="center" /><tbody valign="top"><row><entry /><entry>input</entry><entry>output</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>0 0</entry><entry>0 0 0 1</entry></row><row><entry /><entry>0 1</entry><entry>0 0 1 0</entry></row><row><entry /><entry>1 0</entry><entry>0 1 0 0</entry></row><row><entry /><entry>1 1</entry><entry>1 0 0 0</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 26.7.15 Encoded Tag Data Interface
3235The encoded tag data interface contains an encoded fixed tag data store interface and an encoded variable tag data store interface, as shown in <figref idref="DRAWINGS">FIG. 217</figref>.
3236The two reord units simply reorder the 9 input bits to map low-order codewords into the bit selection component of the address as shown in Table 182. Reordering of write addresses is not necessary since the addresses are already in the correct format.
3237<tables id="TABLE-US-00272" num="00272"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 182</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Reord unit</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="77pt" align="center" /><colspec colname="2" colwidth="7pt" align="center" /><colspec colname="3" colwidth="84pt" align="center" /><colspec colname="4" colwidth="7pt" align="center" /><tbody valign="top"><row><entry /><entry>input</entry><entry /><entry>output</entry><entry /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="21pt" align="left" /><colspec colname="3" colwidth="63pt" align="left" /><colspec colname="4" colwidth="21pt" align="left" /><colspec colname="5" colwidth="70pt" align="left" /><tbody valign="top"><row><entry /><entry>bit#</entry><entry>bit</entry><entry>interpretation</entry><entry>bit</entry><entry>interpretation</entry></row><row><entry /><entry namest="offset" nameend="5" align="center" rowsep="1" /></row><row><entry /><entry>8</entry><entry>A</entry><entry>select 1 of 8</entry><entry>A</entry><entry>select 1 of 4</entry></row><row><entry /><entry /><entry /><entry>codewords</entry><entry /><entry>codeword tables</entry></row><row><entry /><entry>7</entry><entry>B</entry><entry /><entry>B</entry></row><row><entry /><entry>6</entry><entry>C</entry><entry /><entry>D</entry><entry>select 1 of 15</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry>symbols</entry></row><row><entry /><entry>5</entry><entry>D</entry><entry>select 1 of 15</entry><entry>E</entry></row><row><entry /><entry /><entry /><entry>symbols</entry></row><row><entry /><entry>4</entry><entry>E</entry><entry /><entry>F</entry></row><row><entry /><entry>3</entry><entry>F</entry><entry /><entry>G</entry></row><row><entry /><entry>2</entry><entry>G</entry><entry /><entry>C</entry><entry>select 1 of 8 bits</entry></row><row><entry /><entry>1</entry><entry>H</entry><entry>select 1 of 4</entry><entry>H</entry></row><row><entry /><entry /><entry /><entry>bits</entry></row><row><entry /><entry>0</entry><entry>I</entry><entry /><entry>I</entry></row><row><entry /><entry namest="offset" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3238The encoded fixed data interface is a single 15×8-bit RAM with 2 read ports and 1 write port. As it is only written to during page setup time (it is fixed for the duration of a page) there is no need for simultaneous read/write access. However the fixed data store must be capable of decoding two simultaneous reads in a single cycle. <figref idref="DRAWINGS">FIG. 218</figref> shows the implementation of the fixed data store.
3239The encoded variable tag data interface is a double buffered 3×15×8-bit RAM with 2 read ports and 1 write port. The double buffering allows one tag's data to be read (two reads in a single cycle) while the next tag's variable data is being stored. Write addressing is 6 bits: 2 bits of address for selecting 1 of 3, and 4 bits of address for selecting 1 of 15. Read addressing is the same with the addition of 3 more address bits for selecting 1 of 8.
3240<figref idref="DRAWINGS">FIG. 219</figref> shows the implementation of the encoded variable tag data store. Double buffering is implemented via two sub-buffers. Each time an AdvTag pulse is received, the sense of which sub-buffer is being read from or written to changes. This is accomplished by a 1-bit flag called wrsb0. Although the initial state of wrsb0 is irrelevant, it must invert upon receipt of an AdvTag pulse. The structure of each sub-buffer is shown in <figref idref="DRAWINGS">FIG. 220</figref>.
000026.8 Tag Format Structure (TFS) Interface
000026.8.1 Introduction
3241The TFS specifies the contents of every dot position within a tags border i.e.: <ul id="ul0327" list-style="none"><li id="ul0327-0001" num="0000"><ul id="ul0328" list-style="none"><li id="ul0328-0001" num="3242">is the dot part of the background?</li><li id="ul0328-0002" num="3243">is the dot part of the data?</li></ul></li></ul>
3244The TFS is broken up into Tag Line Structures (TLS) which specify the contents of every dot position in a particular line of a tag. Each TLS consists of three tables—A, B and C (see <figref idref="DRAWINGS">FIG. 221</figref>).
3245For a given line of dots, all the tags on that line correspond to the same tag line structure.
3246Consequently, for a given line of output dots, a single tag line structure is required, and not the entire TFS. Double buffering allows the next tag line structure to be fetched from the TFS in DRAM while the existing tag line structure is used to render the current tag line.
3247The TFS interface is responsible for loading the appropriate line of the tag format structure as the tag encoder advances through the page. It is also responsible for producing table A and table B outputs for two consecutive dot positions in the current tag line. <ul id="ul0329" list-style="none"><li id="ul0329-0001" num="0000"><ul id="ul0330" list-style="none"><li id="ul0330-0001" num="3248">There is a TLS for every dot line of a tag.</li><li id="ul0330-0002" num="3249">All tags that are on the same line have the exact same TLS.</li><li id="ul0330-0003" num="3250">A tag can be up to 384 dots wide, so each of these 384 dots must be specified in the TLS.</li><li id="ul0330-0004" num="3251">The TLS information is stored in DRAM and one TLS must be read into the TFS Interface for each line of dots that are outputted to the Tag Plane Line Buffers.</li><li id="ul0330-0005" num="3252">Each TLS is read from DRAM as 5 times 256-bit words with 214 padded bits in the last 256-bit DRAM read. <br /> 26.8.2 I/O Specification </li></ul></li></ul>
3253<tables id="TABLE-US-00273" num="00273"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 183</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Tag Format Structure Interface Port List</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="21pt" align="left" /><colspec colname="3" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry>signal</entry><entry /></row><row><entry>signal name</entry><entry>type</entry><entry>description</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>Pclk</entry><entry>In</entry><entry>SoPEC system clock</entry></row><row><entry>prst_n</entry><entry>In</entry><entry>Active-low, synchronous reset</entry></row><row><entry /><entry /><entry>in pclk domain</entry></row><row><entry>top_go</entry><entry>In</entry><entry>Go signal from TE top level</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>DRAM</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="21pt" align="left" /><colspec colname="3" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>diu_data[63:0]</entry><entry>In</entry><entry>Data from DRAM</entry></row><row><entry>diu_tfs_rack</entry><entry>In</entry><entry>Data acknowledge from DRAM</entry></row><row><entry>diu_tfs_rvalid</entry><entry>In</entry><entry>Data valid from DRAM</entry></row><row><entry>tfs_diu_rreq</entry><entry>Out</entry><entry>Read request to DRAM</entry></row><row><entry>tfs_diu_radr[21:5]</entry><entry>Out</entry><entry>Read address to DRAM</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>tag encoder top level</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="21pt" align="left" /><colspec colname="3" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>top_advtagline</entry><entry>In</entry><entry>Pulsed after the last line of</entry></row><row><entry /><entry /><entry>a row of tags</entry></row><row><entry>top_tagaltsense</entry><entry>In</entry><entry>For even tag rows = 0 i.e.</entry></row><row><entry /><entry /><entry>0, 2, 4 . . .</entry></row><row><entry /><entry /><entry>For odd tag rows = 1 i.e.</entry></row><row><entry /><entry /><entry>1, 3, 5 . . .</entry></row><row><entry>top_lastdotintag</entry><entry>In</entry><entry>Last dot in tag is currently</entry></row><row><entry /><entry /><entry>being processed</entry></row><row><entry>top_dotposvalid</entry><entry>In</entry><entry>Current dot position is a tag</entry></row><row><entry /><entry /><entry>dot and its structure data</entry></row><row><entry /><entry /><entry>and tag data is available</entry></row><row><entry>top_tagdotnum[7:0]</entry><entry>In</entry><entry>Counts from zero up to</entry></row><row><entry /><entry /><entry>TE_tagmaxdotpairs (min. = 1,</entry></row><row><entry /><entry /><entry>max. = 192)</entry></row><row><entry>tfsi_valid</entry><entry>Out</entry><entry>TLS tables A, B and C, ready</entry></row><row><entry /><entry /><entry>for use</entry></row><row><entry>tfsi_ta_dot0[1:0]</entry><entry>Out</entry><entry>Even entry from Table A</entry></row><row><entry /><entry /><entry>corresponding to</entry></row><row><entry /><entry /><entry>top_tagdotnum</entry></row><row><entry>tfsi_ta_dot1[1:0]</entry><entry>Out</entry><entry>Odd entry from Table A</entry></row><row><entry /><entry /><entry>corresponding to</entry></row><row><entry /><entry /><entry>top_tagdotnum</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>tag encoder top level (PCU read decoder)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="21pt" align="left" /><colspec colname="3" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>tfs_te_tfsstartadr[23:0]</entry><entry>Out</entry><entry>TFS tfsstartadr register</entry></row><row><entry>tfs_te_tfsendadr[23:0]</entry><entry>Out</entry><entry>TFS tfsendadr register</entry></row><row><entry>tfs_te_tfsfirstlineadr[23:0]</entry><entry>Out</entry><entry>TFS tfsfirstlineadr register</entry></row><row><entry>tfs_te_currtfsadr[23:0]</entry><entry>Out</entry><entry>TFS currtfsadr register</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>TDI</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="21pt" align="left" /><colspec colname="3" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>tfsi_tdi_adr0[8:0]</entry><entry>Out</entry><entry>Read address for dot0 (even dot)</entry></row><row><entry>tfsi_tdi_adr1[8:0]</entry><entry>Out</entry><entry>Read address for dot1 (odd dot)</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 26.8.2.1 State Machine
3254The state machine is responsible for generating control signals for the various TFS table units, and to load the appropriate line from the TFS. The states are explained below.
3255idle:—Wait for top_go to become active. Pulse adv_tfs_line for 1 cycle to reset tawradr and tbwradr registers. Pulsing adv_tfs_line will switch the read/write sense of Table B so switching Table A here as well to keep things the same i.e. wrta0=NOT(wrta0).
3256diu_access:—In the diu_access state a request is sent to the DIU. Once an ack signal is received Table A write enable is asserted and the FSM moves to the tls_load state.
3257tls_load:—The DRAM access is a burst of 5 256-bit accesses, ultimately returned by the DIU as 5*(4*64 bit) words. There will be 192 padded bits in the last 256-bit DRAM word. The first 12 64-bit words reads are for Table A, words 12 to 15 and some of 16 are for Table B while part of read 16 data is for Table C. The counter read_num is used to identify which data goes to which table. The table B data is stored temporarily in a 288-bit register until the tls_update state hence tbwe does not become active until read_num=16). <ul id="ul0331" list-style="none"><li id="ul0331-0001" num="0000"><ul id="ul0332" list-style="none"><li id="ul0332-0001" num="3258">The DIU data goes directly into Table A (12*64).</li><li id="ul0332-0002" num="3259">The DIU data for Table B is loaded into a 288-bit register.</li><li id="ul0332-0003" num="3260">The DIU data goes directly into Table C.</li></ul></li></ul>
3261tls_update:—The 288-bits in Table B need to written to a 32*9 buffer. The tls_update state takes care of this using the read_num counter.
3262tls_next—This state checks the logic level of tfsvalid and switches the read/write senses of Table A (wrta0) and Table B a cycle later (using the adv_tfs_line pulse). The reason for switching Table A a cycle early is to make sure the top_level address via tagdotnum is pointing to the correct buffer. Keep in mind the top_level is working a cycle ahead of Table A and 2 cycles ahead of Table B.
3263If tfsValid is 1, the state machine waits until the advTagLine signal is received. When it is received, the state machine pulses advTFSLine (to switch read/write sense in tables A, B, C), and starts reading the next line of the TFS from currTFSAdr.
3264If tfsValid is 0, the state machine pulses advTFSLine (to switch read/write sense in tables A, B, C) and then jumps to the tls_tfsvalid_set state where the signal tfsValid is set to 1 (allowing the tag encoder to start, or to continue if it had been stalled). The state machine can then start reading the next line of the TFS from currTFSAdr.
3265tls_tfsvalid_next:—Simply sets the tfsvalid signal and returns the FSM to the diu_access state.
3266If an advTagLine signal is received before the next line of the TFS has been read in, tfsValid is cleared to 0 and processing continues as outlined above.
000026.8.2.2 Bandstore Wrapping
3267Both TD and TFS storage in DRAM can wrap around the bandstore area. The bounds of the band store are described by inputs from the CDU shown in Table. The TD and TFS DRAM interfaces therefore support bandstore wrapping. If the TD or TFS DRAM interface increments an address it is checked to see if it matches the end of bandstore address. If so, then the address is mapped to the start of the bandstore.
3268The TFS state flow diagram is shown in below.
000026.8.3 Generating a Tag from Tables A, B and C
3269The TFS contains an entry for each dot position within the tag's bounding box. Each entry specifies whether the dot is part of the constant background pattern or part of the tag's data component (both fixed and variable).
3270The TFS therefore has TagHeight×TagWidth entries, where TagHeight is the height of the tag in dot-lines and TagWidth is the width of the tag in dots. The TFS entries that specify a single dot-line of a tag are known as a Tag Line Structure.
3271The TFS contains a TLS for each of the 1600 dpi lines in the tag's bounding box. Each TLS contains three contiguous tables, known as tables A, B and C.
3272Table A contains 384 2-bit entries i.e. one entry for each dot in a single line of a tag up to the maximum width of a tag. The actual number of entries used should match the size of the bounding box for the tag in the dot dimension, but all 384 entries must be present.
3273Table B contains 32 9-bit data address that refer to (in order of appearance) the data dots present in the particular line. Again, all 32 entries must be present, even if fewer are used.
3274Table C contains two 5-bit pointers into table B and is followed by 22 unused bits. The total length of each TLS is therefore 34 32-bit words.
3275Each output dot value is generated as follows: Each entry in Table A consists of 2-bits—bit<b>0</b> and bit<b>1</b>. These 2-bits are interpreted according to Table 184, Table 185 and Table 186.
3276<tables id="TABLE-US-00274" num="00274"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 184</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Interpretation of bit0 from entry in Table A</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="49pt" align="center" /><colspec colname="2" colwidth="168pt" align="left" /><tbody valign="top"><row><entry>bit0</entry><entry>interpretation</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>0</entry><entry>the output bit comes directly from bit1 (see Table ).</entry></row><row><entry>1</entry><entry>the output bit comes from a data bit. Bit1 is used in</entry></row><row><entry /><entry>conjunction with Tag Line Structure Table B to</entry></row><row><entry /><entry>determine which data bit will be output.</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3277<tables id="TABLE-US-00275" num="00275"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 185</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Interpretation of bit1 from entry in table A when bit0 = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="126pt" align="center" /><colspec colname="2" colwidth="91pt" align="left" /><tbody valign="top"><row><entry>bit 1</entry><entry>interpretation</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>0</entry><entry>output 0</entry></row><row><entry>1</entry><entry>output 1</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3278<tables id="TABLE-US-00276" num="00276"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 186</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Interpretation of bit1 from entry in table A when bit0 = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="42pt" align="center" /><colspec colname="2" colwidth="175pt" align="left" /><tbody valign="top"><row><entry>bit 1</entry><entry>interpretation</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>0</entry><entry>output data bit pointed to by current index into Table B.</entry></row><row><entry>1</entry><entry>output data bit pointed to by current index into Table B,</entry></row><row><entry /><entry>and advance index by 1.</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3279If bit<b>0</b>=0 then the output dot for this entry is part of the constant background pattern. The dot value itself comes from bit<b>1</b> i.e. if bit<b>1</b>=0 then the output is 0 and if bit<b>1</b>=1 then the output is 1. If bit<b>0</b>=1 then the output dot for this entry comes from the variable or fixed tag data. Bit<b>1</b> is used in conjunction with Tables B and C to determine data bits to use.
3280To understand the interpretation of bit<b>1</b> when bit<b>0</b>=1 we need to know what is stored in Table B. Table B contains the addresses of all the data bits that are used in the particular line of a tag in order of appearance. Therefore, up to 32 different data bits can appear in a line of a tag. The address of the first data dot in a tag will be given by the address stored in entry 0 of Table B. As we advance along the various data dots we will advance through the various Table B entries. Each Table B entry is 9-bits long and each points to a specific variable or fixed data bit for the tag. Each tag contains a maximum of 120 fixed and 360 variable data bits, for a total of 480 data bits. To aid address decoding, the addresses are based on the RS encoded tag data. Table lists the interpretation of the 9-bit addresses.
3281<tables id="TABLE-US-00277" num="00277"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 187</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Interpretation of 9-bit tag data address in Table B</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="21pt" align="left" /><colspec colname="2" colwidth="56pt" align="left" /><colspec colname="3" colwidth="140pt" align="left" /><tbody valign="top"><row><entry>bit</entry><entry /><entry /></row><row><entry>pos</entry><entry>name</entry><entry>description</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>8</entry><entry>CodeWordSelect</entry><entry>Select 1 of 8 codewords.</entry></row><row><entry /><entry /><entry>Codewords 0, 1, 2, 3, 4, 5 are variable data.</entry></row><row><entry /><entry /><entry>Codewords 6, 7 are fixed data.</entry></row><row><entry>7</entry></row><row><entry>6</entry></row><row><entry>5</entry><entry>SymbolSelect</entry><entry>Select 1 of 15 symbols (1111 invalid)</entry></row><row><entry>4</entry></row><row><entry>3</entry></row><row><entry>2</entry></row><row><entry>1</entry><entry>BitSelect</entry><entry>Select 1 of 4 bits from the selected symbols</entry></row><row><entry>0</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3282If the fixed data is supplied to the TE in an unencoded form, the symbols derived from codeword 0 of fixed data are written to codeword 6 and the symbols derived from fixed data codeword 1 are written to codeword 7. The data symbols are stored first and then the remaining redundancy symbols are stored afterwards, for a total of 15 symbols. Thus, when 5 data symbols are used, the 5 symbols derived from bits <b>0</b>–<b>19</b> are written to symbols 0–4, and the redundancy symbols are written to symbols 5–14. When 7 data symbols are used, the 7 symbols derived from bits <b>0</b>–<b>27</b> are written to symbols 0–6, and the redundancy symbols are written to symbols 7–14
3283However, if the fixed data is supplied to the TE in a pre-encoded form, the encoding could theoretically be anything. Consequently the 120 bits of fixed data is copied to codewords 6 and 7 as shown in Table 188.
3284<tables id="TABLE-US-00278" num="00278"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 188</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Mapping of fixed data to codeword/symbols</entry></row><row><entry>when no redundancy encoding</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="84pt" align="center" /><colspec colname="2" colwidth="49pt" align="center" /><colspec colname="3" colwidth="84pt" align="center" /><tbody valign="top"><row><entry /><entry>output</entry><entry>output</entry></row><row><entry>input bits</entry><entry>symbol range</entry><entry>codeword</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry> 0–19</entry><entry>0–4</entry><entry>6</entry></row><row><entry>20–39</entry><entry>0–4</entry><entry>7</entry></row><row><entry>40–59</entry><entry>5–9</entry><entry>6</entry></row><row><entry>60–79</entry><entry>5–9</entry><entry>7</entry></row><row><entry>80–99</entry><entry>10–14</entry><entry>6</entry></row><row><entry>100–119</entry><entry>10–14</entry><entry>7</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3285It is important to note that the interpretation of bit<b>1</b> from Table A (when bit<b>0</b>–<b>1</b>) is relative. A 5-bit index is used to cycle through the data address in Table B. Since the first tag on a particular line may or may not start at the first dot in the tag, an initial value for the index into Table B is needed. Subsequent tags on the same line will always start with an index of 0, and any partial tag at the end of a line will simply finish before the entire tag has been rendered. The initial index required due to the rendering of a partial tag at the start of a line is supplied by Table C. The initial index will be different for each TLS and there are two possible initial indexes since there are effectively two types of rows of tags in terms of initial offsets.
3286Table C provides the appropriate start index into Table B (2 5-bit indices). When rendering even rows of tags, entry 0 is used as the initial index into Table B, and when rendering odd rows of tags, entry 1 is used as the initial index into Table B. The second and subsequent tags start at the left most dots position within the tag, so can use an initial index of 0.
000026.8.4 Architecture
3287A block diagram of the Tag Format Structure Interface can be seen in <figref idref="DRAWINGS">FIG. 223</figref>.
000026.8.4.1 Table A Interface
3288The implementation of table A is two 16×64-bit RAMs with a small amount of control logic, as shown in <figref idref="DRAWINGS">FIG. 224</figref>. While one RAM is read from for the current line's table A data (4 bits representing 2 contiguous table A entries), the other RAM is being written to with the next line's table A data (64-bits at a time).
3289Note:—The Table A data to be printed (if each LSB=0) must be passed to the top_level 2 cycles after the read of Table A due to the 2-stage pipelining in the TFS from registering Table A and Table B outputs hence this extra registering stage for the generation of ta_dot0<sub>—</sub>1 cyclelater and ta_dot1<sub>—</sub>1 cyclelater.
3290Each time an AdvTFSLine pulse is received, the sense of which RAM is being read from or written to changes. This is accomplished by a 1-bit flag called wrta0. Although the initial state of wrta0 is irrelevant, it must invert upon receipt of an AdvTFSLine pulse. A 4-bit counter called taWrAdr keeps the write address for the 12 writes that occur after the start of each line (specified by the AdvTFSLine control input). The tawe (table A write enable) input is set whenever the data in is to be written to table A. The taWrAdr address counter automatically increments with each write to table A. Address generation for tawe and taWrAdr is shown in Table 189.
000026.8.4.2 Table C Interface
3291A block diagram of the table C interface is shown below in <figref idref="DRAWINGS">FIG. 226</figref>.
3292The address generator for table C contains a 5 bit address register adr that is set to a new address at the start of processing the tag (either of the two table C initial values based on tagAltSense at the start of the line, and 0 for subsequent tags on the same line). Each cycle two addresses into table B are generated based on the two 2-bit inputs (in0 and in1). As shown in Section 189, the output address tbRdAdr0 is always adr and tbRdAdr1 is one of adr and adr+1, and at the end of the cycle adr takes on one of adr, adr+1, and adr+2.
3293<tables id="TABLE-US-00279" num="00279"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 189</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>AdrGen lookup table</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="49pt" align="center" /><colspec colname="2" colwidth="14pt" align="center" /><colspec colname="3" colwidth="126pt" align="center" /><colspec colname="4" colwidth="14pt" align="center" /><tbody valign="top"><row><entry /><entry>inputs</entry><entry /><entry>outputs</entry><entry /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="21pt" align="center" /><colspec colname="2" colwidth="42pt" align="center" /><colspec colname="3" colwidth="49pt" align="left" /><colspec colname="4" colwidth="42pt" align="left" /><colspec colname="5" colwidth="49pt" align="left" /><tbody valign="top"><row><entry /><entry>in0</entry><entry>in1</entry><entry>adr0Sel</entry><entry>adr1Sel</entry><entry>adrSel</entry></row><row><entry /><entry namest="offset" nameend="5" align="center" rowsep="1" /></row><row><entry /><entry>00</entry><entry>00</entry><entry>X<sup>18</sup></entry><entry>X</entry><entry>adr</entry></row><row><entry /><entry>00</entry><entry>01</entry><entry>X</entry><entry>adr</entry><entry>adr</entry></row><row><entry /><entry>00</entry><entry>10</entry><entry>X</entry><entry>X</entry><entry>adr</entry></row><row><entry /><entry>00</entry><entry>11</entry><entry>X</entry><entry>adr</entry><entry>adr + 1</entry></row><row><entry /><entry>01</entry><entry>00</entry><entry>adr</entry><entry>X</entry><entry>adr</entry></row><row><entry /><entry>01</entry><entry>01</entry><entry>adr</entry><entry>adr</entry><entry>adr</entry></row><row><entry /><entry>01</entry><entry>10</entry><entry>adr</entry><entry>X</entry><entry>adr</entry></row><row><entry /><entry>01</entry><entry>11</entry><entry>adr</entry><entry>adr</entry><entry>adr + 1</entry></row><row><entry /><entry>10</entry><entry>00</entry><entry>X</entry><entry>X</entry><entry>adr</entry></row><row><entry /><entry>10</entry><entry>01</entry><entry>X</entry><entry>adr</entry><entry>adr</entry></row><row><entry /><entry>10</entry><entry>10</entry><entry>X</entry><entry>X</entry><entry>adr</entry></row><row><entry /><entry>10</entry><entry>11</entry><entry>X</entry><entry>adr</entry><entry>adr + 1</entry></row><row><entry /><entry>11</entry><entry>00</entry><entry>adr</entry><entry>X</entry><entry>adr + 1</entry></row><row><entry /><entry>11</entry><entry>01</entry><entry>adr</entry><entry>adr + 1</entry><entry>adr + 1</entry></row><row><entry /><entry>11</entry><entry>10</entry><entry>adr</entry><entry>X</entry><entry>adr + 1</entry></row><row><entry /><entry>11</entry><entry>11</entry><entry>adr</entry><entry>adr + 1</entry><entry>adr + 2</entry></row><row><entry /><entry namest="offset" nameend="5" align="center" rowsep="1" /></row><row><entry /><entry namest="offset" nameend="5" align="left" id="FOO-00030"><sup>18</sup>X = don't care state</entry></row></tbody></tgroup></table></tables><br /> 26.8.4.3 Table B Interface
3294The table B interface implementation generates two encoded tag data addresses (tfsi_adr0, tfsu_adr1) based on two table B input addresses (tbRdAdr0, tbRdAdr1). A block diagram of table B can be seen in <figref idref="DRAWINGS">FIG. 227</figref>.
3295X=don't care state.
3296Table B data is initially loaded into the 288-bit table B temporary register via the TFS FSM. Once all 288-bit entries have been loaded from DRAM, the data is written in 9-bit chunks to the 32*9 register arrays based on tbwradr.
3297Each time an AdvTFSLine pulse is received, the sense of which sub buffer is being read from or written to changes. This is accomplished by a 1-bit flag called wrtb0. Although the initial state of wrtb0 is irrelevant, it must invert upon receipt of an AdvTFSLine pulse.
3298Note:—The output addresses from Table B are registered.
000027 Tag FIFO Unit (TFU)
000027.1 Overview
3299The Tag FIFO Unit (TFU) provides the means by which data is transferred between the Tag Encoder (TE) and the HCU. By abstracting the buffering mechanism and controls from both units, the interface is clean between the data user and the data generator.
3300The TFU is a simple FIFO interface to the HCU. The Tag Encoder will provide support for arbitrary Y integer scaling up to 1600 dpi. X integer scaling of the tag dot data is performed at the output of the FIFO in the TFU. There is feedback to the TE from the TFU to allow stalling of the TE during a line. The TE interfaces to the TFU with a data width of 8 bits. The TFU interfaces to the HCU with a data width of 1 bit.
3301The depth of the TFU FIFO is chosen as 16 bytes so that the FIFO can store a single 126 dot tag.
000027.1.1 Interfaces Between TE, TFU and HCU
000027.1.1.1 TE-TFU Interface
3302The interface from the TE to the TFU comprises the following signals: <ul id="ul0333" list-style="none"><li id="ul0333-0001" num="0000"><ul id="ul0334" list-style="none"><li id="ul0334-0001" num="3303">te_tfu_wdata, 8-bit write data.</li><li id="ul0334-0002" num="3304">te_tfu_wdatavalid, write data valid.</li><li id="ul0334-0003" num="3305">te_tfu_wradvline, accompanies the last valid 8-bit write data in a line.</li></ul></li></ul>
3306The interface from the TFU to TE comprises the following signal: <ul id="ul0335" list-style="none"><li id="ul0335-0001" num="0000"><ul id="ul0336" list-style="none"><li id="ul0336-0001" num="3307">tfu_te_oktowrite, indicating to the TE that there is space available in the TFU FIFO.</li></ul></li></ul>
3308The TE writes data to the TFU FIFO as long as the TFU's tfu_te_oktowrite output bit is set. The TE write will not occur unless data is accompanied by a data valid signal.
000027.1.1.2 TFU-HCU Interface
3309The interface from the TFU to the HCU comprises the following signals: <ul id="ul0337" list-style="none"><li id="ul0337-0001" num="0000"><ul id="ul0338" list-style="none"><li id="ul0338-0001" num="3310">tfu_hcu_tdata, 1-bit data.</li><li id="ul0338-0002" num="3311">tfu_hcu_avail, data valid signal indicating that there is data available in the TFU FIFO.</li></ul></li></ul>
3312The interface from HCU to TFU comprises the following signal: <ul id="ul0339" list-style="none"><li id="ul0339-0001" num="0000"><ul id="ul0340" list-style="none"><li id="ul0340-0001" num="3313">hcu_tfu_ready, indicating to the TFU to supply the next dot. <br /> 27.1.1.2.1 X Scaling </li></ul></li></ul>
3314Tag data is replicated a scale factor (SF) number of times in the X direction to convert the final output to 1600 dpi. Unlike both the CFU and SFU, which support non-integer scaling, the scaling is integer only. Replication in the X direction is performed at the output of the TFU FIFO on a dot-by-dot basis.
3315To account for the case where there may be two SoPEC devices, each generating its own portion of a dot-line, the first dot in a line may not be replicated the total scale-factor number of times by an individual TFU. The dot will ultimately be scaled-up correctly with both devices doing part of the scaling, one on its lead-out and the other on its lead in.
3316Note two SoPEC TEs may be involved in producing the same byte of output tag data straddling the printhead boundary. The HCU of the left SoPEC will accept from its TE the correct amount of dots, ignoring any dots in the last byte that do not apply to its printhead. The TE of the right SoPEC will be programmed the correct number of dots into the tag and its output will be byte aligned with the left edge of the printhead.
000027.2 Definitions OF I/O
3317<tables id="TABLE-US-00280" num="00280"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 190</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>TFU Port List</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>Port Name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>Clocks and Resets</entry><entry /><entry /><entry /></row><row><entry>Pclk</entry><entry>1</entry><entry>In</entry><entry>SoPEC Functional clock.</entry></row><row><entry>Prst_n</entry><entry>1</entry><entry>In</entry><entry>Global reset signal.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>PCU Interface data and control signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>Pcu_adr[4:2]</entry><entry>2</entry><entry>In</entry><entry>PCU address bus. Only 3</entry></row><row><entry /><entry /><entry /><entry>bits are required to decode</entry></row><row><entry /><entry /><entry /><entry>the address space for this</entry></row><row><entry /><entry /><entry /><entry>block.</entry></row><row><entry>Pcu_dataout[31:0]</entry><entry>32</entry><entry>In</entry><entry>Shared write data bus from</entry></row><row><entry /><entry /><entry /><entry>the PCU.</entry></row><row><entry>Tfu_pcu_datain[31:0]</entry><entry>32</entry><entry>Out</entry><entry>Read data bus from the</entry></row><row><entry /><entry /><entry /><entry>TFU to the PCU.</entry></row><row><entry>Pcu_rwn</entry><entry>1</entry><entry>In</entry><entry>Common read/not-write signal</entry></row><row><entry /><entry /><entry /><entry>from the PCU.</entry></row><row><entry>Pcu_tfu_sel</entry><entry>1</entry><entry>In</entry><entry>Block select from the PCU.</entry></row><row><entry /><entry /><entry /><entry>When pcu_tfu_sel is high</entry></row><row><entry /><entry /><entry /><entry>both pcu_adr and</entry></row><row><entry /><entry /><entry /><entry>pcu_dataout are valid.</entry></row><row><entry>Tfu_pcu_rdy</entry><entry>1</entry><entry>Out</entry><entry>Ready signal to the PCU.</entry></row><row><entry /><entry /><entry /><entry>When tfu_pcu_rdy is high it</entry></row><row><entry /><entry /><entry /><entry>indicates the last cycle of</entry></row><row><entry /><entry /><entry /><entry>the access. For a write cycle</entry></row><row><entry /><entry /><entry /><entry>this means pcu_dataout has been</entry></row><row><entry /><entry /><entry /><entry>registered by the block and</entry></row><row><entry /><entry /><entry /><entry>for a read cycle this means the</entry></row><row><entry /><entry /><entry /><entry>data on tfu_pcu_datain is valid.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>TE Interface data and control signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>Te_tfu_wdata[7:0]</entry><entry>8</entry><entry>In</entry><entry>Write data for TFU FIFO.</entry></row><row><entry>Te_tfu_wdatavalid</entry><entry>1</entry><entry>In</entry><entry>Write data valid signal.</entry></row><row><entry>Te_tfu_wradvline</entry><entry>1</entry><entry>In</entry><entry>Advance line signal strobed</entry></row><row><entry /><entry /><entry /><entry>when the last byte in a line</entry></row><row><entry /><entry /><entry /><entry>is placed on te_tfu_wdata</entry></row><row><entry>tfu_te_oktowrite</entry><entry>1</entry><entry>Out</entry><entry>Ready signal indicating TFU</entry></row><row><entry /><entry /><entry /><entry>has space available in it's</entry></row><row><entry /><entry /><entry /><entry>FIFO and is ready to be</entry></row><row><entry /><entry /><entry /><entry>written to.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>HCU Interface data and control signals</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>Hcu_tfu_advdot</entry><entry>1</entry><entry>In</entry><entry>Signal indicating to the</entry></row><row><entry /><entry /><entry /><entry>TFU that the HCU is ready</entry></row><row><entry /><entry /><entry /><entry>to accept the next dot of</entry></row><row><entry /><entry /><entry /><entry>data from TFU.</entry></row><row><entry>tfu_hcu_tdata</entry><entry>1</entry><entry>Out</entry><entry>Data from the TFU FIFO.</entry></row><row><entry>tfu_hcu_avail</entry><entry>1</entry><entry>Out</entry><entry>Signal indicating valid</entry></row><row><entry /><entry /><entry /><entry>data available from TFU</entry></row><row><entry /><entry /><entry /><entry>FIFO.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 27.3 Configuration Registers
3318<tables id="TABLE-US-00281" num="00281"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 191</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>TFU Configuration Registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="49pt" align="left" /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="21pt" align="left" /><colspec colname="5" colwidth="126pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry /><entry>value</entry><entry /></row><row><entry>Address</entry><entry>register</entry><entry /><entry>on</entry></row><row><entry>TFU_Base+</entry><entry>name</entry><entry>#bits</entry><entry>reset</entry><entry>description</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>Control registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="49pt" align="left" /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="21pt" align="left" /><colspec colname="5" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>0x00</entry><entry>Reset</entry><entry>1</entry><entry>1</entry><entry>A write to this register causes a reset of</entry></row><row><entry /><entry /><entry /><entry /><entry>the TFU.</entry></row><row><entry /><entry /><entry /><entry /><entry>This register can be read to indicate the</entry></row><row><entry /><entry /><entry /><entry /><entry>reset state:</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - reset in progress</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - reset not in progress.</entry></row><row><entry>0x04</entry><entry>Go</entry><entry>1</entry><entry>see</entry><entry>Writing 1 to this register starts the TFU.</entry></row><row><entry /><entry /><entry /><entry>text</entry><entry>Writing 0 to this register halts the TFU.</entry></row><row><entry /><entry /><entry /><entry /><entry>When Go is deasserted the state-</entry></row><row><entry /><entry /><entry /><entry /><entry>machines go to their idle states but all</entry></row><row><entry /><entry /><entry /><entry /><entry>counters and configuration registers</entry></row><row><entry /><entry /><entry /><entry /><entry>keep their values.</entry></row><row><entry /><entry /><entry /><entry /><entry>When Go is asserted all counters are</entry></row><row><entry /><entry /><entry /><entry /><entry>reset, but configuration registers keep</entry></row><row><entry /><entry /><entry /><entry /><entry>their values (i.e. they don't get reset).</entry></row><row><entry /><entry /><entry /><entry /><entry>The TFU must be started before the TE</entry></row><row><entry /><entry /><entry /><entry /><entry>is started.</entry></row><row><entry /><entry /><entry /><entry /><entry>This register can be read to determine if</entry></row><row><entry /><entry /><entry /><entry /><entry>the TFU is running</entry></row><row><entry /><entry /><entry /><entry /><entry>(1 = running, 0 = stopped).</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>Setup registers (constant during processing of page)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="49pt" align="left" /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="21pt" align="left" /><colspec colname="5" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>0x08</entry><entry>XScale</entry><entry>8</entry><entry>1</entry><entry>Tag scale factor in X direction.</entry></row><row><entry>0x0C</entry><entry>XFracScale</entry><entry>8</entry><entry>1</entry><entry>Tag scale factor in X direction for the</entry></row><row><entry /><entry /><entry /><entry /><entry>fFirst dot in a line (must be programmed</entry></row><row><entry /><entry /><entry /><entry /><entry>to be less than or equal to XScale)</entry></row><row><entry>0x10</entry><entry>TEByteCount</entry><entry>12</entry><entry>0</entry><entry>The number of bytes to be accepted</entry></row><row><entry /><entry /><entry /><entry /><entry>from the TE per line. Once this number</entry></row><row><entry /><entry /><entry /><entry /><entry>of bytes have been received</entry></row><row><entry /><entry /><entry /><entry /><entry>subsequent bytes are ignored until</entry></row><row><entry /><entry /><entry /><entry /><entry>there is a strobe on the te_tfu_wradvline</entry></row><row><entry>0x14</entry><entry>HCUDotCount</entry><entry>16</entry><entry>0</entry><entry>The number of (optionally) x-scaled</entry></row><row><entry /><entry /><entry /><entry /><entry>dots per line to be supplied to the HCU.</entry></row><row><entry /><entry /><entry /><entry /><entry>Once this number has been reached</entry></row><row><entry /><entry /><entry /><entry /><entry>the remainder of the current FIFO byte</entry></row><row><entry /><entry /><entry /><entry /><entry>is ignored.</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 27.4 Detailed Description
3319The FIFO is a simple 16-byte store with read and write pointers, and a contents store, <figref idref="DRAWINGS">FIG. 229</figref>. 16 bytes is sufficient to store a single 126 dot tag.
3320Each line a total of TEByteCount bytes is read into the FIFO. All subsequent bytes are ignored until there is a strobe on the te_tfu_wradvline signal, whereupon bytes for the next line are stored. On the HCU side, a total of HCUDotCount dots are produced at the output. Once this count is reached any more dots in the FIFO byte currently being processed are ignored. For the first dot in the next line the start of line scale factor, XFracScale, is used.
3321The behaviour of these signals and the control signals between the TFU and the TE and HCU is detailed below.
3322<tables id="TABLE-US-00282" num="00282"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>// Concurrently Executed Code:</entry></row><row><entry /><entry>// TE always allowed to write when there's either (a)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>room or (b) no room and all</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// bytes for that line have been received.</entry></row><row><entry /><entry>if ((FifoCntnts != FifoMax) OR (FifoCntnts = = FifoMax</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>and ByteToRx = = 0)) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>tfu_te_oktowrite = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>tfu_te_oktowrite = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// Data presented to HCU when there is (a) data in</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>FIFO and (b) the HCU has not</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// received all dots for a line</entry></row><row><entry /><entry>if (FifoCntnts != 0) AND (BitToTx != 0)then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>tfu_hcu_avail = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>tfu_hcu_avail = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// Output mux of FIFO data</entry></row><row><entry /><entry>tfu_hcu_tdata = Fifo[FifoRdPnt] [RdBit]</entry></row><row><entry /><entry>// Sequentially Executed Code:</entry></row><row><entry /><entry>if (te_tfu_wdatavalid = = 1) AND (FifoCntnts !=</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>FifoMax) AND (ByteToRx != 0) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Fifo[FifoWrPnt] = te_tfu_wdata</entry></row><row><entry /><entry>FifoWrPnt ++</entry></row><row><entry /><entry>FifoContents ++</entry></row><row><entry /><entry>ByteToRx − −</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>if (te_tfu_wradvline = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>ByteToRx = TEByteCount</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>if (hcu_tfu_advdot = = 1 and FifoCntnts != 0) then {</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>BitToTx ++</entry></row><row><entry /><entry>if (RepFrac = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>RepFrac = Xscale</entry></row><row><entry /><entry>if (RdBit = 7) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>RdBit = 0</entry></row><row><entry /><entry>FifoRdPnt ++</entry></row><row><entry /><entry>FifoContents − −</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>RdBit++</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>RepFrac− −</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>if (BitToTx = = 1) then {</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>RepFrac = XFracScale</entry></row><row><entry /><entry>RdBit = 0</entry></row><row><entry /><entry>FifoRdPnt ++</entry></row><row><entry /><entry>FifoContents− −</entry></row><row><entry /><entry>BitToTx = HCUDotCount</entry></row><row><entry /><entry>}</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>}</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3323What is not detailed above is the fact that, since this is a circular buffer, both the fifo read and write-pointers wrap-around to zero after they reach two. Also not detailed is the fact that if there is a change of both the read and write-pointer in the same cycle, the fifo contents counter remains unchanged.
000028 Alftoner Compositor Unit (HCU)
000028.1 Overview
3324The Halftoner Compositor Unit (HCU) produces dots for each nozzle in the destination printhead taking account of the page dimensions (including margins). The spot data and tag data are received in bi-level form while the pixel contone data received from the CFU must be dithered to a bi-level representation. The resultant 6 bi-level planes for each dot position on the page are then remapped to 6 output planes and output dot at a time (6 bits) to the next stage in the printing pipeline, namely the dead nozzle compensator (DNC).
000028.2 Data Flow
3325<figref idref="DRAWINGS">FIG. 230</figref> shows a simple dot data flow high level block diagram of the HCU. The HCU reads contone data from the CFU, bi-level spot data from the SFU, and bi-level tag data from the TFU.
3326Dither matrices are read from the DRAM via the DIU. The calculated output dot (6 bits) is read by the DNC.
3327The HCU is given the page dimensions (including margins), and is only started once for the page. It does not need to be programmed in between bands or restarted for each band. The HCU will stall appropriately if its input buffers are starved. At the end of the page the HCU will continue to produce 0 for all dots as long as data is requested by the units further down the pipeline (this allows later units to conveniently flush pipelined data).
3328The HCU performs a linear processing of dots calculating the 6-bit output of a dot in each cycle. The mapping of 6 calculated bits to 6 output bits for each dot allows for such example mappings. as compositing of the spot0 layer over the appropriate contone layer (typically black), the merging of CMY into K (if K is present in the printhead), the splitting of K into CMY dots if there is no K in the printhead, and the generation of a fixative output bitstream.
000028.3 Dram Storage Requirements
3329SoPEC allows for a number of different dither matrix configurations up to 256 bytes wide. The dither matrix is stored in DRAM. Using either a single or double-buffer scheme a line of the dither matrix must be read in by the HCU over a SoPEC line time. SoPEC must produce 13824 dots per line for A4/Letter printing which takes 13824 cycles.
3330The following give the storage and bandwidths requirements for some of the possible configurations of the dither matrix. <ul id="ul0341" list-style="none"><li id="ul0341-0001" num="0000"><ul id="ul0342" list-style="none"><li id="ul0342-0001" num="3331">4 Kbyte DRAM storage required for one 64×64 (preferred) byte dither matrix</li><li id="ul0342-0002" num="3332">6.25 Kbyte DRAM storage required for one 80×80 byte dither matrix</li><li id="ul0342-0003" num="3333">16 Kbyte DRAM storage required for four 64×64 byte dither matrices</li><li id="ul0342-0004" num="3334">64 Kbyte DRAM storage required for one 256×256 byte dither matrix</li></ul></li></ul>
3335It takes 4 or 8 read accesses to load a line of dither matrix into the dither matrix buffer, depending on whether we're using a single or double buffer (configured by DoubleLineBuff register).
000028.4 Implementation
3336A block diagram of the HCU is given in <figref idref="DRAWINGS">FIG. 231</figref>.
000028.4.1 Definition of I/O
3337<tables id="TABLE-US-00283" num="00283"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="287pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 192</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>HCU port list and description</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="175pt" align="left" /><tbody valign="top"><row><entry>Port name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="287pt" align="left" /><tbody valign="top"><row><entry>Clocks and reset</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="175pt" align="left" /><tbody valign="top"><row><entry>Pclk</entry><entry>1</entry><entry>In</entry><entry>System clock.</entry></row><row><entry>prst_n</entry><entry>1</entry><entry>In</entry><entry>System reset, synchronous active low.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="287pt" align="left" /><tbody valign="top"><row><entry>PCU interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="175pt" align="left" /><tbody valign="top"><row><entry>pcu_hcu_sel</entry><entry>1</entry><entry>In</entry><entry>Block select from the PCU. When pcu_hcu_sel is high</entry></row><row><entry /><entry /><entry /><entry>both pcu_adr and pcu_dataout are valid.</entry></row><row><entry>pcu_rwn</entry><entry>1</entry><entry>In</entry><entry>Common read/not-write signal from the PCU.</entry></row><row><entry>pcu_adr[7:2]</entry><entry>6</entry><entry>In</entry><entry>PCU address bus. Only 6 bits are required to decode the</entry></row><row><entry /><entry /><entry /><entry>address space for this block.</entry></row><row><entry>pcu_dataout[31:0]</entry><entry>32</entry><entry>In</entry><entry>Shared write data bus from the PCU.</entry></row><row><entry>hcu_pcu_rdy</entry><entry>1</entry><entry>Out</entry><entry>Ready signal to the PCU. When hcu_pcu_rdy is high it</entry></row><row><entry /><entry /><entry /><entry>indicates the last cycle of the access. For a write cycle</entry></row><row><entry /><entry /><entry /><entry>this means pcu_dataout has been registered by the block</entry></row><row><entry /><entry /><entry /><entry>and for a read cycle this means the data on</entry></row><row><entry /><entry /><entry /><entry>hcu_pcu_datain is valid.</entry></row><row><entry>hcu_pcu_datain[31:0]</entry><entry>32</entry><entry>Out</entry><entry>Read data bus to the PCU.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="287pt" align="left" /><tbody valign="top"><row><entry>DIU interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="175pt" align="left" /><tbody valign="top"><row><entry>hcu_diu_rreq</entry><entry>1</entry><entry>Out</entry><entry>HCU read request, active high. A read request must be</entry></row><row><entry /><entry /><entry /><entry>accompanied by a valid read address.</entry></row><row><entry>diu_hcu_rack</entry><entry>1</entry><entry>In</entry><entry>Acknowledge from DIU, active high. Indicates that a read</entry></row><row><entry /><entry /><entry /><entry>request has been accepted and the new read address</entry></row><row><entry /><entry /><entry /><entry>can be placed on the address bus, hcu_diu_radr.</entry></row><row><entry>hcu_diu_radr[21:5]</entry><entry>17</entry><entry>Out</entry><entry>HCU read address. 17 bits wide (256-bit aligned word).</entry></row><row><entry>diu_hcu_rvalid</entry><entry>1</entry><entry>In</entry><entry>Read data valid, active high. Indicates that valid read data</entry></row><row><entry /><entry /><entry /><entry>is now on the read data bus, diu_data.</entry></row><row><entry>diu_data[63:0]</entry><entry>64</entry><entry>In</entry><entry>Read data from DIU.</entry></row><row><entry>CFU interface</entry></row><row><entry>cfu_hcu_avail</entry><entry>1</entry><entry>In</entry><entry>Indicates valid data present on cfu_hcu_c[3–0]data lines.</entry></row><row><entry>cfu_hcu_c0data[7:0]</entry><entry>8</entry><entry>In</entry><entry>Pixel of data in contone plane 0.</entry></row><row><entry>cfu_hcu_c1data[7:0]</entry><entry>8</entry><entry>In</entry><entry>Pixel of data in contone plane 1.</entry></row><row><entry>cfu_hcu_c2data[7:0]</entry><entry>8</entry><entry>In</entry><entry>Pixel of data in contone plane 2.</entry></row><row><entry>cfu_hcu_c3data[7:0]</entry><entry>8</entry><entry>In</entry><entry>Pixel of data in contone plane 3.</entry></row><row><entry>hcu_cfu_advdot</entry><entry>1</entry><entry>Out</entry><entry>Informs the CFU that the HCU has captured the pixel</entry></row><row><entry /><entry /><entry /><entry>data on cfu_hcu_c[3–0]data lines and the CFU can now</entry></row><row><entry /><entry /><entry /><entry>place the next pixel on the data lines.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="287pt" align="left" /><tbody valign="top"><row><entry>SFU interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="175pt" align="left" /><tbody valign="top"><row><entry>sfu_hcu_avail</entry><entry>1</entry><entry>In</entry><entry>Indicates valid data present on sfu_hcu_sdata.</entry></row><row><entry>sfu_hcu_sdata</entry><entry>1</entry><entry>In</entry><entry>Bi-level dot data.</entry></row><row><entry>hcu_sfu_advdot</entry><entry>1</entry><entry>Out</entry><entry>Informs the SFU that the HCU has captured the dot data</entry></row><row><entry /><entry /><entry /><entry>on sfu_hcu_sdata and the SFU can now place the next</entry></row><row><entry /><entry /><entry /><entry>dot on the data line.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="287pt" align="left" /><tbody valign="top"><row><entry>TFU interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="175pt" align="left" /><tbody valign="top"><row><entry>tfu_hcu_avail</entry><entry>1</entry><entry>In</entry><entry>Indicates valid data present on tfu_hcu_tdata.</entry></row><row><entry>tfu_hcu_tdata</entry><entry>1</entry><entry>In</entry><entry>Tag dot data.</entry></row><row><entry>hcu_tfu_advdot</entry><entry>1</entry><entry>Out</entry><entry>Informs the TFU that the HCU has captured the dot data</entry></row><row><entry /><entry /><entry /><entry>on tfu_hcu_tdata and the TFU can now place the next dot</entry></row><row><entry /><entry /><entry /><entry>on the data line.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="287pt" align="left" /><tbody valign="top"><row><entry>DNC interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="175pt" align="left" /><tbody valign="top"><row><entry>dnc_hcu_ready</entry><entry>1</entry><entry>In</entry><entry>Indicates that DNC is ready to accept data from the HCU.</entry></row><row><entry>hcu_dnc_avail</entry><entry>1</entry><entry>Out</entry><entry>Indicates valid data present on hcu_dnc_data.</entry></row><row><entry>hcu_dnc_data[5:0]</entry><entry>6</entry><entry>Out</entry><entry>Output bi-level dot data in 6 ink planes</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 28.4.2 Configuration Registers
3338The configuration registers in the HCU are programmed via the PCU interface. Refer to section 21.8.2 on page 321 for the description of the protocol and timing diagrams for reading and writing registers in the HCU. Note that since addresses in SoPEC are byte aligned and the PCU only supports 32-bit register reads and writes, the lower 2 bits of the PCU address bus are not required to decode the address space for the HCU. When reading a register that is less than 32 bits wide zeros should be returned on the upper unused bit(s) of hcu_pcu_datain. The configuration registers of the HCU are listed in Table 193.
3339<tables id="TABLE-US-00284" num="00284"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="280pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 193</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>HCU Registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="28pt" align="center" /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry /><entry>Value</entry><entry /></row><row><entry>Address</entry><entry>Register</entry><entry /><entry>on</entry></row><row><entry>(HCU_base+)</entry><entry>Name</entry><entry>#bits</entry><entry>Reset</entry><entry>Description</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="280pt" align="left" /><tbody valign="top"><row><entry>Control registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="91pt" align="left" /><tbody valign="top"><row><entry>0x00</entry><entry>Reset</entry><entry>1</entry><entry>0x1</entry><entry>A write to this register</entry></row><row><entry /><entry /><entry /><entry /><entry>causes a reset of the</entry></row><row><entry /><entry /><entry /><entry /><entry>HCU.</entry></row><row><entry>0x04</entry><entry>Go</entry><entry>1</entry><entry>0x0</entry><entry>Writing 1 to this register</entry></row><row><entry /><entry /><entry /><entry /><entry>starts the HCU. Writing 0</entry></row><row><entry /><entry /><entry /><entry /><entry>to this register halts the</entry></row><row><entry /><entry /><entry /><entry /><entry>HCU.</entry></row><row><entry /><entry /><entry /><entry /><entry>When Go is asserted all</entry></row><row><entry /><entry /><entry /><entry /><entry>counters, flags etc. are</entry></row><row><entry /><entry /><entry /><entry /><entry>cleared or given their</entry></row><row><entry /><entry /><entry /><entry /><entry>initial value, but</entry></row><row><entry /><entry /><entry /><entry /><entry>configuration registers</entry></row><row><entry /><entry /><entry /><entry /><entry>keep their values.</entry></row><row><entry /><entry /><entry /><entry /><entry>When Go is deasserted</entry></row><row><entry /><entry /><entry /><entry /><entry>the state-machines go to</entry></row><row><entry /><entry /><entry /><entry /><entry>their idle states but all</entry></row><row><entry /><entry /><entry /><entry /><entry>counters and</entry></row><row><entry /><entry /><entry /><entry /><entry>configuration registers</entry></row><row><entry /><entry /><entry /><entry /><entry>keep their values.</entry></row><row><entry /><entry /><entry /><entry /><entry>The HCU should be</entry></row><row><entry /><entry /><entry /><entry /><entry>started after the CFU,</entry></row><row><entry /><entry /><entry /><entry /><entry>SFU, TFU, and DNC.</entry></row><row><entry /><entry /><entry /><entry /><entry>This register can be read</entry></row><row><entry /><entry /><entry /><entry /><entry>to determine if the HCU is</entry></row><row><entry /><entry /><entry /><entry /><entry>running</entry></row><row><entry /><entry /><entry /><entry /><entry>(1 = running, 0 =</entry></row><row><entry /><entry /><entry /><entry /><entry>stopped).</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="280pt" align="left" /><tbody valign="top"><row><entry>Setup registers (constant for during processing)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="91pt" align="left" /><tbody valign="top"><row><entry>0x10</entry><entry>AvailMask</entry><entry>4</entry><entry>0x0</entry><entry>Mask used to determine</entry></row><row><entry /><entry /><entry /><entry /><entry>which of the dotgen units</entry></row><row><entry /><entry /><entry /><entry /><entry>etc. are to be checked</entry></row><row><entry /><entry /><entry /><entry /><entry>before a dot is generated</entry></row><row><entry /><entry /><entry /><entry /><entry>by the HCU within the</entry></row><row><entry /><entry /><entry /><entry /><entry>specified margins for the</entry></row><row><entry /><entry /><entry /><entry /><entry>specified color plane. If</entry></row><row><entry /><entry /><entry /><entry /><entry>the specified dotgen unit</entry></row><row><entry /><entry /><entry /><entry /><entry>is stalled, then the HCU</entry></row><row><entry /><entry /><entry /><entry /><entry>will also stall.</entry></row><row><entry /><entry /><entry /><entry /><entry>See Table for bit</entry></row><row><entry /><entry /><entry /><entry /><entry>allocation and definition.</entry></row><row><entry>0x14</entry><entry>TMMask</entry><entry>4</entry><entry>0x0</entry><entry>Same as AvailMask, but</entry></row><row><entry /><entry /><entry /><entry /><entry>used in the top margin</entry></row><row><entry /><entry /><entry /><entry /><entry>area before the</entry></row><row><entry /><entry /><entry /><entry /><entry>appropriate target page is</entry></row><row><entry /><entry /><entry /><entry /><entry>reached.</entry></row><row><entry>0x18</entry><entry>PageMarginY</entry><entry>32</entry><entry>0x0000_0000</entry><entry>The first line considered</entry></row><row><entry /><entry /><entry /><entry /><entry>to be off the page.</entry></row><row><entry>0x1C</entry><entry>MaxDot</entry><entry>16</entry><entry>0x0000</entry><entry>This is the maximum dot</entry></row><row><entry /><entry /><entry /><entry /><entry>number − 1 present</entry></row><row><entry /><entry /><entry /><entry /><entry>across a page. For</entry></row><row><entry /><entry /><entry /><entry /><entry>example if a page</entry></row><row><entry /><entry /><entry /><entry /><entry>contains 13824 dots, then</entry></row><row><entry /><entry /><entry /><entry /><entry>MaxDot will be 13823.</entry></row><row><entry>0x20</entry><entry>TopMargin</entry><entry>32</entry><entry>0x0000_0000</entry><entry>The first line on a page to</entry></row><row><entry /><entry /><entry /><entry /><entry>be considered within the</entry></row><row><entry /><entry /><entry /><entry /><entry>target page for contone</entry></row><row><entry /><entry /><entry /><entry /><entry>and spot data. (0 = first</entry></row><row><entry /><entry /><entry /><entry /><entry>printed line of page)</entry></row><row><entry>0x24</entry><entry>BottomMargin</entry><entry>32</entry><entry>0x0000_0000</entry><entry>The first line in the target</entry></row><row><entry /><entry /><entry /><entry /><entry>bottom margin for</entry></row><row><entry /><entry /><entry /><entry /><entry>contone and spot data</entry></row><row><entry /><entry /><entry /><entry /><entry>(i.e. first line after target</entry></row><row><entry /><entry /><entry /><entry /><entry>page).</entry></row><row><entry>0x28</entry><entry>LeftMargin</entry><entry>16</entry><entry>0x0000</entry><entry>The first dot on a line</entry></row><row><entry /><entry /><entry /><entry /><entry>within the target page for</entry></row><row><entry /><entry /><entry /><entry /><entry>contone and spot data.</entry></row><row><entry>0x2C</entry><entry>RightMargin</entry><entry>16</entry><entry>0xFFFF</entry><entry>The first dot on a line</entry></row><row><entry /><entry /><entry /><entry /><entry>within the target right</entry></row><row><entry /><entry /><entry /><entry /><entry>margin for contone and</entry></row><row><entry /><entry /><entry /><entry /><entry>spot data.</entry></row><row><entry>0x30</entry><entry>TagTopMargin</entry><entry>32</entry><entry>0x0000_0000</entry><entry>The first line on a page to</entry></row><row><entry /><entry /><entry /><entry /><entry>be considered within the</entry></row><row><entry /><entry /><entry /><entry /><entry>target page for tag data.</entry></row><row><entry /><entry /><entry /><entry /><entry>0 = first printed line of</entry></row><row><entry /><entry /><entry /><entry /><entry>page)</entry></row><row><entry>0x34</entry><entry>TagBottomMargin</entry><entry>32</entry><entry>0x0000_0000</entry><entry>The first line in the target</entry></row><row><entry /><entry /><entry /><entry /><entry>bottom margin for tag</entry></row><row><entry /><entry /><entry /><entry /><entry>data (i.e. first line after</entry></row><row><entry /><entry /><entry /><entry /><entry>target page).</entry></row><row><entry>0x38</entry><entry>TagLeftMargin</entry><entry>16</entry><entry>0x0000</entry><entry>The first dot on a line</entry></row><row><entry /><entry /><entry /><entry /><entry>within the target page for</entry></row><row><entry /><entry /><entry /><entry /><entry>tag data.</entry></row><row><entry>0x3C</entry><entry>TagRightMargin</entry><entry>16</entry><entry>0xFFFF</entry><entry>The first dot on a line</entry></row><row><entry /><entry /><entry /><entry /><entry>within the target right</entry></row><row><entry /><entry /><entry /><entry /><entry>margin for tag data.</entry></row><row><entry>0x44</entry><entry>StartDMAdr[21:5]</entry><entry>17</entry><entry>0x0_0000</entry><entry>Points to the first 256-bit</entry></row><row><entry /><entry /><entry /><entry /><entry>word of the first line of the</entry></row><row><entry /><entry /><entry /><entry /><entry>dither matrix in DRAM.</entry></row><row><entry>0x48</entry><entry>EndDMAdr[21:5]</entry><entry>17</entry><entry>0x0_0000</entry><entry>Points to the last address</entry></row><row><entry /><entry /><entry /><entry /><entry>of the group of four 256-</entry></row><row><entry /><entry /><entry /><entry /><entry>bit reads (or 8 if single</entry></row><row><entry /><entry /><entry /><entry /><entry>buffering) that reads in</entry></row><row><entry /><entry /><entry /><entry /><entry>the last line of the dither</entry></row><row><entry /><entry /><entry /><entry /><entry>matrix.</entry></row><row><entry>0x4C</entry><entry>LineIncrement</entry><entry>5</entry><entry>0x2</entry><entry>The number of 256-bit</entry></row><row><entry /><entry /><entry /><entry /><entry>words in DRAM from the</entry></row><row><entry /><entry /><entry /><entry /><entry>start of one line of the</entry></row><row><entry /><entry /><entry /><entry /><entry>dither matrix and the start</entry></row><row><entry /><entry /><entry /><entry /><entry>of the next line, i.e. the</entry></row><row><entry /><entry /><entry /><entry /><entry>value by which the DRAM</entry></row><row><entry /><entry /><entry /><entry /><entry>address is incremented at</entry></row><row><entry /><entry /><entry /><entry /><entry>the start of a line so that it</entry></row><row><entry /><entry /><entry /><entry /><entry>points to the start of the</entry></row><row><entry /><entry /><entry /><entry /><entry>next line of the dither</entry></row><row><entry /><entry /><entry /><entry /><entry>matrix.</entry></row><row><entry>0x50</entry><entry>DMInitIndexC0</entry><entry>8</entry><entry>0x00</entry><entry>If using the single-buffer</entry></row><row><entry /><entry /><entry /><entry /><entry>scheme this register</entry></row><row><entry /><entry /><entry /><entry /><entry>represents the initial index</entry></row><row><entry /><entry /><entry /><entry /><entry>within 256-byte dither</entry></row><row><entry /><entry /><entry /><entry /><entry>matrix line buffer for</entry></row><row><entry /><entry /><entry /><entry /><entry>contone plane 0. If using</entry></row><row><entry /><entry /><entry /><entry /><entry>double-buffer scheme,</entry></row><row><entry /><entry /><entry /><entry /><entry>only the 7 lsbs are used.</entry></row><row><entry>0x54</entry><entry>DMLwrIndexC0</entry><entry>8</entry><entry>0x00</entry><entry>If using the single-buffer</entry></row><row><entry /><entry /><entry /><entry /><entry>scheme this register</entry></row><row><entry /><entry /><entry /><entry /><entry>represents the lower</entry></row><row><entry /><entry /><entry /><entry /><entry>index within 256-byte</entry></row><row><entry /><entry /><entry /><entry /><entry>dither matrix line buffer for</entry></row><row><entry /><entry /><entry /><entry /><entry>contone plane 0. If using</entry></row><row><entry /><entry /><entry /><entry /><entry>double-buffer scheme,</entry></row><row><entry /><entry /><entry /><entry /><entry>only the 7 lsbs are used.</entry></row><row><entry>0x58</entry><entry>DMUprIndexC0</entry><entry>8</entry><entry>0x3F</entry><entry>If using the single-buffer</entry></row><row><entry /><entry /><entry /><entry /><entry>scheme this register</entry></row><row><entry /><entry /><entry /><entry /><entry>represents the upper</entry></row><row><entry /><entry /><entry /><entry /><entry>index within 256-byte</entry></row><row><entry /><entry /><entry /><entry /><entry>dither matrix line buffer for</entry></row><row><entry /><entry /><entry /><entry /><entry>contone plane 0. After</entry></row><row><entry /><entry /><entry /><entry /><entry>reading the data at this</entry></row><row><entry /><entry /><entry /><entry /><entry>location the index wraps</entry></row><row><entry /><entry /><entry /><entry /><entry>to DMLwrIndexC0.</entry></row><row><entry /><entry /><entry /><entry /><entry>If using double-buffer</entry></row><row><entry /><entry /><entry /><entry /><entry>scheme, only the 7 lsbs</entry></row><row><entry /><entry /><entry /><entry /><entry>are used.</entry></row><row><entry>0x5C</entry><entry>DMInitIndexC1</entry><entry>8</entry><entry>0x00</entry><entry>If using the single-buffer</entry></row><row><entry /><entry /><entry /><entry /><entry>scheme this register</entry></row><row><entry /><entry /><entry /><entry /><entry>represents the initial index</entry></row><row><entry /><entry /><entry /><entry /><entry>within 256-byte dither</entry></row><row><entry /><entry /><entry /><entry /><entry>matrix line buffer for</entry></row><row><entry /><entry /><entry /><entry /><entry>contone plane 1. If using</entry></row><row><entry /><entry /><entry /><entry /><entry>double-buffer scheme,</entry></row><row><entry /><entry /><entry /><entry /><entry>only the 7 lsbs are used.</entry></row><row><entry>0x60</entry><entry>DMLwrIndexC1</entry><entry>8</entry><entry>0x00</entry><entry>If using the single-buffer</entry></row><row><entry /><entry /><entry /><entry /><entry>scheme this register</entry></row><row><entry /><entry /><entry /><entry /><entry>represents the lower</entry></row><row><entry /><entry /><entry /><entry /><entry>index within 256-byte</entry></row><row><entry /><entry /><entry /><entry /><entry>dither matrix line buffer for</entry></row><row><entry /><entry /><entry /><entry /><entry>contone plane 1. If using</entry></row><row><entry /><entry /><entry /><entry /><entry>double-buffer scheme,</entry></row><row><entry /><entry /><entry /><entry /><entry>only the 7 lsbs are used.</entry></row><row><entry>0x64</entry><entry>DMUprIndexC1</entry><entry>8</entry><entry>0x3F</entry><entry>If using the single-buffer</entry></row><row><entry /><entry /><entry /><entry /><entry>scheme this register</entry></row><row><entry /><entry /><entry /><entry /><entry>represents the upper</entry></row><row><entry /><entry /><entry /><entry /><entry>index within 256-byte</entry></row><row><entry /><entry /><entry /><entry /><entry>dither matrix line buffer for</entry></row><row><entry /><entry /><entry /><entry /><entry>contone plane 1. After</entry></row><row><entry /><entry /><entry /><entry /><entry>reading the data at this</entry></row><row><entry /><entry /><entry /><entry /><entry>location the index wraps</entry></row><row><entry /><entry /><entry /><entry /><entry>to DMLwrIndexC1. If</entry></row><row><entry /><entry /><entry /><entry /><entry>using double-buffer</entry></row><row><entry /><entry /><entry /><entry /><entry>scheme, only the 7 lsbs</entry></row><row><entry /><entry /><entry /><entry /><entry>are used.</entry></row><row><entry>0x68</entry><entry>DMInitIndexC2</entry><entry>8</entry><entry>0x00</entry><entry>If using the single-buffer</entry></row><row><entry /><entry /><entry /><entry /><entry>scheme this register</entry></row><row><entry /><entry /><entry /><entry /><entry>represents the initial index</entry></row><row><entry /><entry /><entry /><entry /><entry>within 256-byte dither</entry></row><row><entry /><entry /><entry /><entry /><entry>matrix line buffer for</entry></row><row><entry /><entry /><entry /><entry /><entry>contone plane 2. If using</entry></row><row><entry /><entry /><entry /><entry /><entry>double-buffer scheme,</entry></row><row><entry /><entry /><entry /><entry /><entry>only the 7 lsbs are used.</entry></row><row><entry>0x6C</entry><entry>DMLwrIndexC2</entry><entry>8</entry><entry>0x00</entry><entry>If using the single-buffer</entry></row><row><entry /><entry /><entry /><entry /><entry>scheme this register</entry></row><row><entry /><entry /><entry /><entry /><entry>represents the lower</entry></row><row><entry /><entry /><entry /><entry /><entry>index within 256-byte</entry></row><row><entry /><entry /><entry /><entry /><entry>dither matrix line buffer for</entry></row><row><entry /><entry /><entry /><entry /><entry>contone plane 2. If using</entry></row><row><entry /><entry /><entry /><entry /><entry>double-buffer scheme,</entry></row><row><entry /><entry /><entry /><entry /><entry>only the 7 lsbs are used.</entry></row><row><entry>0x70</entry><entry>DMUprIndexC2</entry><entry>8</entry><entry>0x3F</entry><entry>If using the single-buffer</entry></row><row><entry /><entry /><entry /><entry /><entry>scheme this register</entry></row><row><entry /><entry /><entry /><entry /><entry>represents the upper</entry></row><row><entry /><entry /><entry /><entry /><entry>index within 256-byte</entry></row><row><entry /><entry /><entry /><entry /><entry>dither matrix line buffer for</entry></row><row><entry /><entry /><entry /><entry /><entry>contone plane 2. After</entry></row><row><entry /><entry /><entry /><entry /><entry>reading the data at this</entry></row><row><entry /><entry /><entry /><entry /><entry>location the index wraps</entry></row><row><entry /><entry /><entry /><entry /><entry>to DMLwrIndexC2. If</entry></row><row><entry /><entry /><entry /><entry /><entry>using double-buffer</entry></row><row><entry /><entry /><entry /><entry /><entry>scheme, only the 7 lsbs</entry></row><row><entry /><entry /><entry /><entry /><entry>are used.</entry></row><row><entry>0x74</entry><entry>DMInitIndexC3</entry><entry>8</entry><entry>0x00</entry><entry>If using the single-buffer</entry></row><row><entry /><entry /><entry /><entry /><entry>scheme this register</entry></row><row><entry /><entry /><entry /><entry /><entry>represents the initial index</entry></row><row><entry /><entry /><entry /><entry /><entry>within 256-byte dither</entry></row><row><entry /><entry /><entry /><entry /><entry>matrix line buffer for</entry></row><row><entry /><entry /><entry /><entry /><entry>contone plane 3. If using</entry></row><row><entry /><entry /><entry /><entry /><entry>double-buffer scheme,</entry></row><row><entry /><entry /><entry /><entry /><entry>only the 7 lsbs are used.</entry></row><row><entry>0x78</entry><entry>DMLwrIndexC3</entry><entry>8</entry><entry>0x00</entry><entry>If using the single-buffer</entry></row><row><entry /><entry /><entry /><entry /><entry>scheme this register</entry></row><row><entry /><entry /><entry /><entry /><entry>represents the lower</entry></row><row><entry /><entry /><entry /><entry /><entry>index within 256-byte</entry></row><row><entry /><entry /><entry /><entry /><entry>dither matrix line buffer for</entry></row><row><entry /><entry /><entry /><entry /><entry>contone plane 3. If using</entry></row><row><entry /><entry /><entry /><entry /><entry>double-buffer scheme,</entry></row><row><entry /><entry /><entry /><entry /><entry>only the 7 lsbs are used.</entry></row><row><entry>0x7C</entry><entry>DMUprIndexC3</entry><entry>8</entry><entry>0x3F</entry><entry>If using the single-buffer</entry></row><row><entry /><entry /><entry /><entry /><entry>scheme this register</entry></row><row><entry /><entry /><entry /><entry /><entry>represents the upper</entry></row><row><entry /><entry /><entry /><entry /><entry>index within 256-byte dither</entry></row><row><entry /><entry /><entry /><entry /><entry>matrix line buffer for</entry></row><row><entry /><entry /><entry /><entry /><entry>contone plane 3. After</entry></row><row><entry /><entry /><entry /><entry /><entry>reading the data at this</entry></row><row><entry /><entry /><entry /><entry /><entry>location the index wraps</entry></row><row><entry /><entry /><entry /><entry /><entry>to DMLwrIndexC3. If</entry></row><row><entry /><entry /><entry /><entry /><entry>using double-buffer</entry></row><row><entry /><entry /><entry /><entry /><entry>scheme, only the 7 lsbs</entry></row><row><entry /><entry /><entry /><entry /><entry>are used.</entry></row><row><entry>0x80</entry><entry>DoubleLineBuf</entry><entry>1</entry><entry>0x1</entry><entry>Selects the dither line</entry></row><row><entry /><entry /><entry /><entry /><entry>buffer mode to be single</entry></row><row><entry /><entry /><entry /><entry /><entry>or double buffer.</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - single line buffer mode</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - double line buffer</entry></row><row><entry /><entry /><entry /><entry /><entry>mode</entry></row><row><entry>0x84 to 0x98</entry><entry>IOMappingLo</entry><entry>6 × 32</entry><entry>0x0000_0000</entry><entry>The dot reorg mapping for</entry></row><row><entry /><entry /><entry /><entry /><entry>output inks 0 to 5. For</entry></row><row><entry /><entry /><entry /><entry /><entry>each ink's 64-bit</entry></row><row><entry /><entry /><entry /><entry /><entry>IOMapping value,</entry></row><row><entry /><entry /><entry /><entry /><entry>IOMappingLo represents</entry></row><row><entry /><entry /><entry /><entry /><entry>the low order 32 bits.</entry></row><row><entry>0x9C to 0xB0</entry><entry>IOMappingHi</entry><entry>6 × 32</entry><entry>0x0000_0000</entry><entry>The dot reorg mapping for</entry></row><row><entry /><entry /><entry /><entry /><entry>output inks 0 to 5. For</entry></row><row><entry /><entry /><entry /><entry /><entry>each ink's 64-bit</entry></row><row><entry /><entry /><entry /><entry /><entry>IOMapping value,</entry></row><row><entry /><entry /><entry /><entry /><entry>IOMappingHi represents</entry></row><row><entry /><entry /><entry /><entry /><entry>the high order 32 bits.</entry></row><row><entry>0xB4 to 0xC0</entry><entry>cpConstant</entry><entry>4 × 8 </entry><entry>0x00</entry><entry>The constant contone</entry></row><row><entry /><entry /><entry /><entry /><entry>value to output for</entry></row><row><entry /><entry /><entry /><entry /><entry>contone plane N when</entry></row><row><entry /><entry /><entry /><entry /><entry>printing in the margin</entry></row><row><entry /><entry /><entry /><entry /><entry>areas of the page. This</entry></row><row><entry /><entry /><entry /><entry /><entry>value will typically be 0.</entry></row><row><entry>0xC4</entry><entry>sConstant</entry><entry>1</entry><entry>0x0</entry><entry>The constant bi-level</entry></row><row><entry /><entry /><entry /><entry /><entry>value to output for spot</entry></row><row><entry /><entry /><entry /><entry /><entry>when printing in the</entry></row><row><entry /><entry /><entry /><entry /><entry>margin areas of the page.</entry></row><row><entry /><entry /><entry /><entry /><entry>This value will typically</entry></row><row><entry /><entry /><entry /><entry /><entry>be 0.</entry></row><row><entry>0xC8</entry><entry>tConstant</entry><entry>1</entry><entry>0x0</entry><entry>The constant bi-level</entry></row><row><entry /><entry /><entry /><entry /><entry>value to output for tag</entry></row><row><entry /><entry /><entry /><entry /><entry>data when printing in the</entry></row><row><entry /><entry /><entry /><entry /><entry>margin areas of the page.</entry></row><row><entry /><entry /><entry /><entry /><entry>This value will typically be</entry></row><row><entry /><entry /><entry /><entry /><entry>0.</entry></row><row><entry>0xCC</entry><entry>DitherConstant</entry><entry>8</entry><entry>0xFF</entry><entry>The constant value to use</entry></row><row><entry /><entry /><entry /><entry /><entry>for dither matrix when the</entry></row><row><entry /><entry /><entry /><entry /><entry>dither matrix is not</entry></row><row><entry /><entry /><entry /><entry /><entry>available, i.e. when the</entry></row><row><entry /><entry /><entry /><entry /><entry>signal dm_avail is 0. This</entry></row><row><entry /><entry /><entry /><entry /><entry>value will typically be</entry></row><row><entry /><entry /><entry /><entry /><entry>0xFF so that cpConstant</entry></row><row><entry /><entry /><entry /><entry /><entry>can easily be 0x00 or</entry></row><row><entry /><entry /><entry /><entry /><entry>0xFF without requiring a</entry></row><row><entry /><entry /><entry /><entry /><entry>dither matrix</entry></row><row><entry /><entry /><entry /><entry /><entry>(DitherConstant is</entry></row><row><entry /><entry /><entry /><entry /><entry>primarily used for</entry></row><row><entry /><entry /><entry /><entry /><entry>threshold dithering in the</entry></row><row><entry /><entry /><entry /><entry /><entry>margin areas).</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="280pt" align="left" /><tbody valign="top"><row><entry>Debug registers (read only)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="91pt" align="left" /><tbody valign="top"><row><entry>0xD0</entry><entry>HcuPortsDebug</entry><entry>14</entry><entry>N/A</entry><entry>Bit 13 = tfu_hcu_avail</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 12 = hcu_tfu_advdot</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 11 = sfu_hcu_avail</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 10 = hcu_sfu_advdot</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 9 = cfu_hcu_avail</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 8 = hcu_cfu_advdot</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 7 = dnc_hcu_ready</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 6 = hcu_dnc_avail</entry></row><row><entry /><entry /><entry /><entry /><entry>Bits 5–0 = hcu_dnc_data</entry></row><row><entry>0xD4</entry><entry>HcuDotgenDebug</entry><entry>15</entry><entry>N/A</entry><entry>Bit 14 = after_top_margin</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 13 = in_tag_target_page</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 12 = in_target_page</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 11 = tp_avail</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 10 = s_avail</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 9 = cp_avail</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 8 = dm_avail</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 7 = advdot</entry></row><row><entry /><entry /><entry /><entry /><entry>Bits 5–0 =</entry></row><row><entry /><entry /><entry /><entry /><entry>[tp, s, cp3, cp2, cp1, cp0]</entry></row><row><entry /><entry /><entry /><entry /><entry>(i.e. 6 bit input</entry></row><row><entry /><entry /><entry /><entry /><entry>to dot reorg units)</entry></row><row><entry>0xD8</entry><entry>HcuDitherDebug1</entry><entry>17</entry><entry>N/A</entry><entry>Bit 17 = advdot</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 16 = dm_avail</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 15–8 = cp1_dither_val</entry></row><row><entry /><entry /><entry /><entry /><entry>Bits 7–0 = cp0_dither_val</entry></row><row><entry>0xDC</entry><entry>HcuDitherDebug2</entry><entry>17</entry><entry>N/A</entry><entry>Bit 17 = advdot</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 16 = dm_avail</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 15–8 = cp3_dither_val</entry></row><row><entry /><entry /><entry /><entry /><entry>Bits 7–0 = cp2_dither_vall</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 28.4.3 Control Unit
3340The control unit is responsible for controlling the overall flow of the HCU. It is responsible for determining whether or not a dot will be generated in a given cycle, and what dot will actually be generated—including whether or not the dot is in a margin area, and what dither cell values should be used at the specific dot location. A block diagram of the control unit is shown in <figref idref="DRAWINGS">FIG. 232</figref>.
3341The inputs to the control unit are a number of avail flags specifying whether or not a given dotgen unit is capable of supplying ‘real’ data in this cycle. The term ‘real’ refers to data generated from external sources, such as contone line buffers, bi-level line buffers, and tag plane buffers. Each dotgen unit informs the control unit whether or not a dot can be generated this cycle from real data. It must also check that the DNC is ready to receive data.
3342The contone/spot margin unit is responsible for determining whether the current dot coordinate is within the target contone/spot margins, and the tag margin unit is responsible for determining whether the current dot coordinate is within the target tag margins.
3343The dither matrix table interface provides the interface to DRAM for the generation of dither cell values that are used in the halftoning process in the contone dotgen unit.
000028.4.3.1 Determine advdot
3344The HCU does not always require contone planes, bi-level or tag planes in order to produce a page. For example, a given page may not have a bi-level layer, or a tag layer. In addition, the contone and bi-level parts of a page are only required within the contone and bi-level page margins, and the tag part of a page is only required within the tag page margins. Thus output dots can be generated without contone, bi-level or tag data before the respective top margins of a page has been reached, and 0s are generated for all color planes after the end of the page has been reached (to allow later stages of the printing pipeline to flush).
3345Consequently the HCU has an AvailMask register that determines which of the various input avail flags should be taken notice of during the production of a page from the first line of the target page, and a TMMask register that has the same behaviour, but is used in the lines before the target page has been reached (i.e. inside the target top margin area). The dither matrix mask bit TMask[0] is the exception, it applies to all margins areas not just the top margin. Each bit in the AvailMask refers to a particular avail bit: if the bit in the AvailMask register is set, then the corresponding avail bit must be 1 for the HCU to advance a dot. The bit to avail correspondence is shown in Table 194. Care should be taken with TMMask—if the particular data is not available after the top margin has been reached, then the HCU will stall. Note that the avail bits for contone and spot colors are ANDed with in_target_page after the target page area has been reached to allow dot production in the contone/spot margin areas without needing any data in the CFU and SFU. The avail bit for tag color is ANDed with in_tag_target_page after the target tag page area has been reached to allow dot production in the tag margin areas without needing any data in the TFU.
3346<tables id="TABLE-US-00285" num="00285"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 194</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Correspondence between bit in AvailMask and avail flag</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="84pt" align="center" /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="91pt" align="left" /><tbody valign="top"><row><entry>bit # in AvailMask</entry><entry>avail flag</entry><entry>description</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>0</entry><entry>dm_avail</entry><entry>dither matrix data available</entry></row><row><entry>1</entry><entry>cp_avail</entry><entry>contone pixels available</entry></row><row><entry>2</entry><entry>s_avail</entry><entry>spot color available</entry></row><row><entry>3</entry><entry>tp_avail</entry><entry>tag plane available</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3347Each of the input avail bits is processed with its appropriate mask bit and the after_top_margin flag (note the dither matrix is the exception it is processed with in_target_page). The output bits are ANDed together along with Go and output_buff_full (which specifies whether the output buffer is ready to receive a dot in this cycle) to form the output bit advdot. We also generate wr_advdot. In this way, if the output buffer is full or any of the specified avail flags is clear, the HCU will stall. When the end of the page is reached, in_page will be deasserted and the HCU will continue to produce 0 for all dots as long as the DNC requests data. A block diagram of the determine advdot unit is shown in <figref idref="DRAWINGS">FIG. 233</figref>.
3348The advance dot block also determines if current page needs dither matrix, it indicates to the dither matrix table interface block via the dm_read_enable signal. If no dither is required in the margins or in the target page then dm_read_enable will be 0 and no dither will be read in for this page.
000028.4.3.2 Position Unit
3349The position unit is responsible for outputting the position of the current dot (curr_pos, curr_line) and whether or not this dot is the last dot of a line (advline). Both curr_pos and curr_line are set to 0 at reset or when Go transitions from 0 to 1. The position unit relies on the advdot input signal to advance through the dots on a page. Whenever an advdot pulse is received, curr_pos gets incremented. If curr_pos equals max_dot then an advline pulse is generated as this is the last dot in a line, curr_line gets incremented, and the curr_pos is reset to 0 to start counting the dots for the next line.
3350The position unit also generates a filtered version of advline called dm_advline to indicate to the dither matrix pointers to increment to the next line. The dm_advline is only incremented when dither is required for that line.
3351<tables id="TABLE-US-00286" num="00286"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>if ((after_top_margin AND avail_mask[0]) OR tm_mask[0]) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>dm_advline = advline</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>dm_advline = 0</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 28.4.3.3 Margin Unit
3352The responsibility of the margin unit is to determine whether the specific dot coordinate is within the page at all, within the target page or in a margin area (see <figref idref="DRAWINGS">FIG. 234</figref>). This unit is instantiated for both the contone/spot margin unit and the tag margin unit.
3353The margin unit takes the current dot and line position, and returns three flags. <ul id="ul0343" list-style="none"><li id="ul0343-0001" num="0000"><ul id="ul0344" list-style="none"><li id="ul0344-0001" num="3354">the first, in_page is 1 if the current dot is within the page, and 0 if it is outside the page.</li><li id="ul0344-0002" num="3355">the second flag, in_target_page, is 1 if the dot coordinate is within the target page area of the page, and 0 if it is within the target top/left/bottom/right margins.</li><li id="ul0344-0003" num="3356">the third flag, after_top_margin, is 1 if the current dot is below the target top margin, and 0 if it is within the target top margin.</li></ul></li></ul>
3357A block diagram of the margin unit is shown in <figref idref="DRAWINGS">FIG. 235</figref>.
000028.4.3.4 Dither Matrix Table Interface
3358The dither matrix table interface provides the interface to DRAM for the generation of dither cell values that are used in the halftoning process in the contone dotgen unit. The control flag dm_read_enable enables the reading of the dither matrix table line structure from DRAM. If dm_read_enable is 0, the dither matrix is not specified in DRAM and no DRAM accesses are attempted. The dither matrix table interface has an output flag dm_avail which specifies if the current line of the specified matrix is available. The HCU can be directed to stall when dm_avail is 0 by setting the appropriate bit in the HCU's AvailMask or TMMask registers. When dm_avail is 0 the value in the DitherConstant register is used as the dither cell values that are output to the contone dotgen unit.
3359The dither matrix table interface consists of a state machine that interfaces to the DRAM interface, a dither matrix buffer that provides dither matrix values, and a unit to generate the addresses for reading the buffer. <figref idref="DRAWINGS">FIG. 236</figref> shows a block diagram of the dither matrix table interface.
000028.4.3.5 Dither Data Structure in DRAM
3360The dither matrix is stored in DRAM in 256-bit words, transferred to the HCU in 64-bit words and consumed by the HCU in bytes. Table 195 shows the 64-bit words mapping to 256-bit word addresses, and Table 196 shows the 8-bits dither value mapping in the 64-bits word.
3361<tables id="TABLE-US-00287" num="00287"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 195</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Dither Data stored in DRAM</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="161pt" align="center" /><tbody valign="top"><row><entry>Address[21:5]</entry><entry>Data[255:0]</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="42pt" align="left" /><colspec colname="4" colwidth="42pt" align="left" /><colspec colname="5" colwidth="35pt" align="left" /><tbody valign="top"><row><entry>00000</entry><entry>D3</entry><entry>D2</entry><entry>D1</entry><entry>D0</entry></row><row><entry /><entry>[255:192]</entry><entry>[191:128]</entry><entry>[127:64]</entry><entry>[63:0]</entry></row><row><entry>00001</entry><entry>D7</entry><entry>D6</entry><entry>D5</entry><entry>D4</entry></row><row><entry /><entry>[255:192]</entry><entry>[191:128]</entry><entry>[127:64]</entry><entry>[63:0]</entry></row><row><entry>00010</entry><entry>D11</entry><entry>D10</entry><entry>D9</entry><entry>D8</entry></row><row><entry /><entry>[255:192]</entry><entry>[191:128]</entry><entry>[127:64]</entry><entry>[63:0]</entry></row><row><entry>00011</entry><entry>D15</entry><entry>D14</entry><entry>D13</entry><entry>D12</entry></row><row><entry /><entry>[255:192]</entry><entry>[191:128]</entry><entry>[127:64]</entry><entry>[63:0]</entry></row><row><entry>00100</entry><entry>D19</entry><entry>D18</entry><entry>D17</entry><entry>D16</entry></row><row><entry /><entry>[255:192]</entry><entry>[191:128]</entry><entry>[127:64]</entry><entry>[63:0]</entry></row><row><entry>etc</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3362When the HCU first requests data from DRAM, the 64-bits word transfer order will be D0,D1,D2,D3. On the second request the transfer order will be D4,D5,D6,D7 and so on for other requests.
3363<tables id="TABLE-US-00288" num="00288"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 196</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Dither data stored in HCUs line buffer</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="133pt" align="center" /><colspec colname="2" colwidth="84pt" align="left" /><tbody valign="top"><row><entry>Dither</entry><entry /></row><row><entry>index</entry></row><row><entry>[7:0]</entry><entry>Data[7:0]</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>00</entry><entry>D0[7:0]</entry></row><row><entry>01</entry><entry>D0[15:8]</entry></row><row><entry>02</entry><entry>D0[23:16]</entry></row><row><entry>03</entry><entry>D0[31:24]</entry></row><row><entry>04</entry><entry>D0[39:32]</entry></row><row><entry>05</entry><entry>D0[47:40]</entry></row><row><entry>06</entry><entry>D0[55:48]</entry></row><row><entry>07</entry><entry>D0[63:56]</entry></row><row><entry>08</entry><entry>D1[7:0]</entry></row><row><entry>09</entry><entry>D1[15:8]</entry></row><row><entry>0A</entry><entry>D1[23:16]</entry></row><row><entry>0B</entry><entry>D1[31:24]</entry></row><row><entry>0C</entry><entry>D1[39:32]</entry></row><row><entry>0D</entry><entry>D1[47:40]</entry></row><row><entry>0E</entry><entry>D1[55:48]</entry></row><row><entry>0F</entry><entry>D1[63:56]</entry></row><row><entry>10</entry><entry>D2[7:0]</entry></row><row><entry>11</entry><entry>D2[15:8]</entry></row><row><entry>12</entry><entry>D2[23:16]</entry></row><row><entry>13</entry><entry>D2[32:24]</entry></row><row><entry>14</entry><entry>D2[39:32]</entry></row><row><entry>15</entry><entry>D2[47:40]</entry></row><row><entry>16</entry><entry>D2[55:48]</entry></row><row><entry>17</entry><entry>D2[63:56]</entry></row><row><entry>18</entry><entry>D3[7:0]</entry></row><row><entry>19</entry><entry>D3[15:8]</entry></row><row><entry>1A</entry><entry>D3[23:16]</entry></row><row><entry>1B</entry><entry>D3[31:24]</entry></row><row><entry>1C</entry><entry>D3[39:32]</entry></row><row><entry>1D</entry><entry>D3[47:40]</entry></row><row><entry>1E</entry><entry>D3[55:48]</entry></row><row><entry>1F</entry><entry>D3[63:56]</entry></row><row><entry>20</entry><entry>D4[7:0]</entry></row><row><entry>21</entry><entry>D4[15:8]</entry></row><row><entry>22</entry><entry>D4[23:16]</entry></row><row><entry>23</entry><entry>D4[31:24]</entry></row><row><entry>24</entry><entry>D4[39:32]</entry></row><row><entry>25</entry><entry>D4[47:40]</entry></row><row><entry>26</entry><entry>D4[55:48]</entry></row><row><entry>27</entry><entry>D4[63:56]</entry></row><row><entry>28</entry><entry>D5[7:0]</entry></row><row><entry>29</entry><entry>D5[15:8]</entry></row><row><entry>2A</entry><entry>D5[23:16]</entry></row><row><entry>2B</entry><entry>D5[31:24]</entry></row><row><entry>2C</entry><entry>D5[39:32]</entry></row><row><entry>2D</entry><entry>D5[47:40]</entry></row><row><entry>2E</entry><entry>D5[55:48]</entry></row><row><entry>2F</entry><entry>D5[63:56]</entry></row><row><entry>etc.</entry><entry>etc.</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 26.4.3.5.1 Dither Matrix Buffer
3364The state machine loads dither matrix table data a line at a time from DRAM and stores it in a buffer. A single line of the dither matrix is either 256 or 128 8-bit entries, depending on the programmable bit DoubleLineBuf. If this bit is enabled, a double-buffer mechanism is employed such that while one buffer is read from for the current line's dither matrix data (8 bits representing a single dither matrix entry), the other buffer is being written to with the next line's dither matrix data (64-bits at a time). Alternatively, the single buffer scheme can be used, where the data must be loaded at the end of the line, thus incurring a delay.
3365The single/double buffer is implemented using a 256 byte 3-port register array, two reads, one write port, with the reads clocked at double the system clock rate (320 MHz) allowing 4 reads per clock cycle.
3366The dither matrix buffer unit also provides the mechanism for keeping track of the current read and write buffers, and providing the mechanism such that a buffer cannot be read from until it has been written to. In this case, each buffer is a line of the dither matrix, i.e. 256 or 128 bytes.
3367The dither matrix buffer maintains a read and write pointer for the dither matrix. The output value dm_avail is derived by comparing the read and write pointers to determine when the dither matrix is not empty. The write pointer wr_adr is incremented each time a 64-bit word is written to the dither matrix buffer and the read pointer rd_ptr is incremented each time dm_advline is received. If double_line_buf is 0 the rd_ptr will increment by 2, otherwise it will increment by 1. If the dither matrix buffer is full then no further writes will be allowed (buff_full=1), or if the buffer is empty no further buffer reads are allowed (buff_emp=1).
3368The read addresses are byte aligned and are generated by the read address generator. A single dither matrix entry is represented by 8 bits and an entry is read for each of the four contone planes in parallel. If double buffer is used (double_line_buf=1) the read address is derived from 7-bit address from the read address generator and 1-bit from the read pointer. If double_line_buf=0 then the read address is the full 8-bits from the read address generator.
3369<tables id="TABLE-US-00289" num="00289"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="196pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>if (double_line_buf = = 1 )then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="154pt" align="left" /><colspec colname="2" colwidth="28pt" align="left" /><tbody valign="top"><row><entry /><entry>read_port[7:0] = {rd_ptr[0],rd_adr[6:0]}</entry><entry>//</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="196pt" align="left" /><tbody valign="top"><row><entry /><entry>concatenation</entry></row><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>read_port[7:0] = rd_adr[7:0]</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 28.4.3.5.2 Read Address Generator
3370For each contone plane there is a initial, lower and upper index to be used when reading dither cell values from the dither matrix double buffer. The read address for each plane is used to select a byte from the current 256-byte read buffer. When Go gets set (0 to 1 transition), or at the end of a line, the read addresses are set to their corresponding initial index. Otherwise, the read address generator relies on advdot to advance the addresses within the inclusive range specified the lower and upper indices, represented by the following pseudocode:
3371<tables id="TABLE-US-00290" num="00290"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>if (advdot = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>if (advline = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>rd_adr = dm_init_index</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (rd_adr = = dm_upr_index) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>rd_adr = dm_lwr_index</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>rd_adr ++</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>rd_adr = rd_adr</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 28.4.3.5.3 State Machine
3372The dither matrix is read from DRAM in single 256-bit accesses, receiving the data from the DIU over 4 clock cycles (64-bits per cycle). The protocol and timing for read accesses to DRAM is described in section 20.9.1 on page 240. Read accesses to DRAM are implemented by means of the state machine described in <figref idref="DRAWINGS">FIG. 238</figref>.
3373All counters and flags should be cleared after reset or when Go transitions from 0 to 1. While the Go bit is 1, the state machine relies on the dm_read_enable bit to tell it whether to attempt to read dither matrix data from DRAM. When dm_read_enable is clear, the state machine does nothing and remains in the idle state. When dm_read_enable is set, the state machine continues to load dither matrix data, 256-bits at a time (received over 4 clock cycles, 64 bits per cycle), while there is space available in the dither matrix buffer, (buff_full !=1).
3374The read address and line_start_adr are initially set to start_dm_adr. The read address gets incremented after each read access. It takes 4 or 8 read accesses to load a line of dither matrix into the dither matrix buffer, depending on whether we're using a single or double buffer. A count is kept of the accesses to DRAM. When a read access completes and access_count equals 3 or 7, a line of dither matrix has just been loaded from and the read address is updated to line_start_adr plus line_increment so it points to the start of the next line of dither matrix. (line_start_adr is also updated to this value). If the read address equals end_dm_adr then the next read address will be start_dm_adr, thus the read address wraps to point to the start of the area in DRAM where the dither matrix is stored.
3375The write address for the dither matrix buffer is implemented by means of a modulo-32 counter that is initially set to 0 and incremented when diu_hcu_rvalid is asserted.
3376<figref idref="DRAWINGS">FIG. 237</figref> shows an example of setting start_dm_adr and end_dm_adr values in relation to the line increment and double line buffer settings. The calculation of end_dm_adr is
3377<tables id="TABLE-US-00291" num="00291"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>// end_dm_adr calculation</entry></row><row><entry /><entry>dm_height = Dither matrix height in lines</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="98pt" align="left" /><colspec colname="2" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry>if (double_line_buf = = 1)</entry><entry>//</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>end_dm_adr[21:5] = start_dm_adr[21:5] + (((dm_height −</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>1)*line_inc) + 3) << 5)</entry></row><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>end_dm_adr[21:5] = start_dm_adr[21:5] + (((dm_height −</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>1)*line_inc) + 7) << 5)</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 28.4.4 Contone Dotgen Unit
3378The contone dotgen unit is responsible for producing a dot in up to 4 color planes per cycle. The contone dotgen unit also produces a cp_avail flag which specifies whether or not contone pixels are currently available, and the output hcu_cfu_advdot to request the CFU to provide the next contone pixel in up to 4 color planes.
3379The block diagram for the contone dotgen unit is shown in <figref idref="DRAWINGS">FIG. 239</figref>.
3380A dither unit provides the functionality for dithering a single contone plane. The contone image is only defined within the contone/spot margin area. As a result, if the input flag in_target_page is 0, then a constant contone pixel value is used for the pixel instead of the contone plane.
3381The resultant contone pixel is then halftoned. The dither value to be used in the halftoning process is provided by the control data unit. The halftoning process involves a comparison between a pixel value and its corresponding dither value. If the 8-bit contone value is greater than or equal to the 8-bit dither matrix value a 1 is output. If not, then a 0 is output. This means each entry in the dither matrix is in the range 1–255 (0 is not used).
3382Note that constant use is dependant on the in_target_page signal only, if in_target_page is 1 then the cfu_hcu_c*_data should be allowed to pass through, regardless of the stalling behaviour or the avail_mask[1] setting. This allows a constant value to be setup on the CFU output data, and the use of different constants while inside and outside the target page. The hcu_cfu_advdot will always be zero if the avail_mask[1] is zero.
000028.4.5 Spot Dotgen Unit
3383The spot dotgen unit is responsible for producing a dot of bi-level data per cycle. It deals with bi-level data (and therefore does not need to halftone) that comes from the LBD via the SFU. Like the contone layer, the bi-level spot layer is only defined within the contone/spot margin area. As a result, if input flag in_target_page is 0, then a constant dot value (typically this would be 0) is used for the output dot.
3384The spot dotgen unit also produces a s_avail flag which specifies whether or not spot dots are currently available for this spot plane, and the output hcu_sfu_advdot to request the SFU to provide the next bi-level data value. The spot dotgen unit can be represented by the following pseudocode:
3385<tables id="TABLE-US-00292" num="00292"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="196pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>s_avail = sfu_hcu_avail</entry></row><row><entry /><entry>if (in_target_page = = 1 AND avail_mask[2] = = 0 )OR</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>(in_target_page = = 0) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>hcu_sfu_advdot = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="196pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>hcu_sfu_advdot = advdot</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="196pt" align="left" /><tbody valign="top"><row><entry /><entry>if (in_target_page = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>sp = sfu_hcu_sdata</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="196pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>sp = sp_constant</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3386Note that constant use is dependant on the in target_page signal only, if in_target_page is 1 then the sfu_hcu_data should be allowed to pass through, regardless of the stalling behaviour or the avail_mask setting. This allows a constant value to be setup on the SFU output data, and the use of different constants while inside and outside the target page. The hcu_sfu_advdot will always be zero if the avail_mask[2] is zero.
000028.4.6 Tag Dotgen Unit
3387This unit is very similar to the spot dotgen unit (see Section 28.4.5) in that it deals with bi-level data, in this case from the TE via the TFU. The tag layer is only defined within the tag margin area. As a result, if input flag in_tag_target_page is 0, then a constant dot value, tp_constant (typically this would be 0), is used for the output dot. The tagplane dotgen unit also produces a tp_avail flag which specifies whether or not tag dots are currently available for the tagplane, and the output hcu_tfu_advdot to request the TFU to provide the next bi-level data value.
3388The hcu_tfu_advdot generation is similar to the SFU and CFU, except it depends only on in_target_page and advdot. It does not take into account the avail mask when inside the target page.
000028.4.7 Dot Reorg Unit
3389The dot reorg unit provides a means of mapping the bi-level dithered data, the spot0 color, and the tag data to output inks in the actual printhead. Each dot reorg unit takes a set of 6 1-bit inputs and produces a single bit output that represents the output dot for that color plane.
3390The output bit is a logical combination of any or all of the input bits. This allows the spot color to be placed in any output color plane (including infrared for testing purposes), black to be merged into cyan, magenta and yellow (in the case of no black ink in the Memjet printhead), and tag dot data to be placed in a visible plane. An output for fixative can readily be generated by simply combining desired input bits.
3391The dot reorg unit contains a 64-bit lookup to allow complete freedom with regards to mapping. Since all possible combinations of input bits are accounted for in the 64 bit lookup, a given dot reorg unit can take the mapping of other reorg units into account. For example, a black plane reorg unit may produce a 1 only if the contone plane 3 or spot color inputs are set (this effectively composites black bi-level over the contone). A fixative reorg unit may generate a 1 if any 2 of the output color planes is set (taking into account the mappings produced by the other reorg units). If dead nozzle replacement is to be used (see section 29.4.2 on page 473), the dot reorg can be programmed to direct the dots of the specified color into the main plane, and 0 into the other. If a nozzle is then marked as dead in the DNC, swapping the bits between the planes will result in 0 in the dead nozzle, and the required data in the other plane.
3392If dead nozzle replacement is to be used, and there are no tags, the TE can be programmed with the position of dead nozzles and the resultant pattern used to direct dots into the specified nozzle row. If only fixed background TFS is to be used, a limited number of nozzles can be replaced. If variable tag data is to be used to specify dead nozzles, then large numbers of dead nozzles can be readily compensated for.
3393The dot reorg unit can be used to average out the nozzle usage when two rows of nozzles share the same ink and tag encoding is not being used. The TE can be programmed to produce a regular pattern (e.g. 0101 on one line, and 1010 on the next) and this pattern can be used as a directive as to direct dots into the specified nozzle row.
3394Each reorg unit contains a 64-bit IOMapping value programmable as two 32-bit HCU registers, and a set of selection logic based on the 6-bit dot input (2<sup>6</sup>=64 bits), as shown in <figref idref="DRAWINGS">FIG. 240</figref>. The mapping of input bits to each of the 6 selection bits is as defined in Table 197.
3395<tables id="TABLE-US-00293" num="00293"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 197</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Mapping of input bits to 6 selection bits</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="49pt" align="center" /><colspec colname="2" colwidth="112pt" align="left" /><colspec colname="3" colwidth="56pt" align="left" /><tbody valign="top"><row><entry>address</entry><entry /><entry /></row><row><entry>bit of</entry><entry /><entry>likely</entry></row><row><entry>lookup</entry><entry>tied to</entry><entry>interpretation</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>0</entry><entry>bi-level dot from contone layer 0</entry><entry>cyan</entry></row><row><entry>1</entry><entry>bi-level dot from contone layer 1</entry><entry>magenta</entry></row><row><entry>2</entry><entry>bi-level dot from contone layer 2</entry><entry>yellow</entry></row><row><entry>3</entry><entry>bi-level dot from contone layer 3</entry><entry>black</entry></row><row><entry>4</entry><entry>bi-level spot0 dot</entry><entry>black</entry></row><row><entry>5</entry><entry>bi-level tag dot</entry><entry>infra-red</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 28.4.8 Output Buffer
3396The output buffer de-couples the stalling behaviour of the feeder units from the stalling behaviour of the DNC. The larger the buffer the greater de-coupling. Currently the output buffer size is 2, but could be increased if needed at the cost of extra area.
3397If the Go bit is set to 0 no read or write of the output buffer is permitted. On a low to high transition of the Go bit the contents of the output buffer are cleared.
3398The output buffer also implements the interface logic to the DNC. If there is data in the output buffer the hcu_dnc_avail signal will be 1, otherwise is will be 0. If both hcu_dnc_avail and dnc_hcu_ready are 1 then data is read from the output buffer.
3399On the write side if there is space available in the output buffer the logic indicates to the control unit via the output_buff_full signal. The control unit will then allow writes to the output buffer via the wr_advdot signal. If the writes to the output buffer are after the end of a page (indicated by in_page equal to 0) then all dots written into the output buffer are set to zero.
000028.4.8.1 HCU to DNC Interface
3400<figref idref="DRAWINGS">FIG. 241</figref> shows the timing diagram and representative logic of the HCU to DNC interface. The hcu_dnc_avail signal indicate to the DNC that the HCU has data available. The dnc_hcu_ready signal indicates to the HCU that the DNC is ready to accept data. When both signals are high data is transferred from the HCU to the DNC. Once the HCU indicates it has data available (setting the hcu_dnc_avail signal high) it can only set the hcu_dnc_avail low again after a dot is accepted by the DNC.
000028.4.9 Feeder to HCU Interfaces
3401<figref idref="DRAWINGS">FIG. 242</figref> shows the feeder unit to HCU interface timing diagram, and <figref idref="DRAWINGS">FIG. 243</figref> shows representative logic of the interface with the register positions. sfu_hcu_data and sfu_hcu_avail are always registered while the sfu_hcu_advdot is not. The hcu_sfu_avail signal indicates to the HCU that the feeder unit has data available, and sfu_hcu_advdot indicates to the feeder unit that the HCU has captured the last dot. The HCU can never produce an advance dot pulse while the avail is low. The diagrams show the example of the SFU to HCU interface, but the same interface is used for the other feeder units TFU and CFU.
000029 Dead Nozzle Compensator (DNC)
000029.1 Overview
3402The Dead Nozzle Compensator (DNC) is responsible for adjusting Memjet dot data to take account of non-functioning nozzles in the Memjet printhead. Input dot data is supplied from the HCU, and the corrected dot data is passed out to the DWU. The high level data path is shown by the block diagram in <figref idref="DRAWINGS">FIG. 244</figref>.
3403The DNC compensates for a dead nozzles by performing the following operations: <ul id="ul0345" list-style="none"><li id="ul0345-0001" num="0000"><ul id="ul0346" list-style="none"><li id="ul0346-0001" num="3404">Dead nozzle removal, i.e. turn the nozzle off</li><li id="ul0346-0002" num="3405">Ink replacement by direct substitution i.e. K->K</li><li id="ul0346-0003" num="3406">Ink replacement by indirect substitution i.e. K->CMY</li><li id="ul0346-0004" num="3407">Error diffusion to adjacent nozzles</li><li id="ul0346-0005" num="3408">Fixative corrections</li></ul></li></ul>
3409The DNC is required to efficiently support up to 5% dead nozzles, under the expected DRAM bandwidth allocation, with no restriction on where dead nozzles are located and handle any fixative correction due to nozzle compensations. Performance must degrade gracefully after 5% dead nozzles.
000029.2 Dead Nozzle Identification
3410Dead nozzles are identified by means of a position value and a mask value. Position information is represented by a 10-bit delta encoded format, where the 10-bit value defines the number of dots between dead nozzle columns<sup>19</sup>. With the delta information it also reads the 6-bit dead nozzle mask (dn_mask) for the defined dead nozzle position. Each bit in the dn_mask corresponds to an ink plane. A set bit indicates that the nozzle for the corresponding ink plane is dead. The dead nozzle table format is shown in <figref idref="DRAWINGS">FIG. 245</figref>. The DNC reads dead nozzle information from DRAM in single 256-bit accesses. A 10-bit delta encoding scheme is chosen so that each table entry is 16 bits wide, and 16 entries fit exactly in each 256-bit read. Using 10-bit delta encoding means that the maximum distance between dead nozzle columns is 1023 dots. It is possible that dead nozzles may be spaced further than 1023 dots from each other, so a null dead nozzle identifier is required. A null dead nozzle identifier is defined as a 6-bit dn_mask of all zeros. These null dead nozzle identifiers should also be used so that: <sup>19</sup>for a 10-bit delta value of d, if the current column n is a dead nozzle column then the next dead nozzle column is given by n+(d+1). <ul id="ul0347" list-style="none"><li id="ul0347-0001" num="0000"><ul id="ul0348" list-style="none"><li id="ul0348-0001" num="3411">the dead nozzle table is a multiple of 16 entries (so that it is aligned to the 256-bit DRAM locations)</li><li id="ul0348-0002" num="3412">the dead nozzle table spans the complete length of the line, i.e. the first entry dead nozzle table should have a delta from the first nozzle column in a line and the last entry in the dead nozzle table should correspond to the last nozzle column in a line.</li></ul></li></ul>
3413Note that the DNC deals with the width of a page. This may or may not be the same as the width of the printhead (the PHI may introduce some margining to the page so that its dot output matches the width of the printhead). Care must be taken when programming the dead nozzle table so that dead nozzle positions are correctly specified with respect to the page and printhead.
000029.3 Dram Storage and Bandwidth Requirement
3414The memory required is largely a factor of the number of dead nozzles present in the printhead (which in turn is a factor of the printhead size). The DNC is required to read a 16-bit entry from the dead nozzle table for every dead nozzle. Table 198 shows the DRAM storage and average<sup>20 </sup>bandwidth requirements for the DNC for different percentages of dead nozzles and different page sizes. <sup>20</sup>Average bandwidth assumes an even spread of dead nozzles. Clumps of dead nozzles may cause delays due to insufficient available DRAM bandwidth. These delays will occur every line causing an accumulative delay over a page.
3415<tables id="TABLE-US-00294" num="00294"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 198</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Dead Nozzle storage and average bandwidth requirements</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="112pt" align="left" /><colspec colname="1" colwidth="91pt" align="center" /><colspec colname="2" colwidth="14pt" align="center" /><tbody valign="top"><row><entry /><entry>Dead nozzle table</entry><entry /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="56pt" align="center" /><colspec colname="3" colwidth="49pt" align="left" /><colspec colname="4" colwidth="56pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>% Dead</entry><entry>Memory</entry><entry>Bandwidth</entry></row><row><entry /><entry>Page size</entry><entry>Nozzles</entry><entry>(KBytes)</entry><entry>(bits/cycle)</entry></row><row><entry /><entry namest="offset" nameend="4" align="center" rowsep="1" /></row><row><entry /><entry>A4<sup>a</sup></entry><entry> 5%</entry><entry>1.4<sup>c</sup></entry><entry>0.8<sup>d</sup></entry></row><row><entry /><entry /><entry>10%</entry><entry>2.7</entry><entry>1.6</entry></row><row><entry /><entry /><entry>15%</entry><entry>4.1</entry><entry>2.4</entry></row><row><entry /><entry>A3<sup>b</sup></entry><entry> 5%</entry><entry>1.9</entry><entry>0.8</entry></row><row><entry /><entry /><entry>10%</entry><entry>3.8</entry><entry>1.6</entry></row><row><entry /><entry /><entry>15%</entry><entry>5.7</entry><entry>2.4</entry></row><row><entry /><entry namest="offset" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 29.4 Nozzle Compensation
3416DNC receives 6 bits of dot information every cycle from the HCU, 1 bit per color plane. When the dot position corresponds to a dead nozzle column, the associated 6-bit dn_mask indicates which ink plane(s) contains a dead nozzle(s). The DNC first deletes dots destined for the dead nozzle. It then replaces those dead dots, either by placing the data destined for the dead nozzle into an adjacent ink plane (direct substitution) or into a number of ink planes (indirect substitution). After ink replacement, if a dead nozzle is made active again then the DNC performs error diffusion. Finally, following the dead nozzle compensation mechanisms the fixative, if present, may need to be adjusted due to new nozzles being activated, or dead nozzles being removed.
000029.4.1 Dead Nozzle Removal
3417If a nozzle is defined as dead, then the first action for the DNC is to turn off (zeroing) the dot data destined for that nozzle. This is done by a bit-wise ANDing of the inverse of the dn_mask with the dot value.
000029.4.2 Ink Replacement
3418Ink replacement is a mechanism where data destined for the dead nozzle is placed into an adjacent ink plane of the same color (direct substitution, i.e. K->K<sub>alternative</sub>), or placed into a number of ink planes, the combination of which produces the desired color (indirect substitution, i.e. K->CMY). Ink replacement is performed by filtering out ink belonging to nozzles that are dead and then adding back in an appropriately calculated pattern. This two step process allows the optional re-inclusion of the ink data into the original dead nozzle position to be subsequently error diffused. In the general case, fixative data destined for a dead nozzle should not be left active intending it to be later diffused.
3419The ink replacement mechanism has 6 ink replacement patterns, one per ink plane, programmable by the CPU. The dead nozzle mask is ANDed with the dot data to see if there are any planes where the dot is active but the corresponding nozzle is dead. The resultant value forms an enable, on a per ink basis, for the ink replacement process. If replacement is enabled for a particular ink, the values from the corresponding replacement pattern register are ORed into the dot data. The output of the ink replacement process is then filtered so that error diffusion is only allowed for the planes in which error diffusion is enabled. The output of the ink replacement logic is ORed with the resultant dot after dead nozzle removal. See Figure n page 565 on page Error! Bookmark not defined. for implementation details.
3420For example if we consider the printhead color configuration C,M,Y,K<sub>1</sub>,K<sub>2</sub>,IR and the input dot data from the HCU is b101100. Assuming that the K<sub>1 </sub>ink plane and IR ink plane for this position are dead so the dead nozzle mask is b000101. The DNC first removes the dead nozzle by zeroing the K<sub>1 </sub>plane to produce b101000. Then the dead nozzle mask is ANDed with the dot data to give b000100 which selects the ink replacement pattern for K<sub>1 </sub>(in this case the ink replacement pattern for K<sub>1 </sub>is configured as b000010, i.e. ink replacement into the K<sub>2 </sub>plane). Providing error diffusion for K<sub>2 </sub>is enabled, the output from the ink replacement process is b000010. This is ORed with the output of dead nozzle removal to produce the resultant dot b101010. As can be seen the dot data in the defective K<sub>1 </sub>nozzle was removed and replaced by a dot in the adjacent K<sub>2 </sub>nozzle in the same dot position, i.e. direct substitution.
3421In the example above the K<sub>1 </sub>ink plane could be compensated for by indirect substitution, in which case ink replacement pattern for K<sub>1 </sub>would be configured as b111000 (substitution into the CMY color planes), and this is ORed with the output of dead nozzle removal to produce the resultant dot b111000. Here the dot data in the defective K, ink plane was removed and placed into the CMY ink planes.
000029.4.3 Error Diffusion
3422Based on the programming of the lookup table the dead nozzle may be left active after ink replacement. In such cases the DNC can compensate using error diffusion. Error diffusion is a mechanism where dead nozzle dot data is diffused to adjacent dots.
3423When a dot is active and its destined nozzle is dead, the DNC will attempt to place the data into an adjacent dot position, if one is inactive. If both dots are inactive then the choice is arbitrary, and is determined by a pseudo random bit generator. If both neighbor dots are already active then the bit cannot be compensated by diffusion.
3424Since the DNC needs to look at neighboring dots to determine where to place the new bit (if required), the DNC works on a set of 3 dots at a time. For any given set of 3 dots, the first dot received from the HCU is referred to as dot A, and the second as dot B, and the third as dot C. The relationship is shown in <figref idref="DRAWINGS">FIG. 246</figref>.
3425For any given set of dots ABC, only B can be compensated for by error diffusion if B is defined as dead. A 1 in dot B will be diffused into either dot A or dot C if possible. If there is already a 1 in dot A or dot C then a 1 in dot B cannot be diffused into that dot.
3426The DNC must support adjacent dead nozzles. Thus if dot A is defined as dead and has previously been compensated for by error diffusion, then the dot data from dot B should not be diffused into dot A. Similarly, if dot C is defined as dead, then dot data from dot B should not be diffused into dot C.
3427Error diffusion should not cross line boundaries. If dot B contains a dead nozzle and is the first dot in a line then dot A represents the last dot from the previous line. In this case an active bit on a dead nozzle of dot B should not be diffused into dot A. Similarly, if dot B contains a dead nozzle and is the last dot in a line then dot C represents the first dot of the next line. In this case an active bit on a dead nozzle of dot B should not be diffused into dot C.
3428Thus, as a rule, a 1 in dot B cannot be diffused into dot A if <ul id="ul0349" list-style="none"><li id="ul0349-0001" num="0000"><ul id="ul0350" list-style="none"><li id="ul0350-0001" num="3429">a 1 is already present in dot A,</li><li id="ul0350-0002" num="3430">dot A is defined as dead,</li><li id="ul0350-0003" num="3431">or dot A is the last dot in a line.</li></ul></li></ul>
3432Similarly, a 1 in dot B cannot be diffused into dot C if <ul id="ul0351" list-style="none"><li id="ul0351-0001" num="0000"><ul id="ul0352" list-style="none"><li id="ul0352-0001" num="3433">a 1 is already present in dot C,</li><li id="ul0352-0002" num="3434">dot C is defined as dead,</li><li id="ul0352-0003" num="3435">or dot C is the first dot in a line.</li></ul></li></ul>
3436If B is defined to be dead and the dot value for B is 0, then no compensation needs to be done and dots A and C do not need to be changed.
3437If B is defined to be dead and the dot value for B is 1, then B is changed to 0 and the DNC attempts to place the 1 from B into either A or C: <ul id="ul0353" list-style="none"><li id="ul0353-0001" num="0000"><ul id="ul0354" list-style="none"><li id="ul0354-0001" num="3438">If the dot can be placed into both A and C, then the DNC must choose between them. The preference is given by the current output from the random bit generator, 0 for “prefer left” (dot A) or 1 for “prefer right” (dot C).</li><li id="ul0354-0002" num="3439">If dot can be placed into only one of A and C, then the 1 from B is placed into that position.</li><li id="ul0354-0003" num="3440">If dot cannot be placed into either one of A or C, then the DNC cannot place the dot in either position.</li></ul></li></ul>
3441<tables id="TABLE-US-00295" num="00295"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 199</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Error Diffusion Truth Table when dot B is dead</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="140pt" align="center" /><colspec colname="2" colwidth="77pt" align="center" /><tbody valign="top"><row><entry>Input</entry><entry /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="49pt" align="center" /><colspec colname="2" colwidth="14pt" align="center" /><colspec colname="3" colwidth="49pt" align="center" /><colspec colname="4" colwidth="105pt" align="center" /><tbody valign="top"><row><entry>A OR</entry><entry /><entry>C OR</entry><entry /></row><row><entry>A dead OR</entry><entry /><entry>C dead OR</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="center" /><colspec colname="2" colwidth="14pt" align="center" /><colspec colname="3" colwidth="49pt" align="center" /><colspec colname="4" colwidth="28pt" align="center" /><colspec colname="5" colwidth="77pt" align="center" /><tbody valign="top"><row><entry>A last</entry><entry /><entry>C first</entry><entry /><entry>Output</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="7"><colspec colname="1" colwidth="49pt" align="center" /><colspec colname="2" colwidth="14pt" align="center" /><colspec colname="3" colwidth="49pt" align="center" /><colspec colname="4" colwidth="28pt" align="center" /><colspec colname="5" colwidth="35pt" align="left" /><colspec colname="6" colwidth="14pt" align="center" /><colspec colname="7" colwidth="28pt" align="left" /><tbody valign="top"><row><entry>in line</entry><entry>B</entry><entry>in line</entry><entry>Rand′a</entry><entry>A</entry><entry>B</entry><entry>C</entry></row><row><entry namest="1" nameend="7" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="7"><colspec colname="1" colwidth="49pt" align="char" char="." /><colspec colname="2" colwidth="14pt" align="char" char="." /><colspec colname="3" colwidth="49pt" align="char" char="." /><colspec colname="4" colwidth="28pt" align="center" /><colspec colname="5" colwidth="35pt" align="left" /><colspec colname="6" colwidth="14pt" align="center" /><colspec colname="7" colwidth="28pt" align="left" /><tbody valign="top"><row><entry>0</entry><entry>0</entry><entry>0</entry><entry>X</entry><entry>A input</entry><entry>0</entry><entry>C input</entry></row><row><entry>0</entry><entry>0</entry><entry>1</entry><entry>X</entry><entry>A input</entry><entry>0</entry><entry>C input</entry></row><row><entry>0</entry><entry>1</entry><entry>0</entry><entry>0</entry><entry>1′b</entry><entry>0</entry><entry>C input</entry></row><row><entry>0</entry><entry>1</entry><entry>0</entry><entry>1</entry><entry>A input</entry><entry>0</entry><entry>1</entry></row><row><entry>0</entry><entry>1</entry><entry>1</entry><entry>X</entry><entry>1</entry><entry>0</entry><entry>C input</entry></row><row><entry>1</entry><entry>0</entry><entry>0</entry><entry>X</entry><entry>A input</entry><entry>0</entry><entry>C input</entry></row><row><entry>1</entry><entry>0</entry><entry>1</entry><entry>X</entry><entry>A input</entry><entry>0</entry><entry>C input</entry></row><row><entry>1</entry><entry>1</entry><entry>0</entry><entry>X</entry><entry>A input</entry><entry>0</entry><entry>1</entry></row><row><entry>1</entry><entry>1</entry><entry>1</entry><entry>X</entry><entry>A input</entry><entry>0</entry><entry>C input</entry></row><row><entry namest="1" nameend="7" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3442Table 199 shows the truth table for DNC error diffusion operation when dot B is defined as dead. <ul id="ul0355" list-style="none"><li id="ul0355-0001" num="3443">a. Output from random bit generator. Determines direction of error diffusion (0=left, 1=right)</li><li id="ul0355-0002" num="3444">b. Bold emphasis is used to show the DNC inserted a 1</li></ul>
3445The random bit value used to arbitrarily select the direction of diffusion is generated by a 32-bit maximum length random bit generator. The generator generates a new bit for each dot in a line regardless of whether the dot is dead or not. The random bit generator can be initialized with a 32-bit programmable seed value.
000029.4.4 Fixative Correction
3446After the dead nozzle compensation methods have been applied to the dot data, the fixative, if present, may need to be adjusted due to new nozzles being activated, or dead nozzles being removed. For each output dot the DNC determines if fixative is required (using the FixativeRequiredMask register) for the new compensated dot data word and whether fixative is activated already for that dot. For the DNC to do so it needs to know the color plane that has fixative, this is specified by the FixativeMask1 configuration register. Table 200 indicates the actions to take based on these calculations.
3447<tables id="TABLE-US-00296" num="00296"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 200</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Truth table for fixative correction</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="28pt" align="center" /><colspec colname="2" colwidth="70pt" align="center" /><colspec colname="3" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry>Fixative</entry><entry>Fixative</entry><entry /></row><row><entry /><entry>Present</entry><entry>required</entry><entry>Action</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row><row><entry /><entry>1</entry><entry>1</entry><entry>Output dot as is.</entry></row><row><entry /><entry>1</entry><entry>0</entry><entry>Clear fixative plane.</entry></row><row><entry /><entry>0</entry><entry>1</entry><entry>Attempt to add fixative.</entry></row><row><entry /><entry>0</entry><entry>0</entry><entry>Output dot as is.</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3448The DNC also allows the specification of another fixative plane, specified by the FixativeMask2 configuration register, with FixativeMask1 having the higher priority over FixativeMask2. When attempting to add fixative the DNC first tries to add it into the planes defined by FixativeMask1. However, if any of these planes is dead then it tries to add fixative by placing it into the planes defined by FixativeMask2.
3449Note that the fixative defined by FixativeMask1 and FixativeMask2 could possibly be multi-part fixative, i.e. 2 bits could be set in FixativeMask1 with the fixative being a combination of both inks.
000029.5 Implementation
3450A block diagram of the DNC is shown in <figref idref="DRAWINGS">FIG. 247</figref>.
000029.5.1 Definitions of I/O
3451<tables id="TABLE-US-00297" num="00297"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 201</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>DNC port list and description</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="154pt" align="left" /><tbody valign="top"><row><entry>Port name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="left" /><tbody valign="top"><row><entry>Clocks and Resets</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="154pt" align="left" /><tbody valign="top"><row><entry>Pclk</entry><entry>1</entry><entry>In</entry><entry>System Clock.</entry></row><row><entry>prst_n</entry><entry>1</entry><entry>In</entry><entry>System reset, synchronous active low.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="left" /><tbody valign="top"><row><entry>PCU interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="154pt" align="left" /><tbody valign="top"><row><entry>pcu_dnc_sel</entry><entry>1</entry><entry>In</entry><entry>Block select from the PCU. When pcu_dnc_sel is</entry></row><row><entry /><entry /><entry /><entry>high both pcu_adr and pcu_dataout are valid.</entry></row><row><entry>pcu_rwn</entry><entry>1</entry><entry>In</entry><entry>Common read/not-write signal from the PCU.</entry></row><row><entry>pcu_adr[6:2]</entry><entry>5</entry><entry>In</entry><entry>PCU address bus. Only 5 bits are required to</entry></row><row><entry /><entry /><entry /><entry>decode the address space for this block.</entry></row><row><entry>pcu_dataout[31:0]</entry><entry>32</entry><entry>In</entry><entry>Shared write data bus from the PCU.</entry></row><row><entry>dnc_pcu_rdy</entry><entry>1</entry><entry>Out</entry><entry>Ready signal to the PCU. When dnc_pcu_rdy is</entry></row><row><entry /><entry /><entry /><entry>high it indicates the last cycle of the access. For a</entry></row><row><entry /><entry /><entry /><entry>write cycle this means pcu_dataout has been</entry></row><row><entry /><entry /><entry /><entry>registered by the block and for a read cycle this</entry></row><row><entry /><entry /><entry /><entry>means the data on dnc_pcu_datain is valid.</entry></row><row><entry>dnc_pcu_datain[31:0]</entry><entry>32</entry><entry>Out</entry><entry>Read data bus to the PCU.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="left" /><tbody valign="top"><row><entry>DIU interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="154pt" align="left" /><tbody valign="top"><row><entry>dnc_diu_rreq</entry><entry>1</entry><entry>Out</entry><entry>DNC unit requests DRAM read. A read request</entry></row><row><entry /><entry /><entry /><entry>must be accompanied by a valid read address.</entry></row><row><entry>dnc_diu_radr[21:5]</entry><entry>17</entry><entry>Out</entry><entry>Read address to DIU, 256-bit word aligned.</entry></row><row><entry>diu_dnc_rack</entry><entry>1</entry><entry>In</entry><entry>Acknowledge from DIU that read request has</entry></row><row><entry /><entry /><entry /><entry>been accepted and new read address can be</entry></row><row><entry /><entry /><entry /><entry>placed on dnc_diu_radr</entry></row><row><entry>diu_dnc_rvalid</entry><entry>1</entry><entry>In</entry><entry>Read data valid, active high. Indicates that valid</entry></row><row><entry /><entry /><entry /><entry>read data is now on the read data bus, diu_data.</entry></row><row><entry>diu_data[63:0]</entry><entry>64</entry><entry>In</entry><entry>Read data from DIU.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="left" /><tbody valign="top"><row><entry>HCU interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="154pt" align="left" /><tbody valign="top"><row><entry>dnc_hcu_ready</entry><entry>1</entry><entry>Out</entry><entry>Indicates that DNC is ready to accept data from</entry></row><row><entry /><entry /><entry /><entry>the HCU.</entry></row><row><entry>hcu_dnc_avail</entry><entry>1</entry><entry>In</entry><entry>Indicates valid data present on hcu_dnc_data.</entry></row><row><entry>hcu_dnc_data[5:0]</entry><entry>6</entry><entry>In</entry><entry>Output bi-level dot data in 6 ink planes.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="left" /><tbody valign="top"><row><entry>DWU interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="left" /><colspec colname="4" colwidth="154pt" align="left" /><tbody valign="top"><row><entry>dwu_dnc_ready</entry><entry>1</entry><entry>In</entry><entry>Indicates that DWU is ready to accept data from</entry></row><row><entry /><entry /><entry /><entry>the DNC.</entry></row><row><entry>dnc_dwu_avail</entry><entry>1</entry><entry>Out</entry><entry>Indicates valid data present on dnc_dwu_data.</entry></row><row><entry>dnc_dwu_data[5:0]</entry><entry>6</entry><entry>Out</entry><entry>Output bi-level dot data in 6 ink planes.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 29.5.2 Configuration Registers
3452The configuration registers in the DNC are programmed via the PCU interface. Refer to section 21.8.2 on page 321 for the description of the protocol and timing diagrams for reading and writing registers in the DNC. Note that since addresses in SoPEC are byte aligned and the PCU only supports 32-bit register reads and writes, the lower 2 bits of the PCU address bus are not required to decode the address space for the DNC. When reading a register that is less than 32 bits wide zeros should be returned on the upper unused bit(s) of dnc_pcu_datain. Table 202 lists the configuration registers in the DNC.
3453<tables id="TABLE-US-00298" num="00298"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="322pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 202</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>DNC configuration registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="126pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry /><entry>Value</entry><entry /></row><row><entry>Address</entry><entry>Register</entry><entry /><entry>on</entry></row><row><entry>(DNC_base +</entry><entry>name</entry><entry>#bits</entry><entry>reset</entry><entry>Description</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="322pt" align="left" /><tbody valign="top"><row><entry>Control registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="21pt" align="char" char="." /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>0x00</entry><entry>Reset</entry><entry>1</entry><entry>0x1</entry><entry>A write to this register causes a reset of</entry></row><row><entry /><entry /><entry /><entry /><entry>the DNC.</entry></row><row><entry>0x04</entry><entry>Go</entry><entry>1</entry><entry>0x0</entry><entry>Writing 1 to this register starts the DNC.</entry></row><row><entry /><entry /><entry /><entry /><entry>Writing 0 to this register halts the DNC.</entry></row><row><entry /><entry /><entry /><entry /><entry>When Go is asserted all counters, flags</entry></row><row><entry /><entry /><entry /><entry /><entry>etc. are cleared or given their initial</entry></row><row><entry /><entry /><entry /><entry /><entry>value, but configuration registers keep</entry></row><row><entry /><entry /><entry /><entry /><entry>their values.</entry></row><row><entry /><entry /><entry /><entry /><entry>When Go is deasserted the state-</entry></row><row><entry /><entry /><entry /><entry /><entry>machines go to their idle states but all</entry></row><row><entry /><entry /><entry /><entry /><entry>counters and configuration registers</entry></row><row><entry /><entry /><entry /><entry /><entry>keep their values.</entry></row><row><entry /><entry /><entry /><entry /><entry>This register can be read to determine if</entry></row><row><entry /><entry /><entry /><entry /><entry>the DNC is running</entry></row><row><entry /><entry /><entry /><entry /><entry>(1 = running, 0 = stopped).</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="322pt" align="left" /><tbody valign="top"><row><entry>Setup registers (constant during processing)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="21pt" align="char" char="." /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>0x10</entry><entry>MaxDot</entry><entry>16</entry><entry>0x0000</entry><entry>This is the maximum dot number − 1</entry></row><row><entry /><entry /><entry /><entry /><entry>present across a page. For example if a</entry></row><row><entry /><entry /><entry /><entry /><entry>page contains 13824 dots, then MaxDot</entry></row><row><entry /><entry /><entry /><entry /><entry>will be 13823.</entry></row><row><entry /><entry /><entry /><entry /><entry>Note that this number may or may not</entry></row><row><entry /><entry /><entry /><entry /><entry>be the same as the number of dots</entry></row><row><entry /><entry /><entry /><entry /><entry>across the printhead as some margining</entry></row><row><entry /><entry /><entry /><entry /><entry>may be introduced in the PHI.</entry></row><row><entry>0x14</entry><entry>LSFR</entry><entry>32</entry><entry>0x0000_0000</entry><entry>The current value of the LFSR register</entry></row><row><entry /><entry /><entry /><entry /><entry>used as the 32-bit maximum length</entry></row><row><entry /><entry /><entry /><entry /><entry>random bit generator.</entry></row><row><entry /><entry /><entry /><entry /><entry>Users can write to this register to</entry></row><row><entry /><entry /><entry /><entry /><entry>program a seed value for the 32-bit</entry></row><row><entry /><entry /><entry /><entry /><entry>maximum length random bit generator.</entry></row><row><entry /><entry /><entry /><entry /><entry>Must not be all 1s for taps implemented</entry></row><row><entry /><entry /><entry /><entry /><entry>in XNOR form. (It is expected that</entry></row><row><entry /><entry /><entry /><entry /><entry>writing a seed value will not occur during</entry></row><row><entry /><entry /><entry /><entry /><entry>the operation of the LFSR).</entry></row><row><entry /><entry /><entry /><entry /><entry>This LSFR value could also have a</entry></row><row><entry /><entry /><entry /><entry /><entry>possible use as a random source in</entry></row><row><entry /><entry /><entry /><entry /><entry>program code.</entry></row><row><entry>0x20</entry><entry>FixativeMask1</entry><entry>6</entry><entry>0x00</entry><entry>Defines the higher priority fixative</entry></row><row><entry /><entry /><entry /><entry /><entry>plane(s). Bit 0 represents the settings</entry></row><row><entry /><entry /><entry /><entry /><entry>for plane 0, bit 1 for plane 1 etc. For</entry></row><row><entry /><entry /><entry /><entry /><entry>each bit:</entry></row><row><entry /><entry /><entry /><entry /><entry>1 = the ink plane contains fixative.</entry></row><row><entry /><entry /><entry /><entry /><entry>0 = the ink plane does not contain</entry></row><row><entry /><entry /><entry /><entry /><entry>fixative.</entry></row><row><entry>0x24</entry><entry>FixativeMask2</entry><entry>6</entry><entry>0x00</entry><entry>Defines the lower priority fixative</entry></row><row><entry /><entry /><entry /><entry /><entry>plane(s). Bit 0 represents the settings</entry></row><row><entry /><entry /><entry /><entry /><entry>for plane 0, bit 1 for plane 1 etc. Used</entry></row><row><entry /><entry /><entry /><entry /><entry>only when FixativeMask1 planes are</entry></row><row><entry /><entry /><entry /><entry /><entry>dead. For each bit:</entry></row><row><entry /><entry /><entry /><entry /><entry>1 = the ink plane contains fixative.</entry></row><row><entry /><entry /><entry /><entry /><entry>0 = the ink plane does not contain</entry></row><row><entry /><entry /><entry /><entry /><entry>fixative.</entry></row><row><entry>0x28</entry><entry>FixativeRequired</entry><entry>6</entry><entry>0x00</entry><entry>Identifies the ink planes that require</entry></row><row><entry /><entry>Mask</entry><entry /><entry /><entry>fixative. Bit 0 represents the settings for</entry></row><row><entry /><entry /><entry /><entry /><entry>plane 0, bit 1 for plane 1 etc. For each</entry></row><row><entry /><entry /><entry /><entry /><entry>bit:</entry></row><row><entry /><entry /><entry /><entry /><entry>1 = the ink plane requires fixative.</entry></row><row><entry /><entry /><entry /><entry /><entry>0 = the ink plane does not require</entry></row><row><entry /><entry /><entry /><entry /><entry>fixative (e.g. ink is self-fixing)</entry></row><row><entry>0x30</entry><entry>DnTableStartAdr[21:5]</entry><entry>17</entry><entry>0x0_0000</entry><entry>Start address of Dead Nozzle Table in</entry></row><row><entry /><entry /><entry /><entry /><entry>DRAM, specified in 256-bit words.</entry></row><row><entry>0x34</entry><entry>DnTableEndAdr[21:5]</entry><entry>17</entry><entry>0x0_0000</entry><entry>End address of Dead Nozzle Table in</entry></row><row><entry /><entry /><entry /><entry /><entry>DRAM, specified in 256-bit words, i.e.</entry></row><row><entry /><entry /><entry /><entry /><entry>he location containing the last entry in</entry></row><row><entry /><entry /><entry /><entry /><entry>the Dead Nozzle Table.</entry></row><row><entry /><entry /><entry /><entry /><entry>The Dead Nozzle Table should be</entry></row><row><entry /><entry /><entry /><entry /><entry>aligned to a 256-bit boundary, if</entry></row><row><entry /><entry /><entry /><entry /><entry>necessary it can be padded with null</entry></row><row><entry /><entry /><entry /><entry /><entry>entries.</entry></row><row><entry>0x40–0x54</entry><entry>PlaneReplacePattern[5:0]</entry><entry>6 × 6</entry><entry>0x00</entry><entry>Defines the ink replacement pattern for</entry></row><row><entry /><entry /><entry /><entry /><entry>each of the 6 ink planes.</entry></row><row><entry /><entry /><entry /><entry /><entry>PlaneReplacePattern[0] is the ink</entry></row><row><entry /><entry /><entry /><entry /><entry>replacement pattern for plane 0,</entry></row><row><entry /><entry /><entry /><entry /><entry>PlaneReplacePattern[1] is the ink</entry></row><row><entry /><entry /><entry /><entry /><entry>replacement pattern for plane 1, etc.</entry></row><row><entry /><entry /><entry /><entry /><entry>For each 6-bit replacement pattern for a</entry></row><row><entry /><entry /><entry /><entry /><entry>plane, a 1 in any bit positions indicates</entry></row><row><entry /><entry /><entry /><entry /><entry>the alternative ink planes to be used for</entry></row><row><entry /><entry /><entry /><entry /><entry>this plane.</entry></row><row><entry>0x58</entry><entry>DiffuseEnable</entry><entry>6</entry><entry>0x3F</entry><entry>Defines whether, after ink replacement,</entry></row><row><entry /><entry /><entry /><entry /><entry>error diffusion is allowed to be</entry></row><row><entry /><entry /><entry /><entry /><entry>performed on each plane.</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 0 represents the settings for plane 0,</entry></row><row><entry /><entry /><entry /><entry /><entry>bit 1 for plane 1 etc. For each bit:</entry></row><row><entry /><entry /><entry /><entry /><entry>1 = error diffusion is enabled</entry></row><row><entry /><entry /><entry /><entry /><entry>0 = error diffusion is disabled</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="322pt" align="left" /><tbody valign="top"><row><entry>Debug registers (read only)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="21pt" align="char" char="." /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>0x60</entry><entry>DncOutputDebug</entry><entry>8</entry><entry>N/A</entry><entry>Bit 7 = dwu_dnc_ready</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 6 = dnc_dwu_avail</entry></row><row><entry /><entry /><entry /><entry /><entry>Bits 5–0 = dnc_dwu_data</entry></row><row><entry>0x64</entry><entry>DncReplaceDebug</entry><entry>14</entry><entry>N/A</entry><entry>Bit 13 = edu_ready</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 12 = iru_avail</entry></row><row><entry /><entry /><entry /><entry /><entry>Bits 11–6 = iru_dn_mask</entry></row><row><entry /><entry /><entry /><entry /><entry>Bits 5–0 = iru_data</entry></row><row><entry>0x68</entry><entry>DncDiffuseDebug</entry><entry>14</entry><entry>N/A</entry><entry>Bit 13 = dwu_dnc_ready</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 12 = dnc_dwu_avail</entry></row><row><entry /><entry /><entry /><entry /><entry>Bits 11–6 = edu_dn_mask</entry></row><row><entry /><entry /><entry /><entry /><entry>Bits 5–0 = edu_data</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 29.5.3 Ink Replacement Unit
3454<figref idref="DRAWINGS">FIG. 248</figref> shows a sub-block diagram for the ink replacement unit.
000029.5.3.1 Control Unit
3455The control unit is responsible for reading the dead nozzle table from DRAM and making it available to the DNC via the dead nozzle FIFO. The dead nozzle table is read from DRAM in single 256-bit accesses, receiving the data from the DIU over 4 clock cycles (64-bits per cycle). The protocol and timing for read accesses to DRAM is described in section 20.9.1 on page 240. Reading from DRAM is implemented by means of the state machine shown in <figref idref="DRAWINGS">FIG. 249</figref>. All counters and flags should be cleared after reset. When Go transitions from 0 to 1 all counters and flags should take their initial value. While the Go bit is 1, the state machine requests a read access from the dead nozzle table in DRAM provided there is enough space in its FIFO.
3456A modulo-4 counter, rd_count, is used to count each of the 64-bits received in a 256-bit read access. It is incremented whenever diu_dnc_rvalid is asserted. When Go is 1, dn_table_radr is set to dn_table_start_adr. As each 64-bit value is returned, indicated by diu_dnc_rvalid being asserted, dn_table_radr is compared to dn_table_end_adr. <ul id="ul0356" list-style="none"><li id="ul0356-0001" num="0000"><ul id="ul0357" list-style="none"><li id="ul0357-0001" num="3457">If rd_count equals 3 and dn_table_radr equals dn_table_end_adr, then dn_table_radr is updated to dn_table_start_adr.</li><li id="ul0357-0002" num="3458">If rd_count equals 3 and dn_table_radr does not equal dn_table_end_adr, then dn_table_radr is incremented by 1.</li></ul></li></ul>
3459A count is kept of the number of 64-bit values in the FIFO. When diu_dnc_rvalid is 1 data is written to the FIFO by asserting wr_en, and fifo_contents and fifo_wr_adr are both incremented. <ul id="ul0358" list-style="none"><li id="ul0358-0001" num="0000"><ul id="ul0359" list-style="none"><li id="ul0359-0001" num="3460">When fifo_contents[3:0] is greater than 0 and edu_ready is 1, dnc_hcu_ready is asserted to indicate that the DNC is ready to accept dots from the HCU. If hcu_dnc_avail is also 1 then a dotadv pulse is sent to the GenMask unit, indicating the DNC has accepted a dot from the HCU, and iru_avail is also asserted. After Go is set, a single preload pulse is sent to the GenMask unit once the FIFO contains data.</li><li id="ul0359-0002" num="3461">When a rd_adv pulse is received from the GenMask unit, fifo_rd_adr[4:0] is then incremented to select the next 16-bit value. If fifo_rd_adr[1:0]=11 then the next 64-bit value is read from the FIFO by asserting rd_en, and fifo_contents[3:0] is decremented. <br /> 29.5.3.2 Dead Nozzle FIFO </li></ul></li></ul>
3462The dead nozzle FIFO conceptually is a 64-bit input, and 16-bit output FIFO to account for the 64-bit data transfers from the DIU, and the individual 16-bit entries in the dead nozzle table that are used in the GenMask unit. In reality, the FIFO is actually 8 entries deep and 64-bits wide (to accommodate two 256-bit accesses).
3463On the DRAM side of the FIFO the write address is 64-bit aligned while on the GenMask side the read address is 16-bit aligned, i.e. the upper 3 bits are input as the read address for the FIFO and the lower 2 bits are used to select 16 bits from the 64 bits (1st 16 bits read corresponds to bits <b>15</b>–<b>0</b>, second 16 bits to bits <b>31</b>–<b>16</b> etc.).
000029.5.3.3 GenMask Unit
3464The GenMask unit generates the 6-bit dn_mask that is sent to the replace unit. It consists of a 10-bit delta counter and a mask register.
3465After Go is set, the GenMask unit will receive a preload pulse from the control unit indicating the first dead nozzle table entry is available at the output of the dead nozzle FIFO and should be loaded into the delta counter and mask register. A rd_adv pulse is generated so that the next dead nozzle table entry is presented at the output of the dead nozzle FIFO. The delta counter is decremented every time a dotadv pulse is received. When the delta counter reaches 0, it gets loaded with the current delta value output from the dead nozzle FIFO, i.e. bits <b>15</b>–<b>6</b>, and the mask register gets loaded with mask output from the dead nozzle FIFO, i.e. bits <b>5</b>–<b>0</b>. A rd_adv pulse is then generated so that the next dead nozzle table entry is presented at the output of the dead nozzle FIFO.
3466When the delta counter is 0 the value in the mask register is output as the dn_mask, otherwise the dn_mask is all 0s.
3467The GenMask unit has no knowledge of the number of dots in a line, it simply loads a counter to count the delta from one dead nozzle column to the next. Thus as described in section 29.2 on page 472 the dead nozzle table should include null identifiers if necessary so that the dead nozzle table covers the first and last nozzle column in a line.
000029.5.3.4 Replace Unit
3468Dead nozzle removal and ink replacement are implemented by the combinatorial logic shown in <figref idref="DRAWINGS">FIG. 250</figref>. Dead nozzle removal is performed by bit-wise ANDing of the inverse of the dn_mask with the dot value.
3469The ink replacement mechanism has 6 ink replacement patterns, one per ink plane, programmable by the CPU. The dead nozzle mask is ANDed with the dot data to see if there are any planes where the dot is active but the corresponding nozzle is dead. The resultant value forms an enable, on a per ink basis, for the ink replacement process. If replacement is enabled for a particular ink, the values from the corresponding replacement pattern register are ORed into the dot data. The output of the ink replacement process is then filtered so that error diffusion is only allowed for the planes in which error diffusion is enabled.
3470The output of the ink replacement process is ORed with the resultant dot after dead nozzle removal. If the dot position does not contain a dead nozzle then the dn_mask will be all 0s and the dot, hcu_dnc_data, will be passed through unchanged.
000029.5.4 Error Diffusion Unit
3471<figref idref="DRAWINGS">FIG. 251</figref> shows a sub-block diagram for the error diffusion unit.
000029.5.4.1 Random Bit Generator
3472The random bit value used to arbitrarily select the direction of diffusion is generated by a maximum length 32-bit LFSR. The tap points and feedback generation are shown in <figref idref="DRAWINGS">FIG. 252</figref>. The LFSR generates a new bit for each dot in a line regardless of whether the dot is dead or not, i.e shifting of the LFSR is enabled when advdot equals 1. The LFSR can be initialised with a 32-bit programmable seed value, random_seed. This seed value is loaded into the LFSR whenever a write occurs to the RandomSeed register. Note that the seed value must not be all 1 s as this causes the LFSR to lock-up.
000029.5.4.2 Advance Dot Unit
3473The advance dot unit is responsible for determining in a given cycle whether or not the error diffuse unit will accept a dot from the ink replacement unit or make a dot available to the fixative correct unit and on to the DWU. It therefore receives the dwu_dnc_ready control signal from the DWU, the iru_avail flag from the ink replacement unit, and generates dnc_dwu_avail and edu_ready control flags.
3474Only the dwu_dnc_ready signal needs to be checked to see if a dot can be accepted and asserts edu_ready to indicate this. If the error diffuse unit is ready to accept a dot and the ink replacement unit has a dot available, then a advdot pulse is given to shift the dot into the pipeline in the diffuse unit. Note that since the error diffusion operates on 3 dots, the advance dot unit ignores dwu_dnc_ready initially until 3 dots have been accepted by the diffuse unit. Similarly dnc_dwu_avail is not asserted until the diffuse unit contains 3 dots and the ink replacement unit has a dot available.
000029.5.4.3 Diffuse Unit
3475The diffuse unit contains the combinatorial logic to implement the truth table from Table. The diffuse unit receives a dot consisting of 6 color planes (1 bit per plane) as well as an associated 6-bit dead nozzle mask value.
3476Error diffusion is applied to all 6 planes of the dot in parallel. Since error diffusion operates on 3 dots, the diffuse unit has a pipeline of 3 dots and their corresponding dead nozzle mask values.
3477The first dot received is referred to as dot A, and the second as dot B, and the third as dot C. Dots are shifted along the pipeline whenever advdot is 1. A count is also kept of the number of dots received. It is incremented whenever advdot is 1, and wraps to 0 when it reaches max_dot. When the dot count is 0 dot C corresponds to the first dot in a line. When the dot count is 1 dot A corresponds to the last dot in a line.
3478In any given set of 3 dots only dot B can be defined as containing a dead nozzle(s). Dead nozzles are identified by bits set in iru_dn_mask. If dot B contains a dead nozzle(s), the corresponding bit(s) in dot A, dot C, the dead nozzle mask value for A, the dead nozzle mask value for C, the dot count, as well as the random bit value are input to the truth table logic and the dots A, B and C assigned accordingly. If dot B does not contain a dead nozzle then the dots are shifted along the pipeline unchanged.
000029.5.5 Fixative Correction Unit
3479The fixative correction unit consists of combinatorial logic to implement fixative correction as defined in Table 203. For each output dot the DNC determines if fixative is required for the new compensated dot data word and whether fixative is activated already for that dot.
3480<tables id="TABLE-US-00299" num="00299"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>FixativePresent = ((FixativeMask1 | FixativeMask2) &</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>edu_data) != 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>FixativeRequired = (FixativeRequiredMask & edu_data) != 0</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3481It then looks up the truth table to see what action, if any, needs to be taken.
3482<tables id="TABLE-US-00300" num="00300"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 203</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Truth table for fixative correction</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="35pt" align="center" /><colspec colname="2" colwidth="28pt" align="center" /><colspec colname="3" colwidth="84pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>Fixative</entry><entry>Fixative</entry><entry /><entry /></row><row><entry>Present</entry><entry>required</entry><entry>Action</entry><entry>Output</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>1</entry><entry>1</entry><entry>Output dot as is.</entry><entry>dnc_dwu_data = edu_data</entry></row><row><entry>1</entry><entry>0</entry><entry>Clear fixative plane.</entry><entry>dnc_dwu_data = (edu_data) &</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="35pt" align="center" /><colspec colname="2" colwidth="112pt" align="center" /><colspec colname="3" colwidth="112pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>~(FixativeMask1 | FixativeMask2)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="35pt" align="center" /><colspec colname="2" colwidth="28pt" align="center" /><colspec colname="3" colwidth="84pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>0</entry><entry>1</entry><entry>Attempt to add fixative.</entry><entry>if (FixativeMask1 & DnMask)!= 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="35pt" align="center" /><colspec colname="2" colwidth="126pt" align="center" /><colspec colname="3" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>dnc_dwu_data = (edu_data) |</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="35pt" align="center" /><colspec colname="2" colwidth="112pt" align="center" /><colspec colname="3" colwidth="112pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>(FixativeMask2 & ~DnMask)</entry></row><row><entry /><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="35pt" align="center" /><colspec colname="2" colwidth="126pt" align="center" /><colspec colname="3" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>dnc_dwu_data = (edu_data) |</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="35pt" align="center" /><colspec colname="2" colwidth="112pt" align="center" /><colspec colname="3" colwidth="112pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>(FixativeMask1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="35pt" align="center" /><colspec colname="2" colwidth="28pt" align="center" /><colspec colname="3" colwidth="84pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>0</entry><entry>0</entry><entry>Output dot as is.</entry><entry>dnc_dwu_data = edu_data</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3483When attempting to add fixative the DNC first tries to add it into the plane defined by FixativeMask1. However, if this plane is dead then it tries to add fixative by placing it into the plane defined by FixativeMask2. Note that if both FixativeMask1 and FixativeMask2 are both all 0s then the dot data will not be changed.
000030 Dotline Writer Unit (DWU)
000030.1 Overview
3484The Dotline Writer Unit (DWU) receives 1 dot (6 bits) of color information per cycle from the DNC. Dot data received is bundled into 256-bit words and transferred to the DRAM. The DWU (in conjunction with the LLU) implements a dot line FIFO mechanism to compensate for the physical placement of nozzles in a printhead, and provides data rate smoothing to allow for local complexities in the dot data generate pipeline.
000030.2 Physical Requirement Imposed by the Printhead
3485The physical placement of nozzles in the printhead means that in one firing sequence of all nozzles, dots will be produced over several print lines. The printhead consists of 12 rows of nozzles, one for each color of odd and even dots. Odd and even nozzles are separated by D<sub>2 </sub>print lines and nozzles of different colors are separated by D<sub>1 </sub>print lines. See <figref idref="DRAWINGS">FIG. 254</figref> for reference. The first color to be printed is the first row of nozzles encountered by the incoming paper. In the example this is color 0 odd, although is dependent on the printhead type (see [10] for other printhead arrangments). Paper passes under printhead moving downwards.
3486For example if the physical separation of each half row is 80 μm equating to D<sub>1</sub>=D<sub>2</sub>=5 print lines at 1600 dpi. This means that in one firing sequence, color 0 odd nozzles will fire on dotline L, color 0 even nozzles will fire on dotline L-D<sub>1</sub>, color 1 odd nozzles will fire on dotline L-D<sub>1</sub>-D<sub>2 </sub>and so on over 6 color planes odd and even nozzles. The total number of lines fired over is given as 0+5+5 . . . +5=0+11×5=55. See <figref idref="DRAWINGS">FIG. 255</figref> for example diagram.
3487It is expected that the physical spacing of the printhead nozzles will be 80 μm (or 5 dot lines), although there is no dependency on nozzle spacing. The DWU is configurable to allow other line nozzle spacings.
3488<tables id="TABLE-US-00301" num="00301"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 204</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Relationship between Nozzle color/sense and line firing</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="77pt" align="center" /><colspec colname="2" colwidth="7pt" align="center" /><colspec colname="3" colwidth="77pt" align="center" /><colspec colname="4" colwidth="7pt" align="center" /><tbody valign="top"><row><entry /><entry>Even line</entry><entry /><entry>Odd line</entry><entry /></row><row><entry /><entry>encountered first</entry><entry /><entry>encountered first</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="35pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="42pt" align="left" /><colspec colname="4" colwidth="42pt" align="left" /><colspec colname="5" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry>Color</entry><entry>Sense</entry><entry>line</entry><entry>sense</entry><entry>line</entry></row><row><entry /><entry namest="offset" nameend="5" align="center" rowsep="1" /></row><row><entry /><entry>Color 0</entry><entry>Even</entry><entry>L</entry><entry>even</entry><entry>L-5</entry></row><row><entry /><entry /><entry>Odd</entry><entry>L-5</entry><entry>odd</entry><entry>L</entry></row><row><entry /><entry>Color 1</entry><entry>Even</entry><entry>L-10</entry><entry>even</entry><entry>L-15</entry></row><row><entry /><entry /><entry>Odd</entry><entry>L-15</entry><entry>odd</entry><entry>L-10</entry></row><row><entry /><entry>Color 2</entry><entry>Even</entry><entry>L-20</entry><entry>even</entry><entry>L-25</entry></row><row><entry /><entry /><entry>Odd</entry><entry>L-25</entry><entry>odd</entry><entry>L-20</entry></row><row><entry /><entry>Color 3</entry><entry>Even</entry><entry>L-30</entry><entry>even</entry><entry>L-35</entry></row><row><entry /><entry /><entry>Odd</entry><entry>L-35</entry><entry>odd</entry><entry>L-30</entry></row><row><entry /><entry>Color 4</entry><entry>Even</entry><entry>L-40</entry><entry>even</entry><entry>L-45</entry></row><row><entry /><entry /><entry>Odd</entry><entry>L-45</entry><entry>odd</entry><entry>L-40</entry></row><row><entry /><entry>Color 5</entry><entry>Even</entry><entry>L-50</entry><entry>even</entry><entry>L-55</entry></row><row><entry /><entry /><entry>Odd</entry><entry>L-55</entry><entry>odd</entry><entry>L-50</entry></row><row><entry /><entry namest="offset" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 30.3 Line Rate De-coupling
3489The DWU block is required to compensate for the physical spacing between lines of nozzles. It does this by storing dot lines in a FIFO (in DRAM) until such time as they are required by the LLU for dot data transfer to the printhead interface. Colors are stored separately because they are needed at different times by the LLU. The dot line store must store enough lines to compensate for the physical line separation of the printhead but can optionally store more lines to allow system level data rate variation between the read (printhead feed) and write sides (dot data generation pipeline) of the FIFOs.
3490A logical representation of the FIFOs is shown in <figref idref="DRAWINGS">FIG. 256</figref>, where N is defined as the optional number of extra half lines in the dot line store for data rate de-coupling.
000030.4 Dot Line Store Storage Requirements
3491For an arbitrary page width of d dots (where d is even), the number of dots per half line is d/2.
3492For interline spacing of D<sub>2 </sub>and inter-color spacing of D<sub>1</sub>, with C colors of odd and even half lines, the number of half line storage is (C−1)(D<sub>2</sub>+D<sub>1</sub>)+D1.
3493For N extra half line stores for each color odd and even, the storage is given by (N*C*2).
3494The total storage requirement is ((C−1)(D<sub>2</sub>+D<sub>1</sub>)+D1+(N*C*2))*d/2 in bits.
3495Note that when determining the storage requirements for the dot line store, the number of dots per line is the page width and not necessarily the printhead width. The page width is often the dot margin number of dots less than the printhead width. They can be the same size for full bleed printing.
3496For example in an A4 page a line consists of 13824 dots at 1600 dpi, or 6912 dots per half dot line. To store just enough dot lines to account for an inter-line nozzle spacing of 5 dot lines it would take 55 half dot lines for color 5 odd, 50 dot lines for color 5 even and so on, giving 55+50+45 . . . 10+5+0=330 half dot lines in total. If it is assumed that N=4 then the storage required to store 4 extra half lines per color is 4×12=48, in total giving 330+48=378 half dot lines. Each half dot line is 6912 dots, at 1 bit per dot give a total storage requirement of 6912 dots×378 half dot lines/8 bits=Approx 319 Kbytes. Similarly for an A3 size page with 19488 dots per line, 9744 dots per half line×378 half dot lines/8=Approx 899 Kbytes.
3497<tables id="TABLE-US-00302" num="00302"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 205</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Storage requirement for dot line store</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="7"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="21pt" align="left" /><colspec colname="2" colwidth="42pt" align="center" /><colspec colname="3" colwidth="28pt" align="center" /><colspec colname="4" colwidth="42pt" align="center" /><colspec colname="5" colwidth="28pt" align="center" /><colspec colname="6" colwidth="42pt" align="center" /><tbody valign="top"><row><entry /><entry /><entry /><entry>Lines</entry><entry>Storage</entry><entry>Lines</entry><entry>Storage</entry></row><row><entry /><entry>Page</entry><entry>Nozzle</entry><entry>required</entry><entry>(N = 0)</entry><entry>required</entry><entry>(N = 4)</entry></row><row><entry /><entry>size</entry><entry>Spacing</entry><entry>(N = 0)</entry><entry>Kbytes</entry><entry>(N = 4)</entry><entry>Kbytes</entry></row><row><entry /><entry namest="offset" nameend="6" align="center" rowsep="1" /></row><row><entry /><entry>A4</entry><entry>4</entry><entry>264</entry><entry>223</entry><entry>312</entry><entry>263</entry></row><row><entry /><entry /><entry>5</entry><entry>330</entry><entry>278</entry><entry>378</entry><entry>319</entry></row><row><entry /><entry>A3</entry><entry>4</entry><entry>264</entry><entry>628</entry><entry>312</entry><entry>742</entry></row><row><entry /><entry /><entry>5</entry><entry>330</entry><entry>785</entry><entry>378</entry><entry>899</entry></row><row><entry /><entry namest="offset" nameend="6" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3498The potential size of the dot line store makes it unfeasible to be implemented in on-chip SRAM, requiring the dot line store to be implemented in embedded DRAM. This allows a configurable dotline store where unused storage can be redistributed for use by other parts of the system.
000030.5 Nozzle Row Skew
3499Due to construction limitations of the bi-lithic printhead it is possible that nozzle rows may be misaligned relative to each other. Odd and even rows, and adjacent color rows may be horizontally misaligned by up to 2 dot positions. Vertical misalignment can also occur but is compensated for in the LLU and not considered here. The DWU is required to compensate for the horizontal misalignment.
3500Dot data from the HCU (through the DNC) produces a dot of 6 colors all destined for the same physical location on paper. If the nozzle rows in the printhead are aligned as shown in <figref idref="DRAWINGS">FIG. 254</figref> then no adjustment of the dot data is needed.
3501A conceptual misaligned printhead is shown in <figref idref="DRAWINGS">FIG. 257</figref>. The exact shape of the row alignment is arbitrary, although is most likely to be sloping (if sloping, it could be sloping in either direction). The DWU is required to adjust the shape of the dot streams to take account of the join between printhead ICs. The introduction of the join shape before the data is written to the DRAM means that the PHI sees a single crossover point in the data since all lines are the same length and the crossover point (since all rows are of equal length) is a vertical line—i.e. the crossover is at the same time for all even rows, and at the same time for all odd rows as shown in <figref idref="DRAWINGS">FIG. 258</figref>.
3502To insert the shape of the join into the dot stream, for each line we must first insert the dots for non-printable area 1, then the printable area data (from the DNC), and then finally the dots for non-printable area 2. This can also be considered as: first produce the dots for non-printable area 1 for line n, and then a repetition of: <ul id="ul0360" list-style="none"><li id="ul0360-0001" num="0000"><ul id="ul0361" list-style="none"><li id="ul0361-0001" num="3503">produce the dots for the printable area for line n (from the DNC)</li><li id="ul0361-0002" num="3504">produce the dots for the non-printable area 2 (for line n) followed by the dots of non-printable area 1 (for line n+1)</li></ul></li></ul>
3505The reason for considering the problem this way is that regardless of the shape of the join, the shape of non-printable area 2 merged with the shape of non-printable area 1 will always be a rectangle since the widths of non-printable areas 1 and 2 are identical and the lengths of each row are identical. Hence step 2 can be accomplished by simply inserting a constant number (MaxNozzleSkew) of 0 dots into the stream.
3506For example, if the color n even row non-printable area 1 is of length X, then the length of color n even row non-printable area 2 will be of length MaxNozzleSkew−X. The split between non-printable areas 1 and 2 is defined by the NozzleSkew registers.
3507Data from the DNC is destined for the printable area only, the DWU must generate the data destined for the non-printable areas, and insert DNC dot data correctly into the dot data stream before writing dot data to the fifos. The DWU inserts the shape of the misalignment into the dot stream by delaying dot data destined to different nozzle rows by the relative misalignment skew amount.
000030.6 Local Buffering
3508An embedded DRAM is expected to be of the order of 256 bits wide, which results in 27 words per half line of an A4 page, and 54 words per half line of A3. This requires 27 words×12 half colors (6 colors odd and even)=324×256-bit DRAM accesses over a dotline print time, equating to 6 bits per cycle (equal to DNC generate rate of 6 bits per cycle). Each half color is required to be double buffered, while filling one buffer the other buffer is being written to DRAM. This results in 256 bits×2 buffers×12 half colors i.e. 6144 bits in total.
3509The buffer requirement can be reduced, by using 1.5 buffering, where the DWU is filling 128 bits while the remaining 256 bits are being written to DRAM. While this reduces the required buffering locally it increases the peak bandwidth requirement to the DRAM. With 2× buffering the average and peak DRAM bandwidth requirement is the same and is 6 bits per cycle, alternatively with 1.5× buffering the average DRAM bandwidth requirement is 6 bits per cycle but the peak bandwidth requirement is 12 bits per cycle. The amount of buffering used will depend on the DRAM bandwidth available to the DWU unit.
3510Should the DWU fail to get the required DRAM access within the specified time, the DWU will stall the DNC data generation. The DWU will issue the stall in sufficient time for the DNC to respond and still not cause a FIFO overrun. Should the stall persist for a sufficiently long time, the PHI will be starved of data and be unable to deliver data to the printhead in time. The sizing of the dotline store FIFO and internal FIFOs should be chosen so as to prevent such a stall happening.
000030.7 Dotline Data in Memory
3511The dot data shift register order in the printhead is shown in <figref idref="DRAWINGS">FIG. 254</figref> (the transmit order is the opposite of the shift register order). In the example the type 0 printhead IC transmit order is increasing even color data followed by decreasing odd color data. The type 1 printhead IC transmit order is decreasing odd color data followed by increasing even color data. For both printhead ICs the even data is always increasing order and odd data is always decreasing. The PHI controls which printhead IC data gets shifted to.
3512From this it is beneficial to store even data in increasing order in DRAM and odd data in decreasing order. While this order suits the example printhead, other printheads exist where it would be beneficial to store even data in decreasing order, and odd data in increasing order, hence the order is configurable. The order that data is stored in memory is controlled by setting the ColorLineSense register.
3513The dot order in DRAM for increasing and decreasing sense is shown in <figref idref="DRAWINGS">FIG. 260</figref> and <figref idref="DRAWINGS">FIG. 261</figref> respectively. For each line in the dot store the order is the same (although for odd lines the numbering will be different the order will remain the same). Dot data from the DNC is always received in increasing dot number order. For increasing sense dot data is bundled into 256-bit words and written in increasing order in DRAM, word 0 first, then word 1, and so on to word N, where N is the number of words in a line.
3514For decreasing sense dot data is also bundled into 256-bit words, but is written to DRAM in decreasing order, i.e. word N is written first then word N−1 and so on to word 0. For both increasing and decreasing sense the data is aligned to bit <b>0</b> of a word, i.e. increasing sense always starts at bit <b>0</b>, decreasing sense always finishes at bit <b>0</b>.
3515Each half color is configured independently of any other color. The ColorBaseAdr register specifies the position where data for a particular dotline FIFO will begin writing to. Note that for increasing sense colors the ColorBaseAdr register specifies the address of the first word of first line of the fifo, whereas for decreasing sense colors the ColorBaseAdr register specifies the address of last word of the first line of the FIFO.
3516Dot data received from the DNC is bundled in 256-bit words and transferred to the DRAM. Each line of data is stored consecutively in DRAM, with each line separated by ColorLineInc number of words.
3517For each line stored in DRAM the DWU increments the line count and calculates the DRAM address for the next line to store.
3518This process continues until ColorFifoSize number of lines are stored, after which the DRAM address will wrap back to the ColorBaseAdr address.
3519As each line is written to the FIFO, the DWU increments the FifoFillLevel register, and as the LLU reads a line from the FIFO the FifoFillLevel register is decremented. The LLU indicates that it has completed reading a line by a high pulse on the llu_dwu_line_rd line.
3520When the number of lines stored in the FIFO is equal to the MaxWriteAhead value the DWU will indicate to the DNC that it is no longer able to receive data (i.e. a stall) by deasserting the dwu_dnc_ready signal.
3521The ColorEnable register determines which color planes should be processed, if a plane is turned off, data is ignored for that plane and no DRAM accesses for that plane are generated.
000030.8 Specifying Dot FIFOs
3522The dot line FIFOs when accessed by the LLU are specified differently than when accessed by the DWU. The DWU uses a start address and number of lines value to specify a dot FIFO, the LLU uses a start and end address for each dot FIFO. The mechanisms differ to allow more efficient implementations in each block.
3523As a result of limitations in the LLU the dot FIFOs must be specified contiguously and increasing in DRAM. See section 31.6 on page 504 for further information.
000030.9 Implementation
000030.9.1 Definitions of I/O
3524<tables id="TABLE-US-00303" num="00303"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="273pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 206</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>DWU I/O Definition</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="154pt" align="left" /><tbody valign="top"><row><entry>Port name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="273pt" align="left" /><tbody valign="top"><row><entry>Clocks and Resets</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="154pt" align="left" /><tbody valign="top"><row><entry>Pclk</entry><entry>1</entry><entry>In</entry><entry>System Clock</entry></row><row><entry>prst_n</entry><entry>1</entry><entry>In</entry><entry>System reset, synchronous active low</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="273pt" align="left" /><tbody valign="top"><row><entry>DNC Interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="154pt" align="left" /><tbody valign="top"><row><entry>dwu_dnc_ready</entry><entry>1</entry><entry>Out</entry><entry>Indicates that DWU is ready to accept data from</entry></row><row><entry /><entry /><entry /><entry>the DNC.</entry></row><row><entry>dnc_dwu_avail</entry><entry>1</entry><entry>In</entry><entry>Indicates valid data present on dnc_dwu_data.</entry></row><row><entry>dnc_dwu_data[5:0]</entry><entry>6</entry><entry>In</entry><entry>Input bi-level dot data in 6 ink planes.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="273pt" align="left" /><tbody valign="top"><row><entry>LLU Interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="154pt" align="left" /><tbody valign="top"><row><entry>dwu_llu_line_wr</entry><entry>1</entry><entry>Out</entry><entry>DWU line write. Indicates that the DWU has</entry></row><row><entry /><entry /><entry /><entry>completed a full line write. Active high</entry></row><row><entry>llfu_dwu_line_rd</entry><entry>1</entry><entry>In</entry><entry>LLU line read. Indicates that the LLU has</entry></row><row><entry /><entry /><entry /><entry>completed a line read. Active high.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="273pt" align="left" /><tbody valign="top"><row><entry>PCU Interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="154pt" align="left" /><tbody valign="top"><row><entry>pcu_dwu_sel</entry><entry>1</entry><entry>In</entry><entry>Block select from the PCU. When pcu_dwu_sel is</entry></row><row><entry /><entry /><entry /><entry>high both pcu_adr and pcu_dataout are valid.</entry></row><row><entry>pcu_rwn</entry><entry>1</entry><entry>In</entry><entry>Common read/not-write signal from the PCU.</entry></row><row><entry>pcu_adr[7:2]</entry><entry>5</entry><entry>In</entry><entry>PCU address bus. Only 6 bits are required to</entry></row><row><entry /><entry /><entry /><entry>decode the address space for this block.</entry></row><row><entry>pcu_dataout[31:0]</entry><entry>32</entry><entry>In</entry><entry>Shared write data bus from the PCU.</entry></row><row><entry>dwu_pcu_rdy</entry><entry>1</entry><entry>Out</entry><entry>Ready signal to the PCU. When dwu_pcu_rdy is</entry></row><row><entry /><entry /><entry /><entry>high it indicates the last cycle of the access. For a</entry></row><row><entry /><entry /><entry /><entry>write cycle this means pcu_dataout has been</entry></row><row><entry /><entry /><entry /><entry>registered by the block and for a read cycle this</entry></row><row><entry /><entry /><entry /><entry>means the data on dwu_pcu_datain is valid.</entry></row><row><entry>dwu_pcu_datain[31:0]</entry><entry>32</entry><entry>Out</entry><entry>Read data bus to the PCU.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="273pt" align="left" /><tbody valign="top"><row><entry>DIU Interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="154pt" align="left" /><tbody valign="top"><row><entry>dwu_diu_wreq</entry><entry>1</entry><entry>Out</entry><entry>DWU requests DRAM write. A write request must</entry></row><row><entry /><entry /><entry /><entry>be accompanied by a valid write address together</entry></row><row><entry /><entry /><entry /><entry>with valid write data and a write valid.</entry></row><row><entry>dwu_diu_wadr[21:5]</entry><entry>17</entry><entry>Out</entry><entry>Write address to DIU</entry></row><row><entry /><entry /><entry /><entry>17 bits wide (256-bit aligned word)</entry></row><row><entry>diu_dwu_wack</entry><entry>1</entry><entry>In</entry><entry>Acknowledge from DIU that write request has</entry></row><row><entry /><entry /><entry /><entry>been accepted and new write address can be</entry></row><row><entry /><entry /><entry /><entry>placed on dwu_diu_wadr</entry></row><row><entry>dwu_diu_data[63:0]</entry><entry>64</entry><entry>Out</entry><entry>Data from DWU to DIU. 256-bit word transfer over</entry></row><row><entry /><entry /><entry /><entry>4 cycles</entry></row><row><entry /><entry /><entry /><entry>First 64-bits is bits 63:0 of 256 bit word</entry></row><row><entry /><entry /><entry /><entry>Second 64-bits is bits 127:64 of 256 bit word</entry></row><row><entry /><entry /><entry /><entry>Third 64-bits is bits 191:128 of 256 bit word</entry></row><row><entry /><entry /><entry /><entry>Fourth 64-bits is bits 255:192 of 256 bit word</entry></row><row><entry>dwu_diu_wvalid</entry><entry>1</entry><entry>Out</entry><entry>Signal from DWU indicating that data on</entry></row><row><entry /><entry /><entry /><entry>dwu_diu_data is valid.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 30.9.2 DWU Partition <br /> 30.9.3 Configuration Registers
3525The configuration registers in the DWU are programmed via the PCU interface. Refer to section 21.8.2 on page 321 for a description of the protocol and timing diagrams for reading and writing registers in the DWU. Note that since addresses in SoPEC are byte aligned and the PCU only supports 32-bit register reads and writes, the lower 2 bits of the PCU address bus are not required to decode the address space for the DWU. When reading a register that is less than 32 bits wide zeros should be returned on the upper unused bit(s) of dwu_pcu_data. Table 207 lists the configuration registers in the DWU.
3526<tables id="TABLE-US-00304" num="00304"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="308pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 207</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>DWU registers description</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="35pt" align="center" /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="126pt" align="center" /><tbody valign="top"><row><entry>Address</entry><entry /><entry /><entry /><entry /></row><row><entry>DWU_base+</entry><entry>Register</entry><entry>#bits</entry><entry>Reset</entry><entry>Description</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="308pt" align="left" /><tbody valign="top"><row><entry>Control Registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="35pt" align="char" char="." /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>0x00</entry><entry>Reset</entry><entry>1</entry><entry>0x1</entry><entry>Active low synchronous reset, self de-</entry></row><row><entry /><entry /><entry /><entry /><entry>activating. A write to this register will</entry></row><row><entry /><entry /><entry /><entry /><entry>cause a DWU block reset.</entry></row><row><entry>0x04</entry><entry>Go</entry><entry>1</entry><entry>0x0</entry><entry>Active high bit indicating the DWU is</entry></row><row><entry /><entry /><entry /><entry /><entry>programmed and ready to use. A low to</entry></row><row><entry /><entry /><entry /><entry /><entry>high transition will cause DWU block</entry></row><row><entry /><entry /><entry /><entry /><entry>internal states to reset (configuration</entry></row><row><entry /><entry /><entry /><entry /><entry>registers are not reset).</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="308pt" align="left" /><tbody valign="top"><row><entry>Dot Line Store Configuration</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="35pt" align="center" /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>0x08–0x34</entry><entry>ColorBaseA</entry><entry> 12 × 17</entry><entry>0x000 00</entry><entry>Specifies the base address (in words) in</entry></row><row><entry /><entry>dr[11:0][21:5]</entry><entry /><entry /><entry>memory where data from a particular</entry></row><row><entry /><entry /><entry /><entry /><entry>half color (N) will be placed. For</entry></row><row><entry /><entry /><entry /><entry /><entry>increasing sense colors the ColorBase-</entry></row><row><entry /><entry /><entry /><entry /><entry>Adr register specifies the address of the</entry></row><row><entry /><entry /><entry /><entry /><entry>first word of first line of the fifo, whereas</entry></row><row><entry /><entry /><entry /><entry /><entry>for decreasing sense colors the</entry></row><row><entry /><entry /><entry /><entry /><entry>ColorBaseAdr register specifies the</entry></row><row><entry /><entry /><entry /><entry /><entry>address of last word of the first line of</entry></row><row><entry /><entry /><entry /><entry /><entry>the fifo.</entry></row><row><entry>0x38–0x64</entry><entry>ColorFifoSize[11:0]</entry><entry>12 × 8</entry><entry>0x00</entry><entry>Indicates the number of lines in the</entry></row><row><entry /><entry /><entry /><entry /><entry>FIFO before the line increment will wrap</entry></row><row><entry /><entry /><entry /><entry /><entry>around in memory.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="35pt" align="char" char="." /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="49pt" align="left" /><colspec colname="6" colwidth="77pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry /><entry /><entry>Bus 0,1 -</entry><entry>Even, Odd line color 0</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 2,3 -</entry><entry>Even, Odd line color 1</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 4,5 -</entry><entry>Even, Odd line color 2</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 6,7 -</entry><entry>Even, Odd line color 3</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 8,9 -</entry><entry>Even, Odd line color 4</entry></row><row><entry /><entry /><entry /><entry /><entry>bus 10,11 -</entry><entry>Even, Odd line color 5</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="35pt" align="char" char="." /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>0x68</entry><entry>ColorLineSense</entry><entry>2</entry><entry>0x2</entry><entry>Specifies whether data written to DRAM</entry></row><row><entry /><entry /><entry /><entry /><entry>for this half color is increasing or</entry></row><row><entry /><entry /><entry /><entry /><entry>decreasing sense</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - Decreasing sense</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - Increasing sense</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 0 Defines even color sense,</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 1 Defines odd color sense.</entry></row><row><entry>0x6C</entry><entry>ColorEnable</entry><entry>6</entry><entry>0x3F</entry><entry>Indicates whether a particular color is</entry></row><row><entry /><entry /><entry /><entry /><entry>active or not.</entry></row><row><entry /><entry /><entry /><entry /><entry>When inactive no data is written to</entry></row><row><entry /><entry /><entry /><entry /><entry>DRAM for that color.</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - Color off</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - Color on</entry></row><row><entry /><entry /><entry /><entry /><entry>One bit per color, bit 0 is Color 0 and so</entry></row><row><entry /><entry /><entry /><entry /><entry>on.</entry></row><row><entry>0x70</entry><entry>MaxWriteAhead</entry><entry>8</entry><entry>0x00</entry><entry>Specifies the maximum number of lines</entry></row><row><entry /><entry /><entry /><entry /><entry>that the DWU can be ahead of the LLU</entry></row><row><entry>0x74</entry><entry>LineSize</entry><entry>16</entry><entry>0x000 0</entry><entry>Indicates the number of dots per line</entry></row><row><entry /><entry /><entry /><entry /><entry>produced by the DWU.</entry></row><row><entry>0x78</entry><entry>MaxNozzleSkew</entry><entry>4</entry><entry>0x0</entry><entry>Specifies the number of dot-pairs the</entry></row><row><entry /><entry /><entry /><entry /><entry>DWU needs to generate to flush the</entry></row><row><entry /><entry /><entry /><entry /><entry>data skew buffers. Corresponds to the</entry></row><row><entry /><entry /><entry /><entry /><entry>non-printable area of the printhead.</entry></row><row><entry>0x7C–0xA8</entry><entry>NozzleSkew</entry><entry>12 × 4</entry><entry>0x0</entry><entry>Specifies the relative skew of dot data</entry></row><row><entry /><entry /><entry /><entry /><entry>nozzle rows in the printhead. Valid</entry></row><row><entry /><entry /><entry /><entry /><entry>range is 0 (no skew) through to 12.</entry></row><row><entry /><entry /><entry /><entry /><entry>Units represent dot-pairs, a skew of 1</entry></row><row><entry /><entry /><entry /><entry /><entry>for a row represents two dots on the</entry></row><row><entry /><entry /><entry /><entry /><entry>page.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="35pt" align="char" char="." /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="49pt" align="left" /><colspec colname="6" colwidth="77pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry /><entry /><entry>Bus 0,1 -</entry><entry>Even, Odd line color 0</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 2,3 -</entry><entry>Even, Odd line color 1</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 4,5 -</entry><entry>Even, Odd line color 2</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 6,7 -</entry><entry>Even, Odd line color 3</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 8,9 -</entry><entry>Even, Odd line color 4</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 10,11 -</entry><entry>Even, Odd line color 5</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="35pt" align="char" char="." /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>0xAC</entry><entry>ColorLineInc</entry><entry>8</entry><entry>0x00</entry><entry>Specifies the number of words (256-bit</entry></row><row><entry /><entry /><entry /><entry /><entry>words) per dot line - 1.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="308pt" align="left" /><tbody valign="top"><row><entry>Working Registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="35pt" align="char" char="." /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>0xB0</entry><entry>LineDotCnt</entry><entry>16</entry><entry>0x000 0</entry><entry>Indicates the number of remaining dots</entry></row><row><entry /><entry /><entry /><entry /><entry>in the current line. (Read Only)</entry></row><row><entry>0xB4</entry><entry>FifoFillLevel</entry><entry>8</entry><entry>0x00</entry><entry>Number of lines in the FIFO, written to</entry></row><row><entry /><entry /><entry /><entry /><entry>but not read. (Read Only)</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3527A low to high transition of the Go register causes the internal states of the DWU to be reset. All configuration registers will remain the same. The block indicates the transition to other blocks via the dwu_go_pulse signal.
000030.9.4 Data Skew
3528The data skew block inserts the shape of the printhead join into the dot data stream by delaying dot data by the relative nozzle skew amount (given by nozzle_skew). It generates zero fill data introduced introduced into the dot data stream to achieve the relative skew (and also to flush dot data from the delay registers).
3529The data skew block consists of 12 12-bit shift registers, one per color odd and even. The shift registers are in groups of 6, one group for even colors, and one for odd colors. Each time a valid data word is received from the DNC the dot data is shifted into either the odd or even group of shift registers. The odd_even_sel register determines which group of shift registers are valid for that cycle and alternates for each new valid data word. When a valid word is received for a group of shift registers, the shift register is shifted by one location with the new data word shifted into the registers (the top word in the register will be discarded).
3530When the dot counter determines that the data skew block should zero fill (zero_fill), the data skew block will shift zero dot data into the shift registers until the line has completed. During this time the DNC will be stalled by the de-assertion of the dwu_dnc_ready signal.
3531The data skew block selects dot data from the shift registers and is passed to the buffer address generator block. The data bits selected is determined by the configured index values in the NozzleSkew registers.
3532<tables id="TABLE-US-00305" num="00305"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>// determine when data is valid</entry></row><row><entry>data_valid = (((dnc_dwu_avail = = 1)OR(zero_fill = = 1)) AND</entry></row><row><entry>(dwu_ready = =1))</entry></row><row><entry>// implement the zero fill mux</entry></row><row><entry>if (zero_fill = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>dot_data_in = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>dot_data_in = dnc_dwu_data</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>// the data delay buffers</entry></row><row><entry>if (dwu_go_pulse = =1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="119pt" align="left" /><colspec colname="2" colwidth="28pt" align="left" /><colspec colname="3" colwidth="56pt" align="left" /><tbody valign="top"><row><entry /><entry>data_delay[1:0][11:0][5:0]</entry><entry>= 0</entry><entry>// reset all</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>delay buffer odd=1,even=0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="119pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry>odd_even_sel</entry><entry>= 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>elsif (data_valid = = 1) then {</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>odd_even_sel = ~odd_even_sel</entry></row><row><entry /><entry>// update the odd/even buffers, with shift</entry></row><row><entry /><entry>data_delay[odd_even_sel][11:1][5:0]=</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>data_delay[odd_even_sel][10:0][5:0] // shift data</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>data delay[odd even sel][0][5:0] = dot data in [5:0]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>// shift in new data</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// select the correct output data</entry></row><row><entry /><entry>for (i=0;i<6; i++) {</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>// skew selector</entry></row><row><entry /><entry>skew = nozzle skew[ {i,odd even sel} ]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>// temporary variable</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>// data select array, include data delay and input dot</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>data</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>data_select[12:0] = {data_delay[odd_even_sel][11:0],</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>dot_data_in}</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>// mux output the data word to next block (13 to 1 mux)</entry></row><row><entry /><entry>dot_data[i] = data_select[skew][i]</entry></row><row><entry /><entry>}</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>}</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 30.9.5 Fifo Fill Level
3533The DWU keeps a running total of the number of lines in the dot store FIFO. Each time the DWU writes a line to DRAM (determined by the DIU interface subblock and signalled via line_wr) it increments the filllevel and signals the line increment to the LLU (pulse on dwu_llu_line_wr). Conversely if it receives an active llu_dwu_line_rd pulse from the LLU, the filllevel is decremented. If the filllevel increases to the programmed max level (max_write_ahead) then the DWU stalls and indicates back to the DNC by de-asserting the dwu_dnc_ready signal.
3534If one or more of the DIU buffers fill, the DIU interface signals the fill level logic via the buf_full signal which in turn causes the DWU to de-assert the dwu_dnc_ready signal to stall the DNC. The buf_full signals will remain active until the DIU services a pending request from the full buffer, reducing the buffer level.
3535When the dot counter block detects that it needs to insert zero fill dots (zero_fill equals 1) the DWU will stall the DNC while the zero dots are being generated (by de-asserting dwu_dnc_ready), but will allow the data skew block to generate zero fill data (the dwu_ready signal).
3536<tables id="TABLE-US-00306" num="00306"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>dwu_dnc_ready = ~((buf_full= = 1) OR (filllevel = =</entry></row><row><entry /><entry>max_write_ahead ) OR (zero_fill = = 1))</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>dwu_ready</entry><entry>= ~((buf_full= = 1) OR (filllevel = =</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>max_write_ahead ))</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3537The DWU does not increment the fill level until a complete line of dot data is in DRAM not just a complete line received from the DNC. This ensures that the LLU cannot start reading a partial line from DRAM before the DWU has finished writing the line.
3538The fill level is reset to zero each time a new page is started, on receiving a pulse via the dwu_go_pulse signal.
3539The line fifo fill level can be read by the CPU via the PCU at any time by accessing the FifoFillLevel register.
000030.9.6 Buffer Address Generator
000030.9.6.1 Buffer Address Generator Description
3540The buffer address generator subblock is responsible for accepting data from the data skew block and writing it to the DIU buffers in the correct order.
3541The buffer address and active bit-write for a particular dot data write is calculated by the buffer address generator based on the dot count of the current line, programmed sense of the color and the line size.
3542All configuration registers should be programmed while the Go bit is set to zero, once complete the block can be enabled by setting the Go bit to one. The transition from zero to one will cause the internal states to reset.
3543If the color_line_sense signal for a color is one (i.e. increasing) then the bit-write generation is straight forward as dot data is aligned with a 256-bit boundary. So for the first dot in that color, the bit <b>0</b> of the wr_bit bus will be active (in buffer word 0), for the second dot bit <b>1</b> is active and so on to the 255<sup>th </sup>dot where bit <b>63</b> is active (in buffer word 3). This is repeated for all 256-bit words until the final word where only a partial number of bits are written before the word is transferred to DRAM.
3544If color_line_sense signal for a color is zero (i.e. decreasing) the bit-write generation for that color is adjusted by an offset calculated from the pre-programmed line length (line_size). The offset adjusts the bit write to allow the line to finish on a 256-bit boundary. For example if the line length was 400, for the first dot received bit <b>7</b> (line length is halved because of odd/even lines of color) of the wr_bit is active (buffer word 3), the second bit <b>6</b> (buffer word 3), to the 200<sup>th </sup>dot of data with bit <b>0</b> of wr_bit active (buffer word 0).
000030.9.6.2 Bit-write Decode
3545The buffer address generator contains 2 instances of the bit-write decode, one configured for odd dot data the other for even. The counter (either up or down counter) used to generate the addresses is selected by the color_line_sense signal. Each block determines if it is active on this cycle by comparing its configured type with the current dot count address and the data_active signal.
3546The wr_bit bus is a direct decoding of the lower 6 count bits (count[6:1]), and the DIU buffer address is the remaining higher bits of the counter (count[10:7]).
3547The signal generation is given as follows:
3548<tables id="TABLE-US-00307" num="00307"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>// determine the counter to use</entry></row><row><entry>if (color_line_sense = = 1 )</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>count = up_cnt[10:0]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>count = dn_cnt[10:0]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>// determine if active, based on instance type</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>wr_en</entry><entry>= data_active & (count[0] {circumflex over ( )}odd_even_type)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>// odd =1, even =0</entry></row><row><entry>// determine the bit write value</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="161pt" align="left" /><tbody valign="top"><row><entry>wr_bit[63:0]</entry><entry>= decode(count[6:1])</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>// determine the buffer 64-bit address</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="161pt" align="left" /><tbody valign="top"><row><entry>wr_adr[3:0]</entry><entry>= count[10:7]</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 30.9.6.3 Up Counter Generator
3549The up counter increments for each new dot and is used to determine the write position of the dot in the DIU buffers for increasing sense data. At the end of each line of dot data (as indicated by line_fin), the counter is rounded up to the nearest 256-bit word boundary. This causes the DIU buffers to be flushed to DRAM including any partially filled 256-bit words. The counter is reset to zero if the dwu_go_pulse is one.
3550<tables id="TABLE-US-00308" num="00308"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>// Up-Counter Logic</entry></row><row><entry /><entry>if (dwu_go_pulse = = 1) then {</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>up_cnt[10:0] = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (line_fin = = 1 ) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>// round up</entry></row><row><entry /><entry>if (up_cnt[8:1] != 0)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="84pt" align="left" /><colspec colname="1" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>up_cnt[10:9]++</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="84pt" align="left" /><colspec colname="1" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>up_cnt[10:9]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>// bit-selector</entry></row><row><entry /><entry>up_cnt[7:0]=0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (data_valid = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>up_cnt[7:0]++</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 30.9.6.4 Down Counter Generator
3551The down counter logic decrements for each new dot and is used to determine the write position of the dot in the DUI buffers for decreasing sense data. When the dwu_go_pulse bit is one the lower bits (i.e. 8 to 0) of the counter are reset to line size value (line_size), and the higher bits to zero. The bits used to determine the bit-write values and 64-bit word addresses in the DIU buffers begin at line size and count down to zero. The remaining higher bits are used to determine the DIU buffer 256-bit address and buffer fill level, begin at zero and count up. The counter is active when valid dot data is present, i.e. data_valid equals 1.
3552When the end of line is detected (line_fin equals 1) the counter is rounded to the next 256-bit word, and the lower bits are reset to the line size value.
3553<tables id="TABLE-US-00309" num="00309"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>//Down-Counter Logic</entry></row><row><entry /><entry>if (dwu_go_pulse = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>dn_cnt[8:0] = line_size[8:0]</entry></row><row><entry /><entry>dn_cnt[10:9] = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (line_fin = = 1 ) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>// perform rounding up</entry></row><row><entry /><entry>if (dn_cnt[8:1] != 0)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>dn_cnt[10:9]++</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>dn_cnt[10:9]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>// bit-select is reset</entry></row><row><entry /><entry>dn_cnt[8:0]=line_size[8:0] // bit select bits</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (data_valid = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>dn_cnt[8:0] − −</entry></row><row><entry /><entry>dn_cnt[10:9]++</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 30.9.6.5 Dot Counter
3554The dot counter simply counts each active dot received from the data skew block. It sets the counter to line_size and decrements each time a valid dot is received. When the count equals zero the line_fin signal is pulsed and the counter is reset to line_size.
3555When the count is less than the max_nozzle_skew* 2 value the dot counter indicates to the data skew block to zero fill the remainder of the line (via the zero_fill signal). Note that the max_nozzle_skew units are dot-pairs as opposed to dots, hence the by 2 multiplication for comparison with the dot counter.
3556The counter is reset to line_size when dwu_go_pulse is 1.
000030.9.7 DIU Buffer
3557The DIU buffer is a 64 bit×8 word dual port register array with bit write capability. The buffer could be implemented with flip-flops should it prove more efficient.
000030.9.8 DIU Interface
000030.9.8.1 DIU Interface General Description
3558The DIU interface determines when a buffer needs a data word to be transferred to DRAM. It generates the DRAM address based on the dot line position, the color base address and the other programmed parameters. A write request is made to DRAM and when acknowledged a 256-bit data word is transferred. The interface determines if further words need to be transferred and repeats the transfer process.
3559If the FIFO in DRAM has reached its maximum level, or one of the buffers has temporarily filled, the DWU will stall data generation from the DNC.
3560A similar process is repeated for each line until the end of page is reached. At the end of a page the CPU is required to reset the internal state of the block before the next page can be printed. A low to high transition of the Go register will cause the internal block reset, which causes all registers in the block to reset with the exception of the configuration registers. The transition is indicated to subblocks by a pulse on dwu_go_pulse signal.
000030.9.8.2 Interface Controller
3561The interface controller state machine waits in Idle state until an active request is indicated by the read pointer (via the req_active signal). When an active request is received the machine proceeds to the ColorSelect state to determine which buffers need a data transfer. In the ColorSelect state it cycles through each color and determines if the color is enabled (and consequently the buffer needs servicing), if enabled it jumps to the Request state, otherwise the color_cnt is incremented and the next color is checked.
3562In the Request state the machine issues a write request to the DIU and waits in the Request state until the write request is acknowledged by the DIU (diu_dwu_wack). Once an acknowledge is received the state machine clocks through 4 cycles transferring 64-bit data words each cycle and incrementing the corresponding buffer read address. After transferring the data to the DIU the machine returns to the ColorSelect state to determine if further buffers need servicing. On the transition the controller indicates to the address generator (adr_update) to update the address for that selected color.
3563If all colors are transferred (color_cnt equal to 6) the state machine returns to Idle, updating the last word flags (group_fin) and request logic (req_update).
3564The dwu_diu_wvalid signal is a delayed version of the buf_rd_en signal to allow for pipeline delays between data leaving the buffer and being clocked through to the DIU block.
3565The state machine will return from any state to Idle if the reset or the dwu_go_pulse is 1.
000030.9.8.3 Address Generator
3566The address generator block maintains 12 pointers (color adr[11:0]) to DRAM corresponding to current write address in the dot line store for each half color. When a DRAM transfer occurs the address pointer is used first and then updated for the next transfer for that color. The pointer used is selected by the req_sel bus, and the pointer update is initiated by the adr_update signal from the interface controller.
3567The pointer update is dependent on the sense of the color of that pointer, the pointer position in a line and the line position in the FIFO. The programming of the color_base_adr needs to be adjusted depending of the sense of the colors. For increasing sense colors the color_base_adr specifies the address of the first word of first line of the fifo, whereas for decreasing sense colors the color_base_adr specifies the address of last word of the first line of the FIFO.
3568For increasing colors, the initialization value (i.e. when dwu_go_pulse is 1) is the color_base_adr.
3569For each word that is written to DRAM the pointer is incremented. If the word is the last word in a line (as indicated by last_wd from that read pointers) the pointer is also incremented. If the word is the last word in a line, and the line is the last line in the FIFO (indicated by fifo_end from the line counter) the pointer is reset to color_base_adr.
3570In the case of decreasing sense colors, the initialization value (i.e. when dwu_go_pulse is 1) is the color_base_adr. For each line of decreasing sense color data the pointer starts at the line end and decrements to the line start. For each word that is written to DRAM the pointer is decremented. If the word is the last word in a line the pointer is incremented by color_line_inc*2+1. One line length to account for the line of data just written, and another line length for the next line to be written. If the word is the last word in a line, and the line is the last line in the FIFO the pointer is reset to the initialization value (i.e. color_base_adr).
0000The address is calculated as follows:
3571<tables id="TABLE-US-00310" num="00310"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>if (dwu_go_pulse = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>color_adr[11:0] = color_base_adr[11:0][21:5]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>elsif (adr_update = = 1) then {</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// determine the color</entry></row><row><entry /><entry>color = req_sel[3:0]</entry></row><row><entry /><entry>// line end and fifo wrap</entry></row><row><entry /><entry>if ((fifo_end[color] = = 1) AND (last_wd = = 1)) then {</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>// line end and fifo wrap</entry></row><row><entry /><entry>color_adr[color] = color_base_adr[color][21:5]</entry></row><row><entry /><entry>}</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif ( last_wd = = 1) then {</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>// just a line end no fifo wrap</entry></row><row><entry /><entry>if (color_line_sense[color % 2] = = 1) then //</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>increasing sense</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>color_adr[color] ++</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="105pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry><entry>// decreasing</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>sense</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>color_adr[color] = color_adr[color] + (</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>color_line_inc * 2) + 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>}</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>else {</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>// regular word write</entry></row><row><entry /><entry>if (color_line_sense[color % 2] = = 1) then //</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>increasing sense</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>color_adr[color]++</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry><entry>// decreasing sense</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>color_adr[color]− −</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>}</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>}</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>// select the correct address, for this transfer</entry></row><row><entry>dwu_diu_wadr = color_adr[req_sel]</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 30.9.8.4 Line Count
3572The line counter logic counts the number of dot data lines stored in DRAM for each color. A separate pointer is maintained for each color. A line pointer is updated each time the final word of a line is transferred to DRAM. This is determined by a combination of adr_update and last_wd signals. The pointer to update is indicated by the req_sel bus.
3573When an update occurs to a pointer it is compared to zero, if it is non-zero the count is decremented, otherwise the counter is reset to color_fifo_size. If a counter is zero the fifo_end signals is set high to indicates to the address generator block that the line is the last line of this colors fifo.
3574If the dwu_go_pulse signal is one the counters are reset to color_fifo_size.
3575<tables id="TABLE-US-00311" num="00311"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="196pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>if (dwu_go_pulse = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>line_cnt[11:0] = color_fifo_size[11:0]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="196pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif ((adr_update = = 1) AND (last_wd = = 1)) then {</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>// determine the pointer to operate on</entry></row><row><entry /><entry>color = req_sel[3:0]</entry></row><row><entry /><entry>// update the pointer</entry></row><row><entry /><entry>if (line_cnt[color] = = 0) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>line_cnt[color] = color_fifo_size[color]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>line_cnt[i] − −</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>}</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="196pt" align="left" /><tbody valign="top"><row><entry /><entry>// count is zero its the last line of fifo</entry></row><row><entry /><entry>for(i=0 ;i <12;i++){</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>fifo_end[i] = (line_cnt[i] = = 0)</entry></row><row><entry /><entry>}</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 30.9.8.5 Read Pointer
3576The read pointer logic maintains the buffer read address pointers. The read pointer is used to determine which 64-bit words to read from the buffer for transfer to DRAM.
3577The read pointer logic compares the read and write pointers of each DIU buffer to determine which buffers require data to be transferred to DRAM, and which buffers are full (the buf_full signal).
3578Buffers are grouped into odd and even buffers groups. If an odd buffer requires DRAM access the odd_pend signals will be active, if an even buffer requires DRAM access the even_pend signals will be active. If both odd and even buffers require DRAM access at exactly the same time, the even buffers will get serviced first. If a group of odd buffers are being serviced and an even buffer becomes pending, the odd group of buffers will be completed before the starting the even group, and vice versa.
3579If any buffer requires a DRAM transfer, the logic will indicate to the interface controller via the req_active signal, with the odd_even_sel signal determining which group of buffers get serviced. The interface controller will check the color_enable signal and issue DRAM transfers for all enabled colors in a group. When the transfers are complete it tells the read pointer logic to update the requests pending via req update signal.
3580The req_sel[3:0] signal tells the address generator which buffer is being serviced, it is constructed from the odd_even_sel signal and the color_cnt[2:0] bus from the interface controller. When data is being transferred to DRAM the word pointer and read pointer for the corresponding buffer are updated. The req_sel determines which pointer should be incremented.
3581<tables id="TABLE-US-00312" num="00312"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>// determine if request is active even</entry></row><row><entry>if ( wr_adr[0][3:2] != rd_adr[0][3:2] )</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>even_pend = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>even_pend = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>// determine if request is active odd</entry></row><row><entry>if ( wr_adr[1][3:2] != rd_adr[1][3:2] )</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>even_pend = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>even_pend = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>// determine if any buffer is full</entry></row><row><entry>if ((wr_adr[0][3:0] − rd_adr[0][3:0]) > 7)OR((wr_adr[1][3:0]</entry></row><row><entry>− rd_adr[1][3:0])> 7)) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>buf_full = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>// fixed servicing order, only update when controller</entry></row><row><entry>dictates so</entry></row><row><entry>if (req_update = = 1) then {</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="126pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><tbody valign="top"><row><entry /><entry>if (even_pend = = 1) then</entry><entry>// even always first</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="112pt" align="left" /><tbody valign="top"><row><entry /><entry>odd_even_sel</entry><entry>= 0</entry></row><row><entry /><entry>req_active</entry><entry>= 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="126pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (odd_pend = = 1 ) then</entry><entry>// then check odd</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="112pt" align="left" /><tbody valign="top"><row><entry /><entry>odd_even_sel</entry><entry>= 0</entry></row><row><entry /><entry>req_active</entry><entry>= 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="126pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry><entry>// nothing active</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="112pt" align="left" /><tbody valign="top"><row><entry /><entry>odd_even_sel</entry><entry>= 0</entry></row><row><entry /><entry>req_active</entry><entry>= 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>}</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>// selected requestor</entry></row><row><entry>req_sel[3:0] = {color_cnt[2:0] , odd_even_sel} //</entry></row><row><entry>concatentation</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3582The read address pointer logic consists of 2 2-bit counters and a word select pointer. The pointers are reset when dwu_go_pulse is one. The word pointer (word_ptr) is common to all buffers and is used to read out the 64-bit words from the DIU buffer. It is incremented when buf_rd_en is active. When a group of buffers are updated the state machine increments the read pointer (rd_ptr[odd_even_sel]) via the group_fin signal. A concatenation of the read pointer and the word pointer are use to construct the buffer read address. The read pointers are not reset at the end of each line.
3583<tables id="TABLE-US-00313" num="00313"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>// determine which pointer to update</entry></row><row><entry>if (dwu_go_pulse = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="119pt" align="left" /><tbody valign="top"><row><entry /><entry>rd_ptr[1:0]</entry><entry>= 0</entry></row><row><entry /><entry>word_ptr</entry><entry>= 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>elsif (buf_rd_en = = 1) then {</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="119pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry>word_ptr++</entry><entry>// word pointer update</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>elsif (group_fin = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="133pt" align="left" /><colspec colname="2" colwidth="70pt" align="left" /><tbody valign="top"><row><entry /><entry>rd_ptr [odd_even_sel]++</entry><entry>// update the read</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>pointer</entry></row><row><entry>// create the address from the pointer, and word reader</entry></row><row><entry>rd_adr[odd_even_sel] = {rd_ptr[odd_even_sel],word_ptr} //</entry></row><row><entry>concatenation</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3584The read pointer block determines if the word being read from the DIU buffers is the last word of a line. The buffer address generator indicate the last dot is being written into the buffers via the line fin signal. When received the logic marks the 256-bit word in the buffers as the last word. When the last word is read from the DIU buffer and transferred to DRAM, the flag for that word is reflected to the address generator.
3585<tables id="TABLE-US-00314" num="00314"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>// line end set the flags</entry></row><row><entry /><entry>if (dwu_go_pulse = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>last_flag[1:0][1:0] = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (line_fin = = 1 ) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>// determines the current 256-bit word even been written</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>to</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="119pt" align="left" /><colspec colname="2" colwidth="70pt" align="left" /><tbody valign="top"><row><entry /><entry>last_flag[0][wr_adr[0][2]] = 1</entry><entry>// even group flag</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>// determines the current 256-bit word odd been written to</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="119pt" align="left" /><colspec colname="2" colwidth="70pt" align="left" /><tbody valign="top"><row><entry /><entry>last_flag[1][wr_adr[1][2]] = 1</entry><entry>// odd group flag</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// last word reflection to address generator</entry></row><row><entry /><entry>last_wd = last_flag[odd_even_sel][rd_ptr[req_sel][0]]</entry></row><row><entry /><entry>// clear the flag</entry></row><row><entry /><entry>if (group_fin = = 1 ) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>last_flag[odd_even_sel][rd_ptr[req_sel][0]] = 0</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3586When a complete line has been written into the DIU buffers (but has not yet been transferred to DRAM), the buffer address generator block will pulse the line_fin signal. The DWU must wait until all enabled buffers are transferred to DRAM before signaling the LLU that a complete line is available in the dot line store (dwu_llu_line_wr signal). When the line_fin is received all buffers will require transfer to DRAM. Due to the arbitration, the even group will get serviced first then the odd. As a result the line finish pulse to the LLU is generated from the last_flag of the odd group.
3587<tables id="TABLE-US-00315" num="00315"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>// must be odd,odd group transfer complete and the last word</entry></row><row><entry>dwu_llu_line_wr = odd_even_sel AND group_fin AND last_wd</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 31 Line Loader Unit (LLU) <br /> 31.1 Overview
3588The Line Loader Unit (LLU) reads dot data from the line buffers in DRAM and structures the data into even and odd dot channels destined for the same print time. The blocks of dot data are transferred to the PHI and then to the printhead. <figref idref="DRAWINGS">FIG. 267</figref> shows a high level data flow diagram of the LLU in context.
000031.2 Physical Requirement Imposed by the Printhead
3589The DWU re-orders dot data into 12 separate dot data line FIFOs in the DRAM. Each FIFO corresponds to 6 colors of odd and even data. The LLU reads the dot data line FIFOs and sends the data to the printhead interface. The LLU decides when data should be read from the dot data line FIFOs to correspond with the time that the particular nozzle on the printhead is passing the current line. The interaction of the DWU and LLU with the dot line FIFOs compensates for the physical spread of nozzles firing over several lines at once. For further explanation see Section 30 Dotline Writer Unit (DWU) and Section 32 Printhead Interface (PHI). <figref idref="DRAWINGS">FIG. 268</figref> shows the physical relationship of nozzle rows and the line time the LLU starts reading from the dot line store.
3590Within each line of dot data the LLU is required to generate an even and odd dot data stream to the PHI block. <figref idref="DRAWINGS">FIG. 269</figref> shows the even and dot streams as they would map to an example bi-lithic printhead. The PHI block determines which stream should be directed to which printhead IC.
000031.3 Dot Generate and Transmit Order
3591The structure of the printhead ICs dictate the dot transmit order to each printhead IC. The LLU reads data from the dot line FIFO, generates an even and odd dot stream which is then re-ordered (in the PHI) into the transmit order for transfer to the printhead.
3592The DWU separates dot data into even and odd half lines for each color and stores them in DRAM. It can store odd or even dot data in increasing or decreasing order in DRAM. The order is programmable but for descriptive purposes assume even in increasing order and odd in decreasing order. The dot order structure in DRAM is shown in <figref idref="DRAWINGS">FIG. 261</figref>.
3593The LLU contains 2 dot generator units. Each dot generator reads dot data from DRAM and generates a stream of odd or even dots. The dot order may be increasing or decreasing depending on how the DWU was programmed to write data to DRAM. An example of the even and odd dot data streams to DRAM is shown in <figref idref="DRAWINGS">FIG. 270</figref>. In the example the odd dot generator is configured to produce odd dot data in decreasing order and the even dot generator produces dot data_in increasing order.
3594The PHI block accepts the even and odd dot data streams and reconstructs the streams into transmit order to the printhead.
3595The LLU line size refers to the page width in dots and not necessarily the printhead width. The page width is often the dot margin number of dots less than the printhead width. They can be the same size for full bleed printing.
000031.4 LLU Start-up
3596At the start of a page the LLU must wait for the dot line store in DRAM to fill to a configured level (given by FifoReadThreshold) before starting to read dot data. Once the LLU starts processing dot data for a page it must continue until the end of a page, the DWU (and other PEP blocks in the pipeline) must ensure there is always data in the dot line store for the LLU to read, otherwise the LLU will stall, causing the PHI to stall and potentially generate a print error. The FifoReadThreshold should be chosen to allow for data rate mismatches between the DWU write side and the LLU read side of the dot line FIFO. The LLU will not generate any dot data until FifoReadThreshold level in the dot line FIFO is reached.
3597Once the FifoReadThreshold is reached the LLU begins page processing, the FifoReadThreshold is ignored from then on.
3598When the LLU begins page processing it produces dot data for all colors (although some dot data color may be null data). The LLU compares the line count of the current page, when the line count exceeds the ColorRelLine configured value for a particular color the LLU will start reading from that colors FIFO in DRAM. For colors that have not exceeded the ColorRelLine value the LLU will generate null data (zero data) and not read from DRAM for that color. ColorRelLine[N] specifies the number of lines separating the N<sup>th </sup>half color and the first half color to print on that page. For the example printhead shown in <figref idref="DRAWINGS">FIG. 268</figref>, color 0 odd will start at line 0, the remaining colors will all have null data. Color 0 odd will continue with real data until line 5, when color 0 odd and even will contain real data the remaining colors will contain null data. At line 10, color 0 odd and even and color 1 odd will contain real data, with remaining colors containing null data. Every 5 lines a new half color will contain real data and the remaining half colors null data until line 55, when all colors will contain real data. In the example ColorRelLine[O]=5, ColorRelLine[1]=0, ColorRelLine[2]=15, ColorRelLine[3]=10. etc.
3599It is possible to turn off any one of the color planes of data (via the ColorEnable register), in such cases the LLU will generate zeroed dot data information to the PHI as normal but will not read data from the DRAM.
000031.4.1 LLU Bandwidth Requirements
3600The LLU is required to generate data for feeding to the printhead interface, the rate required is dependent on the printhead construction and on the line rate configured. The maximum data rate the LLU can produce is 12 bits of dot data per cycle, but the PHI consumes at 12 bits every 2 pclk cycles out of 3, i.e. 8 bits per pclk cycle. Therefore the DRAM bandwidth requirement for a double buffered LLU is 8 bits per cycle on average. If 1.5 buffering is used then the peak bandwidth requirement is doubled to 16 bits per cycle but the average remains at 8 bits per cycle. Note that while the LLU and PHI could produce data at the 8 bits per cycle rate, the DWU can only produce data at 6 bits per cycle rate.
000031.5 Vertical Row Skew
3601Due to construction limitations of the bi-lithic printhead it is possible that nozzle rows may be misaligned relative to each other. Odd and even rows, and adjacent color rows may be horizontally misaligned by up to 2 dot positions. Vertical misalignment can also occur between both printhead ICs used to construct the printhead. The DWU compensates for the horizontal misalignment (see Section 30.5), and the LLU compensates for the vertical misalignment. For each color odd and even the LLU maintains 2 pointers into DRAM, one for feeding printhead A (CurrentPtrA) and other for feeding printhead B (CurrentPtrB). Both pointers are updated and incremented in exactly the same way, but differ in their initial value programming. They differ by vertical skew number of lines, but point to the same relative position within a line.
3602At the start of a line the LLU reads from the FIFO using CurrentPtrA until the join point between the printhead ICs is reached (specified by JoinPoint), after which the LLU reads from DRAM using CurrentPtrB. If the JoinPoint coincides with a 256-bit word boundary, the swap over from pointer A to pointer B is straightforward. If the JoinPoint is not on a 256-bit word boundary, the LLU must read the 256-bit word of data from CurrentPtrA location, generate the dot data up to the join point and then read the 256-bit word of data from CurrentPtrB location and generate dot data from the join point to the word end. This means that if the JoinPoint is not on a 256-bit boundary then the LLU is required to perform an extra read from DRAM at the join point and not increment the address pointers.
000031.5.1 Dot Line FIFO Initialization
3603For each dot line FIFO there are 2 pointers reading from it, each skewed by a number of dot lines in relation to the other (the skew amount could be positive or negative). Determining the exact number of valid lines in the dot line store is complicated by two pointers reading from different positions in the FIFO. It is convenient to remove the problem by pre-zeroing the dot line FIFOs effectively removing the need to determine exact data validity. The dot FIFOs can be initialized in a number of ways, including <ul id="ul0362" list-style="none"><li id="ul0362-0001" num="0000"><ul id="ul0363" list-style="none"><li id="ul0363-0001" num="3604">the CPU writing 0s,</li><li id="ul0363-0002" num="3605">the LBD/SFU writing a set of 0 lines (16 bits per cycle),</li><li id="ul0363-0003" num="3606">the HCU/DNC/DWU being programmed to produce 0 data <br /> 31.6 Specifying Dot FIFOS </li></ul></li></ul>
3607The dot line FIFOs when accessed by the LLU are specified differently than when accessed by the DWU. The DWU uses a start address and number of lines value to specify a dot FIFO, the LLU uses a start and end address for each dot FIFO. The mechanisms differ to allow more efficient implementations in each block.
3608The start address for each half color N is specified by the ColorBaseAdr[N] registers and the end address (actually the end address plus 1) is specified by the ColorBaseAdr[N+1]. Note there are 12 colors in total, 0 to 11, the ColorBaseAdr[12] register specifies the end of the color 11 dot FIFO and not the start of a new dot FIFO. As a result the dot FIFOs must be specified contiguously and increasing in DRAM.
000031.7 Implementation
000031.7.1 LLU Partition
000031.7.2 Definitions of I/O
3609<tables id="TABLE-US-00316" num="00316"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 208</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>LLU I/O definition</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>Port name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="left" /><tbody valign="top"><row><entry>Clocks and Resets</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>Pclk</entry><entry>1</entry><entry>In</entry><entry>System clock</entry></row><row><entry>prst_n</entry><entry>1</entry><entry>In</entry><entry>System reset, synchronous active low</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="left" /><tbody valign="top"><row><entry>PHI Interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>llu_phi_data[1:0][5:0]</entry><entry>2 × 6</entry><entry>Out</entry><entry>Dot Data from LLU to the PHI, each bit is a</entry></row><row><entry /><entry /><entry /><entry>color plane 5 down to 0.</entry></row><row><entry /><entry /><entry /><entry>Bus 0 - Even dot data stream</entry></row><row><entry /><entry /><entry /><entry>Bus 1 - Odd dot data stream</entry></row><row><entry /><entry /><entry /><entry>Data is active when corresponding bit is active</entry></row><row><entry /><entry /><entry /><entry>in llu_phi_avail bus</entry></row><row><entry>phi_llu_ready[1:0]</entry><entry>2</entry><entry>In</entry><entry>Indicates that PHI is ready to accept data from</entry></row><row><entry /><entry /><entry /><entry>the LLU</entry></row><row><entry /><entry /><entry /><entry>0 - Even dot data stream</entry></row><row><entry /><entry /><entry /><entry>1 - Odd dot data stream</entry></row><row><entry>llu_phi_avail[1:0]</entry><entry>2</entry><entry>Out</entry><entry>Indicates valid data present on corresponding</entry></row><row><entry /><entry /><entry /><entry>llu_phi_data.</entry></row><row><entry /><entry /><entry /><entry>0 - Even dot data stream</entry></row><row><entry /><entry /><entry /><entry>1 - Odd dot data stream</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="left" /><tbody valign="top"><row><entry>DIU Interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>llu_diu_rreq</entry><entry>1</entry><entry>Out</entry><entry>LLU requests DRAM read. A read request must</entry></row><row><entry /><entry /><entry /><entry>be accompanied by a valid read address.</entry></row><row><entry>llu_diu_radr[21:5]</entry><entry>17</entry><entry>Out</entry><entry>Read address to DIU</entry></row><row><entry /><entry /><entry /><entry>17 bits wide (256-bit aligned word).</entry></row><row><entry>diu_llu_rack</entry><entry>1</entry><entry>In</entry><entry>Acknowledge from DIU that read request has</entry></row><row><entry /><entry /><entry /><entry>been accepted and new read address can be</entry></row><row><entry /><entry /><entry /><entry>placed on llu_diu_radr</entry></row><row><entry>diu_data[63:0]</entry><entry>64</entry><entry>In</entry><entry>Data from DIU to LLU. Each access is 256-bits</entry></row><row><entry /><entry /><entry /><entry>received over 4 clock cycles</entry></row><row><entry /><entry /><entry /><entry>First 64-bits is bits 63:0 of 256 bit word</entry></row><row><entry /><entry /><entry /><entry>Second 64-bits is bits 127:64 of 256 bit word</entry></row><row><entry /><entry /><entry /><entry>Third 64-bits is bits 191:128 of 256 bit word</entry></row><row><entry /><entry /><entry /><entry>Fourth 64-bits is bits 255:192 of 256 bit word</entry></row><row><entry>diu_llu_rvalid</entry><entry>1</entry><entry>In</entry><entry>Signal from DIU telling LLU that valid read data</entry></row><row><entry /><entry /><entry /><entry>is on the diu_data bus</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="left" /><tbody valign="top"><row><entry>DWU Interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>dwu_llu_line_wr</entry><entry>1</entry><entry>In</entry><entry>DWU line write. Indicates that the DWU has</entry></row><row><entry /><entry /><entry /><entry>completed a full line write. Active high</entry></row><row><entry>llu_dwu_line_rd</entry><entry>1</entry><entry>Out</entry><entry>LLU line read. Indicates that the LLU has</entry></row><row><entry /><entry /><entry /><entry>completed a line read. Active high.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="266pt" align="left" /><tbody valign="top"><row><entry>PCU Interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>pcu_llu_sel</entry><entry>1</entry><entry>In</entry><entry>Block select from the PCU. When pcu_llu_sel is</entry></row><row><entry /><entry /><entry /><entry>high both pcu_adr and pcu_dataout are valid.</entry></row><row><entry>pcu_rwn</entry><entry>1</entry><entry>In</entry><entry>Common read/not-write signal from the PCU.</entry></row><row><entry>pcu_adr[7:2]</entry><entry>6</entry><entry>In</entry><entry>PCU address bus. Only 6 bits are required to</entry></row><row><entry /><entry /><entry /><entry>decode the address space for this block.</entry></row><row><entry>pcu_dataout[31:0]</entry><entry>32</entry><entry>In</entry><entry>Shared write data bus from the PCU.</entry></row><row><entry>llu_pcu_rdy</entry><entry>1</entry><entry>Out</entry><entry>Ready signal to the PCU. When llu_pcu_rdy is</entry></row><row><entry /><entry /><entry /><entry>high it indicates the last cycle of the access. For</entry></row><row><entry /><entry /><entry /><entry>a write cycle this means pcu_dataout has been</entry></row><row><entry /><entry /><entry /><entry>registered by the block and for a read cycle this</entry></row><row><entry /><entry /><entry /><entry>means the data on llu_pcu_datain is valid.</entry></row><row><entry>llu_pcu_datain[31 :0]</entry><entry>32</entry><entry>Out</entry><entry>Read data bus to the PCU.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 31.7.3 Configuration Registers
3610The configuration registers in the LLU are programmed via the PCU interface. Refer to section 21.8.2 on page 321 for a description of the protocol and timing diagrams for reading and writing registers in the LLU. Note that since addresses in SoPEC are byte aligned and the PCU only supports 32-bit register reads and writes, the lower 2 bits of the PCU address bus are not required to decode the address space for the LLU. When reading a register that is less than 32 bits wide zeros should be returned on the upper unused bit(s) of llu_pcu_datain. Table 209 lists the configuration registers in the LLU.
3611<tables id="TABLE-US-00317" num="00317"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="315pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 209</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>LLU registers description</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><colspec colname="3" colwidth="28pt" align="center" /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="126pt" align="center" /><tbody valign="top"><row><entry>Address</entry><entry /><entry /><entry /><entry /></row><row><entry>LLU_base+</entry><entry>Register</entry><entry>#bits</entry><entry>Reset</entry><entry>Description</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="315pt" align="left" /><tbody valign="top"><row><entry>Control Registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>0x00</entry><entry>Reset</entry><entry>1</entry><entry>0x1</entry><entry>Active low synchronous reset, self de-</entry></row><row><entry /><entry /><entry /><entry /><entry>activating. A write to this register will</entry></row><row><entry /><entry /><entry /><entry /><entry>cause a LLU block reset.</entry></row><row><entry>0x04</entry><entry>Go</entry><entry>1</entry><entry>0x0</entry><entry>Active high bit indicating the LLU is</entry></row><row><entry /><entry /><entry /><entry /><entry>programmed and ready to use. A low to</entry></row><row><entry /><entry /><entry /><entry /><entry>high transition will cause LLU block</entry></row><row><entry /><entry /><entry /><entry /><entry>internal states to reset.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="315pt" align="left" /><tbody valign="top"><row><entry>Configuration</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><colspec colname="3" colwidth="28pt" align="center" /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>0x08–0x38</entry><entry>ColorBaseAdr[12:0][21:5]</entry><entry>13 × 17</entry><entry>0x000 00</entry><entry>Specifies the base address (in words) in</entry></row><row><entry /><entry /><entry /><entry /><entry>memory where data from a particular</entry></row><row><entry /><entry /><entry /><entry /><entry>half color (N) will be placed.</entry></row><row><entry /><entry /><entry /><entry /><entry>Also specifies the end address + 1 (256-</entry></row><row><entry /><entry /><entry /><entry /><entry>bit words) in memory where fifo data for</entry></row><row><entry /><entry /><entry /><entry /><entry>a particular half color ends. For color N</entry></row><row><entry /><entry /><entry /><entry /><entry>the start address is ColorBaseAdr[N]</entry></row><row><entry /><entry /><entry /><entry /><entry>and the end address +1 is ColorBase-</entry></row><row><entry /><entry /><entry /><entry /><entry>Adr[N+1]</entry></row><row><entry>0x3C</entry><entry>ColorEnable</entry><entry>6</entry><entry>0x3F</entry><entry>Indicates whether a particular color is</entry></row><row><entry /><entry /><entry /><entry /><entry>active or not.</entry></row><row><entry /><entry /><entry /><entry /><entry>When inactive no data is written to</entry></row><row><entry /><entry /><entry /><entry /><entry>DRAM for that color.</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - Color off</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - Color on</entry></row><row><entry /><entry /><entry /><entry /><entry>One bit per color, bit 0 is Color 0 and so</entry></row><row><entry /><entry /><entry /><entry /><entry>on.</entry></row><row><entry>0x40</entry><entry>LineSize</entry><entry>16</entry><entry>0x000 0</entry><entry>Indicates the number of dots per line.</entry></row><row><entry>0x44</entry><entry>FifoReadThreshold</entry><entry>8</entry><entry>0x00</entry><entry>Specifies the number of lines that should</entry></row><row><entry /><entry /><entry /><entry /><entry>be in the FIFO before the LLU starts</entry></row><row><entry /><entry /><entry /><entry /><entry>reading.</entry></row><row><entry>0x48–0x74</entry><entry>ColorRelLine[11:0]</entry><entry>12 × 8 </entry><entry>0x00</entry><entry>Specifies the relative number of lines to</entry></row><row><entry /><entry /><entry /><entry /><entry>wait from the first before starting to read</entry></row><row><entry /><entry /><entry /><entry /><entry>dot data from the corresponding dot data</entry></row><row><entry /><entry /><entry /><entry /><entry>FIFO</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="49pt" align="left" /><colspec colname="6" colwidth="77pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry /><entry /><entry>Bus 0,1 -</entry><entry>Even, Odd line color 0</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 2,3 -</entry><entry>Even, Odd line color 1</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 4,5 -</entry><entry>Even, Odd line color 2</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 6,7 -</entry><entry>Even, Odd line color 3</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 8,9 -</entry><entry>Even, Odd line color 4</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 10,11 -</entry><entry>Even, Odd line color 5</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><colspec colname="3" colwidth="28pt" align="center" /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>0x78–0x7C</entry><entry>JoinPoint</entry><entry> 2 × 16</entry><entry>0x000 0</entry><entry>Specifies the join point in dots between</entry></row><row><entry /><entry /><entry /><entry /><entry>both printhead ICs.</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 0 - Even dot generator join point</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 1 - Odd dot generator join point</entry></row><row><entry>0x80–0x84</entry><entry>JoinWord</entry><entry>2 × 8</entry><entry>0x00</entry><entry>Specifies the join point in words between</entry></row><row><entry /><entry /><entry /><entry /><entry>both printhead ICs.</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 0 - Even dot generator join point</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 1 - Odd dot generator join point</entry></row><row><entry>0x90–0xBC</entry><entry>CurrentAdrA[11:0][21:5]</entry><entry>12 × 17</entry><entry>0x000 0</entry><entry>Current Address pointers associated</entry></row><row><entry /><entry /><entry /><entry /><entry>with printhead A</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="49pt" align="left" /><colspec colname="6" colwidth="77pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry /><entry /><entry>Bus 0,1 -</entry><entry>Even, Odd line color 0</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 2,3 -</entry><entry>Even, Odd line color 1</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 4,5 -</entry><entry>Even, Odd line color 2</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 6,7 -</entry><entry>Even, Odd line color 3</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 8,9 -</entry><entry>Even, Odd line color 4</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 10,11 -</entry><entry>Even, Odd line color 5</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="126pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry /><entry /><entry>Working registers</entry></row><row><entry>0xC0–0xEC</entry><entry>CurrentAdrB[11:0][21:5]</entry><entry>12 × 17</entry><entry>0x000 0</entry><entry>Current Address pointers associated</entry></row><row><entry /><entry /><entry /><entry /><entry>with printhead B</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="49pt" align="left" /><colspec colname="6" colwidth="77pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry /><entry /><entry>Bus 0,1 -</entry><entry>Even, Odd line color 0</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 2,3 -</entry><entry>Even, Odd line color 1</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 4,5 -</entry><entry>Even, Odd line color 2</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 6,7 -</entry><entry>Even, Odd line color 3</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 8,9 -</entry><entry>Even, Odd line color 4</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 10,11 -</entry><entry>Even, Odd line color 5</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="126pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry /><entry /><entry>Working registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="315pt" align="left" /><tbody valign="top"><row><entry>Working Registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>0xF0</entry><entry>FifoFillLevel</entry><entry>8</entry><entry>0x00</entry><entry>Number of lines in the dot line FIFO, line</entry></row><row><entry /><entry /><entry /><entry /><entry>written in but not read out. (Read Only)</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3612A low to high transition of the Go register causes the internal states of the LLU to be reset. All configuration registers will remain the same. The block indicates the transition to other blocks via the llu_go_pulse signal.
000031.7.4 Dot Generator
3613The dot generator block is responsible for reading dot data from the DIU buffers and sending the dot data in the correct order to the PHI block. The dot generator waits for llu_en signal from the fifo fill level block, once active it starts reading data from the 6 DIU buffers and generating dot data for feeding to the PHI.
3614In the LLU there are two instances of the dot generator, one generating odd data and the other generating even data.
3615At any time the ready bit from the PHI could be de-asserted, if this happens the dot generator will stop generating data, and wait for the ready bit to be re-asserted.
000031.7.4.1 Dot Count
3616In normal operation the dot counter will wait for the llu_en and the ready to be active before starting to count. The dot count will produce data as long as the phi_llu_ready is active. If the phi_llu_ready signal goes low the count will be stalled.
3617The dot counter increments for each dot that is processed per line. It is used to determine the line finish position, and the bit select value for reading from the DIU buffers. The counter is reset after each line is processed (line_fin signal). It determines when a line is finished by comparing the dot count with the configured line size divided by 2 (note that odd numbers of dots will be rounded down).
3618<tables id="TABLE-US-00318" num="00318"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>// define the line finish</entry></row><row><entry /><entry>if (dot_cnt [14:0] = = line_size[15:1] )then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>line_fin = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>line_fin = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// determine if word is valid</entry></row><row><entry /><entry>dot_active = ((llu_en = = 1) AND (phi_llu_ready = = 1) AND</entry></row><row><entry /><entry>(buf_emp = = 0))</entry></row><row><entry /><entry>// counter logic</entry></row><row><entry /><entry>if (llu_go_pulse = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>dot_cnt = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif ((dot_active = = 1)AND (line_fin = = 1)) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry>dot_cnt</entry><entry>= 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (dot_active = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry>dot_cnt</entry><entry>= dot_cnt + 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry>dot_cnt</entry><entry>= dot_cnt</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// calculate the word select bits</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="98pt" align="left" /><colspec colname="2" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry>bit_sel[5:0]</entry><entry>:= dot_cnt[5:0]</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3619The dot generator also maintains a read buffer pointer which is incremented each time a 64-bit word is processed. The pointer is used to address the correct 64-bit dot data word within the DIU buffers. The pointer is reset when llu_go_pulse is 1. Unlike the dot counter the read pointer is not reset each line but rounded up the nearest 256-bit word. This allows for more efficient use of the DIU buffers at line finish.
3620When the dot counter reaches the join point for the dot generator (join_point), it jumps to the next 256 bit word in the DIU buffer but continues to read from the next bit position within that word. If the join point coincides with a word boundary, no 256-bit increment is required.
3621<tables id="TABLE-US-00319" num="00319"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>// read pointer logic</entry></row><row><entry>if (llu_go_pulse = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>read_adr = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>elsif ((dot_active = = 1)AND((dot_cnt[7:0] = = 255)OR(line_fin</entry></row><row><entry>= = 1)))then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// end of line round up</entry></row><row><entry /><entry>read_adr[3:2] ++</entry></row><row><entry /><entry>read_adr[1:0] = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="35pt" align="left" /><colspec colname="2" colwidth="56pt" align="left" /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="70pt" align="left" /><colspec colname="5" colwidth="28pt" align="left" /><tbody valign="top"><row><entry>elsif</entry><entry>((dot_active</entry><entry>= =</entry><entry>1)AND(dot_cnt</entry><entry>= =</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>join_point)AND(dot_cnt[5:0] = = 63)) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// join point jump 256 bits</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><colspec colname="2" colwidth="28pt" align="left" /><tbody valign="top"><row><entry /><entry>read_adr[1:0] ++</entry><entry>//</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>regular increment</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="105pt" align="left" /><colspec colname="2" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry>read_adr[3:2] ++</entry><entry>// join</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>point 256 increment</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="35pt" align="left" /><colspec colname="2" colwidth="56pt" align="left" /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="70pt" align="left" /><colspec colname="5" colwidth="28pt" align="left" /><tbody valign="top"><row><entry>elsif</entry><entry>((dot_active</entry><entry>= =</entry><entry>1)AND(dot_cnt</entry><entry>= =</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>join_point)AND(dot_cnt[5:0] != 63)) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// join point jump 256 bits, bottom bits remain the same</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="105pt" align="left" /><colspec colname="2" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry>read_adr[3:2] ++</entry><entry>// join</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>point 256 increment only</entry></row><row><entry>elsif ((dot_active = = 1)AND(dot_cnt[5:0] = = 63)) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><colspec colname="2" colwidth="28pt" align="left" /><tbody valign="top"><row><entry /><entry>read_adr [3:0] ++</entry><entry>//</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>regular increment</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 31.7.5 Fifo Fill Level
3622The LLU keeps a running total of the number of lines in the dot line store FIFO. Every time the DWU signals a line end (dwu_llu_line_wr active pulse) it increments the filllevel. Conversely if the LLU detects a line end (line_rd pulse) the filllevel is decremented and the line read is signalled to the DWU via the llu_dwu_line_rd signal.
3623The LLU fill level block is used to determine when the dot line has enough data stored before the LLU should begin to start reading. The LLU at page start is disabled. It waits for the DWU to write lines to the dot line FIFO, and for the fill level to increase. The LLU remains disabled until the fill level has reached the programmed threshold (fifo read thres). When the threshold is reached it signals the LLU to start processing the page by setting llu_en high. Once the LLU has started processing dot data for a page it will not stop if the filllevel falls below the threshold, but will stall is filllevel falls to zero.
3624The line fifo filllevel can be read by the CPU via the PCU at any time by accessing the FifoFillLevel register. The CPU must toggle the Go register in the LLU for the block to be correctly initialized at page start and the fifo level reset to zero.
3625<tables id="TABLE-US-00320" num="00320"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>if (llu_go_pulse = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>filllevel = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif ((line_rd = = 1) AND (dwu_llu_line_wr = = 1)) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>// do nothing</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (line_rd = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>filllevel − −</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (dwu_llu_line_wr = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>filllevel ++</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// determine the threshold, and set the LLU going</entry></row><row><entry /><entry>if (llu_go_pulse = = 1) OR (filllevel = = 0 )) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>llu_en = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (filllevel = = fifo_read_threshold ) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>llu_en = 1</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 31.7.6 DIU Interface <br /> 31.7.6.1 DIU Interface Description
3626The DIU interface block is responsible for determining when dot data needs to be read from DRAM, keeping the dot generators supplied with data and calculating the DRAM read address based on configured parameters, FIFO fill levels and position in a line.
3627The fill level block enables DIU requests by activating llu_en signal. The DIU interface controller then issues requests to the DIU for the LLU buffers to be filled with dot line data (or fill the LLU buffers with null data without requesting DRAM access, if required).
3628At page start the DIU interface determines which buffers should be filled with null data and which should request DRAM access. New requests are issued until the dot line is completely read from DRAM.
3629For each request to the DRAM the address generator calculates where in the DRAM the dot data should be read from. The color_enable bus determines which colors are enabled, the interface never issues DRAM requests for disabled colors.
000031.7.6.2 Interface Controller
3630The interface controller co-ordinates and issues requests for data transfers from DRAM. The state machine waits in Idle state until it is enabled by the LLU controller (llu_en) and a request for data transfer is received from the write pointer block.
3631When an active request is received (req_active equals 1) the state machine jumps to the ColorSelect state to determine which colors (color_cnt) in the group need a data transfer. A group is defined as all odd colors or all even colors. If the color isn't enabled (color_enable) the count just increments, and no data is transferred. If the color is enabled, the state machine takes one of two options, either a null data transfer or an actual data transfer from DRAM. A null data transfer writes zero data to the DIU buffer and does not issue a request to DRAM.
3632The state machine determines if a null transfer is required by checking the color_start signal for that color.
3633If a null transfer is required the state machine doesn't need to issue a request to the DIU and so jumps directly to the data transfer states (Data0 to Data3). The machine clocks through the 4 states each time writing a null 64-bit data word to the buffer. Once complete the state machine returns to the ColorSelect state to determine if further transfers are required.
3634If the color_start is active then a data transfer is required. The state machine jumps to the Request state and issue a request to the DIU controller for DRAM access by setting llu_diu_rreq high. The DIU responds by acknowledging the request (diu_llu_rack equals 1) and then sending 4 64-bit words of data. The transition from Request to Data0 state signals the address generator to update the address pointer (adr_update). The state machine clocks through Data0 to Data3 states each time writing the 64-bit data into the buffer selected by the req_sel bus. Once complete the state machine returns to the ColorSelect state to determine if further transfers are required.
3635When in the ColorSelect state and all data transfers for colors in that group have been serviced (i.e. when color_cnt is 6) the state machine will return to the Idle state. On transition it will update the word counter logic (word_dec) and enabled the request logic (req_update).
3636A reset or llu_go_pulse set to 1 will cause the state machine to jump directly to Idle. The controller will remain in Idle state until it is enabled by the LLU controller via the llu_en signal. This prevents the DIU attempting the fill the DIU buffers before the dot line store FIFO has filled over its threshold level.
000031.7.6.3 Color Activate
3637The color activate logic maintains an absolute line count indicating the line number currently being processed by the LLU. The counter is reset when the llu_go_pulse is 1 and incremented each time a line_rd pulse is received. The count value (line_cnt) is used to determine when to start reading data for a color.
3638The count is implemented as follows:
3639<tables id="TABLE-US-00321" num="00321"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="63pt" align="left" /><colspec colname="1" colwidth="154pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>if ( llu_go_pulse = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="77pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>line_cnt = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="63pt" align="left" /><colspec colname="1" colwidth="154pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif ( line_rd = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="77pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>line_cnt ++</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3640The color activate logic compares line count with the relative line value to determine when the LLU should start reading data from DRAM for a particular half color. It signals the interface controller block which colors are active for this dot line in a page (via the color_start bus). It is used by the interface controller to determine which DIU buffers require null data.
3641Once the color_start bit for a color is set it cannot be cleared in the normal page processing process. The bits must be reset by the CPU at the end of a page by transitioning the Go bit and causing a pulse on the llu_go_pulse signal.
3642Any color not enabled by the color_enable bus will never have its color_start bit set.
3643<tables id="TABLE-US-00322" num="00322"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>for (i=0; i<12;i++){</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>if ( llu_go_pulse = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>col_on[i] = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif ( color_enable[i % 6] = = 1 ) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>col_on[i] = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif ( line_cnt = = color_rel_line[i]) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>col_on[i] = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>}</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>// select either odd or even colors</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="119pt" align="left" /><colspec colname="2" colwidth="98pt" align="left" /><tbody valign="top"><row><entry>if ( odd_even_sel = = 1 ) then</entry><entry>// odd selected</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><colspec colname="2" colwidth="28pt" align="left" /><tbody valign="top"><row><entry /><entry>color_start[5:0]</entry><entry>=</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>{col_on[11],col_on[9],col_on[7],col_on[5],col_on[3],col_on[1</entry></row><row><entry>]}</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="119pt" align="left" /><colspec colname="2" colwidth="98pt" align="left" /><tbody valign="top"><row><entry>else</entry><entry>// even selected</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><colspec colname="2" colwidth="28pt" align="left" /><tbody valign="top"><row><entry /><entry>color start[5:0]</entry><entry>=</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>{col_on[10],col_on[8],col_on[6],col_on[4],col_on[2],col_on[0</entry></row><row><entry>]}</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 31.7.6.4 Address Generator
3644The address generator block maintains 24 pointers (current_adr_a[11:0] and current_adr_b[11:0]) to DRAM corresponding to 2 read addresses in the dot line FIFO for each half color. The current_adr a group of pointers are used when the dot generator is feeding printhead channel A, and the current_adr_b group of pointers are used when the dot generator is feeding printhead channel B. For each DRAM access the 2 address pointers are updated but only one can be used for an access. The word counter block determines which pointer group should be used to access DRAM, via the pointer select signals (ptr_sel). In certain cases (e.g. the join point is not 256-bit aligned and the word is on the join point) the address pointers should not be updated for an access, the word counter block determines the exception cases and indicates to the address generator to skip the update via the join_stall signal.
3645When a DRAM transfer occurs the address pointer is used first and then updated for the next transfer for the color. The pointer used is selected by the req_sel and ptr_sel buses, and the pointer update is initiated by the adr_update signal from the interface controller.
3646The address update is calculated as follows (pointer group A logic is shown but the same logic is used to update the B pointer group a clock cycle later):
3647<tables id="TABLE-US-00323" num="00323"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>// update the A pointers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="126pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><tbody valign="top"><row><entry /><entry>if (ptra_wr_en = = 1) then</entry><entry>// write from the</entry></row><row><entry /><entry>configuration block</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>current_adr_a[ptr_adr] = ptr_wr_data;</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="119pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif ( adr_update a = = 1) then {</entry><entry>// address update from</entry></row><row><entry /><entry>state machine</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>if ((req_sel = = NULL )OR (join_stall = = 1)) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>// do nothing</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>// temporary variable setup</entry></row><row><entry /><entry>next_adr = current_adr_a[req_sel] + 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>start_adr = color_base_adr[req_sel]</entry></row><row><entry /><entry>end_adr = color_base_adr[req_sel + 1]</entry></row><row><entry /><entry>// determine how to update the pointer</entry></row><row><entry /><entry>if (next_adr = = end_adr) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>current_adr_a[req_sel] = start_adr</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>current_adr_a[req_sel] = next_adr</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>}</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3648The correct address to use for a transfer is selected by the ptr_sel signals from the word counter block. They indicate which set of address pointers should be used based on the current word being transferred from the DRAM and the configured join point values (join_word).
3649<tables id="TABLE-US-00324" num="00324"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>// select the address pointer to use for access</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="182pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><tbody valign="top"><row><entry>if (req_sel[0] = = 1) then</entry><entry> // odd</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>pointer selector</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>if (ptr_sel[1] = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><colspec colname="2" colwidth="49pt" align="left" /><tbody valign="top"><row><entry /><entry>llu_diu_radr = current_adr_b[req_sel]</entry><entry>// latter part</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>of line</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><colspec colname="2" colwidth="49pt" align="left" /><tbody valign="top"><row><entry /><entry>llu_diu_radr = current_adr_a[req_sel]</entry><entry>// former part</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>of line</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="182pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><tbody valign="top"><row><entry>else</entry><entry>// even</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>pointer selector</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>if (ptr_sel[0] = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><colspec colname="2" colwidth="49pt" align="left" /><tbody valign="top"><row><entry /><entry>llu_diu_radr = current_adr_b[req_sel]</entry><entry>// latter part</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>of line</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><colspec colname="2" colwidth="49pt" align="left" /><tbody valign="top"><row><entry /><entry>llu_diu_radr = current_adr_a[req_sel]</entry><entry>// former part</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>of line</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 31.7.6.5 Write Pointer
3650The write pointer logic maintains the buffer write address pointers, determines when the DIU buffers need a data transfer and signals when the DIU buffers are empty. The write pointer determines the address in the DIU buffer that the data should be transferred to.
3651The write pointer logic compares the read and write pointers of each DIU buffer to determine which buffers require data to be transferred from DRAM, and which buffers are empty (the buf_emp signals).
3652Buffers are grouped into odd and even buffers, if an odd buffer requires DRAM access the odd_pend signals will be active, if an even buffer requires DRAM access the even_pend signals will be active. If both odd and even buffers require DRAM access at exactly the same time, the even buffers will get serviced first. If a group of odd buffers are being serviced and an even buffer becomes pending, the odd group of buffers will be completed before the starting the even group, and vice versa.
3653If any buffer requires a DRAM transfer, the logic will indicate to the interface controller via the req_active signal, with the odd_even_sel signal determining which group of buffers get serviced. The interface controller will check the color_enable signal and issue DRAM transfers for all enabled colors in a group. When the transfers are complete it tells the write pointer logic to update the request pending via req_update signal.
3654The req_sel[3:0] signal tells the address generator which buffer is being serviced, it is constructed from the odd_even_sel signal and the color_cnt[2:0] bus from the interface controller. When data is being transferred to DRAM the word pointer and write pointer for the corresponding buffer are updated. The req_sel determines which pointer should be incremented.
3655The write pointer logic operates the same way regardless of whether the transfer is null or not.
3656<tables id="TABLE-US-00325" num="00325"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>// determine which buffers need updates</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="140pt" align="left" /><tbody valign="top"><row><entry>buf_emp[1:0]</entry><entry>= 0</entry></row><row><entry>odd_pend</entry><entry>= 0</entry></row><row><entry>even_pend</entry><entry>= 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>if ( wr_adr[0][3:2] = = rd_adr[0][3:2] )</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>even_pend = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>if ( wr_adr[1][3:2] = = rd_adr[1][3:2] )</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>odd_pend = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>// determine if buffers are empty</entry></row><row><entry>if ((wr_adr[0][3:0] = = rd_adr[0][3:0])) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>buf_emp[0] = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>if ((wr_adr[1][3:0] = = rd_adr[1][3:0])) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>buf_emp[1] = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>// fixed servicing order, only update when controller</entry></row><row><entry>dictates so</entry></row><row><entry>if (req_update = = 1) then {</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="126pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><tbody valign="top"><row><entry /><entry>if (even_pend = = 1) then</entry><entry>// even always first</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="112pt" align="left" /><tbody valign="top"><row><entry /><entry>odd_even_sel</entry><entry>= 0</entry></row><row><entry /><entry>req_active</entry><entry>= 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="126pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (odd_pend = = 1 ) then</entry><entry>// then check odd</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="112pt" align="left" /><tbody valign="top"><row><entry /><entry>odd_even_sel</entry><entry>= 0</entry></row><row><entry /><entry>req_active</entry><entry>= 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="126pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry><entry>// nothing active</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="112pt" align="left" /><tbody valign="top"><row><entry /><entry>odd_even_sel</entry><entry>= 0</entry></row><row><entry /><entry>req_active</entry><entry>= 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>}</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>// selected requestor</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="28pt" align="left" /><colspec colname="3" colwidth="119pt" align="left" /><colspec colname="4" colwidth="14pt" align="left" /><tbody valign="top"><row><entry>req_sel[3:0]</entry><entry>=</entry><entry> {color_cnt[2:0],odd_even_sel}</entry><entry>//</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>concatentation</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3657The write address pointer logic consists of 2 2-bit counters and a word select pointer. The counters are reset when llu_go_pulse is one. The word pointer (word_ptr) is common to all buffers and is used to write 64-bit words into the DIU buffer. It is incremented when buf_rd_en is active.
3658When a group of buffers are updated the state machine increments the write pointer (wr_ptr[odd_even_sel]) via the group_fin signal. A concatenation of the write pointer and the word pointer are use to construct the buffer write address. The write pointers are not reset at the end of each line.
3659<tables id="TABLE-US-00326" num="00326"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>// determine which pointer to update</entry></row><row><entry>if (llu_go_pulse = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="119pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry>wr_ptr[1:0]</entry><entry>= 0</entry></row><row><entry /><entry>word_ptr</entry><entry>= 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>elsif (buf_rd_en = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>word_ptr++</entry></row><row><entry /><entry>wr_en[req_sel] = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>elsif (group_fin = 1 ) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>wr_ptr[odd_even_sel]++</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>// create the address from the write pointer and word</entry></row><row><entry>pointer.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="203pt" align="left" /><colspec colname="2" colwidth="14pt" align="left" /><tbody valign="top"><row><entry>wr_adr[odd_even_sel] = {wr_ptr[odd_even_sel],word_ptr}</entry><entry>//</entry></row><row><entry>concatenation</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 31.7.6.6 Word Count
3660The word count logic maintains 2 counters to track the number of words transferred from DRAM per line, one counter for odd data, and one counter for even. On receipt of a llu_go_pulse, the counters are initialized to a join_word value (number of words to the join point for that printhead channel) and the pointer select values to zero (ptr_sel). When a group of words are transferred to DRAM as indicated by the word_dec signal from the interface controller, the corresponding counter is decremented. The counter to decrement is indicated by the odd_even_sel signal from the write pointer block (even=0, odd=1).
3661When a counter is zero and the ptr_sel is zero, the counter is re-initialized to the second join_word value and ptr_sel is inverted. The counter continues to count down to zero each time a word_dec signal is received. When a counter is zero and the ptr_sel is one, it signals the end of a line (the last_wd signal) and initializes the counter to the first join_point value for the next line transfer.
3662The ptr_sel signal is used in the address generator to select the correct address pointer to use for that particular access.
3663<tables id="TABLE-US-00327" num="00327"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>// determine which counter to decrement</entry></row><row><entry>if (llu_go_pulse = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><colspec colname="3" colwidth="77pt" align="left" /><tbody valign="top"><row><entry /><entry>word_cnt[0]</entry><entry>= join_word[0]</entry><entry>// even count</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="98pt" align="left" /><colspec colname="3" colwidth="63pt" align="left" /><tbody valign="top"><row><entry /><entry>ptr_sel[0]</entry><entry> = 0</entry><entry>// even</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>generator starts with pointer A</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><colspec colname="3" colwidth="77pt" align="left" /><tbody valign="top"><row><entry /><entry>word_cnt[1]</entry><entry>= join_word[1]</entry><entry>// odd count</entry></row><row><entry /><entry>ptr_sel[1]</entry><entry>= 0</entry><entry>// odd generator</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>starts with pointer A</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="196pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><tbody valign="top"><row><entry>elsif (word_dec = = 1) then {</entry><entry>// need to</entry></row><row><entry>decrement one word counter</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><tbody valign="top"><row><entry /><entry>if (odd_even_sel = = 0) then</entry><entry> // even counter</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>update</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>if (word_cnt[0] = = 0) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><colspec colname="3" colwidth="77pt" align="left" /><tbody valign="top"><row><entry /><entry>word_cnt[0]</entry><entry>= join_word[ptr_sel[0]]</entry><entry>// re-initialize</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>pointer</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>ptr_sel[0]</entry><entry>= ~(ptr_sel[0])</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><tbody valign="top"><row><entry /><entry>if (ptr_sel[0]= = 1) then</entry><entry> // determine if</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>this the last word</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>last_wd = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="154pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><tbody valign="top"><row><entry /><entry>word_cnt [0] − −</entry><entry> // normal</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>decrement</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry><entry> // odd counter</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>update</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>if (word_cnt[1] = = 0) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><colspec colname="3" colwidth="77pt" align="left" /><tbody valign="top"><row><entry /><entry>word_cnt[1] </entry><entry>= join_word[ptr_sel[1]]</entry><entry>// re-initialize</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>pointer</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>ptr_sel[1]</entry><entry>= ~(ptr_sel[1])</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><tbody valign="top"><row><entry /><entry>if (ptr_sel[1] = = 1) then</entry><entry> // determine if</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>this the last word</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>last_wd = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="154pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><tbody valign="top"><row><entry /><entry>word_cnt [1] − −</entry><entry> // normal</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>decrement</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>}</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3664The word count logic also determines if the current word to be transferred is the join word, and if so it determines if it is aligned on a 256-bit boundary or not. If the join point is aligned to a boundary there is no need to prevent the address counter from incrementing, otherwise the address pointers are stalled for that word transfer (join_stall).
3665<tables id="TABLE-US-00328" num="00328"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>join_stall = (((ptr_sel[0] = = 0)AND (word_cnt[0] = = 0)AND</entry></row><row><entry /><entry>(join_point[0][7:0] != 0))</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>AND ((ptr_sel[1] = = 0)AND (word_cnt[1] = = 0)AND</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>(join_point[1][7:0] != 0)))</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3666The word count logic also determines when a complete line has been read from DRAM, it then signals the fifo fill level logic in both the LLU and DWU (via line_rd signal) that a complete line has been read by the LLU (llu_dwu_line_rd).
3667<tables id="TABLE-US-00329" num="00329"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>// line finish logic</entry></row><row><entry /><entry>if (llu_go_pulse = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>line_fin = 0</entry></row><row><entry /><entry>line_rd = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif ((last_wd = = 1) AND (line_fin = = 0)) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="98pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry>line_fin = 1</entry><entry> // first group last_wd</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>finish pulse</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>line_rd = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif ((last_wd = = 1) AND (line_fin = = 1)) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="98pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry>line_fin = 0</entry><entry>// second group last_wd</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>finish pulse</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>line_rd = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry>line_fin = line_fin</entry><entry>// stay the same</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>line_rd = 0</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 32 Printhead Interface (PHI) <br /> 32.1 Overview
3668The Printhead interface (PHI) accepts dot data from the LLU and transmits the dot data to the printhead, using the printhead interface mechanism. The PHI generates the control and timing signals necessary to load and drive the bi-lithic printhead. The CPU determines the line update rate to the printhead and adjusts the line sync frequency to produce the maximum print speed to account for the printhead IC's size ratio and inherent latencies in the syncing system across multiple SoPECs.
3669The PHI also needs to consider the order in which dot data is loaded in the printhead. This is dependent on the construction of the printhead and the relative sizes of printhead ICs used to create the printhead. See Bi-lithic Printhead Reference document for a complete description of printhead types [10].
3670The printing process is a real-time process. Once the printing process has started, the next printline's data must be transferred to the printhead before the next line sync pulse is received by the printhead. Otherwise the printing process will terminate with a buffer underrun error.
3671The PHI can be configured to drive a single printhead IC with or without synchronization to other SoPECs. For example the PHI could drive a single IC printhead (i.e. a printhead constucted with one IC only), or dual IC printhead with one SoPEC device driving each printhead IC.
3672The PHI interface provides a mechanism for the CPU to directly control the PHI interface pins, allowing the CPU to access the bi-lithic printhead to: <ul id="ul0364" list-style="none"><li id="ul0364-0001" num="0000"><ul id="ul0365" list-style="none"><li id="ul0365-0001" num="3673">determine printhead temperature</li><li id="ul0365-0002" num="3674">test for and determine dead nozzles for each printhead IC</li><li id="ul0365-0003" num="3675">initialize each printhead IC</li><li id="ul0365-0004" num="3676">pre-heat each printhead IC</li></ul></li></ul>
3677<figref idref="DRAWINGS">FIG. 277</figref> shows a high level data flow diagram of the PHI in context.
000032.2 Printhead Modes of Operation
3678The printhead has 8 different modes of operations (although some modes are re-used). The mode of operation is defined by the state of the output pins phi_lsyncl and phi_readl and the internal printhead mode register. The modes of operation are defined in Table 210.
3679<tables id="TABLE-US-00330" num="00330"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="322pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 210</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Printhead modes of operation</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="28pt" align="center" /><colspec colname="3" colwidth="35pt" align="center" /><colspec colname="4" colwidth="42pt" align="center" /><colspec colname="5" colwidth="42pt" align="left" /><colspec colname="6" colwidth="112pt" align="left" /><tbody valign="top"><row><entry /><entry>Internal</entry><entry /><entry /><entry /><entry /></row><row><entry>Name</entry><entry>Mode</entry><entry>phi_readl</entry><entry>phi_lsyncl</entry><entry>State</entry><entry>Description</entry></row><row><entry namest="1" nameend="6" align="center" rowsep="1" /></row><row><entry>NORMAL</entry><entry>XXX</entry><entry>1</entry><entry>1</entry><entry>N/A</entry><entry>Normal print mode, dot data is</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry>clocked into the printhead shift</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry>register, on each falling edge of</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry>phi_srclk</entry></row><row><entry>DOT_LOAD/</entry><entry>XXX</entry><entry>1</entry><entry>0</entry><entry>phi_frclk=0</entry><entry>Dot Load Mode, data stored in the</entry></row><row><entry>FIRE_INIT</entry><entry /><entry /><entry /><entry /><entry>dot shift register is transferred into</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry>the dot latch on the falling edge of</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry>phi_lsyncl, and latched in on the</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry>rising edge of phi_lsyncl</entry></row><row><entry /><entry /><entry /><entry /><entry>phi_srclk=1</entry><entry>Fire load mode. Parameter for</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry>generating fire pattern are loaded</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry>into generator, data on</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry>phi_ph_data[1:0][0] is clocked into</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry>the generator on each rising edge of</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry>phi_frclk</entry></row><row><entry>NOZZLE_RESET</entry><entry>001</entry><entry>0</entry><entry>1</entry><entry>N/A</entry><entry>Reset Nozzle Test mode. Reset the</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry>state on nozzle test.</entry></row><row><entry>CMOS_TEST</entry><entry>111</entry><entry>0</entry><entry>1</entry><entry>N/A</entry><entry>CMOS test mode.</entry></row><row><entry>FIRE_GEN</entry><entry>000</entry><entry>0</entry><entry>1</entry><entry>N/A</entry><entry>Fire Initialise mode. The initialised</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry>generator creates the fire pattern</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry>and shift select pattern. The pattern</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry>is clocked into the fire shift register</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry>and select shift register on the rising</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry>edge of phi_frclk</entry></row><row><entry>TEMP_TEST</entry><entry>010</entry><entry>0</entry><entry>0</entry><entry>N/A</entry><entry>Temperature test output.</entry></row><row><entry>NOZZLE_TEST</entry><entry>001</entry><entry>0</entry><entry>0</entry><entry>N/A</entry><entry>Nozzle test output.</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry>The result of a nozzle test is output</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry>on phi_frclk_i.</entry></row><row><entry namest="1" nameend="6" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 32.3 Data Rate Equalization
3680The LLU can generate dot data at the rate of 12 bits per cycle, where a cycle is at the system clock frequency. In order to achieve the target print rate of 30 sheets per minute, the printhead needs to print a line every 100 μs (calculated from 300 mm @ 65.2 dots/mm divided by 2 seconds=˜100 μsec). For a 7:3 constructed printhead this means that 9744 cycles at 320 Mhz is quick enough to transfer the 6-bit dot data (at 2 bits per cycle). The input FIFOs are used to de-couple the read and write clock domains as well as provide for differences between consume and fill rates of the PHI and LLU.
3681Nominally the system clock (pclk) is run at 160 Mhz and the printhead interface clock (doclk) is at 320 Mhz.
3682If the PHI was to transfer data at the full printhead interface rate, the transfer of data to the shorter printhead IC would be completed sooner than the longer printhead IC. While in itself this isn't an issue it requires that the LLU be able to supply data at the maximum rate for short duration, this requires uneven bursty access to DRAM which is undesirable. To smooth the LLU DRAM access requirements over time the PHI transfers dot data to the printhead at a pre-programmed rate, proportional to the ratio of the shorter to longer printhead ICs.
3683The printhead data rate equalization is controlled by PrintheadRate[1:0] registers (one per printhead IC). The register is a 16 bit bitmap of active clock cycles in a 16 clock cycle window. For example if the register is set to 0xFFFF then the output rate to the printhead will be full rate, if it's set to 0xF0F0 then the output rate is 50% where there is 4 active cycles followed by 4 inactive cycles and so on. If the register was set to 0x0000 the rate would be 0%. The relative data transfer rate of the printhead can be varied from 0–100% with a granularity of 1/16 steps.
3684<tables id="TABLE-US-00331" num="00331"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 211</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Example rate equalization values for common printheads</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="70pt" align="center" /><colspec colname="2" colwidth="70pt" align="left" /><colspec colname="3" colwidth="77pt" align="left" /><tbody valign="top"><row><entry>Printhead</entry><entry>Printhead A</entry><entry>Printhead B</entry></row><row><entry>Ratio A:B</entry><entry>rate (%)</entry><entry>rate (%)</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>8:2</entry><entry>0xFFFF (100%)</entry><entry>0x1111 (25%)</entry></row><row><entry>7:3</entry><entry>0xFFFF (100%)</entry><entry>0x5551 (43.7%)</entry></row><row><entry>6:4</entry><entry>0xFFFF (100%)</entry><entry>0xF1F2 (68.7%)</entry></row><row><entry>5:5</entry><entry>0xFFFF (100%)</entry><entry>0xFFFF (100%)</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3685If both printhead ICs are the same size (e.g. a 5:5 printhead) it may be desirable to reduce the data rate to both printhead ICs, to reduce the read bandwidth from the DRAM.
000032.4 Dot Generate and Transmit Order
3686Several printhead types and arrangements exists (see [10] for other arrangements). The PHI is capable of driving all possible configurations, but for the purposes of simplicity only one arrangement (arrangement 1- see [10] for definition) is described in the following examples. The structure of the printhead ICs dictate the dot transmit order to each printhead IC. The PHI accepts two streams of dot data from the LLU, one even stream the other odd. The PHI constructs the dot transmit order streams from the dot generate order received from the LLU. Each stream of data has already been arranged in increasing or decreasing dot order sense by the DWU. The exact sense choice is dependent on the type of printhead ICs used to construct the printhead, but regardless of configuration the odd and even stream should be of opposing sense. The dot transmit order is shown in <figref idref="DRAWINGS">FIG. 281</figref>. Dot data is shifted into the printhead in the direction of the arrow, so from the diagram (taking the type 0 printhead IC) even dot data is transferred in increasing order to the mid point first (0, 2, 4, . . . , m−6, m−4, m−2), then odd dot data in decreasing order is transferred (m−1, m−3, m−5, . . . , 5, 3, 1). For the type 1 printhead IC the order is reversed, with odd dots in increasing order transmitted first, followed by even dot data in decreasing order. Note for any given color the odd and even dot data transferred to the printhead ICs are from different dot lines, in the example in the diagram they are separated by 5 dot lines. Table 212 shows the transmit dot order for some common A4 printheads. Different type printheads may have the sense reversed and may have an odd before even transmit order or vice versa.
3687<tables id="TABLE-US-00332" num="00332"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 212</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Example printhead ICs, and dot data transmit</entry></row><row><entry>order for A4 (13824 dots) page</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="center" /><colspec colname="2" colwidth="28pt" align="center" /><colspec colname="3" colwidth="161pt" align="center" /><tbody valign="top"><row><entry>Size</entry><entry>Dots</entry><entry>Dot Order</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><tbody valign="top"><row><entry>Type 0 Printhead IC</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="28pt" align="char" char="." /><colspec colname="2" colwidth="28pt" align="char" char="." /><colspec colname="3" colwidth="91pt" align="left" /><colspec colname="4" colwidth="70pt" align="left" /><tbody valign="top"><row><entry>8</entry><entry>11160</entry><entry>0, 2, 4, 8 . . . ,</entry><entry>5579, 5577, 5575 . . .</entry></row><row><entry /><entry /><entry>5574, 5576, 5578</entry><entry>7, 5, 3, 1</entry></row><row><entry>7</entry><entry>9744</entry><entry>0, 2, 4, 8 . . . ,</entry><entry>4871, 4869, 4867 . . .</entry></row><row><entry /><entry /><entry>4866, 4868, 4870</entry><entry>7, 5, 3, 1</entry></row><row><entry>6</entry><entry>8328</entry><entry>0, 2, 4, 8 . . . ,</entry><entry>4163, 4161, 4159 . . .</entry></row><row><entry /><entry /><entry>4158, 4160, 4162</entry><entry>7, 5, 3, 1</entry></row><row><entry>5</entry><entry>6912</entry><entry>0, 2, 4, 8 . . . ,</entry><entry>3455, 3453, 3451 . . .</entry></row><row><entry /><entry /><entry>3450, 3452, 3454</entry><entry>7, 5, 3, 1</entry></row><row><entry>4</entry><entry>5496</entry><entry>0, 2, 4, 8 . . . ,</entry><entry>2847, 2845, 2843 . . .</entry></row><row><entry /><entry /><entry>2742, 2744, 2746</entry><entry>7, 5, 3, 1</entry></row><row><entry>3</entry><entry>4080</entry><entry>0, 2, 4, 8 . . . ,</entry><entry>2039, 2037, 2035 . . .</entry></row><row><entry /><entry /><entry>2034, 2036, 2038</entry><entry>7, 5, 3, 1</entry></row><row><entry>2</entry><entry>2664</entry><entry>0, 2, 4, 8 . . . ,</entry><entry>1331, 1329, 1327 . . .</entry></row><row><entry /><entry /><entry>1326, 1328, 1330</entry><entry>7, 5, 3, 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><tbody valign="top"><row><entry>Type 1 Printhead IC</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="28pt" align="char" char="." /><colspec colname="2" colwidth="28pt" align="char" char="." /><colspec colname="3" colwidth="91pt" align="left" /><colspec colname="4" colwidth="70pt" align="left" /><tbody valign="top"><row><entry>8</entry><entry>11160</entry><entry>13823, 13821, 13819 . . . ,</entry><entry>1332, 1334, 1336 . . .</entry></row><row><entry /><entry /><entry>1337, 1335, 1333</entry><entry>13818, 13820, 13822</entry></row><row><entry>7</entry><entry>9744</entry><entry>13823, 13821, 13819 . . . ,</entry><entry>2040, 2042, 2044 . . .</entry></row><row><entry /><entry /><entry>2045, 2043, 2041</entry><entry>13818, 13820, 13822</entry></row><row><entry>6</entry><entry>8328</entry><entry>13823, 13821, 13819 . . . ,</entry><entry>2848, 2850, 2852 . . .</entry></row><row><entry /><entry /><entry>2853, 2851, 2849</entry><entry>13818, 13820, 13822</entry></row><row><entry>5</entry><entry>6912</entry><entry>13823, 13821, 13819 . . . ,</entry><entry>3456, 3458, 3460 . . .</entry></row><row><entry /><entry /><entry>3461, 3459, 3457</entry><entry>13818, 13820, 13822</entry></row><row><entry>4</entry><entry>5496</entry><entry>13823, 13821, 13819 . . . ,</entry><entry>4164, 4166, 4168 . . .</entry></row><row><entry /><entry /><entry>4169, 4167, 4165</entry><entry>13818, 13820, 13822</entry></row><row><entry>3</entry><entry>4080</entry><entry>13823, 13821, 13819 . . . ,</entry><entry>4872, 4874, 4876 . . .</entry></row><row><entry /><entry /><entry>4877, 4875, 4873</entry><entry>13818, 13820, 13822</entry></row><row><entry>2</entry><entry>2664</entry><entry>13823, 13821, 13819 . . . ,</entry><entry>5580, 5582, 5584 . . .</entry></row><row><entry /><entry /><entry>5585, 5583, 5581</entry><entry>13818, 13820, 13822</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 32.4.1 Dual Printhead IC
3688The LLU contains 2 dot generator units. Each dot generator reads dot data from DRAM and generates a stream of dots in increasing or decreasing order. A dot generator can be configured to produce odd or even dot data streams, and the dot sense is also configurable. In <figref idref="DRAWINGS">FIG. 281</figref> the odd dot generator is configured to produce odd dot data in decreasing order and the even dot generator produces dot data in increasing order. The LLU takes care of any vertical misalignment between the 2 printhead ICs, presenting the PHI with the appropriate data ready to be transmitted to the printhead.
3689In order to reconstruct the dot data streams from the generate order to the transmit order, the connection between the generators and transmitters needs to be switched at the mid point. At line start the odd dot generator feeds the type 1 printhead, and the even dot generator feeds the type 0 printhead. This continues until both printheads have received half the number of dots they require (defined as the mid point). The mid point is calculated from the configured printhead size registers (PrintheadSize). Once both printheads have reached the mid point, the PHI switches the connections between the dot generators and the printhead, so now the odd dot generator feeds the type 0 printhead and the even dot generator feeds the type 1 printhead. This continues until the end of the line.
3690It is possible that both printheads will not be the same size and as a result one dot generator may reach the mid point before the other. In such cases the quicker dot generator is stalled until both dot generators reach the mid point, the connections are switched and both dot generators are restarted.
3691Note that in the example shown in <figref idref="DRAWINGS">FIG. 281</figref> the dot generators could generate an A4 line of data in 6912 cycles, but because of the mismatch in the printhead IC sizes the transmit time takes 9744 cycles.
000032.4.2 Single Printhead IC
3692In some cases only one printhead IC may be connected to the PHI. In <figref idref="DRAWINGS">FIG. 282</figref> the dot generate and transmit order is shown for a single IC printhead of 9744 dots width. While the example shows the printhead IC connected to channel A, either channel could be used. The LLU generates odd and even dot streams as normal, it has no knowledge of the physical printhead configuration. The PHI is configured with the printhead size (PrintheadSize[1] register) for channel B set to zero and channel A is set to 9744.
3693Note that in the example shown in <figref idref="DRAWINGS">FIG. 283</figref> the dot generators could generate an 7 inch line of data in 4872 cycles, but because the printhead is using one IC, the transmit time takes 9744 cycles, the same speed as an A4 line with a 7:3 printhead.
000032.4.3 Summary of Generate and Transmit Order Requirements
3694In order to support all the possible printhead arrangements, the PHI (in conjuction with the LLU/DWU) must be capable of re-ordering the bits according to the following criteria: <ul id="ul0366" list-style="none"><li id="ul0366-0001" num="0000"><ul id="ul0367" list-style="none"><li id="ul0367-0001" num="3695">Be able to output the even or odd plane first.</li><li id="ul0367-0002" num="3696">Be able to output even and odd planes independently.</li><li id="ul0367-0003" num="3697">Be able to reverse the sequence in which the color planes of a single dot are output to the printhead. <br /> 32.5 Print Sequence </li></ul></li></ul>
3698The PHI is responsible for accepting dot data streams from the LLU, restructuring the dot data sequence and transferring the dot data to each printhead within a line time (i.e before the next line sync).
3699Before a page can be printed the printhead ICs must be initialized. The exact initialization sequence is configuration dependent, but will involve the fire pattern generation initialization and other optional steps. The initialization sequence is implemented in software.
3700Once the first line of data has been transferred to the printhead, the PHI will interrupt the CPU by asserting the phi_icu_print_rdy signal. The interrupt can be optionally masked in the ICU and the CPU can poll the signal via the PCU or the ICU. The CPU must wait for a print ready signal in all printing SoPECs before starting printing.
3701Once the CPU in the PrintMaster SoPEC is satisfied that printing should start, it triggers the LineSyncMaster SoPEC by writing to the PrintStart register of all printing SoPECs. The transition of the PrintStart register in the LineSyncMaster SoPEC will trigger the start of lsyncl pulse generation. The PrintMaster and LineSyncMaster SoPEC are not necessarily the same device, but often are the same. For a more in depth definition see section 12.1.1 Multi-SoPEC systems on page 105.
3702Writing a 1 to the PrintStart register enables the generation of the line sync in the LineSyncMaster which is in turn used to align all SoPECs in a multi-SoPEC system. All printhead signaling is aligned to the line sync. The PrintStart is only used to align the first line sync in a page.
3703When a SoPEC receives a line sync pulse it means that the line previously transferred to the printhead is now printing, so the PHI can begin to transfer the next line of data to the printhead. When the transfer is complete the PHI will wait for the next line sync pulse before repeating the cycle. If a line sync arrives before a complete line is transferred to the printhead (i.e. a buffer error) the PHI generates a buffer underrun interrupt, and halts the block.
3704For each line in a page the PHI must transfer a full line of data to the printhead before the next line sync is generated or received.
000032.5.1 Sync Pulse Control
3705If the PHI is configured as the LineSyncMaster SoPEC it will start generating line sync signals LsyncPre number of pclk cycles after PrintStart register rising transition is detected. All other signals in the PHI interface are referenced from the rising edge of phi_lsyncl signal.
3706If the SoPEC is in line sync slave mode it will receive a line sync pulse from the LineSyncMaster SoPEC through the phi_lsyncl pin which will be programmed into input mode. The phi_lsyncl input pin is treated as an asynchronous input and is passed through a de-glitch circuit of programmable de-glitch duration (LsyncDeglitchCnt).
3707The phi_lsyncl will remain low for LsyncLow cycles, and then high for LsyncHigh cycles. The phi_lsyncl profile is repeated until the page is complete. The period of the phi_lsyncl is given by LsyncLow+LsyncHigh cycles. Note that the LsyncPre value is only used to vary the time between the generation of the first phi_lsyncl and the PageStart indication from the CPU. See <figref idref="DRAWINGS">FIG. 284</figref> for reference diagram.
3708If the SoPEC device is in line sync slave mode, the LsyncHigh register specifies the minimum allowed phi_lsyncl period. Any phi_lsyncl pulses received before the LsyncHigh has expired will trigger a buffer underrun error.
000032.5.2 Shift Register Signal Control
3709Once the PHI receives the line sync pulse, the sequence of data transfer to the printhead begins. All PHI control signals are specified from the rising edge of the line sync.
3710The phi_srclk (and consequently phi_ph_data) is controlled by the SrclkPre, SrclkPost registers. The SrclkPre specifies the number of pclk cycles to wait before beginning to transfer data to the printhead. Once data transfer has started, the profile of the phi_srclk is controlled by PrintheadRate register and the status of the PHI input FIFO. For example it is possible that the input FIFO could empty and no data would be transferred to the printhead while the PHI was waiting. After all the data for a printhead is transferred to the PHI, it counts SrclkPost number of pclk cycles. If a new phi_lsyncl falling edge arrives before the count is complete the PHI will generate a buffer underrun interrupt (phi_icu_underrun).
000032.5.3 Firing Sequence Signal Control
3711The profile of the phi_frclk pulses per line is determined by 4 registers FrclkPre, FrclkLow, FrclkHigh, FrclkNum. The FrclkPre register specifies the number of cycles between line sync rising edge and the phi_frclk pulse high. It remains high for FrclkHigh cycles and then low for FrclkLow cycles. The number of pulses generated per line is determined by FrclkNum register. The total number of cycles required to complete a firing sequence should be less than the phi_lsyncl period i.e. ((FrclkHigh+FrclkLow)*FrclkNum)+FrclkPre<(LsyncLow+LsyncHigh). Note that when in CPU direct control mode (PrintheadCpuCtrl=1) and PrintheadCpuCtrlMode[x]=1, the frclk generator is triggered by the transition of the FireGenSoftTrigger[0]0 bit from 0 to 1. <figref idref="DRAWINGS">FIG. 284</figref> details the timing parameters controlling the PHI. All timing parameters are measured in number of pclk cycles.
000032.5.4 Page Complete
3712The PHI counts the number of lines processed through the interface. The line count is initialised to the PageLenLine and decrements each time a line is processed. When the line count is zero it pulses the phi icu_page_finish signal. A pulse on the phi_icu_page_finish automatically resets the PHI Go register, and can optionally cause an interrupt to the CPU. Should the page terminate abnormally, i.e. a buffer underrun, the Go register will be reset and an interrupt generated.
000032.5.5 Line Sync Interrupt
3713The PHI will generate an-interrupt to the CPU after a predefined number of line syncs have occured. The number of line syncs to count is configured by the LineSyncInterrupt register. The interrupt can be disabled by setting the register to zero.
000032.6 Dot Line Margin
3714The PHI block allows the generation of margins either side of the received page from the LLU block. This allows the page width used within PEP blocks to differ from the physical printhead size.
3715This allows SoPEC to store data for a page minus the margins, resulting in less storage requirements in the shared DRAM and reduced memory bandwidth requirements. The difference between the dot data line size and the line length generated by the PHI is the dot line margin length. There are two margins specified for any sheet, a margin per printhead IC side.
3716The margin value is set by programming the DotMargin register per printhead IC. It should be noted that the DotMargin register represents half the width of the actual margin (either left or right margin depending on paper flow direction). For example, if the margin in dots is 1 inch (1600 dots), then DotMargin should be set to 800. The reason for this is that the PHI only supports margin creation cases 1 and 3 described below.
3717See example in <figref idref="DRAWINGS">FIG. 284</figref>.
3718In the example the margin for the type 0 printhead IC is set at 100 dots (DotMargin==100), implying an actual margin of 200 dots.
3719If case one is used the PHI takes a total of 9744 phi_srclk cycles to load the dot data into the type 0 printhead. It also requires 9744 dots of data from the LLU which in turn gets read from the DRAM. In this case the first 100 and last 100 dots would be zero but are processed though the SoPEC system consuming memory and DRAM bandwidth at each step.
3720In case 2 the LLU no longer generates the margin dots, the PHI generates the zeroed out dots for the margining. The phi_srclk still needs to toggle 9744 times per line, although the LLU only needs to generate 9544 dots giving the reduction in DRAM storage and associated bandwidth.
3721The case 2 senario is not supported by the PHI because the same effect can be supported by means of case 1 and case 3.
3722If case 3 is used the benefits of case 2 are achieved, but the phi_srclk no longer needs to toggle the full 9744 clock cycles. The phi_srclk cycles count can be reduced by the margin amount (in this case 9744−100=9644 dots), and due to the reduction in phi_srclk cycles the phi_lsyncl period could also be reduced, increasing the line processing rate and consequently increasing print speed. Case 3 works by shifting the odd (or even) dots of a margin from line Y to become the even (or odd) dots of the margin for line Y-4, (Y-5 adjusted due to being printed one line later). This works for all lines with the exception of the first line where there has been no previous line to generate the zeroed out margin. This situation is handled by adding the line reset sequence to the printhead initialization procedure, and is repeated between pages of a document.
000032.7 Dot Counter
3723For each color the PHI keeps a dot usage count for each of the color planes (called AccumDotCount). If a dot is used in particular color plane the corresponding counter is incremented. Each counter is 32 bits wide and saturates if not reset. A write to the DotCountSnap register causes the AccumDotCount[N] values to be transferred to the DotCount[N] registers (where N is 5 to 0, one per color). The AccumDotCount registers are cleared on value transfer.
3724The DotCount[N] registers can be written to or read from by the CPU at any time. On reset the counters are reset to zero.
3725The dot counter only counts dots that are passed from the LLU through the PHI to the printhead.
3726Any dots generated by direct CPU control of the PHI pins will not be counted.
000032.8 CPU IO Control
3727The PHI interface provides a mechanism for the CPU to directly control the PHI interface pins, allowing the CPU to access the bi-lithic printhead: <ul id="ul0368" list-style="none"><li id="ul0368-0001" num="0000"><ul id="ul0369" list-style="none"><li id="ul0369-0001" num="3728">Determine printhead temperature</li><li id="ul0369-0002" num="3729">Test for and determine dead nozzles for each printhead IC</li><li id="ul0369-0003" num="3730">Printhead IC initialization</li><li id="ul0369-0004" num="3731">Printhead pre-heat function</li></ul></li></ul>
3732The CPU can gain direct control of the printhead interface connections by setting the PrintheadCpuCtrl register to one. Once enabled the printhead bits are driven directly by the PrintheadCpuOut control register, where the values in the register are reflected directly on the printhead pins and the status of the printhead input pins can be read directly from the PrintheadCpuIn. The direction of pins is controlled by programming PrintheadCpuDir register.
3733The register to pin mapping is as follows:
3734<tables id="TABLE-US-00333" num="00333"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 213</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>CPU control and status registers mapping to printhead interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="28pt" align="left" /><colspec colname="3" colwidth="112pt" align="left" /><tbody valign="top"><row><entry /><entry>Register Name</entry><entry>bits</entry><entry>Printhead pin</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row><row><entry /><entry>PrintHeadCpuOut</entry><entry>0</entry><entry>phi_lsyncl_o</entry></row><row><entry /><entry /><entry>1</entry><entry>phi_frclk_o</entry></row><row><entry /><entry /><entry>2</entry><entry>Reserved</entry></row><row><entry /><entry /><entry>4:3</entry><entry>phi_ph_data_o[0][1:0]</entry></row><row><entry /><entry /><entry>6:5</entry><entry>phi_ph_data_o[1][1:0]</entry></row><row><entry /><entry /><entry>8:7</entry><entry>phi_srclk[1:0]</entry></row><row><entry /><entry /><entry>9</entry><entry>phi_readl</entry></row><row><entry /><entry>PrintHeadCpuDir</entry><entry>0</entry><entry>phi_lsyncl_e direction control</entry></row><row><entry /><entry /><entry /><entry>1 - output mode</entry></row><row><entry /><entry /><entry /><entry>0 - input mode</entry></row><row><entry /><entry /><entry>1</entry><entry>phi_frclk_e direction control</entry></row><row><entry /><entry /><entry /><entry>1 - output mode</entry></row><row><entry /><entry /><entry /><entry>0 - input mode</entry></row><row><entry /><entry /><entry>2</entry><entry>Reserved</entry></row><row><entry /><entry>PrintHeadCpuIn</entry><entry>0</entry><entry>phi_lsyncl_i</entry></row><row><entry /><entry /><entry>1</entry><entry>phi_frclk_i</entry></row><row><entry /><entry /><entry>2</entry><entry>Reserved</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3735It is important to note that once in PrintheadCpuCtrl mode it is the responsibility of the CPU to drive the printhead correctly and not create situations where the printhead could be destroyed such as activating all nozzles together.
3736The phi_srclk is a double data rate clock (DDR) and as such will clock data on both edges in the printhead.
3737Note the following procedures are based on current printhead capabilities, and are subject to change.
000032.9 Implementation
000032.9.1 Definitions of I/O
3738<tables id="TABLE-US-00334" num="00334"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="294pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 214</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Printhead interface I/O definition</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="175pt" align="left" /><tbody valign="top"><row><entry>Port name</entry><entry>Pins</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="294pt" align="left" /><tbody valign="top"><row><entry>Clocks and Resets</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="175pt" align="left" /><tbody valign="top"><row><entry>Pclk</entry><entry>1</entry><entry>In</entry><entry>System Clock</entry></row><row><entry>Doclk</entry><entry>1</entry><entry>In</entry><entry>Data out clock (2 × pclk) used to transfer data to</entry></row><row><entry /><entry /><entry /><entry>printhead</entry></row><row><entry>prst_n</entry><entry>1</entry><entry>In</entry><entry>System reset, synchronous active low. Synchronous to</entry></row><row><entry /><entry /><entry /><entry>pclk</entry></row><row><entry>dorst_n</entry><entry>1</entry><entry>In</entry><entry>System reset, synchronous active low. Synchronous to</entry></row><row><entry /><entry /><entry /><entry>doclk</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="294pt" align="left" /><tbody valign="top"><row><entry>General</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="175pt" align="left" /><tbody valign="top"><row><entry>phi_icu_print_rdy</entry><entry>1</entry><entry>Out</entry><entry>Indicates that the first line of data is transferred to the</entry></row><row><entry /><entry /><entry /><entry>printhead Active high.</entry></row><row><entry>phi_icu_page_finish</entry><entry>1</entry><entry>Out</entry><entry>Indicates that data for a complete page has transferred.</entry></row><row><entry /><entry /><entry /><entry>Active high</entry></row><row><entry>phi_icu_underrun</entry><entry>1</entry><entry>Out</entry><entry>Indicates the PHI has detected a buffer underrun. Active</entry></row><row><entry /><entry /><entry /><entry>high</entry></row><row><entry>phi_icu_linesync_int</entry><entry>1</entry><entry>Out</entry><entry>Indicates the PHI has detected LineSyncInterrupt</entry></row><row><entry /><entry /><entry /><entry>number of line syncs.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="294pt" align="left" /><tbody valign="top"><row><entry>Debug</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="175pt" align="left" /><tbody valign="top"><row><entry>debug_data_valid</entry><entry>1</entry><entry>In</entry><entry>Output debug data valid to be muxed on to the PHI pin</entry></row><row><entry>debug_cntrl</entry><entry>1</entry><entry>In</entry><entry>Control signal for the PHI to indicate whether or not the</entry></row><row><entry /><entry /><entry /><entry>debug data valid (and pclk) should be selected by the</entry></row><row><entry /><entry /><entry /><entry>pin mux. Active high.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="294pt" align="left" /><tbody valign="top"><row><entry>LLU Interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="175pt" align="left" /><tbody valign="top"><row><entry>llu_phi_data[1:0][5:0]</entry><entry>2 × 6</entry><entry>In</entry><entry>Dot Data from LLU to the PHI, each bit is a color plane</entry></row><row><entry /><entry /><entry /><entry>5 down to 0.</entry></row><row><entry /><entry /><entry /><entry>Bus 0 - Even dot data stream</entry></row><row><entry /><entry /><entry /><entry>Bus 1 - Odd dot data stream</entry></row><row><entry /><entry /><entry /><entry>Data is active when corresponding bit is active in</entry></row><row><entry /><entry /><entry /><entry>llu_phi_avail bus</entry></row><row><entry>phi_llu_ready[1:0]</entry><entry>2</entry><entry>Out</entry><entry>Indicates that PHI is ready to accept data from the LLU</entry></row><row><entry /><entry /><entry /><entry>0 - Even dot data stream</entry></row><row><entry /><entry /><entry /><entry>1 - Odd dot data stream</entry></row><row><entry>llu_phi_avail[1:0]</entry><entry>2</entry><entry>In</entry><entry>Indicates valid data present on corresponding</entry></row><row><entry /><entry /><entry /><entry>llu_phi_data.</entry></row><row><entry /><entry /><entry /><entry>0 - Even dot data stream</entry></row><row><entry /><entry /><entry /><entry>1 - Odd dot data stream</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="294pt" align="left" /><tbody valign="top"><row><entry>Printhead Interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="175pt" align="left" /><tbody valign="top"><row><entry>phi_ph_data[1:0][1:0]</entry><entry>2 × 2</entry><entry>Out</entry><entry>Dot data output to printhead. Each bus to each</entry></row><row><entry /><entry /><entry /><entry>printhead contains 2 bits of data</entry></row><row><entry /><entry /><entry /><entry>Bus 0 - Printhead channel A</entry></row><row><entry /><entry /><entry /><entry>Bus 1 - Printhead channel B</entry></row><row><entry>phi_srclk[1:0]</entry><entry>2</entry><entry>Out</entry><entry>Dot data shift clock used to clock in printhead data, data</entry></row><row><entry /><entry /><entry /><entry>is shifted on both edges of clock(i.e. double data rate</entry></row><row><entry /><entry /><entry /><entry>DDR).</entry></row><row><entry /><entry /><entry /><entry>Bus 0 - Printhead channel A</entry></row><row><entry /><entry /><entry /><entry>Bus 1 - Printhead channel B</entry></row><row><entry>phi_readl</entry><entry>1</entry><entry>Out</entry><entry>Common printhead mode control. Used in conjunction</entry></row><row><entry /><entry /><entry /><entry>with phi_lsyncl to determine the printhead mode</entry></row><row><entry /><entry /><entry /><entry>0 - SoPEC receiving, printhead driving</entry></row><row><entry /><entry /><entry /><entry>1 - SoPEC driving, printhead receiving</entry></row><row><entry>phi_frclk_o</entry><entry>1</entry><entry>Out</entry><entry>Common Fire pattern clock needs to toggle once per</entry></row><row><entry /><entry /><entry /><entry>fire cycle</entry></row><row><entry>phi_frclk_e</entry><entry>1</entry><entry>In</entry><entry>phi_frclk_o output enable, when high phi_frclk_o pin is</entry></row><row><entry /><entry /><entry /><entry>driving</entry></row><row><entry>phi_frclk_l</entry><entry>1</entry><entry>In</entry><entry>phi_frclk_i input from printhead</entry></row><row><entry>phi_lsyncl_o</entry><entry>1</entry><entry>Out</entry><entry>Capture dot data for next print line, output mode</entry></row><row><entry>phi_lsyncl_e</entry><entry>1</entry><entry>In</entry><entry>phi_lsyncl output enable, when high phi_lsyncl pin is</entry></row><row><entry /><entry /><entry /><entry>driving</entry></row><row><entry>phi_lsyncl_i</entry><entry>1</entry><entry>In</entry><entry>Line Sync Pulse from Master SoPEC</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="294pt" align="left" /><tbody valign="top"><row><entry>PCU Interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="175pt" align="left" /><tbody valign="top"><row><entry>pcu_phi_sel</entry><entry>1</entry><entry>In</entry><entry>Block select from the PCU. When pcu_phi_sel is high</entry></row><row><entry /><entry /><entry /><entry>both pcu_adr and pcu_dataout are valid.</entry></row><row><entry>pcu_rwn</entry><entry>1</entry><entry>In</entry><entry>Common read/not-write signal from the PCU.</entry></row><row><entry>pcu_adr[7:2]</entry><entry>6</entry><entry>In</entry><entry>PCU address bus. Only 6 bits are required to decode</entry></row><row><entry /><entry /><entry /><entry>the address space for this block.</entry></row><row><entry>pcu_dataout[31:0]</entry><entry>32</entry><entry>In</entry><entry>Shared write data bus from the PCU.</entry></row><row><entry>phi_pcu_rdy</entry><entry>1</entry><entry>Out</entry><entry>Ready signal to the PCU. When phi_pcu_rdy is high it</entry></row><row><entry /><entry /><entry /><entry>indicates the last cycle of the access. For a write cycle</entry></row><row><entry /><entry /><entry /><entry>this means pcu_dataout has been registered by the</entry></row><row><entry /><entry /><entry /><entry>block and for a read cycle this means the data on</entry></row><row><entry /><entry /><entry /><entry>phi_pcu_datain is valid.</entry></row><row><entry>phi_pcu_datain[31:0]</entry><entry>32</entry><entry>Out</entry><entry>Read data bus to the PCU.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 32.9.2 PHI Sub-block Partition <br /> 32.9.3 Configuration Registers
3739The configuration registers in the PHI are programmed via the PCU interface. Refer to section 21.8.2 on page 321 for a description of the protocol and timing diagrams for reading and writing registers in the PHI. Note that since addresses in SoPEC are byte aligned and the PCU only supports 32-bit register reads and writes, the lower 2 bits of the PCU address bus are not required to decode the address space for the PHI. When reading a register that is less than 32 bits wide zeros should be returned on the upper unused bit(s) of phi_pcu_datain. Table 215 lists the configuration registers in the PHI
3740<tables id="TABLE-US-00335" num="00335"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="329pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 215</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>PHI registers description</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="28pt" align="center" /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="133pt" align="left" /><tbody valign="top"><row><entry>Address</entry><entry /><entry /><entry /><entry /></row><row><entry>PHI_base+</entry><entry>Register</entry><entry>#bits</entry><entry>Reset</entry><entry>Description</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="329pt" align="left" /><tbody valign="top"><row><entry>Control Registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="133pt" align="left" /><tbody valign="top"><row><entry>0x00</entry><entry>Reset</entry><entry>1</entry><entry>0x1</entry><entry>Active low synchronous reset, self de-</entry></row><row><entry /><entry /><entry /><entry /><entry>activating. A write to this register will</entry></row><row><entry /><entry /><entry /><entry /><entry>cause a PHI block reset.</entry></row><row><entry>0x04</entry><entry>Go</entry><entry>1</entry><entry>0x0</entry><entry>Active high bit indicating the PHI is</entry></row><row><entry /><entry /><entry /><entry /><entry>programmed and ready to use. A low</entry></row><row><entry /><entry /><entry /><entry /><entry>to high transition will cause PHI block</entry></row><row><entry /><entry /><entry /><entry /><entry>internal state to reset. Will be</entry></row><row><entry /><entry /><entry /><entry /><entry>automatically reset if a page finish or a</entry></row><row><entry /><entry /><entry /><entry /><entry>buffer underrun is detected.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="329pt" align="left" /><tbody valign="top"><row><entry>General Control</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="133pt" align="left" /><tbody valign="top"><row><entry>0x08</entry><entry>PageLenLine</entry><entry>32</entry><entry>0x0000_0000</entry><entry>Specifies the number of dot lines in a</entry></row><row><entry /><entry /><entry /><entry /><entry>page.</entry></row><row><entry /><entry /><entry /><entry /><entry>Indicates the number of lines left to</entry></row><row><entry /><entry /><entry /><entry /><entry>process in this page while the PHI is</entry></row><row><entry /><entry /><entry /><entry /><entry>running (Working register)</entry></row><row><entry>0x0c</entry><entry>PrintStart</entry><entry>1</entry><entry>0x0</entry><entry>A high level enables printing to start</entry></row><row><entry /><entry /><entry /><entry /><entry>via the generation of line syncs in a</entry></row><row><entry /><entry /><entry /><entry /><entry>master, and acceptance of line syncs</entry></row><row><entry /><entry /><entry /><entry /><entry>in a slave. Can be set in advance of</entry></row><row><entry /><entry /><entry /><entry /><entry>the print ready signal.</entry></row><row><entry>0x10–0x14</entry><entry>DotMargin[1:0]</entry><entry>2 × 16</entry><entry>0x0000</entry><entry>Specifies for each printhead IC, the</entry></row><row><entry /><entry /><entry /><entry /><entry>width of the margin in dots divided by</entry></row><row><entry /><entry /><entry /><entry /><entry>2.</entry></row><row><entry /><entry /><entry /><entry /><entry>Value must be divisible by 2 (i.e. the</entry></row><row><entry /><entry /><entry /><entry /><entry>low bit must be 0)</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - Printhead IC Channel A</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - Printhead IC Channel B</entry></row><row><entry>0x18–0x2C</entry><entry>DotCount[5:0]</entry><entry>6 × 32</entry><entry>0x0000_0000</entry><entry>Indicates the number of Dots used for</entry></row><row><entry /><entry /><entry /><entry /><entry>a particular color, where N specifies a</entry></row><row><entry /><entry /><entry /><entry /><entry>color from 0 to 5. Value valid after a</entry></row><row><entry /><entry /><entry /><entry /><entry>write access to DotCountSnap</entry></row><row><entry>0x30</entry><entry>DotCountSnap</entry><entry>1</entry><entry>0x0</entry><entry>Write access causes the</entry></row><row><entry /><entry /><entry /><entry /><entry>AccumDotCount values to be</entry></row><row><entry /><entry /><entry /><entry /><entry>transferred to the DotCount registers.</entry></row><row><entry /><entry /><entry /><entry /><entry>The AccumDotCount are reset</entry></row><row><entry /><entry /><entry /><entry /><entry>afterwards.(Reads as zero)</entry></row><row><entry>0x34</entry><entry>PhiHeadSwap</entry><entry>1</entry><entry>0x0</entry><entry>Controls which signals are connected</entry></row><row><entry /><entry /><entry /><entry /><entry>to printhead channels A and B</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - Normal, specifies bit 0 is channel A,</entry></row><row><entry /><entry /><entry /><entry /><entry>bit 1 is channel B</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - Swapped, specifies bit 0 is channel</entry></row><row><entry /><entry /><entry /><entry /><entry>B, bit 1 is channel A.</entry></row><row><entry>0x38</entry><entry>PhiMode</entry><entry>1</entry><entry>0x0</entry><entry>Indicates whether the PHI is operating</entry></row><row><entry /><entry /><entry /><entry /><entry>in master or slave mode</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - Slave Mode</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - Master Mode</entry></row><row><entry>0x3C–0x40</entry><entry>PhiSerialOrder</entry><entry>2 × 1 </entry><entry>0x0</entry><entry>Specifies the serialization order of dots</entry></row><row><entry /><entry /><entry /><entry /><entry>before transfer to the printhead.</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 0 - Printhead Channel A</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 1 - Printhead Channel B</entry></row><row><entry /><entry /><entry /><entry /><entry>If set to zero the order is dot[1:0], then</entry></row><row><entry /><entry /><entry /><entry /><entry>dot[3:2] then dot[5:4]. If set to one then</entry></row><row><entry /><entry /><entry /><entry /><entry>the order is dot[5:4], dot[3:2], dot[1:0].</entry></row><row><entry>0x44–0x48</entry><entry>PrintHeadSize</entry><entry>2 × 16</entry><entry>0x0000</entry><entry>Specifies the number of non-margin</entry></row><row><entry /><entry /><entry /><entry /><entry>dots in the printhead ICs (must be</entry></row><row><entry /><entry /><entry /><entry /><entry>even). If margining is to be used then</entry></row><row><entry /><entry /><entry /><entry /><entry>the configured PrintHeadSize should</entry></row><row><entry /><entry /><entry /><entry /><entry>be adjusted by the dot margin value</entry></row><row><entry /><entry /><entry /><entry /><entry>i.e. PrintHeadSize = (Physical-</entry></row><row><entry /><entry /><entry /><entry /><entry>PrintHeadSize − (DotMargin * 2)).</entry></row><row><entry /><entry /><entry /><entry /><entry>Value must be divisible by 2 (i.e. the</entry></row><row><entry /><entry /><entry /><entry /><entry>low bit must be 0)</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 0 - Specifies printhead on</entry></row><row><entry /><entry /><entry /><entry /><entry>Channel A</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 1 - Specifies printhead on</entry></row><row><entry /><entry /><entry /><entry /><entry>Channel B</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="329pt" align="left" /><tbody valign="top"><row><entry>CPU Direct PHI Control (See Table 213.)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="133pt" align="left" /><tbody valign="top"><row><entry>0x4C</entry><entry>PrintHeadCpuln</entry><entry>3</entry><entry>0x0</entry><entry>PHI interface pins input status. Only</entry></row><row><entry /><entry /><entry /><entry /><entry>active in direct CPU mode (Read Only</entry></row><row><entry /><entry /><entry /><entry /><entry>Register)</entry></row><row><entry>0x50</entry><entry>PrintHeadCpuDir</entry><entry>3</entry><entry>0x0</entry><entry>PHI interface pins direction control.</entry></row><row><entry /><entry /><entry /><entry /><entry>Only active in direct CPU mode</entry></row><row><entry>0x54</entry><entry>PrintHeadCpuOut</entry><entry>10</entry><entry>0x000</entry><entry>PHI interface pins output control. Only</entry></row><row><entry /><entry /><entry /><entry /><entry>active in direct CPU mode</entry></row><row><entry>0x58</entry><entry>PrintHeadCpuCtrl</entry><entry>1</entry><entry>0x1</entry><entry>Control direct access CPU access to</entry></row><row><entry /><entry /><entry /><entry /><entry>the PHI pins</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - Normal Mode</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - Direct CPU Control mode</entry></row><row><entry>0x5C</entry><entry>Print-HeadCpuCtrlMode</entry><entry>1</entry><entry>0x0</entry><entry>Specifies if the pin is controlled by the</entry></row><row><entry /><entry /><entry /><entry /><entry>PrintHeadCpuOut register or by the</entry></row><row><entry /><entry /><entry /><entry /><entry>Fire generator logic. Only active when</entry></row><row><entry /><entry /><entry /><entry /><entry>PrintHeadCpuCtrl is 1 and pin is in</entry></row><row><entry /><entry /><entry /><entry /><entry>output mode.</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 0 - controls the frclk pin</entry></row><row><entry /><entry /><entry /><entry /><entry>When the bit is</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - Pin is controlled by PrintHeadCpuOut</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - Pin is controlled by Fire Generator Logic</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="329pt" align="left" /><tbody valign="top"><row><entry>Line Sync Control</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="133pt" align="left" /><tbody valign="top"><row><entry>0x60</entry><entry>LsyncHigh</entry><entry>24</entry><entry>0x00_0000</entry><entry>In Master mode specifies the number</entry></row><row><entry /><entry /><entry /><entry /><entry>of pclk cycles phi_lsyncl should remain</entry></row><row><entry /><entry /><entry /><entry /><entry>high.</entry></row><row><entry /><entry /><entry /><entry /><entry>In Slave mode specifies the minimum</entry></row><row><entry /><entry /><entry /><entry /><entry>number of pclk cycles between Lsync</entry></row><row><entry /><entry /><entry /><entry /><entry>pulses. Lsync pulses of a shorter</entry></row><row><entry /><entry /><entry /><entry /><entry>period will cause the PHI to halt due to</entry></row><row><entry /><entry /><entry /><entry /><entry>buffer underrun.</entry></row><row><entry>0x64</entry><entry>LsyncLow</entry><entry>16</entry><entry>0x0000</entry><entry>Number of pclk cycles phi_lsyncl</entry></row><row><entry /><entry /><entry /><entry /><entry>should remain low.</entry></row><row><entry>0x68</entry><entry>LsyncPre</entry><entry>16</entry><entry>0x0000</entry><entry>Number of pclk cycles between</entry></row><row><entry /><entry /><entry /><entry /><entry>PrintStart rising transition and the</entry></row><row><entry /><entry /><entry /><entry /><entry>generated phi_lsyncl falling edge</entry></row><row><entry>0x6C</entry><entry>LsyncDeglitchCnt</entry><entry>4</entry><entry>0x3</entry><entry>Number of pclk cycles to filter the</entry></row><row><entry /><entry /><entry /><entry /><entry>incoming Lsync pulse from the master.</entry></row><row><entry /><entry /><entry /><entry /><entry>Only used in slave mode.</entry></row><row><entry>0x70</entry><entry>LineSyncInterrupt</entry><entry>16</entry><entry>0x0000</entry><entry>Number of line syncs to occur before</entry></row><row><entry /><entry /><entry /><entry /><entry>generating an interrupt. When set to</entry></row><row><entry /><entry /><entry /><entry /><entry>zero interrupt is disabled.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="329pt" align="left" /><tbody valign="top"><row><entry>Shift Register Control</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="133pt" align="left" /><tbody valign="top"><row><entry>0x74</entry><entry>SrclkPre</entry><entry>14</entry><entry>0x0000</entry><entry>Number of pclk cycles between</entry></row><row><entry /><entry /><entry /><entry /><entry>phi_lsyncl falling edge and phi_srclk</entry></row><row><entry /><entry /><entry /><entry /><entry>pulse generation, or printhead data</entry></row><row><entry /><entry /><entry /><entry /><entry>transfer</entry></row><row><entry>0x78</entry><entry>SrclkPost</entry><entry>14</entry><entry>0x0000</entry><entry>Number of pclk cycles allowed margin</entry></row><row><entry /><entry /><entry /><entry /><entry>from last srclk pulse in a line to before</entry></row><row><entry /><entry /><entry /><entry /><entry>next line sync</entry></row><row><entry>0x7C–0x80</entry><entry>PrintHeadRate[1:0]</entry><entry>2 × 16</entry><entry>0xFFFF</entry><entry>Specifies the active to inactive ratio of</entry></row><row><entry /><entry /><entry /><entry /><entry>phi_srclk for the printhead ICs. A 1</entry></row><row><entry /><entry /><entry /><entry /><entry>indicates Active.</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 0 - Printhead IC channel A</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 1 - Printhead IC channel B</entry></row><row><entry>0x84</entry><entry>DotOrderMode</entry><entry>1</entry><entry>0x0</entry><entry>Specifies the dot transmit order to the</entry></row><row><entry /><entry /><entry /><entry /><entry>printhead Channel A. Printhead</entry></row><row><entry /><entry /><entry /><entry /><entry>Channel B is always the opposing</entry></row><row><entry /><entry /><entry /><entry /><entry>order.</entry></row><row><entry /><entry /><entry /><entry /><entry>0 - Even before Odd dots</entry></row><row><entry /><entry /><entry /><entry /><entry>1 - Odd before Even dots</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="329pt" align="left" /><tbody valign="top"><row><entry>Fire Control</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="133pt" align="left" /><tbody valign="top"><row><entry>0x98</entry><entry>FrclkPre</entry><entry>14</entry><entry>0x0000</entry><entry>Number of pclk cycles after lsyncl</entry></row><row><entry /><entry /><entry /><entry /><entry>transitions from 0 to 1 to phi_frclk</entry></row><row><entry /><entry /><entry /><entry /><entry>pulse generation</entry></row><row><entry>0x9C</entry><entry>FrclkLow</entry><entry>14</entry><entry>0x0000</entry><entry>Number of pclk cycles phi_frclk should</entry></row><row><entry /><entry /><entry /><entry /><entry>remain low.</entry></row><row><entry>0xA0</entry><entry>FrclkHigh</entry><entry>14</entry><entry>0x0000</entry><entry>Number of pclk cycles phi_frclk should</entry></row><row><entry /><entry /><entry /><entry /><entry>remain high.</entry></row><row><entry>0xA4</entry><entry>FrclkNum</entry><entry>16</entry><entry>0x0000</entry><entry>Number of phi_frclk pulses per line</entry></row><row><entry /><entry /><entry /><entry /><entry>time.</entry></row><row><entry>0xA8</entry><entry>FireGenSoftTrigger</entry><entry>1</entry><entry>0x0</entry><entry>Only active when</entry></row><row><entry /><entry /><entry /><entry /><entry>PrintHeadCpuCtrlMode is set to 1,</entry></row><row><entry /><entry /><entry /><entry /><entry>PrintHeadCpuCtrl is 1 and pin is in</entry></row><row><entry /><entry /><entry /><entry /><entry>output mode.</entry></row><row><entry /><entry /><entry /><entry /><entry>Bit 0 controls frclk generator.</entry></row><row><entry /><entry /><entry /><entry /><entry>A 0 to 1 transition on a bit triggers the</entry></row><row><entry /><entry /><entry /><entry /><entry>corresponding generator to create the</entry></row><row><entry /><entry /><entry /><entry /><entry>programmed pulse profile (configured</entry></row><row><entry /><entry /><entry /><entry /><entry>by</entry></row><row><entry /><entry /><entry /><entry /><entry>FrclkNum, FrclkHigh, FrclkLow, FrclkPre</entry></row><row><entry /><entry /><entry /><entry /><entry>registers) when complete the bit gets</entry></row><row><entry /><entry /><entry /><entry /><entry>reset to 0.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="329pt" align="left" /><tbody valign="top"><row><entry>Working Registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="28pt" align="center" /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="133pt" align="left" /><tbody valign="top"><row><entry>0xAC–0xB0</entry><entry>LineDotCnt</entry><entry>2 × 16</entry><entry>0x0000</entry><entry>Indicates the number of dot processed</entry></row><row><entry /><entry /><entry /><entry /><entry>in the current line</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 0 - Printhead Channel A</entry></row><row><entry /><entry /><entry /><entry /><entry>Bus 1 - Printhead Channel B</entry></row><row><entry /><entry /><entry /><entry /><entry>(Read Only Registers)</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3741The configuration registers in the PHI block are clocked at pclk rates but some blocks in the PHI are clocked by different and asynchronous clocks. Configuration values are not re-synchronized, it is therefore important that the Go register be set to zero while updating configuration values. This prevents logic from entering unknown states due to metastable clock domain transfers.
3742Some registers can be written to at any time such as the direct CPU control registers (PrintheadCpuIn, PrintheadCpuDir, PrintheadCpuOut and PrintheadCpuCtrl), the Go register and the PrintStart register. All registers can be read from at any time.
000032.9.4 Dot Counter
3743The dot counter keeps a running count of the number of dots fired for each color plane. The counters are 32 bits wide and will saturate. When the CPU wants to read the dot count for a particular color plane it must write to the DotCountSnap register. This causes all 6 running counter values to be transferred to the DotCount registers in the configuration registers block. The running counter values are reset.
3744<tables id="TABLE-US-00336" num="00336"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>// reset if being snapped</entry></row><row><entry>if (dot_cnt_snap = = 1) then{</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="105pt" align="left" /><colspec colname="2" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry>dot_count[5:0]</entry><entry>= accum_dot_count[5:0]</entry></row><row><entry /><entry>accum_dot_count[5:0]</entry><entry>= 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>}</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>// update the counts</entry></row><row><entry>for (color=0;color < 6;color++) {</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>if (accum_dot_count[color] != 0xffff_ffff) {</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>// data valid, first dot stream</entry></row><row><entry /><entry>data_valid = ((phi_llu_ready[0] = = 1) AND</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>(llu_phi_avail[0] = = 1))</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>if ((data_valid = = 1) AND (llu_phi_data[0][color] = =</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>1)) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>accum_dot_count[color] ++</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>// data valid, second dot stream</entry></row><row><entry /><entry>data_valid = ((phi_llu_ready[1] = = 1) AND</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>(llu_phi_avail[1] = = 1))</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>if ((data_valid = = 1) AND (llu_phi_data[1][color] = =</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>1)) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>accum_dot_count[color] ++</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>}</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>}</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 32.9.5 Sync Generator
3745The sync generator logic has two modes of operation, master and slave mode. In master mode (configured by the PhiMode register) it generates the lsyncl_o output based on configured values and control triggers from the PHI controller. In slave mode it de-glitches the incoming lsyncl_i signal, and filters the lsyncl signal with the minimum configured period.
3746After reset or a pulse on phi_go_pulse the machine returns to the Reset state, regardless of what state it's currently in.
3747The state machine waits until it's enabled (sync_en==1) by the PHI controller state machine. When enabled it can proceed to the SyncPre or SyncWait depending on whether the state machine is configured in master or slave mode. In master mode it generates the lsyncl pulses, in slave mode it receives and filters the lsyncl pulses from the master sync generator.
3748On transition to the SyncPre state a counter is loaded with the LsyncPre value, and while in the SyncPre the counter is decremented. When the count is zero the machine proceeds to the SyncLow state loading the counter with LsyncLow value.
3749The machine waits in the SyncLow state until the counter has decremented to zero. It proceeds to the SyncHigh state pulsing the line_st signal on transition and counts LsyncHigh number of cycles. This indicates to the PHI controller the line start aligned to the lsyncl positive edge. While in LsyncLow state the lsyncl_o output is set to 0 and in SyncHigh the lsyncl_o output is set to 1. When the count is zero and the current line is not the last (last_line==0), the machine returns to the SyncLow state to begin generating a new line sync pulse. The transition pulses the line_fin signal to the PHI controller.
3750The loop is repeated until the current line is the last (last_line==1), and the machine returns to the Reset state to wait for the next page start.
3751In slave mode the state machine proceeds to the SyncWait state when enabled. It waits in this state until a-lsync_pulse_rise is received from the input de-glitch circuit. When a pulse is detected the machine jumps to the SyncPeriod state and begins counting down the LsyncHigh number of clock cycles before returning to the SyncWait state. Note in slave mode the LsyncHigh specifies the minimum number of pclk cycles between Lsync pulses. On transition from the SyncWait to the SyncPeriod state the line_st signal to the PHI controller is pulsed to indicate the line start. While in the SyncPeriod state if a lsync_pulse_fall is detected the state machine will signal a sync error (via sync_err) to the PHI controller and cause a buffer underrun interrupt.
000032.9.5.1 Lsyncl Input De-glitch
3752The lsync_i input is considered an asynchronous input to the PHI, and is passed through a synchronizer to reduce the possibility of metastable states occurring before being passed to the de-glitch logic.
3753The input de-glitch logic rejects input states of duration less than the configured number of clock cycles (lsync_deglitch_cnt), input states of greater duration are reflected on the output, and are negative and positive edge detected to produce the lsync_pulse_fall and lsync_pulse_rise signal to the main generator state machine. The counter logic is given by
3754<tables id="TABLE-US-00337" num="00337"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>if ( lsync_i != lsync_i_delay) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="112pt" align="left" /><tbody valign="top"><row><entry /><entry>cnt</entry><entry>= lsync_deglitch_cnt</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>output_en = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (cnt = = 0 ) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="112pt" align="left" /><tbody valign="top"><row><entry /><entry>cnt</entry><entry>= cnt</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>output_en = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>cnt − −</entry></row><row><entry /><entry>output_en = 0</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 32.9.5.2 Line Sync Interrupt Logic
3755The line sync interrupt logic counts the number of line syncs that occur (either internally or externally generated line syncs) and determines whether to generate an interrupt or not. The number of line syncs it counts before an interrupt is generated is configured by the LineSyncInterrupt register. The interrupt is disabled if LineSyncInterrupt is set to zero.
3756<tables id="TABLE-US-00338" num="00338"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>// implement the interrupt counter</entry></row><row><entry /><entry>if (phi_go_pulse = =1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>line_count = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif (line_st = = 1) AND (line_count = = 0)) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>line_count = linecount_int</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif ((line_st = = 1) AND (line_count != 0)) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>line_count − −</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>// determine when to pulse the interrupt</entry></row><row><entry /><entry>if (linesync_int = = 0 ) then // interrupt disabled</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>phi_icu_linesync_int = 0;</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif ((line_st = = 1) AND (line_count = = 1)) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>phi_icu_linesync_int = 1</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 32.9.6 Fire Generator
3757The fire generator block creates the signal profile for the phi_frclk signal to the printhead. The frclk is based on configured values and is timed in relation to the fire_st pulse from the PHI controller block. Should the phi_frclk state machine receive a fire_st pulse before it has completed the sequence the machine will restart regardless of its current state.
3758Alternatively the frclk state machine can be triggered to generate their configured pulse profile by software. A low to high transition on the FireGenSoftTrigger register will cause a pulse on soft_frclk_st triggering the state machine to begin generating the pulse profile. When the state machine has completed its sequence it will clear the FireGenSoftTrigger register bit (via soft_fire_clr signal). The FireGenSoftTrigger register will only be active when the printhead interface is in CPU direct control mode (PrintheadCpuCtrl=1), the fire generator is in software trigger mode (PrintheadCpuCtrlMode[x]=1) and the pin is configured to be output mode (PrintheadCpuDir[x]=1).
3759The fire generator consists of a state machine for creating the phi_frclk signal. The phi_frclk signal is generated relative to the lsyncl signal.
3760The machine is reset to the Reset state when phi_go_pulse==1 or the reset is active, regardless of the current state.
3761The machine waits in the reset state until it receives a fire_st pulse from the PHI controller (or an soft_fire_st from the configuration registers). The controller will generate a fire_st pulse at the beginning of each dot line. On the state transition the cycle counter is loaded with the FrclkPre value and the repeat counter is loaded with the FrclkNum value.
3762The state machine waits in the FirePre state until the cycle counter is zero, after which it jumps to the FireHigh state and loads the cycle counter with FrclkHigh value. Again the state machine waits until the count is zero and then proceeds to the FireLow state. On transition the cycle counter is loaded with the FireLow value. The state machine waits in the FireLow state while the cycle counter is decremented.
3763When the cycle counter reaches zero and the repeat_count is non-zero, the repeat_count is decremented, the cycle counter is loaded with the FrclkHigh value and the state machine jumps to the FireHigh state to repeat the phi_frclk generation cycle. The loop is repeated until the repeat_count is zero. In such cases_the state machine goes to the reset state resetting FireGenSoftTrigger (via the soft_fire_clr signal) register on the transition and waits for the next fire_st pulse.
3764When in the Reset state the fire_rdy signal is active to indicate to the controller that the fire generator is ready.
000032.9.7 PHI Controller
3765The PHI controller is responsible for controlling all functions of the PHI block on a line by line basis. It controls and synchronizes the sync generator, the fire generator, and datapath unit, as well as signalling back to the CPU the PHI status. It also contains a line counter to determine when a full page has completed printing.
3766The PHI controller state machine is reset to Reset state by a reset or phi_go_pulse==1.
3767It will remain in reset until the block is enabled by phi_go==1. Once enabled the state machine will jump to the FirstLine state, trigger the transfer of one line of data to the printhead (data_st==1) and the line counter will be initialized to the page length (PageLenLine). Once the line is transferred (data_fin from the datapath unit) the machine will go to PrintStart state and signal the CPU using an interrupt that the PHI is ready to begin printing (phi_icu_print_rdy). The line counter will also be decremented. It will then wait in the PrintStart state until the CPU acknowledges the print ready signal and enables printing by writing to the PrintStart register.
3768The state machine proceeds to the SyncWait state and waits for a line start condition (line_st==1). The line start condition is different depending on whether the PHI is configured as being in a master or slave SoPEC (the PhiMode register). In either case the sync generator determines the correct line start source and signals the PHI controller via the line_st signal. Once received the machine proceeds to the LineTrans state, with the transition triggering the fire generator to start (fire_st), the datapath unit to start (data_st) and the sync generator to start (sync_st).
3769While in the LineTrans state the fire, sync and datapath unit will be producing line data. When finished processing a line the datapath unit will assert the line finished (data_fin) signal. If the line counter is not equal to 1 (i.e. not the last line) the state machine will jump back to the SyncWait state and wait for the start condition for the next line. The line counter will be decremented. If the line counter is one then the machine will proceed to the LastLine state.
3770The LastLine state generates one more line of fire pulses to print the last line held in the shift registers of the printhead. Once complete (fire_fin==1) the state machine returns to the reset state and waits for the next page of data. On page completion the state machine generates a phi_icu_page_finish interrupt to signal to the CPU that the page has completed, the phi_icu_page_finish will also cause the Go register to reset automatically.
3771While the state machine is in the LineTrans state (or in FirstLine state and the PHI is in slave mode) and waiting for the datapath unit to complete line processing, it is possible (e.g. an excessive PEP stall) that a line finish condition occurs (line_fin==1) but the datapath unit is not ready. In this case an underrun error is generated. The state machine goes to the Underrun state and generates a phi_icu_underrun interrupt to the CPU. The PHI cannot recover from a buffer underrun error, the CPU must reset the PEP blocks and re-start printing. The phi_icu_underrun will also cause the Go register to reset automatically.
000032.9.8 CPU IO Control
3772The CPU IO control block is responsible for providing direct CPU control of the IO pins via the configuration registers. It also accepts the input signals from the printhead and re-synchronizes them to the pclk domain, and debug signals from the RDU and muxes them to output pins. Table contains the direct mapping of configuration registers to printhead IO pins. Direct CPU control is enabled only when PrintheadCpuCtrl is set to one. In normal operation (i.e. PrintheadCpuCtrl==0) the printhead frclk pin is always in output mode (phi_frclk_e=1), the phi_lsyncl will be in output if the SoPEC is the master, i.e. phi_lsyncl_e=phi_mode, and readl will be set high.
3773The PrintheadCpuCtrlMode register determine whether the frclk pin should be driven by the fire generator logic or direct from the CPU PrintheadCpuOut register.
3774The pseudocode for the CPU IO control is:
3775<tables id="TABLE-US-00339" num="00339"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>if (printhead_cpu_ctrl = = 1) then // CPU access enabled</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>// outputs</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><colspec colname="2" colwidth="49pt" align="left" /><tbody valign="top"><row><entry /><entry>if (PrintHeadCpuCtrlMode[0] = = 1) then</entry><entry> // fire</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>generator controlled</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>phi_frclk_o</entry><entry>= frclk</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="105pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="49pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry><entry /><entry>// normal</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>direct CPU control</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>phi_frclk_o</entry><entry>= printhead_cpu_out [1]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>phi_ph_data_o[0][1:0]</entry><entry> = printhead_cpu_out[4:3]</entry></row><row><entry /><entry>phi_ph_data_o[1][1:0]</entry><entry> = printhead_cpu_out[6:5]</entry></row><row><entry /><entry>phi_srclk[1:0]</entry><entry> = printhead_cpu_out[8:7]</entry></row><row><entry /><entry>phi_readl</entry><entry> = printhead_cpu_out [9]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>// direction control</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>phi_lsyncl_e</entry><entry> = printhead_cpu_dir[0]</entry></row><row><entry /><entry>phi_frclk_e</entry><entry> = printhead_cpu_dir[1]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>// input assignments</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>printhead_cpu_in[0]</entry><entry> = synchronize(phi_lsyncl_i)</entry></row><row><entry /><entry>printhead_cpu_in[1]</entry><entry> = synchronize(phi_frclk_i)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>else // normal connections</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>// outputs</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="98pt" align="left" /><colspec colname="2" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>phi_ph_data_o[0][1:0]</entry><entry>= ph_data[0][1:0]</entry></row><row><entry /><entry>phi_ph_data_o[1][1:0]</entry><entry>= ph_data[1][1:0]</entry></row><row><entry /><entry>phi_lsyncl_o</entry><entry>= lsync_o</entry></row><row><entry /><entry>phi_readl</entry><entry>= 1</entry></row><row><entry /><entry>phi_srclk[1:0]</entry><entry>= srclk[1:0]</entry></row><row><entry /><entry>phi_frclk_o</entry><entry>= frclk</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>// direction control</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="98pt" align="left" /><colspec colname="2" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>phi_frclk_e</entry><entry>= 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="98pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="70pt" align="left" /><tbody valign="top"><row><entry /><entry>phi_lsyncl_e</entry><entry> = phi_mode </entry><entry>// depends on Master</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>or Slave mode</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>// inputs</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="112pt" align="left" /><colspec colname="2" colwidth="119pt" align="left" /><tbody valign="top"><row><entry /><entry>lsyncl_i</entry><entry>= phi_lsync_i // connected</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>regardless</entry></row><row><entry /><entry>// debug overrides any other connections</entry></row><row><entry /><entry>if (debug_cntrl[0] = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>phi_frclk_o</entry><entry>= debug_data_valid</entry></row><row><entry /><entry>phi_frclk_e</entry><entry>= 1</entry></row><row><entry /><entry>phi_readl</entry><entry>= pclk</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3776The debug signalling is controlled by the RDU block (see Section 11.8 Realtime Debug Unit (RDU)), the 10 control in the PHI muxes debug data onto the PHI pins based on the control signals from the RDU.
000032.9.9 Datapath Unit
000032.9.10 Dot Order Controller
3777The dot order controller is responsible for controlling the dot order blocks. It monitors the status of each block and determines the switch over point, at which the connections from odd and even dot streams to printhead channels are swapped.
3778The machine is reset to the Reset state when phi_go_pulse==1 or the reset is active. The machine will wait until it receives a data st pulse from the PHI controller before proceeding to the LineStart state. On the transition to the LineStart state it will reset the dot counter in each dot order block via the dot_cnt_rst signal.
3779While in the LineStart state both dot order blocks are enabled (gen_en==1). The dot order blocks process data until each of them reach their mid point. The mid point of a line is defined by the configured printhead size (i.e. print_head_size). When a dot order block reaches the mid point it immediately stops processing and waits for the remaining dot order block. When both dot order blocks are at the mid point (mid_pt==11) the controller clocks through the LineMid state to allow the pipeline to empty and immediately goes to LineEnd state.
3780In the LineEnd state the mode_sel is switched and the dot order blocks re-enabled, in this state the dot order blocks are reading data from the opposite LLU dot data stream as in LineStart state. The controller remains in the LineEnd state until both dot order blocks have processed a line i.e. line_fin==11.
3781On completion of both blocks the controller returns to the Reset state and again awaits the next data_st pulse from the PHI controller. When in Reset state the machine signals the PHI controller that it's ready to begin processing dot data via the dot_order_rdy signal.
3782The dot order controller selects which dot streams should feed which printhead channels. The order can be changed by configuring the DotOrderMode register. In all cases Channel A and Channel B must be in opposing dot order modes. Table 216 shows the possible modes of operation.
3783<tables id="TABLE-US-00340" num="00340"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 216</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Mode selection in Dot order controller.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="35pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="56pt" align="left" /><colspec colname="4" colwidth="84pt" align="left" /><tbody valign="top"><row><entry>Channel</entry><entry>Mode_sel</entry><entry>DotOrderMode</entry><entry>Dot transmit order</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>A</entry><entry>0</entry><entry>0</entry><entry>Even before Odd (EBO</entry></row><row><entry /><entry /><entry /><entry>mode), even dot</entry></row><row><entry /><entry /><entry /><entry>stream feeds Channel A</entry></row><row><entry /><entry /><entry /><entry>printhead, first half</entry></row><row><entry /><entry /><entry /><entry>line.</entry></row><row><entry /><entry>0</entry><entry>1</entry><entry>Odd before Even (OBE</entry></row><row><entry /><entry /><entry /><entry>mode), odd dot</entry></row><row><entry /><entry /><entry /><entry>stream feeds Channel A</entry></row><row><entry /><entry /><entry /><entry>printhead, first half</entry></row><row><entry /><entry /><entry /><entry>line.</entry></row><row><entry /><entry>1</entry><entry>0</entry><entry>Even before Odd (EBO</entry></row><row><entry /><entry /><entry /><entry>mode), even dot stream</entry></row><row><entry /><entry /><entry /><entry>feeds Channel A</entry></row><row><entry /><entry /><entry /><entry>printhead, second</entry></row><row><entry /><entry /><entry /><entry>half line.</entry></row><row><entry /><entry>1</entry><entry>1</entry><entry>Odd before Even (OBE</entry></row><row><entry /><entry /><entry /><entry>mode), odd dot stream</entry></row><row><entry /><entry /><entry /><entry>feeds Channel A</entry></row><row><entry /><entry /><entry /><entry>printhead, second</entry></row><row><entry /><entry /><entry /><entry>half line.</entry></row><row><entry>B</entry><entry>0</entry><entry>0</entry><entry>Odd before Even (OBE</entry></row><row><entry /><entry /><entry /><entry>mode), odd dot</entry></row><row><entry /><entry /><entry /><entry>stream feeds Channel B</entry></row><row><entry /><entry /><entry /><entry>printhead, second</entry></row><row><entry /><entry /><entry /><entry>half line</entry></row><row><entry /><entry>0</entry><entry>1</entry><entry>Even before Odd (EBO</entry></row><row><entry /><entry /><entry /><entry>mode), even dot</entry></row><row><entry /><entry /><entry /><entry>stream feeds Channel B</entry></row><row><entry /><entry /><entry /><entry>printhead, second</entry></row><row><entry /><entry /><entry /><entry>half line.</entry></row><row><entry /><entry>1</entry><entry>0</entry><entry>Odd before Even (OBE</entry></row><row><entry /><entry /><entry /><entry>mode), odd dot</entry></row><row><entry /><entry /><entry /><entry>stream feeds Channel B</entry></row><row><entry /><entry /><entry /><entry>printhead, first half</entry></row><row><entry /><entry /><entry /><entry>line.</entry></row><row><entry /><entry>1</entry><entry>1</entry><entry>Even before Odd (EBO</entry></row><row><entry /><entry /><entry /><entry>mode), even dot</entry></row><row><entry /><entry /><entry /><entry>stream feeds Channel B</entry></row><row><entry /><entry /><entry /><entry>printhead, first half</entry></row><row><entry /><entry /><entry /><entry>line.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 32.9.10.1 Dot Order Unit
3784The dot order control accepts dot data from either dot stream from the LLU and writes the dot data into the dot buffer. It has two modes of operation, odd before even (OBE) and even before odd (EBO). In the OBE mode data from the odd stream dot data is accepted first then even, in EBO mode it's vice versa. The mode is configurable by the DotOrderMode register.
3785The dot order unit maintains a dot count that is decremented each time a new dot is received from the LLU. The dot order controller resets the dot counter to the print_head_size[15:0] at the start of a new line via the dot_cnt_rst signal. The dot count is compared with the printhead size (print_head_size[15:0] divided by 2) to determine the mid point (mid_Pt) and the line finish point (line_fin) when the dot counter is zero.
3786The mid point is defined as the half the number of dots in a particular printhead, and is derived from the the print_head_size bus by dividing by 2 and rounding down.
3787<tables id="TABLE-US-00341" num="00341"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>// define the mid point</entry></row><row><entry /><entry>if (dot_cnt[15:0] = = print_head_size[15:1] )then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>mid_pt = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>mid_pt = 0</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3788The dot order unit logic maintains the dot data write pointer. Each time a new dot is written to the dot buffer the write pointer is incremented. The fill level of the dot buffer is determined by comparing the read and write pointers. The fill level is used to determine when to backpressure the LLU (ready signal) due to the dot buffer filling. A suitable threshold value is determined to allow for the full LLU pipeline to empty into the dot buffer.
3789The dot order stalling control is given by:
3790<tables id="TABLE-US-00342" num="00342"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>// determine the ready/avail signal to use, based on mode</entry></row><row><entry /><entry>select</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>if (mode_sel</entry><entry>= = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>dot_active</entry><entry>= llu_phi_avail[0] AND ready</entry></row><row><entry /><entry>wr_data</entry><entry>= llu_phi_data[0]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>dot_active</entry><entry>= llu_phi_avail[1] AND ready</entry></row><row><entry /><entry>wr_data</entry><entry>= llu_phi_data[1]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// update the counters</entry></row><row><entry /><entry>if (dot_active = = 1) then {</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>wr_en = 1</entry></row><row><entry /><entry>wr_adr ++</entry></row><row><entry /><entry>if (dot_cnt = = 0) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>dot_cnt = print_head_size</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>dot_cnt− −</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>}</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3791The dot writer needs to determine when to stall the LLU dot data stream. A number of factors could stall the dot stream in the LLU such as buffer filling, waiting for the mid point, waiting for the line finish or the dot order controller is waiting for the line start condition from the PHI controller.
3792The stall logic is given by:
3793<tables id="TABLE-US-00343" num="00343"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>// determine when to stall the LLU generator</entry></row><row><entry /><entry>fill_level = wr_adr − rd_adr</entry></row><row><entry /><entry>if (fill_level > (32 − THRESHOLD ))then // THRESHOLD is</entry></row><row><entry /><entry>open value</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry>ready = 0</entry><entry>// buffer is close</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>to full</entry></row><row><entry /><entry>elsif ( gen_en = = 0) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry>ready = 0</entry><entry>// stalled by the</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>datapath controller</entry></row><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry>ready = 1</entry><entry>// everything good</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>no stall</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 32.9.10.2 Data Generator
3794The data generator block reads data from the dot buffer and feeds dot data to the printhead at a configured rate (set by the PrintheadRate). It also generates the margin zero data and aligns the dot data generation to the synchronization pulse from the PHI controller.
3795The data generator controller waits in Reset state until it receives a line start pulse from the PHI controller (data_st signal). Once a start pulse is received it proceeds to the SrclkPre state loading a counter with the SrclkPre value. While in this state it decrements the counter. No data is read or output at this stage. When the count is zero the machine proceeds to the DataGen1 state.
3796On transition it loads the counter with the printhead size (print_head_size). If margining is to be used then the configured print head_size should be adjusted by the dot margin value i.e. print_head_size=(physical_print_head_size−(dot_margin*2)).
3797Dot data is transferred to the printhead serializer in dot-pairs, with one dot-pair transferred every 3 pclk cycles. To construct a dot data pair the state machine reads one dot in the DataGen1 state, one dot in the DataGen2 state and waits for one clock cycle in the DataGen3 while the data is transferred to the data serializer. The counter will decrement for every dot data word transferred. The exact data rate is dictated by the dot buffer fill levels and the configured printhead rate (PrintheadRate). When in DataGen3 state the machine determines if it should waits for 3 cycles or transfer another dot pair to the data serializer. The generator determines the rate by comparing the rate counter (rate_cnt) with the configured PrintheadRate value. If the bit selected by the rate_cnt in the print_head_rate bus is one data is transferred, otherwise the 3 cycles are skipped (Wait1, Wait2 and Wait3). If the PrintheadRate is set to all zeros then no data will ever get transferred. The rate counter is decremented (rate_cnt) while in the DataGen2 and Wait2 states. The rate counter is allowed to wrap normally.
3798The pseudo-code for the rate control DataGen3 (or Wait3) state is given by:
3799<tables id="TABLE-US-00344" num="00344"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>// decrement the rate count</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="112pt" align="left" /><tbody valign="top"><row><entry /><entry>rate_cnt − −</entry><entry>// happens in DataGen2, or</entry></row><row><entry /><entry>Wait2</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>// determine if data should be read</entry></row><row><entry /><entry>// first determine if data is available in buffer</entry></row><row><entry /><entry>if (rd_adr != wr_adr ) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>if (print_head_rate[rate_cnt] = = 1 ) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="63pt" align="left" /><colspec colname="1" colwidth="154pt" align="left" /><tbody valign="top"><row><entry /><entry>dot_active = 1</entry></row><row><entry /><entry>gate_srclk = 1</entry></row><row><entry /><entry>count − −</entry></row><row><entry /><entry>next_state = DataGen1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="63pt" align="left" /><colspec colname="1" colwidth="154pt" align="left" /><tbody valign="top"><row><entry /><entry>dot_active = 0</entry></row><row><entry /><entry>gate_srclk = 0</entry></row><row><entry /><entry>next_state = Wait1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="63pt" align="left" /><colspec colname="1" colwidth="154pt" align="left" /><tbody valign="top"><row><entry /><entry>dot_active = 0</entry></row><row><entry /><entry>gate_srclk = 0</entry></row><row><entry /><entry>next_state = Wait1</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3800When the dot counter reaches zero the state machine will jump to the MarginGen1 state if the configured margin value is non-zero, otherwise it will jump directly to the SrclkPost state. On transition to MarginGen1 state it loads the cycle counter with the dot_margin value, and begins to count down. While in the MarginGen1, MarginGen2 and MarginGen3 state machine loop the data generator logic block writes dot data to the printhead but does not read from the dot buffers. It creates zero dot data words for the margin duration. As with normal dot data, it creates one dot in MarginGen1 and MarginGen2 states, then wait a clock cycle to allow the transfer to the data serializer to complete.
3801When the counter reaches zero the machine jumps to the SrclkPost state, loads the clock counter with the SrclkPost value and decrements. When the count is finished the state machine returns to the Reset and awaits the next start pulse. Should a line sync arrive before the data generators have completed (data_fin signal) the PHI controller will detect a print error and stall the PHI interface.
3802As a consequence of the data transfer mechanism of dot pair cycles followed by a wait state, the printhead size (print_head_size) and dot margin (dot_margin) must always be even dot values.
000032.9.10.3 Data Serializer
3803The data serializer block converts 12-bit dot data at pclk rates (nominally 160 MHz) to 2-bit data at doclk rates (nominally 320 MHz).
3804The srclk is only active when data is available for transfer to the printhead, as enabled by the gate_srclk signal. The data rate mechanism in the data generator block will mean that data is not transferred to the printhead on every set of 3 pclk cycles. Both the dot_data and gate_srclk signals are controlled by the data generator block and can only change on a fixed 3 pclk cycle boundary. Data is transferred to the printhead on both edges of srclk (i.e double data rate DDR). Directly after a line sync pulse the mux control logic and the srclk generation logic are reset to a known state (the srclk is set high). Before data can begin transfer to the printhead it must generate a line setup edge on srclk, causing srclk to go low. The line setup edge happens SrclkPre number of pclk cycles after the line sync falling edge (indicated by the sr_init signal from the data generator block).
3805All data transfers to the printhead will be in groups of 6 2-bit data words, each word clocked on an edge of srclk. For each group srclk will start low and end low.
3806At the end of a full line of data transfer the srclk must generate a line complete edge to return the srclk to a high state before the next line sync pulse. The data generator block generates a sr_corn signal to indicate that the data transfer to the printhead has completed and that the line complete edge can be inserted. The sr_com signal is generated before the SrClkPost period.
3807The data serializer block allows easy separation of clock gating and clock to logic structures from the rest of the PHI interface.
3808The mux logic determines which data bits from the dot_data bus should be selected for output on the ph_data bus to the printhead. The mux selector is initialized by an edge detect on the sr_init signal from the data generator.
3809<tables id="TABLE-US-00345" num="00345"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>// determine wrap and init points</entry></row><row><entry /><entry>if (phi_serial_order = = 1) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>mux_wrap = 5</entry></row><row><entry /><entry>mux_init = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>mux_wrap = 0</entry></row><row><entry /><entry>mux_init = 5</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// the mux selector logic</entry></row><row><entry /><entry>if ((sr_init_edge = = 1)OR( mux_sel = = mux_wrap )) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>mux_sel = mux_init</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif ( phi_serial_order = = 1 ) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="119pt" align="left" /><tbody valign="top"><row><entry /><entry>mux_sel− −</entry><entry>// decrement order</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="119pt" align="left" /><tbody valign="top"><row><entry /><entry>mux_sel++</entry><entry>// increment order</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3810The dot data serialization order can be configured by PhiSerialOrder register. If the PhiSerialOrder is zero the order is dot[1:0], then dot[3:2] then dot[5:4]. If the register is one then the order is dot[5:4], dot[3:2], dot[1:0].
3811The srclk control logic is initialized to 1 when a line_st positive edge is detected. If either sr_com_edge, sr_init_edge or gate_srclk are equal to one srclk is transitioned. srclk is always clocked out to the output pins on the negative edge of doclk to place the clock edge in the centre of the data.
3812The pseudo code for the control logic is:
3813<tables id="TABLE-US-00346" num="00346"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>if (line_st_edge = =1 ) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>srclk_gen = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>elsif ((gate_srclk = =1) OR (sr_init_edge= =1) OR</entry></row><row><entry /><entry>(sr_com_edge= =1)) then</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>srclk_gen = ~srclk_gen</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>// hold</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 33 Package and Test <br /> Test Units <br /> 33.1 JTAG Interface
3814A standard JTAG (Joint Test Action Group) Interface is included in SoPEC for Bonding and 10 testing purposes. The JTAG port will provide access to all internal BIST (Built In Self Test) structures.
000033.2 Scan Test I/O
3815The SoPEC device will require several test IO's for running scan tests. In general scan in and scan out pins will be multiplexed with functional pins.
000033.3 Analog Test Units
000033.3.1 USB PHY Testing
3816The USB phy analog macro, will contain built-in in test structure, which can be access by either the CPU or through the JTAG port.
000033.3.2 Embedded PLL Testing
3817The embedded clock generator PLL will require test access from JTAG port.
000034 SoPEC Pinning and Package
000034.1 Overview
3818It is intended that the SoPEC package be a 100 pin LQFP. Any spare pins in the package may be used by increasing the number of available GPIO pins or adding extra power and ground pin. The pin list shows the minimum pin requirement for the SoPEC device.
3819<tables id="TABLE-US-00347" num="00347"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="399pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 217</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>SoPEC Pin List (100 LQFP)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="12"><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="14pt" align="center" /><colspec colname="5" colwidth="28pt" align="left" /><colspec colname="6" colwidth="21pt" align="center" /><colspec colname="7" colwidth="21pt" align="center" /><colspec colname="8" colwidth="28pt" align="center" /><colspec colname="9" colwidth="49pt" align="left" /><colspec colname="10" colwidth="56pt" align="left" /><colspec colname="11" colwidth="42pt" align="left" /><colspec colname="12" colwidth="49pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry /><entry /><entry /><entry /><entry>I/O</entry><entry /><entry /><entry /><entry /><entry>Test</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry>Rate</entry><entry>Freq</entry><entry /><entry>IO Cell</entry><entry>Test</entry><entry>Macro</entry></row><row><entry>Group</entry><entry>Pin Name</entry><entry>#pins</entry><entry>Dir</entry><entry>Type</entry><entry>Volt</entry><entry>(S/D)</entry><entry>(Mhz)</entry><entry>Description</entry><entry>Type</entry><entry>Function</entry><entry>Function</entry></row><row><entry namest="1" nameend="12" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="399pt" align="left" /><tbody valign="top"><row><entry>Clocks and resets</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="12"><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="21pt" align="char" char="." /><colspec colname="4" colwidth="14pt" align="center" /><colspec colname="5" colwidth="28pt" align="left" /><colspec colname="6" colwidth="21pt" align="center" /><colspec colname="7" colwidth="21pt" align="center" /><colspec colname="8" colwidth="28pt" align="char" char="." /><colspec colname="9" colwidth="49pt" align="left" /><colspec colname="10" colwidth="56pt" align="left" /><colspec colname="11" colwidth="42pt" align="left" /><colspec colname="12" colwidth="49pt" align="left" /><tbody valign="top"><row><entry>Group 1</entry><entry>Xtalin</entry><entry>1</entry><entry>I</entry><entry /><entry>N/A</entry><entry>N/A</entry><entry>32</entry><entry>Crystal</entry><entry>AINSA<sub>—</sub></entry><entry>None</entry><entry /></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>Input pin</entry><entry>PM_A</entry></row><row><entry /><entry>Xtalout</entry><entry>1</entry><entry>O</entry><entry /><entry>N/A</entry><entry>N/A</entry><entry>32</entry><entry>Crystal</entry><entry>ABNST<sub>—</sub></entry><entry>None</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>output pin</entry><entry>PM_A</entry></row><row><entry>Group 2</entry><entry>reset_n</entry><entry>1</entry><entry>I</entry><entry>LVTTL</entry><entry>3.3 v</entry><entry>s</entry><entry>10</entry><entry>Asynchronous</entry><entry>IT33LTPUT<sub>—</sub></entry><entry>LT</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>active low</entry><entry>PM_A</entry><entry>(leakage</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>reset</entry><entry /><entry>test)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="399pt" align="left" /><tbody valign="top"><row><entry>PrintHead Interface</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="12"><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="21pt" align="char" char="." /><colspec colname="4" colwidth="14pt" align="center" /><colspec colname="5" colwidth="28pt" align="left" /><colspec colname="6" colwidth="21pt" align="center" /><colspec colname="7" colwidth="21pt" align="center" /><colspec colname="8" colwidth="28pt" align="char" char="." /><colspec colname="9" colwidth="49pt" align="left" /><colspec colname="10" colwidth="56pt" align="left" /><colspec colname="11" colwidth="42pt" align="left" /><colspec colname="12" colwidth="49pt" align="left" /><tbody valign="top"><row><entry>Group 3</entry><entry>phead<sub>—</sub></entry><entry>8</entry><entry>O</entry><entry>LVDS</entry><entry>1.5 v</entry><entry>d</entry><entry>160</entry><entry>Print head</entry><entry>OLVDS15<sub>—</sub></entry><entry>None</entry><entry /></row><row><entry /><entry>data</entry><entry /><entry /><entry /><entry /><entry /><entry /><entry>data</entry><entry>PM_A</entry></row><row><entry /><entry>Srclk</entry><entry>4</entry><entry>O</entry><entry>LVDS</entry><entry>1.5 v</entry><entry>d</entry><entry>160</entry><entry>Print head</entry><entry>OLVDS15<sub>—</sub></entry><entry>None</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>clock</entry><entry>PM_A</entry></row><row><entry>Group 4</entry><entry>Readl</entry><entry>1</entry><entry>O</entry><entry>LVTTL</entry><entry>3.3 v</entry><entry>s</entry><entry>160</entry><entry>Common</entry><entry>BT3365T<sub>—</sub></entry><entry>A_Clock</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>Print head</entry><entry>PM_A</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>mode</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>control</entry></row><row><entry /><entry>Frclk</entry><entry>1</entry><entry>I/O</entry><entry>LVTTL</entry><entry>3.3 v</entry><entry>s</entry><entry>160</entry><entry>Common</entry><entry>BT3365T<sub>—</sub></entry><entry>B_Clock</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>Fire pattern</entry><entry>PM_A</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>shift clock,</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>needs to</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>toggle once</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>per fire</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>cycle</entry></row><row><entry /><entry>phi_spare</entry><entry>1</entry><entry>I/O</entry><entry>LVTTL</entry><entry>3.3 v</entry><entry>s</entry><entry>160</entry><entry>PHI spare</entry><entry>BT3365T<sub>—</sub></entry><entry>C_Clock1</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>pin (old</entry><entry>PM_A</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>profile pin)</entry></row><row><entry /><entry>Lsyncl</entry><entry>1</entry><entry>I/O</entry><entry>LVTTL</entry><entry>3.3 v</entry><entry>s</entry><entry>160</entry><entry>Line Sync</entry><entry>BT3365T<sub>—</sub></entry><entry>C_Clock2</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>output from</entry><entry>PM_A</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>Master to</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>Slaves</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="399pt" align="left" /><tbody valign="top"><row><entry>USB Connections</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="12"><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="21pt" align="char" char="." /><colspec colname="4" colwidth="14pt" align="center" /><colspec colname="5" colwidth="28pt" align="left" /><colspec colname="6" colwidth="21pt" align="center" /><colspec colname="7" colwidth="21pt" align="center" /><colspec colname="8" colwidth="28pt" align="char" char="." /><colspec colname="9" colwidth="49pt" align="left" /><colspec colname="10" colwidth="56pt" align="left" /><colspec colname="11" colwidth="42pt" align="left" /><colspec colname="12" colwidth="49pt" align="left" /><tbody valign="top"><row><entry>Group 5</entry><entry>Usb_hostd</entry><entry>2</entry><entry>I/O</entry><entry>Differ-</entry><entry>3.3 v</entry><entry>s</entry><entry>12</entry><entry>USB</entry><entry>BUSB2<sub>—</sub></entry><entry>None</entry><entry /></row><row><entry /><entry /><entry /><entry /><entry>ential</entry><entry /><entry /><entry /><entry>differential</entry><entry>PM_A</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>data for</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>host</entry></row><row><entry /><entry>Usb_devd</entry><entry>2</entry><entry>I/O</entry><entry>Differ-</entry><entry>3.3 v</entry><entry>s</entry><entry>12</entry><entry>USB</entry><entry>BUSB2<sub>—</sub></entry><entry>None</entry></row><row><entry /><entry /><entry /><entry /><entry>ential</entry><entry /><entry /><entry /><entry>differential</entry><entry>PM_A</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>data for</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>device</entry></row><row><entry>Group 6</entry><entry>usbd<sub>—</sub></entry><entry>1</entry><entry>I</entry><entry>LVTTL</entry><entry>3.3 v</entry><entry>s</entry><entry>10</entry><entry>USB device</entry><entry>BT3365T<sub>—</sub></entry><entry>1 scan out</entry></row><row><entry /><entry>vbus<sub>—</sub></entry><entry /><entry /><entry /><entry /><entry /><entry /><entry>VBUS</entry><entry>PM_C</entry></row><row><entry /><entry>sense</entry><entry /><entry /><entry /><entry /><entry /><entry /><entry>power</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>sense</entry></row><row><entry /><entry>usbd<sub>—</sub></entry><entry>1</entry><entry>O</entry><entry>LVTTL</entry><entry>3.3 v</entry><entry>s</entry><entry>10</entry><entry>USB device</entry><entry>BT3365T<sub>—</sub></entry><entry>1 scan out</entry></row><row><entry /><entry>pull<sub>—</sub></entry><entry /><entry /><entry /><entry /><entry /><entry /><entry>termination</entry><entry>PM_C</entry></row><row><entry /><entry>up_en</entry><entry /><entry /><entry /><entry /><entry /><entry /><entry>enable</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="399pt" align="left" /><tbody valign="top"><row><entry>JTAG</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="12"><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="21pt" align="char" char="." /><colspec colname="4" colwidth="14pt" align="center" /><colspec colname="5" colwidth="28pt" align="left" /><colspec colname="6" colwidth="21pt" align="center" /><colspec colname="7" colwidth="21pt" align="center" /><colspec colname="8" colwidth="28pt" align="char" char="." /><colspec colname="9" colwidth="49pt" align="left" /><colspec colname="10" colwidth="56pt" align="left" /><colspec colname="11" colwidth="42pt" align="left" /><colspec colname="12" colwidth="49pt" align="left" /><tbody valign="top"><row><entry>Group 7</entry><entry>Tdo</entry><entry>1</entry><entry>O</entry><entry>LVTTL</entry><entry>3.3 v</entry><entry>s</entry><entry>10</entry><entry>JTAG Test</entry><entry>BT3365T<sub>—</sub></entry><entry>C_Clock3</entry><entry /></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>data out</entry><entry>PM_A</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>port</entry></row><row><entry /><entry>Tms</entry><entry>1</entry><entry>I</entry><entry>LVTTL</entry><entry>3.3 v</entry><entry>s</entry><entry>10</entry><entry>JTAG Test</entry><entry>IT33RIT<sub>—</sub></entry><entry>RI</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>mode select</entry><entry>PM_A</entry></row><row><entry /><entry>Tdi</entry><entry>1</entry><entry>I</entry><entry>LVTTL</entry><entry>3.3 v</entry><entry>s</entry><entry>10</entry><entry>JTAG Test</entry><entry>IT33D1PUT<sub>—</sub></entry><entry>DI1</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>data in port</entry><entry>PM_A</entry></row><row><entry /><entry>Tck</entry><entry>1</entry><entry>I</entry><entry>LVTTL</entry><entry>3.3 v</entry><entry>s</entry><entry>10</entry><entry>JTAG Test</entry><entry>IT33D2PUT<sub>—</sub></entry><entry>DI2</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>access port</entry><entry>PM_A</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>clock</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="399pt" align="left" /><tbody valign="top"><row><entry>General Purpose IO</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="12"><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="21pt" align="char" char="." /><colspec colname="4" colwidth="14pt" align="center" /><colspec colname="5" colwidth="28pt" align="left" /><colspec colname="6" colwidth="21pt" align="center" /><colspec colname="7" colwidth="21pt" align="center" /><colspec colname="8" colwidth="28pt" align="char" char="." /><colspec colname="9" colwidth="49pt" align="left" /><colspec colname="10" colwidth="56pt" align="left" /><colspec colname="11" colwidth="42pt" align="left" /><colspec colname="12" colwidth="49pt" align="left" /><tbody valign="top"><row><entry>Group 8</entry><entry>Gpio</entry><entry>4</entry><entry>I/O</entry><entry>LVTTL</entry><entry>3.3 v</entry><entry>s</entry><entry>32</entry><entry>ISI</entry><entry>BT3335PUT<sub>—</sub></entry><entry>4 Scanin</entry><entry /></row><row><entry /><entry>[3:0]</entry><entry /><entry /><entry /><entry /><entry /><entry /><entry>interface</entry><entry>PM_B</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>pins/GPIO</entry></row><row><entry>Group 9</entry><entry>Gpio</entry><entry>4</entry><entry>I/O</entry><entry>High</entry><entry>3.3 v</entry><entry>s</entry><entry>32</entry><entry>LED driver</entry><entry>BT3365T<sub>—</sub></entry><entry>4 Scanin</entry><entry>PCNT</entry></row><row><entry /><entry>[7:4]</entry><entry /><entry /><entry>Drive</entry><entry /><entry /><entry /><entry>pins/</entry><entry>PM_C</entry><entry /><entry>PROGSROM</entry></row><row><entry /><entry /><entry /><entry /><entry>LVTTL</entry><entry /><entry /><entry /><entry>general</entry><entry /><entry /><entry>OSC</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>purpose</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>Input/Output</entry></row><row><entry>Group</entry><entry>Gpio</entry><entry>12</entry><entry>I/O</entry><entry>LVTTL</entry><entry>3.3 v</entry><entry>s</entry><entry>32</entry><entry>General</entry><entry>BT3365PUT<sub>—</sub></entry><entry>2 Scanin</entry><entry>DIAGOUT</entry></row><row><entry>10</entry><entry>[19:8]</entry><entry /><entry /><entry /><entry /><entry /><entry /><entry>purpose</entry><entry>PM_B</entry><entry>10 Scanout</entry><entry>(aka</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>Input/Output</entry><entry /><entry /><entry>MRSTR0)</entry></row><row><entry>Group</entry><entry>Gpio</entry><entry>3</entry><entry>I/O</entry><entry>LVTTL</entry><entry>3.3 v</entry><entry>s</entry><entry>32</entry><entry>General</entry><entry>BT3365PUT<sub>—</sub></entry><entry>CE0_Scan</entry></row><row><entry>11</entry><entry>[22:20]</entry><entry /><entry /><entry /><entry /><entry /><entry /><entry>purpose</entry><entry>PM_B</entry><entry>TESTM3</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>Input/Output</entry><entry /><entry>TSTN1</entry></row><row><entry>Group</entry><entry>Gpio</entry><entry>10</entry><entry>I/O</entry><entry>LVTTL</entry><entry>3.3 v</entry><entry>s</entry><entry>32</entry><entry>Functional</entry><entry>BT3365T<sub>—</sub></entry><entry>6 Scanin</entry></row><row><entry>12</entry><entry>[31:23]</entry><entry /><entry /><entry /><entry /><entry /><entry /><entry>Spare IOs</entry><entry>PM_C</entry><entry>4 scanout</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>required for</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>scan test</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="399pt" align="left" /><tbody valign="top"><row><entry>Analog Power IO</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="12"><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="21pt" align="char" char="." /><colspec colname="4" colwidth="14pt" align="center" /><colspec colname="5" colwidth="28pt" align="left" /><colspec colname="6" colwidth="21pt" align="center" /><colspec colname="7" colwidth="21pt" align="center" /><colspec colname="8" colwidth="28pt" align="center" /><colspec colname="9" colwidth="49pt" align="left" /><colspec colname="10" colwidth="56pt" align="left" /><colspec colname="11" colwidth="42pt" align="left" /><colspec colname="12" colwidth="49pt" align="left" /><tbody valign="top"><row><entry>Group</entry><entry>agnd</entry><entry>1</entry><entry>I</entry><entry>Power</entry><entry>N/A</entry><entry>N/A</entry><entry>N/A</entry><entry>PLL analog</entry><entry>AINSD3<sub>—</sub></entry><entry>None</entry><entry /></row><row><entry>13</entry><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>gnd</entry><entry>PM_A</entry></row><row><entry /><entry>avdd</entry><entry>1</entry><entry>I</entry><entry>Power</entry><entry>N/A</entry><entry>N/A</entry><entry>N/A</entry><entry>PLL analog</entry><entry>AINSD3<sub>—</sub></entry><entry>None</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>vdd</entry><entry>PM_A</entry></row><row><entry /><entry>agnd</entry><entry>1</entry><entry>I</entry><entry>Power</entry><entry>N/A</entry><entry>N/A</entry><entry>N/A</entry><entry>Oscillator</entry><entry>AINSD<sub>—</sub></entry><entry>None</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>analog gnd</entry><entry>PM_A</entry></row><row><entry /><entry>avdd</entry><entry>1</entry><entry>I</entry><entry>Power</entry><entry>N/A</entry><entry>N/A</entry><entry>N/A</entry><entry>Oscillator</entry><entry>AINSD<sub>—</sub></entry><entry>None</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>analog vdd</entry><entry>PM_A</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="399pt" align="left" /><tbody valign="top"><row><entry>Test Only Pin</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="12"><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="21pt" align="char" char="." /><colspec colname="4" colwidth="14pt" align="center" /><colspec colname="5" colwidth="28pt" align="left" /><colspec colname="6" colwidth="21pt" align="center" /><colspec colname="7" colwidth="21pt" align="center" /><colspec colname="8" colwidth="28pt" align="center" /><colspec colname="9" colwidth="49pt" align="left" /><colspec colname="10" colwidth="56pt" align="left" /><colspec colname="11" colwidth="42pt" align="left" /><colspec colname="12" colwidth="49pt" align="left" /><tbody valign="top"><row><entry>Group</entry><entry>TE</entry><entry>1</entry><entry>I</entry><entry>CMOS</entry><entry>1.5 v</entry><entry>N/A</entry><entry>N/A</entry><entry>Test Enable</entry><entry>IC15TEPDT<sub>—</sub></entry><entry>Test only</entry><entry /></row><row><entry>14</entry><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>PM_A</entry></row><row><entry /><entry>VPP</entry><entry>1</entry><entry>I</entry><entry>CMOS</entry><entry>1.5 v</entry><entry>N/A</entry><entry>N/A</entry><entry>Fat Wire</entry><entry>DRAMVPP<sub>—</sub></entry><entry>Test only</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>Analog</entry><entry>PM</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>Receiver/D</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>river for</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>Embedded</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>DRAM</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>Analog</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>Inputs</entry></row><row><entry /><entry>VWP</entry><entry>1</entry><entry>I</entry><entry>CMOS</entry><entry>1.5 v</entry><entry>N/A</entry><entry>N/A</entry><entry>Fat Wire</entry><entry>DRAMVWP<sub>—</sub></entry><entry>Test only</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>Analog</entry><entry>PM</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>Receiver/D</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>river for</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>Embedded</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>DRAM</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>Analog</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>Inputs</entry></row><row><entry /><entry>VREFX</entry><entry>1</entry><entry>I</entry><entry>CMOS</entry><entry>1.5 v</entry><entry>N/A</entry><entry>N/A</entry><entry>Fat Wire</entry><entry>DRAMVREFX<sub>—</sub></entry><entry>Test only</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>Analog</entry><entry>PM</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>Receiver/D</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>river for</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>Embedded</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>DRAM</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>Analog</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>Inputs</entry></row><row><entry /><entry>DLT</entry><entry>1</entry><entry>I</entry><entry>CMOS</entry><entry>1.5 v</entry><entry>N/A</entry><entry>N/A</entry><entry>DRAM</entry><entry>IC15DLTPUT<sub>—</sub></entry><entry>Test only</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>Iddq Test</entry><entry>PM</entry></row><row><entry /><entry>MC</entry><entry>1</entry><entry>I</entry><entry>CMOS</entry><entry>1.5 v</entry><entry>N/A</entry><entry>N/A</entry><entry>IO Mode</entry><entry>IC15MCT<sub>—</sub></entry><entry>Test only</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>Control</entry><entry>PM_A</entry></row><row><entry /><entry>DRAM<sub>—</sub></entry><entry>1</entry><entry>I</entry><entry>CMOS</entry><entry>1.5 v</entry><entry>N/A</entry><entry>N/A</entry><entry>DRAM</entry><entry>IC15LTPUT<sub>—</sub></entry><entry>Test only</entry></row><row><entry /><entry>EN</entry><entry /><entry /><entry /><entry /><entry /><entry /><entry>Enable(EN)</entry><entry>PM_A</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="161pt" align="left" /><colspec colname="4" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>Total Signal Pins</entry><entry>73</entry><entry>Functional pin count is 62</entry><entry>Test IO count 51</entry></row><row><entry>Power Only Pins</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="12"><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="21pt" align="char" char="." /><colspec colname="4" colwidth="14pt" align="center" /><colspec colname="5" colwidth="28pt" align="left" /><colspec colname="6" colwidth="21pt" align="center" /><colspec colname="7" colwidth="21pt" align="center" /><colspec colname="8" colwidth="28pt" align="center" /><colspec colname="9" colwidth="49pt" align="left" /><colspec colname="10" colwidth="56pt" align="left" /><colspec colname="11" colwidth="42pt" align="left" /><colspec colname="12" colwidth="49pt" align="left" /><tbody valign="top"><row><entry>Group</entry><entry>Gnd</entry><entry>8</entry><entry>I</entry><entry>Power</entry><entry>N/A</entry><entry>N/A</entry><entry>N/A</entry><entry>gnd</entry><entry>GND<sub>—</sub></entry><entry>None</entry><entry /></row><row><entry>15</entry><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>PM_A</entry></row><row><entry /><entry>Vdd</entry><entry>4</entry><entry>I</entry><entry>Power</entry><entry>N/A</entry><entry>N/A</entry><entry>N/A</entry><entry>vdd 1.5 v,</entry><entry>VDD150<sub>—</sub></entry><entry>None</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>core</entry><entry>PM_A</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>voltage</entry></row><row><entry /><entry>vdd330</entry><entry>4</entry><entry>I</entry><entry>Power</entry><entry>N/A</entry><entry>N/A</entry><entry>N/A</entry><entry>vdd 3.3 v,</entry><entry>VDD330<sub>—</sub></entry><entry>None</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>IO voltage</entry><entry>PM_A</entry></row><row><entry>Group</entry><entry>vdd/gnd</entry><entry>11</entry><entry>I</entry><entry>Power</entry><entry>N/A</entry><entry>N/A</entry><entry>N/A</entry><entry>Power pin</entry><entry>GND_PM_A/</entry><entry>None</entry></row><row><entry>15</entry><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>fill,</entry><entry>VDD150_P</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>GND.Vdd1.5,</entry><entry>M_A/</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>Vdd3.3</entry><entry>VDD330<sub>—</sub></entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>as required</entry><entry>PM_A</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="11"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="14pt" align="center" /><colspec colname="4" colwidth="28pt" align="left" /><colspec colname="5" colwidth="21pt" align="center" /><colspec colname="6" colwidth="21pt" align="center" /><colspec colname="7" colwidth="28pt" align="char" char="." /><colspec colname="8" colwidth="49pt" align="left" /><colspec colname="9" colwidth="56pt" align="left" /><colspec colname="10" colwidth="42pt" align="left" /><colspec colname="11" colwidth="49pt" align="left" /><tbody valign="top"><row><entry>Total Pins</entry><entry>100</entry></row><row><entry namest="1" nameend="11" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> Bilithic Printheads <br /> 1 Background
3820Silverbrook's bilithic Memjet™ printheads are the target printheads for printing systems which will be controlled by SoPEC and MoPEC devices.
3821This document presents the format and structure of these printheads, and describes the their possible arrangements in the target systems. It also defines a set of terms used to differentiate between the types of printheads and the systems which use them.
0000Bilithic Printhead Configurations
00002 Definitions
3822This document presents terminology and definitions used to describe the bilithic printhead systems. These terms and definitions are as follows: <ul id="ul0370" list-style="none"><li id="ul0370-0001" num="0000"><ul id="ul0371" list-style="none"><li id="ul0371-0001" num="3823">Printhead Type—There are 3 parameters which define the type of printhead used in a system:</li><li id="ul0371-0002" num="3824">Direction of the data flow through the printhead (clockwise or anti-clockwise, with the printhead shooting ink down onto the page).</li><li id="ul0371-0003" num="3825">Location of the left-most dot (upper row or lower row, with respect to V<sub>+</sub>,).</li><li id="ul0371-0004" num="3826">Printhead footprint (type A or type B, characterized by the data pin being on the left or the right of V<sub>+</sub>, where V<sub>+</sub> is at the top of the printhead).</li><li id="ul0371-0005" num="3827">Printhead Arrangement—Even though there are 8 printhead types, each arrangement has to use a specific pairing of printheads, as discussed in Section 3. This gives 4 pairs of printheads. However, because the paper can flow in either direction with respect to the printheads, there are a total of eight possible arrangements, e.g. Arrangement 1 has a Type 0 printhead on the left with respect to the paper flow, and a Type 1 printhead on the right. Arrangement 2 uses the same printhead pair as Arrangement 1, but the paper flows in the opposite direction.</li><li id="ul0371-0006" num="3828">Color 0 is always the first color plane encountered by the paper.</li><li id="ul0371-0007" num="3829">Dot 0 is defined as the nozzle which can print a dot in the left-most side of the page.</li><li id="ul0371-0008" num="3830">The Even Plane of a color corresponds to the row of nozzles that prints dot 0.</li></ul></li></ul>
3831Note that in all of the relevant drawings, printheads should be interpreted as shooting ink down onto the page.
3832<figref idref="DRAWINGS">FIG. 295</figref> shows the 8 different possible printhead types. Type 0 is identical to the Right Printhead presented in <figref idref="DRAWINGS">FIG. 297</figref> in [1], and Type 1 is the same as the Left Printhead as defined in [1].
3833While the printheads shown in <figref idref="DRAWINGS">FIG. 295</figref> look to be of equal width (having the same number of nozzles) it is important to remember that in a typical system, a pair of unequal sized printheads may be used.
00002.1 Combining Bilithic Printheads
3834Although the printheads can be physically joined in the manner shown in <figref idref="DRAWINGS">FIG. 296</figref>, it is preferable to provide an arrangment that allows greater spacing between the 2 printheads will be required for two main reasons: <ul id="ul0372" list-style="none"><li id="ul0372-0001" num="0000"><ul id="ul0373" list-style="none"><li id="ul0373-0001" num="3835">inaccuracies in the backetch</li><li id="ul0373-0002" num="3836">cheaper manufacturing cost due to decreasing the tolerance requirements in sealing the ink reservoirs behind the printhead</li></ul></li></ul>
3837Failing to account for these inaccuracies and tolerances can lead to misalignment of the nozzle rows both vertically and horizontally, as shown in <figref idref="DRAWINGS">FIG. 297</figref>.
3838An even row of color n on printhead A may be vertically misaligned from the even row of color n on printhead B by some number of dots e.g. in <figref idref="DRAWINGS">FIG. 297</figref> this is shown to be 5 dots. And there can also be horizontal misalignment, in that the even row of color n printhead A is not necessarily aligned with the even row of color n+1 on printhead A, e.g. in <figref idref="DRAWINGS">FIG. 297</figref> this horizontal misalignment is 6 dots.
3839The resultant conceptual printhead definition, shown in <figref idref="DRAWINGS">FIG. 297</figref> has properties that are appropriately parameterized in SoPEC and MoPEC to cater for this class of printheads.
3840The preferred printheads can be characterized by the following features: <ul id="ul0374" list-style="none"><li id="ul0374-0001" num="0000"><ul id="ul0375" list-style="none"><li id="ul0375-0001" num="3841">All nozzle rows are the same length (although may be horizontally displaced some number of dots even within a color on a single printhead)</li><li id="ul0375-0002" num="3842">The nozzles for color n printhead A may not be printing on the same line of the page as the nozzles for color n printhead B. In the example shown in <figref idref="DRAWINGS">FIG. 297</figref>, there is a 5 dot displacement between adjacent rows of the printheads.</li><li id="ul0375-0003" num="3843">The exact shape of the join is an arbitrary shape although is most likely to be sloping (if sloping, it could be sloping either direction)</li><li id="ul0375-0004" num="3844">The maximum slope is 2 dots per row of nozzles</li><li id="ul0375-0005" num="3845">Although shift registers are provided in the printhead at the 2 sides of the joined printhead, they do not drive nozzles—this means the printable area is less than the actual shift registers, as highlighted by <figref idref="DRAWINGS">FIG. 298</figref>. <br /> 2.2 Printhead Arrangements </li></ul></li></ul>
3846Table 218 defines the printhead pairing and location of the each printhead type, with respect to the flow of paper, for the 8 possible arrangements
3847<tables id="TABLE-US-00348" num="00348"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="70pt" align="left" /><colspec colname="3" colwidth="77pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row><row><entry /><entry /><entry>Printhead on left</entry><entry>Printhead on right</entry></row><row><entry /><entry>Printhead</entry><entry>side, with respect</entry><entry>side, with respect</entry></row><row><entry /><entry>Arrangement</entry><entry>to the flow of paper</entry><entry>to the flow of paper</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>Arrangement 1</entry><entry>Type 0</entry><entry>Type 1</entry></row><row><entry /><entry>Arrangement 2</entry><entry>Type 1</entry><entry>Type 0</entry></row><row><entry /><entry>Arrangement 3</entry><entry>Type 2</entry><entry>Type 3</entry></row><row><entry /><entry>Arrangement 4</entry><entry>Type 3</entry><entry>Type 2</entry></row><row><entry /><entry>Arrangement 5</entry><entry>Type 4</entry><entry>Type 5</entry></row><row><entry /><entry>Arrangement 6</entry><entry>Type 5</entry><entry>Type 4</entry></row><row><entry /><entry>Arrangement 7</entry><entry>Type 6</entry><entry>Type 7</entry></row><row><entry /><entry>Arrangement 8</entry><entry>Type 7</entry><entry>Type 6</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 3 Bilithic Printhead Systems
3848When using the bilithic printheads, the position of the power/gnd bars coupled with the physical footprint of the printheads mean that we must use a specific pairing of printheads together for printing on the same side of an A4 (or wider) page, e.g. we must always use a Type 0 printhead with a Type 1 printhead etc.
3849While a given printing system can use any one of the eight possible arrangements of printheads, this document only presents two of them, Arrangement 1 and Arrangement 2, for purposes of illustration. These two arrangements are discussed in subsequent sections of this document. However, the other 6 possibilities also need to be considered.
3850The main difference between the two printhead arrangements discussed in this document is the direction of the paper flow. Because of this, the dot data has to be loaded differently in Arrangement 1 compared to Arrangement 2, in order to render the page correctly.
3.1 EXAMPLE 1
Printhead Arrangement 1
3851<figref idref="DRAWINGS">FIG. 299</figref> shows an Arrangement 1 printing setup, where the bilithic printheads are arranged as follows: <ul id="ul0376" list-style="none"><li id="ul0376-0001" num="0000"><ul id="ul0377" list-style="none"><li id="ul0377-0001" num="3852">The Type 0 printhead is on the left with respect to the direction of the paper flow.</li><li id="ul0377-0002" num="3853">The Type 1 printhead is on the right.</li></ul></li></ul>
3854Table 219 lists the order in which the dot data needs to be loaded into the above printhead system, to ensure color 0-dot 0 appears on the left side of the printed page.
3855<tables id="TABLE-US-00349" num="00349"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 219</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Order in which the even and odd dots are</entry></row><row><entry>loaded for printhead Arrangement 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="70pt" align="left" /><colspec colname="3" colwidth="77pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Type 0 printhead</entry><entry>Type 1 printhead</entry></row><row><entry /><entry>Dot Sense</entry><entry>when on the left</entry><entry>when on the right</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row><row><entry /><entry>Odd</entry><entry>Loaded second in</entry><entry>Loaded first in</entry></row><row><entry /><entry /><entry>descending order.</entry><entry>descending order.</entry></row><row><entry /><entry>Even</entry><entry>Loaded first in</entry><entry>Loaded second in</entry></row><row><entry /><entry /><entry>ascending order.</entry><entry>ascending order.</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3856<figref idref="DRAWINGS">FIG. 300</figref> shows how the dot data is demultiplexed within the printheads.
3857<figref idref="DRAWINGS">FIG. 301</figref> and <figref idref="DRAWINGS">FIG. 302</figref> show the way in which the dot data needs to be loaded into the printheads in Arrangement 1, to ensure that color 0-dot 0 appears on the left side of the printed page. Note that no data is transferred to the printheads on the first and last edges of SrClk.
3.2 EXAMPLE 2
Printhead Arrangement 2
3858<figref idref="DRAWINGS">FIG. 303</figref> shows an Arrangement 2 printing setup, where the bilithic printheads are arranged as follows: <ul id="ul0378" list-style="none"><li id="ul0378-0001" num="0000"><ul id="ul0379" list-style="none"><li id="ul0379-0001" num="3859">The Type 1 printhead is on the left with respect to the direction of the paper flow.</li><li id="ul0379-0002" num="3860">The Type 0 printhead is on the right.</li></ul></li></ul>
3861Table 220 lists the order in which the dot data needs to be loaded into the above printhead system, to ensure color 0-dot 0 appears on the left side of the printed page.
3862<tables id="TABLE-US-00350" num="00350"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 220</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Order in which the even and odd dots are</entry></row><row><entry>loaded for printhead Arrangement 2</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="70pt" align="left" /><colspec colname="3" colwidth="77pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>Type 0 printhead</entry><entry>Type 1 printhead</entry></row><row><entry /><entry>Dot Sense</entry><entry>when on the right</entry><entry>when on the left</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row><row><entry /><entry>Odd</entry><entry>Loaded first in</entry><entry>Loaded second in</entry></row><row><entry /><entry /><entry>descending order.</entry><entry>descending order.</entry></row><row><entry /><entry>Even</entry><entry>Loaded second in</entry><entry>Loaded first in</entry></row><row><entry /><entry /><entry>ascending order.</entry><entry>ascending order.</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3863<figref idref="DRAWINGS">FIG. 304</figref> shows how the dot data is demultiplexed within the printheads.
3864<figref idref="DRAWINGS">FIG. 305</figref> and <figref idref="DRAWINGS">FIG. 306</figref> show the way in which the dot data needs to be loaded into the printheads in Arrangement 2, to ensure that color 0-dot 0 appears on the left side of the printed page.
3865Note that no data is transferred to the printheads on the first and last edges of SrClk.
4 CONCLUSIONS
3866Comparing the signalling diagrams for Arrangement 1 with those shown for Arrangement 2, it can be seen that the color/dot sequence output for a printhead type in Arrangement 1 is the reverse of the sequence for same printhead in Arrangement 2 in terms of the order in which the color plane data is output, as well as whether even or odd data is output first. However, the order within a color plane remains the same, i.e. odd descending, even ascending.
3867From <figref idref="DRAWINGS">FIG. 307</figref> and Table 221, it can be seen that the plane which has to be loaded first (i.e. even or odd) depends on the arrangement. Also, the order in which the dots have to be loaded (e.g. even ascending or descending etc.) is dependent on the arrangement.
3868As well as having a mechanism to cope with the shape of the join between the printheads, as discussed in Section 2.1, if the device controlling the printheads can re-order the bits according to the following criteria, then it should be able to operate in all the possible printhead arrangements: <ul id="ul0380" list-style="none"><li id="ul0380-0001" num="0000"><ul id="ul0381" list-style="none"><li id="ul0381-0001" num="3869">Be able to output the even or odd plane first.</li><li id="ul0381-0002" num="3870">Be able to output even and odd planes in either ascending or descending order, independently.</li><li id="ul0381-0003" num="3871">Be able to reverse the sequence in which the color planes of a single dot are output to the printhead.</li></ul></li></ul>
3872<tables id="TABLE-US-00351" num="00351"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 221</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Order in which even and odd dots and planes are</entry></row><row><entry>loaded into the various printhead arrangements</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="70pt" align="left" /><colspec colname="3" colwidth="70pt" align="left" /><tbody valign="top"><row><entry /><entry>Printhead</entry><entry>Left side of</entry><entry>Right side of</entry></row><row><entry /><entry>Arrangement</entry><entry>printed page</entry><entry>printed page</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row><row><entry /><entry>Arrangement 1</entry><entry>Even ascending</entry><entry>Odd descending</entry></row><row><entry /><entry /><entry>loaded first</entry><entry>loaded first</entry></row><row><entry /><entry /><entry>Odd descending</entry><entry>Even ascending</entry></row><row><entry /><entry /><entry>loaded second</entry><entry>loaded second</entry></row><row><entry /><entry>Arrangement 2</entry><entry>Odd descending</entry><entry>Even ascending</entry></row><row><entry /><entry /><entry>loaded first</entry><entry>loaded first</entry></row><row><entry /><entry /><entry>Even ascending</entry><entry>Odd descending</entry></row><row><entry /><entry /><entry>loaded second</entry><entry>loaded second</entry></row><row><entry /><entry>Arrangement 3</entry><entry>Odd ascending</entry><entry>Even descending</entry></row><row><entry /><entry /><entry>loaded first</entry><entry>loaded first</entry></row><row><entry /><entry /><entry>Even descending</entry><entry>Odd ascending</entry></row><row><entry /><entry /><entry>loaded second</entry><entry>loaded second</entry></row><row><entry /><entry>Arrangement 4</entry><entry>Even descending</entry><entry>Odd ascending</entry></row><row><entry /><entry /><entry>loaded first</entry><entry>loaded first</entry></row><row><entry /><entry /><entry>Odd ascending</entry><entry>Even descending</entry></row><row><entry /><entry /><entry>loaded second</entry><entry>loaded second</entry></row><row><entry /><entry>Arrangement 5</entry><entry>Odd ascending</entry><entry>Even descending</entry></row><row><entry /><entry /><entry>loaded first</entry><entry>loaded first</entry></row><row><entry /><entry /><entry>Even descending</entry><entry>Odd ascending</entry></row><row><entry /><entry /><entry>loaded second</entry><entry>loaded second</entry></row><row><entry /><entry>Arrangement 6</entry><entry>Even descending</entry><entry>Odd ascending</entry></row><row><entry /><entry /><entry>loaded first</entry><entry>loaded first</entry></row><row><entry /><entry /><entry>Odd ascending</entry><entry>Even descending</entry></row><row><entry /><entry /><entry>loaded second</entry><entry>loaded second</entry></row><row><entry /><entry>Arrangement 7</entry><entry>Even ascending</entry><entry>Odd descending</entry></row><row><entry /><entry /><entry>loaded first</entry><entry>loaded first</entry></row><row><entry /><entry /><entry>Odd descending</entry><entry>Even ascending</entry></row><row><entry /><entry /><entry>loaded second</entry><entry>loaded second</entry></row><row><entry /><entry>Arrangement 8</entry><entry>Odd descending</entry><entry>Even ascending</entry></row><row><entry /><entry /><entry>loaded first</entry><entry>loaded first</entry></row><row><entry /><entry /><entry>Even ascending</entry><entry>Odd descending</entry></row><row><entry /><entry /><entry>loaded second</entry><entry>loaded second</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> CMOS Support on Bilithic Printhead <br /> 1 Basic Requirements
3873To create a two part printhead, of A4/Letter portrait width to print a page in 2 seconds. Matching Left/Right chips can be of different lengths to make up this length facilitating increased wafer usage. the left and right chips are to be imaged on an 8 inch wafer by “Stitching” reticle images.
3874The memjet nozzles have a horizontal pitch of 32 um, two rows of nozzles are used for a single colour. These rows have a horizontal offset of 16 um. This gives an effective dot pitch of 16 um, or 62.5 dots per mm, or 1587.5 dots per inch, close enough to market as 1600 dpi.
3875The first nozzle of the right chip should have a 32 um horizontal offset from the final nozzle of the left chip for the same color row. There is no ink nozzle overlap (of the same colour) scheme employed.
00001.1 Power Supply
3876Vdd/Vpos and Ground supply is made through 30 um wide pads along the length of the chip using conductive adhesive to bus bar beside the chips. Vdd/Vpos is 3.3 Volts. (12V was considered for Vpos but routing of CMOS Vdd at 3.3V would be a problem over the length of the chips, but this will be revisited).
00001.2 MEMS Cells
3877The preferred memjet device requires 180 nJ of energy to fire, with a pulse of current for 1 usec. Assuming 95% efficiency, this requires a 55 ohm actuator drawing 57.4 mA during this pulse.
00001.2.1 Issue!!!
3878For 1 pages per 2 second, or ˜300 mm*62.5 (dots/mm)/2 sec˜=10 kHz or 100 usec per line. With 1 usec fire pulse cycle, every 100th nozzle needs to fire at the same time. We have 13824 nozzles across the page, so we fire 138 nozzles at a time.
00001.2.2 64 um Unit Cell Height
3879This cell would have 4 line spacing between the odd and even dots, and 8 line spacing between adjacent colours.
00001.2.3 80 um Unit Cell Height
3880This cell would have 5 line spacing between the odd and even dots, and 10 line spacing between adjacent colours.
00001.3 Versions
00001.3.1 6 Colour 1600 dpi with 64 um Unit Cell
3881Left and Right Chip.
00001.3.2 6 Colour 1600 dpi with 80 um Unit Cell
3882Left and Right Chip.
00001.3.3 4 Colour 800 dpi with 80 um Unit Cell
3883For camera application. Single nozzle row per colour.
00001.4 Air Supply
3884Air must be supplied to the MEMS region through holes in the chip.
00002 Head Sizes
3885The combined heads have 13824 nozzles per colour totalling 221.184 mm of print area. Enough to provide full breadth for A4 (210 mm) and Letter (8.5 inch or 215.9 mm).
3886<tables id="TABLE-US-00352" num="00352"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 1</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Head Combinations</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="77pt" align="center" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="77pt" align="center" /><colspec colname="4" colwidth="21pt" align="center" /><tbody valign="top"><row><entry /><entry>Left Head</entry><entry /><entry>Right Head</entry><entry /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="21pt" align="center" /><colspec colname="2" colwidth="77pt" align="center" /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="77pt" align="center" /><tbody valign="top"><row><entry /><entry>Stitch</entry><entry>Nozzles</entry><entry>Stitch</entry><entry>Nozzles</entry></row><row><entry /><entry>Parts</entry><entry>per Colour</entry><entry>Parts</entry><entry>per Colour</entry></row><row><entry /><entry namest="offset" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="21pt" align="center" /><colspec colname="2" colwidth="77pt" align="char" char="." /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="77pt" align="char" char="." /><tbody valign="top"><row><entry /><entry>8</entry><entry>11160</entry><entry>2</entry><entry>2664</entry></row><row><entry /><entry>7</entry><entry>9744</entry><entry>3</entry><entry>4080</entry></row><row><entry /><entry>6</entry><entry>8328</entry><entry>4</entry><entry>5496</entry></row><row><entry /><entry>5</entry><entry>6912</entry><entry>5</entry><entry>6912</entry></row><row><entry /><entry>4</entry><entry>5496</entry><entry>6</entry><entry>8328</entry></row><row><entry /><entry>3</entry><entry>4080</entry><entry>7</entry><entry>9744</entry></row><row><entry /><entry>2</entry><entry>2664</entry><entry>8</entry><entry>11160</entry></row><row><entry /><entry namest="offset" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3887Nozzles per Colour is calculated as ((“Stitch Parts” −1)*118+104)*12. Nozzles per row is half this value. Most likely the 8:2 head set will not be manufactured. The preferred wafer layout, manages to avoid this set, without any loses.
00003 Interface
3888Each print head has the same I/O signals (but the Left and Right versions might have a different pin out).
3889<tables id="TABLE-US-00353" num="00353"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 2</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>I/O pins</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="14pt" align="left" /><colspec colname="3" colwidth="91pt" align="left" /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="28pt" align="center" /><tbody valign="top"><row><entry /><entry /><entry /><entry /><entry>Max</entry></row><row><entry /><entry /><entry /><entry /><entry>Speed</entry></row><row><entry>Name</entry><entry>I/O</entry><entry>Function</entry><entry>Common</entry><entry>(MHz)</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="14pt" align="left" /><colspec colname="3" colwidth="91pt" align="left" /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="28pt" align="char" char="." /><tbody valign="top"><row><entry>Data[0–1]</entry><entry>I</entry><entry>Dot data for colours 0–5,</entry><entry>No</entry><entry>320</entry></row><row><entry /><entry /><entry>using Differential</entry></row><row><entry /><entry /><entry>Signalling (DataL the</entry></row><row><entry /><entry /><entry>complementary signal),</entry></row><row><entry /><entry /><entry>colours[0–2] on Data[0],</entry></row><row><entry /><entry /><entry>colour[3–5] on Data[1]</entry></row><row><entry>DataL[0–1]</entry><entry>I</entry><entry>complementary signal of</entry></row><row><entry /><entry /><entry>Data[0–1]</entry></row><row><entry>SrClk</entry><entry>I</entry><entry>Dot data shift clock</entry><entry>No<sup>1</sup></entry><entry>320</entry></row><row><entry /><entry /><entry>using Differential</entry></row><row><entry /><entry /><entry>Signalling (SrClkL</entry></row><row><entry /><entry /><entry>the complementary signal)</entry></row><row><entry>SrClkL</entry><entry>I</entry><entry>complementary signal</entry></row><row><entry /><entry /><entry>of SrClk</entry></row><row><entry>ReadL</entry><entry>I</entry><entry>FrClk, Pr, LSyncL output</entry><entry>Yes</entry><entry>1</entry></row><row><entry /><entry /><entry>mode if signal mode</entry></row><row><entry /><entry /><entry>bit is set</entry></row><row><entry>FrClk</entry><entry>I</entry><entry>Fire pattern shift clock</entry><entry>Yes</entry><entry>1</entry></row><row><entry /><entry>O</entry><entry>nozzle test result</entry><entry>Yes<sup>2</sup></entry></row><row><entry /><entry /><entry>(mode = 0b001),</entry></row><row><entry /><entry /><entry>LsyncL = 0</entry></row><row><entry /><entry /><entry>CMOS testing (mode =</entry></row><row><entry /><entry /><entry>0b111), LsyncL = 1</entry></row><row><entry>Pr</entry><entry>I</entry><entry>Pulse Profile for all colours</entry><entry>Yes</entry><entry> 1<sup>3</sup></entry></row><row><entry /><entry>O</entry><entry>Temperature Output</entry><entry>Yes<sup>b</sup></entry></row><row><entry /><entry /><entry>(mode = 0b010),</entry></row><row><entry /><entry /><entry>LsyncL = 0</entry></row><row><entry /><entry /><entry>CMOS testing (mode =</entry></row><row><entry /><entry /><entry>0b111), LsyncL = 1</entry></row><row><entry>LsyncL</entry><entry>I</entry><entry>0 - Capture dot data for</entry><entry>Yes</entry><entry>0.1<sup>4</sup></entry></row><row><entry /><entry /><entry>next print line</entry></row><row><entry /><entry>O</entry><entry>CMOS testing (mode =</entry><entry>Yes<sup>b</sup></entry></row><row><entry /><entry /><entry>0b111), LsyncL = 1</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row><row><entry namest="1" nameend="5" align="left" id="FOO-00034"><sup>1</sup>Functionally could be common, but for timing/electrical reasons should run point to point.</entry></row><row><entry namest="1" nameend="5" align="left" id="FOO-00035"><sup>2</sup>Can be shared if one side has mode = 0b000</entry></row><row><entry namest="1" nameend="5" align="left" id="FOO-00036"><sup>3</sup>1 MHz cycle, but the resolution of the mark/space ratio may require 50 ns.</entry></row><row><entry namest="1" nameend="5" align="left" id="FOO-00037"><sup>4</sup>10 kHz cycle, with minimum low pulse of 10 ns (no maximum).</entry></row></tbody></tgroup></table></tables>
3890Pins marked as common can be controlled by the same signal from the controller (SOPEC).
00003.1 Dot Firing
3891To fire a nozzle, three signals are needed. A dot data, a fire signal, and a profile signal. When all signals are high, the nozzle will fire.
3892The dot data is provide to the chip through a dot shift register with input Data[x], and clocked into the chip with SrClk. The dot data is multiplex on to the Data signals, as Dot[0–2] on Data[0], and Dot[3–51 on Data[2]. After the dots are shifted into the dot shift register, this data is transfer into the dot latch, with a low pulse in LsyncL. The value in the dot latch forms the dot data used to fire the nozzle. The use of the dot latch allows the next line of data to be loaded into the dot shift register, at the same time the dot pattern in the dot latch is been fired.
3893Across the top of a column of nozzles, containing 12 nozzles, 2 of each colour (odd and even dots, 4 or 5 lines apart), is two fire register bits and a select register bit. The fire registers forms the fire shift register that runs length of the chip and back again with one register bit in each direction flow. The select register forms the Select Shift Register that runs the length of the chip. The select register, selects which of the two fire registers is used to enables this column. A ‘0’ in this register selects the forward direction fire register, and a ‘1’ selects the reverse direction fire register. This output of this block provides the fire signal for the column.
3894The third signal needed, the profile, is provide for all colours with input Pr across the whole colour row at the same time (with a slight propagation delay per column).
00003.2 Dot Shift Register Orientation
3895The left side print head (chip) and the right side print head that form complete bi-lithic print head, have different nozzle arrangement with respect to the dot order mapping of the dot shift register to the dot position on the page.
3896With this mapping, the following data streams will need to provided.
3897<tables id="TABLE-US-00354" num="00354"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="217pt" align="center" /><colspec colname="2" colwidth="154pt" align="center" /><tbody valign="top"><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>Left Head</entry><entry>Right Head</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="21pt" align="left" /><colspec colname="2" colwidth="21pt" align="left" /><colspec colname="3" colwidth="175pt" align="left" /><colspec colname="4" colwidth="154pt" align="left" /><tbody valign="top"><row><entry>Size</entry><entry>n-m</entry><entry>dot order</entry><entry>m</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="21pt" align="left" /><colspec colname="2" colwidth="21pt" align="left" /><colspec colname="3" colwidth="175pt" align="left" /><colspec colname="4" colwidth="21pt" align="left" /><colspec colname="5" colwidth="133pt" align="left" /><tbody valign="top"><row><entry>7:3</entry><entry>97 44</entry><entry>[13822, 13820, 13818, . . . , 4084, 4082, 4080,] line y + 5</entry><entry>40 80</entry><entry>[1, 3, 5, . . . , 4075, 4077, 4079,] line y</entry></row><row><entry /><entry /><entry>[4081, 4083, 4085, . . . , 13819, 13821, 13823] line y</entry><entry /><entry>[4078, 4076, 4074, . . . , 4, 2, 0] line y + 5</entry></row><row><entry>6:4</entry><entry>83 28</entry><entry>[13822, 13820, 13818, . . . , 5500, 5498, 5496,] line y + 5</entry><entry>54 96</entry><entry>[1, 3, 5, . . . , 5491, 5493, 5495,] line y</entry></row><row><entry /><entry /><entry>[5497, 5499, 5501, . . . , 13819, 13821, 13823] line y</entry><entry /><entry>[5494, 5492, 5490, . . . , 4, 2, 0] line y + 5</entry></row><row><entry>5:5</entry><entry>69 12</entry><entry>[13822, 13820, 13818, . . . , 6916, 6914, 6912,] line y + 5</entry><entry>69 12</entry><entry>[1, 3, 5, . . . , 6907, 6909, 6911,] line y</entry></row><row><entry /><entry /><entry>[6913, 6915, 6917, . . . , 13819, 13821, 13823] line y</entry><entry /><entry>[6910, 6908, 6906, . . . , 4, 2, 0] line y + 5</entry></row><row><entry>4:6</entry><entry>54 96</entry><entry>[13822, 13820, 13818, . . . , 8332, 8330, 8328,] line y + 5</entry><entry>83 28</entry><entry>[1, 3, 5, . . . , 8323, 8325, 8327,] line y</entry></row><row><entry /><entry /><entry>[8329, 8331, 8333, . . . , 13819, 13821, 13823] line y</entry><entry /><entry>[8326, 8324, 8322, . . . , 4, 2, 0] line y + 5</entry></row><row><entry>3:7</entry><entry>40 80</entry><entry>[13822, 13820, 13818, . . . , 9748, 9746, 9744,] line y + 5</entry><entry>97 44</entry><entry>[1, 3, 5, . . . , 9739, 9741, 9743,] line y</entry></row><row><entry /><entry /><entry>[9745, 97447, 9749, . . . , 13819, 13821, 13823] line y</entry><entry /><entry>9742, 9740, 9738, . . . , 4, 2, 0] line y + 5</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3898The data needs to be multiplexed onto the data pins, such that Data[0] has {(C0, C1, C2), (C0, C1, C2) . . . } in the above order, and Data[1] has {(C3, C4, C5), (C3, C4, C5) . . . }.
3899<figref idref="DRAWINGS">FIG. 311</figref> shows the timing of data transfer during normal printing mode. Note SrClk has a default state of high and data is transferred on both edges of SrClk. If there are L nozzles per colour, SrClk would have L+2 edges, where the first and last edges do not transfer data.
3900Data requires a setup and hold about the both edges of SrClk. Data transfers starts on the first rising after LSyncL rising. SrClk default state is high and needs to return to high after the last data of the line. This means the first edge of SrClk (falling) after LSyncL rising, and the last edge of SrClk as it returns to the default state, no data is transferred to the print head. LSyncL rising requires setup to the first falling SrClk, and must stay high during the entire line data transfer until after last rising SrClk.
00003.3 Fire Shift Register
3901The fire shift register controls the rate of nozzle fire. If the register is full of ‘1’s then the you could print the entire print head in a single FrClk cycle, although electrical current limitations will prevent this happening in any reasonable implementation.
3902Ideally, a ‘1’ is shifted in to the fire shift register, in every n<sup>th </sup>position, and a ‘0’ in all other position. In this manner, after n cycles of FrClk, the entire print head will be printed.
3903The fire shift register and select shift registers allow the generation of a horizontal print line that on close inspection would not have a discontinuity of a “saw tooth” pattern, <figref idref="DRAWINGS">FIGS. 312</figref><i>a</i>) & <i>b</i>) but a “sharks tooth” pattern of c).
3904This is done by firing 2 nozzles in every 2n group of nozzle at the same time starting from the outer 2 nozzles working towards the centre two (or the starting from the centre, and working towards the outer two) at the fire rate controlled by FrClk.
3905To achieve this fire pattern the fire shift register and select shift register need to be set up as show in <figref idref="DRAWINGS">FIG. 313</figref>.
3906The pattern has shifted a ‘1’ into the fire shift register every n<sup>th </sup>positions (where n is usually is a minimum of about 100) and n ‘1’s, followed n ‘0’s in the select shift register. At a start of a print cycle, these patterns need to be aligned as above, with the 1000 . . . ” of a forward half of fire shift register, matching an n grouping of ‘1’ or ‘0’s in the select shift register. As well, with the “1000 . . . ” of a reverse half of the fire shift register, matching an n grouping of ‘1’ or ‘0’s in the select shift register. And to continue this print pattern across the butt ends of the chips, the select shift register in each should end with a complete block of n ‘1’s (or ‘0’s).
3907Since the two chips can be of different lengths, initialisation of these patterns is an issue. This is solved by building initialisation circuitry into chips. This circuit is controlled by two registers, nlen(14) and count(14) and b(1). These registers are loaded serially through Data[0], while LSyncL is low, and ReadL is high with FrClk.
3908The scan order from input is b, n[13–0],c[0–13],color[5–0], mode[2–0] therefore b is shifted in last. The system color and mode registers are unrelated to the Fire Shift Register, but are loaded at the same time as this block. There function is described later.
3909<tables id="TABLE-US-00355" num="00355"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="280pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 4</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Head Combinations Initialisation for n = 100</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="8"><colspec colname="1" colwidth="35pt" align="center" /><colspec colname="2" colwidth="35pt" align="center" /><colspec colname="3" colwidth="42pt" align="center" /><colspec colname="4" colwidth="42pt" align="center" /><colspec colname="5" colwidth="14pt" align="center" /><colspec colname="6" colwidth="14pt" align="center" /><colspec colname="7" colwidth="42pt" align="center" /><colspec colname="8" colwidth="56pt" align="center" /><tbody valign="top"><row><entry /><entry /><entry /><entry>count<sub>A </sub>=</entry><entry /><entry /><entry /><entry>count<sub>B </sub>=</entry></row><row><entry>Nozzle s</entry><entry>Nozzle s</entry><entry>nlen<sub>(A&B) </sub>=</entry><entry>(L<sub>A</sub>/2) mod</entry><entry /><entry /><entry>rem =</entry><entry>(L<sub>A </sub>− L<sub>B </sub>+ rem)</entry></row><row><entry>L<sub>B</sub></entry><entry>L<sub>A</sub></entry><entry>n − 1</entry><entry>n − 1</entry><entry>b <sub>A</sub></entry><entry>b <sub>B</sub></entry><entry>(L<sub>B</sub>/2) mod n</entry><entry>mod n − 1</entry></row><row><entry namest="1" nameend="8" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="8"><colspec colname="1" colwidth="35pt" align="center" /><colspec colname="2" colwidth="35pt" align="center" /><colspec colname="3" colwidth="42pt" align="center" /><colspec colname="4" colwidth="42pt" align="center" /><colspec colname="5" colwidth="14pt" align="center" /><colspec colname="6" colwidth="14pt" align="center" /><colspec colname="7" colwidth="42pt" align="center" /><colspec colname="8" colwidth="56pt" align="char" char="." /><tbody valign="top"><row><entry>4080</entry><entry>9744</entry><entry>99</entry><entry>71</entry><entry>0</entry><entry>0</entry><entry>40</entry><entry>3</entry></row><row><entry>5496</entry><entry>8328</entry><entry>99</entry><entry>63</entry><entry>0</entry><entry>0</entry><entry>48</entry><entry>79</entry></row><row><entry>6912</entry><entry>6912</entry><entry>99</entry><entry>55</entry><entry>0</entry><entry>0</entry><entry>56</entry><entry>55</entry></row><row><entry namest="1" nameend="8" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
3910The following table shows the values to programme the bi-lithic head pairs using a fire pattern length of 100. The calculation assumes head ‘A’ is the longest head of the pair and once the registers are initialised with LA FrClk cycles (ReadL=‘0’, LSyncL=‘1’). rem would be the correct value for count<sub>B </sub>if chip B was only clocked (FrClk) L<sub>B </sub>times. But this chip will be over clocked L<sub>A</sub>−L<sub>B </sub>cycles. The values of b<sub>A </sub>and b<sub>B </sub>are either the same or inverse of each other. The actually value does not matter. They need to be different from each other if the select shift registers would end up with different values at the butt ends. If (L<sub>A</sub>/2n) is even (and count<sub>A </sub>is non zero), then the final run in ‘A’s select shift register will be !b<sub>A</sub>. If (L<sub>A</sub>−L<sub>B</sub>/2) mod n is even (and count<sub>b </sub>is non zero) then the final run in ‘B’s select shift register will be !b<sub>B</sub>.
00003.4 System Registers
3911As describe above, the Fire Shift Register generation block, also contains some system registers.
3912<tables id="TABLE-US-00356" num="00356"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 5</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>System Registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="28pt" align="center" /><colspec colname="3" colwidth="161pt" align="left" /><tbody valign="top"><row><entry>Name</entry><entry>Size</entry><entry>Function</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>Color</entry><entry>6</entry><entry>Each bit is an enable for the corresponding colour.</entry></row><row><entry /><entry /><entry>If color[X] = 0, then Pr<sub>x </sub>is 0 and SrClk<sub>x </sub>is 0.</entry></row><row><entry /><entry /><entry>If color[X] = 1, then Pr<sub>x </sub>follows the Pr signal and</entry></row><row><entry /><entry /><entry>SrClk<sub>x </sub>is deserialised SrClk.</entry></row><row><entry>Mode</entry><entry>3</entry><entry>Mode[0] = 1, then FrClk pin is used as an output,</entry></row><row><entry /><entry /><entry>internally the FrClk signal is set to 0</entry></row><row><entry /><entry /><entry>Mode[1] = 1, then Pr pin is used as an output,</entry></row><row><entry /><entry /><entry>internally the Pr signal is set to 0</entry></row><row><entry /><entry /><entry>Mode[2] = 1, then LsyncL pin is used as an output,</entry></row><row><entry /><entry /><entry>internally the LsyncL signal is set to 1</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 3.5 Profile Pattern
3913A profile pattern is repeated at FrClk rate. It is expected to be a single pulse about 1 us long. But it could be a more complicated series of pulse. The actual pattern depends on the ink type.
3914The following figure show the external timing to print a line of data. In this example the line is printed in 8 cycles of FrClk.
00003.6 Interface Modes
3915The print head has eight different modes controlled by signals ReadL and LSyncL and system mode register. As seen in <figref idref="DRAWINGS">FIG. 318</figref> with both LSyncL and ReadL high, the chip in normal printing mode. Some of these modes can operate at the same time, but may interfere with the result of the other modes.
3916<tables id="TABLE-US-00357" num="00357"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 6</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Print Head Modes</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="35pt" align="center" /><colspec colname="2" colwidth="28pt" align="center" /><colspec colname="3" colwidth="70pt" align="left" /><colspec colname="4" colwidth="28pt" align="center" /><colspec colname="5" colwidth="56pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry /><entry>Mode</entry><entry /></row><row><entry /><entry /><entry /><entry>Reg-</entry><entry>Internal</entry></row><row><entry>ReadL</entry><entry>LSyncL</entry><entry>Function</entry><entry>ister</entry><entry>Mapping</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row><row><entry>1</entry><entry>1</entry><entry>Normal Print Mode</entry><entry>000</entry><entry>SrClk = SrClk/3</entry></row><row><entry /><entry /><entry /><entry>(XXX)</entry><entry>frclk = FrClk</entry></row><row><entry /><entry /><entry /><entry /><entry>SelClk = 0</entry></row><row><entry /><entry /><entry /><entry /><entry>FsClk = FrClk</entry></row><row><entry /><entry /><entry /><entry /><entry>Scan = 0</entry></row><row><entry /><entry /><entry /><entry /><entry>CoreScan = 0</entry></row><row><entry>X</entry><entry>0</entry><entry>Dot Load Mode</entry><entry>000</entry></row><row><entry /><entry /><entry>Dot latches are open,</entry><entry>(XXX)</entry></row><row><entry /><entry /><entry>loaded with Dot shift</entry></row><row><entry /><entry /><entry>registers, latch once</entry></row><row><entry /><entry /><entry>LSyncL returns to 1</entry></row><row><entry /><entry /><entry>(this happens</entry></row><row><entry /><entry /><entry>regardless of ReadL)</entry></row><row><entry /><entry /><entry>Enables Dot Shift</entry></row><row><entry /><entry /><entry>register to capture</entry></row><row><entry /><entry /><entry>fire result.</entry></row><row><entry>1</entry><entry>0</entry><entry>Fire Load Mode</entry><entry>000</entry><entry>SrClk = X</entry></row><row><entry /><entry /><entry>Data[0] will</entry><entry>(XXX)</entry><entry>frclk = X</entry></row><row><entry /><entry /><entry>shift through mode,</entry><entry /><entry>SelClk = X</entry></row><row><entry /><entry /><entry>color, nlen,</entry><entry /><entry>FsClk = FrClk</entry></row><row><entry /><entry /><entry>count and b with</entry><entry /><entry>Scan = 1</entry></row><row><entry /><entry /><entry>FrClk</entry><entry /><entry>CoreScan = X</entry></row><row><entry>0</entry><entry>1</entry><entry>Reset Nozzle Test</entry><entry>001</entry><entry>SrClk = SrClk</entry></row><row><entry /><entry /><entry>Resets the state of</entry><entry /><entry>FrClk = FrClk</entry></row><row><entry /><entry /><entry>nozzle test circuit</entry><entry /><entry>SelClk = FrClk</entry></row><row><entry /><entry /><entry /><entry /><entry>FsClk = FrClk</entry></row><row><entry /><entry /><entry /><entry /><entry>Scan = 0</entry></row><row><entry /><entry /><entry /><entry /><entry>CoreScan = 1</entry></row><row><entry>0</entry><entry>1</entry><entry>CMOS testing mode</entry><entry>111</entry></row><row><entry /><entry /><entry>The contents of the</entry></row><row><entry /><entry /><entry>dot shift registers</entry></row><row><entry /><entry /><entry>are serial shifted</entry></row><row><entry /><entry /><entry>out on LsyncL</entry></row><row><entry /><entry /><entry>(colour0–1),</entry></row><row><entry /><entry /><entry>FrClk (colour2–3),</entry></row><row><entry /><entry /><entry>Pr (colour4–5)</entry></row><row><entry /><entry /><entry>with SrClk</entry></row><row><entry>0</entry><entry>1</entry><entry>Fire Initialise mode</entry><entry>000</entry></row><row><entry /><entry /><entry>The contents of the</entry><entry>(XX0)</entry></row><row><entry /><entry /><entry>fire shift register</entry></row><row><entry /><entry /><entry>and select shift</entry></row><row><entry /><entry /><entry>register is generated</entry></row><row><entry /><entry /><entry>with FrClk</entry></row><row><entry>0</entry><entry>0</entry><entry>Temperature Output</entry><entry>010</entry><entry>SrClk = X</entry></row><row><entry /><entry /><entry>The series of Sigma</entry><entry /><entry>frclk = 0</entry></row><row><entry /><entry /><entry>Delta output are</entry><entry /><entry>SelClk = 0</entry></row><row><entry /><entry /><entry>clocked out on Pr</entry><entry /><entry>FsClk = 0</entry></row><row><entry /><entry /><entry>with FrClk. The</entry><entry /><entry>Scan = 0</entry></row><row><entry /><entry /><entry>sum of these bits</entry><entry /><entry>CoreScan = X</entry></row><row><entry /><entry /><entry>represent the</entry></row><row><entry /><entry /><entry>temperature of the</entry></row><row><entry /><entry /><entry>chip.</entry></row><row><entry>0</entry><entry>0</entry><entry>Nozzle Test Output</entry><entry>001</entry></row><row><entry /><entry /><entry>The result of a</entry></row><row><entry /><entry /><entry>nozzle test is</entry></row><row><entry /><entry /><entry>output on FrClk.</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 3.6.1 Printing
3917<figref idref="DRAWINGS">FIG. 318</figref> shows show timing for normal printing. During this action, we drop out of Normal Print Mode, to Dot Load Mode between line transfers. For printing to perform correctly, all other signals should be stable.
00003.6.2 Initialising for Printing
3918To initialise for printing the fire shift registers and select shift registers need to be setup into a state as shown in <figref idref="DRAWINGS">FIG. 318</figref>. To do this the chips are put into Fire Load Mode and the values for nlen, count and b are serially shifted from Data[0] clocked by FrClk. As the two chip have separate Data line, and common FrClk, this happens at the same time. Once this is done, mode is changed to Fire Initialise Mode, and further LA FrClk cycles are provided to both chips. During all these operation Pr should be low, to prevent unintentional firing for nozzles.
00003.6.3 Nozzle Testing
3919Nozzle testing is done by firing a single nozzle at a time and monitoring the FrClk pin in the Nozzle Test Output mode.
3920Each nozzle has a test switch which closes when the nozzle is fired with an energy level greater than required for normal ink ejection. All 12 switches in a nozzle column are connect in parallel to the following circuit.
3921This circuit is initialised when ever LSyncL is high and ReadL is low (Reset Nozzle Test mode). This forces all “switch nodes” to low, and the feedback through lower NOR gate will latches this value. With LSyncL low and ReadL still low (Nozzle Test Output mode) the Testout of the first nozzle column is output on FrClk. If any switch is closed, the switch node of this column will be pulled up, and will ripple through to the output as transition from high to low.
3922Nozzle testing requires a setup phase in order to fire only one nozzle. There are many ways to achieve this. Simplest might be to load a single colour with 101010 through the even nozzles, and 010101 . . . for the odd nozzles (0's for all other colours), and set up a fire pattern with n=L<sub>A</sub>/2. With this fire pattern only one nozzle will fire in each Pr pulse. After firing in Nozzle Test Output mode, a single FrClk will advance to next nozzle, then Reset and Test. After L<sub>A</sub>/2 cycles of this testing, a single SrClk will advance the dot shift registers to setup the untested nozzles of this colour, and another L<sub>A</sub>/2 cycles of FrClk, Reset and Test will finished testing this colour. Then repeat test procedure for other colours.
00003.6.4 Temperature Output
3923This mode is not well defined yet. In this mode, Pr will output a series of ones and zeros clocked by FrClk. After a (currently unknown) number of FrClk cycles the sum of this series will represent the temperature of the chip. Clocking frequency in this mode it expected to be in the range 10 kHz–1 MHz.
3924The Frequency of FrClk and the number of cycles need to be programmable. Since this mode cycles FrClk, the result of fire shift register and select shift register would be changed, but in this mode FrClk is disabled to these circuit. So printing can resume without reinitialising.
00003.6.5 CMOS Testing
3925CMOS testing is a mode meant for chip testing before MEMS as added to the chip. This mode allows the dot shift register to be shifted out on the LsyncL, FrClk and Pr pins. Much like the nozzle test mode, the nozzles are fired while LSyncL is low, but during the firing SrClk will be pulsed, loading the dot shift register with the signal that would fire the nozzle. Once captured, the result can be shifted out.
3926The Dot Load Mode above violates normal printing procedure by firing the nozzles (Pr) and modify the dot shift register (SrClk).
00004 Reticle Layout
3927To make long chips we need to stitch the CMOS (and MEMS) together by overlapping the reticle stepping field. The reticle will contain two areas:
3928The top edge of Area <b>2</b>, PAD END contains the pads that stitch on bottom edge of Area <b>1</b>, CORE. Area <b>1</b> contains the core array of nozzle logic. The top edge of Area <b>1</b> will stitch to the bottom edge of itself. Finally the bottom edge of Area <b>2</b>, BUTT END will stitch to the top edge of Area <b>1</b>. The BUTT END to used to complete a feedback wiring and seal the chip.
3929The above region will then be exposed across a wafer bottom to top. Area <b>2</b>, Area <b>1</b>, Area <b>1</b> . . . , Area <b>2</b>. Only the PAD END of Area <b>2</b> needs to fit on the wafer. The final exposure of Area <b>2</b> only requires the BUTT END on the wafer.
00004.1 TSMC U-frame Requirements.
3930TSMC will be building us frames 10 mm×0.23 mm which will be placed either side of both Area <b>1</b> and Area <b>2</b>.
3931TSMC requires 6 mm area for blading between the two exposure area. This translates to 3 mm on the reticle, as some reticules are 2× size, while most are 5×, the worst case must be used.
0000Security Overview
00001 Introduction
3932A number of hardware, software and protocol solutions to security issues have been developed. These range from authorization and encryption protocols for enabling secure communication between hardware and software modules, to physical and electrical systems that protect the integrity of integrated circuits and other hardware.
3933It should be understood that in many cases, principles described with reference to hardware such as integrated circuits (ie, chips) can be implemented wholly or partly in software running on, for example, a computer. Mixed systems in which software and hardware (and combinations) embody various entities, modules and units can also be constructed using may of these principles, particularly in relation to authorization and authentication protocols. The particular extent to which the principles described below can be translated to or from hardware or software will be apparent to one skilled in the art, and so will not always explicitly be explained.
3934It should also be understood that many of the techniques disclosed below have application to many fields other than printing. Some specific examples are described towards the end of this description.
3935A “QA Chip” is a quality assurance chip can allows certain security functions and protocols to be implemented. The preferred QA Chip is described in some detail later in this specification.
00001.5 QA Chip Terminology
3936The Authentication Protocols documents [5] and [6] refer to QA Chips by their function in particular protocols: <ul id="ul0382" list-style="none"><li id="ul0382-0001" num="0000"><ul id="ul0383" list-style="none"><li id="ul0383-0001" num="3937">For authenticated reads in [5], ChipR is the QA Chip being read from, and ChipT is the QA Chip that identifies whether the data read from ChipR can be trusted. ChipR and ChipT are referred to as Untrusted QA Device and Trusted QA Device respectively in [6].</li><li id="ul0383-0002" num="3938">For replacement of keys in [5], ChipP is the QA Chip being programmed with the new key, and ChipF is the factory QA Chip that generates the message to program the new key. ChipF is referred to as the Key Programmer QA Device in [6].</li><li id="ul0383-0003" num="3939">For upgrades of data in memory vectors in [5], ChipU is the QA Chip being upgraded, and ChipS is the QA Chip that signs the upgrade value. ChipS is referred to as the Value Upgrader QA Device and Parameter Upgrader QA Device in [6].</li></ul></li></ul>
3940Any given physical QA Chip will contain functionality that allows it to operate as an entity in some number of these protocols.
3941Therefore, wherever the terms ChipR, ChipT, ChipP, ChipF, ChipU and ChipS are used in this document, they are referring to logical entities involved in an authentication protocol as defined in [5] and [6].
3942Physical QA Chips are referred to by their location. For example, each ink cartridge may contain a QA Chip referred to as an INK_QA, with all INK_QA chips being on the same physical bus. In the same way, the QA Chip inside the printer is referred to as PRINTER_QA, and will be on a separate bus to the INK_QA chips.
00002 Requirements
00002.1 Security
3943When applied to a printing environment, the functional security requirements for the preferred embodiment are: <ul id="ul0384" list-style="none"><li id="ul0384-0001" num="0000"><ul id="ul0385" list-style="none"><li id="ul0385-0001" num="3944">Code of QA chip owner or licensee co-existing safely with code of authorized OEMs</li><li id="ul0385-0002" num="3945">Chip owner/licensee operating parameters authentication</li><li id="ul0385-0003" num="3946">Parameters authentication for authorized OEMs</li><li id="ul0385-0004" num="3947">Ink usage authentication</li></ul></li></ul>
3948Each of these is outlined in subsequent sections.
3949The authentication requirements imply that: <ul id="ul0386" list-style="none"><li id="ul0386-0001" num="0000"><ul id="ul0387" list-style="none"><li id="ul0387-0001" num="3950">OEMs and end-users must not be able to replace or tamper with QA chip manufacturer/owner's program code or data</li><li id="ul0387-0002" num="3951">OEMs and end-users must not be able to perform unauthorized activities for example by calling chip manufacturer/owner's code</li><li id="ul0387-0003" num="3952">End-users must not be able to replace or tamper with OEM program code or data</li><li id="ul0387-0004" num="3953">End-users must not be able to call unauthorized functions within OEM program code</li><li id="ul0387-0005" num="3954">Manufacturer/owner's development program code must not be capable of running on all SoPECs.</li><li id="ul0387-0006" num="3955">OEMs must be able to test products at their highest upgradable status, yet not be able to ship them outside the terms of their license</li><li id="ul0387-0007" num="3956">OEMs and end-users must not be able to directly access the print engine pipeline (PEP) hardware, the LSS Master (for QA Chip access) or any other peripheral block with the exception of operating system permitted GPIO pins and timers. <br /> 2.1.1 QA Manufacturer/Owner Code and OEM Program Code Co-existing Safely </li></ul></li></ul>
3957SoPEC includes a CPU that must run both manufacturer/owner program code and OEM program code. The execution model envisaged for SoPEC is one where Manufacturer/owner program code forms an operating system (O/S), providing services such as controlling the print engine pipeline, interfaces to communications channels etc. The OEM program code must run in a form of user mode, protected from harming the Manufacturer/owner program code. The OEM program code is permitted to obtain services by calling functions in the O/S, and the O/S may also call OEM code at specific times. For example, the OEM program code may request that the O/S call an OEM interrupt service routine when a particular GPIO pin is activated.
3958In addition, we may wish to permit the OEM code to directly call functions in Manufacturer/owner code with the same permissions as the OEM code. For example, the Manufacturer/owner code may provide SHA1 as a service, and the OEM could call the SHA1 function, but execute that function with OEM permissions and not Silverbook permissions.
3959A basic requirement then, for SoPEC, is a form of protection management, whereby Manufacturer/owner and OEM program code can co-exist without the OEM program code damaging operations or services provided by the Manufacturer/owner O/S. Since services rely on SoPEC peripherals (such as USB2 Host, LSS Master, Timers etc) access to these peripherals should also be restricted to Manufacturer/owner program code only.
00002.1.2 Manufacturer/Owner Operating Parameters Authentication
3960A particular OEM will be licensed to run a Print Engine with a particular set of operating parameters (such as print speed or quality). The OEM and/or end-user can upgrade the operating license for a fee and thereby obtain an upgraded set of operating parameters.
3961Neither the OEM nor end-user should be able to upgrade the operating parameters without paying the appropriate fee to upgrade the license. Similarly, neither the OEM nor end-user should be able to bypass the authentication mechanism via any program code on SoPEC. This implies that OEMs and end-users must not be able to tamper with or replace Manufacturer/owner program code or data, nor be able to call unauthorized functions within Manufacturer/owner program code.
3962However, the OEM must be capable of assembly-line testing the Print Engine at the upgraded status before selling the Print Engine to the end-user.
00002.1.3 OEM Operating Parameters Authentication
3963The OEM may provide operating parameters to the end-user independent of the Manufacturer/owner operating parameters. For example, the OEM may want to sell a franking machine<sup>1</sup>. <sup>1</sup>a franking machine print stamps
3964The end-user should not be able to upgrade the operating parameters without paying the appropriate fee to the OEM. Similarly, the end-user should not be able to bypass the authentication mechanism via any program code on SoPEC. This implies that end-users must not be able to tamper with or replace OEM program code or data, as well as not be able to tamper with the PEP blocks or service-related peripherals.
00002.2 Acceptable Compromises
3965If an end user takes the time and energy to hack the print engine and thereby succeeds in upgrading the single print engine only, yet not be able to use the same keys etc on another print engine, that is an acceptable security compromise. However it doesn't mean we have to make it totally simple or cheap for the end-user to accomplish this.
3966Software-only attacks are the most dangerous, since they can be transmitted via the internet and have no perceived cost. Physical modification attacks are far less problematic, since most printer users are not likely to want their print engine to be physically modified. This is even more true if the cost of the physical modification is likely to exceed the price of a legitimate upgrade.
00002.3 Implementation Constraints
3967Any solution to the requirements detailed in Section 2.1 should also meet certain preferred implementation constraints. These are: <ul id="ul0388" list-style="none"><li id="ul0388-0001" num="0000"><ul id="ul0389" list-style="none"><li id="ul0389-0001" num="3968">No flash memory inside SoPEC</li><li id="ul0389-0002" num="3969">SoPEC must be simple to verify</li><li id="ul0389-0003" num="3970">Manufacturer/owner program code must be updateable</li><li id="ul0389-0004" num="3971">OEM program code must be updateable</li><li id="ul0389-0005" num="3972">Must be bootable from activity on USB2</li><li id="ul0389-0006" num="3973">Must be bootable from an external ROM to allow stand-alone printer operation</li><li id="ul0389-0007" num="3974">No extra pins for assigning IDs to slave SoPECs</li><li id="ul0389-0008" num="3975">Cannot trust the comms channel to the QA Chip in the printer (PRINTER QA)</li><li id="ul0389-0009" num="3976">Cannot trust the comms channel to the QA Chip in the ink cartridges (INK_QA)</li><li id="ul0389-0010" num="3977">Cannot trust the USB comms channel</li></ul></li></ul>
3978These constraints are detailed below.
00002.3.1 No Flash Memory Inside SoPEC
3979The preferred embodiment of SoPEC is intended to be implemented in 0.13 micron or smaller. Flash memory will not be available in any of the target processes being considered.
00002.3.2 SoPEC Must be Simple to Verify
3980All combinatorial logic and embedded program code within SoPEC must be verified before manufacture. Every increase in complexity in either of these increases verification effort and increases risk.
00002.3.3 Manufacturer/Owner Program Code Must be Updateable
3981It is neither possible nor desirable to write a single complete operating system that is: <ul id="ul0390" list-style="none"><li id="ul0390-0001" num="0000"><ul id="ul0391" list-style="none"><li id="ul0391-0001" num="3982">verified completely (see Section 2.3.1)</li><li id="ul0391-0002" num="3983">correct for all possible future uses of SoPEC systems</li><li id="ul0391-0003" num="3984">finished in time for SoPEC manufacture</li></ul></li></ul>
3985Therefore the complete Manufacturer/owner program code must not permanently reside on SoPEC. It must be possible to update the Manufacturer/owner program code as enhancements to functionality are made and bug fixes are applied.
3986In the worst case, only new printers would receive the new functionality or bug fixes. In the best case, existing SoPEC users can download new embedded code to enable functionality or bug fixes. Ideally, these same users would be obtaining these updates from the OEM website or equivalent, and not require any interaction with Manufacturer/owner.
00002.3.4 OEM Program Code Must be Updateable
3987Given that each OEM will be writing specific program code for printers that have not yet been conceived, it is impossible for all OEM program code to be embedded in SoPEC at the ASIC manufacture stage.
3988Since flash memory is not available (see Section 2.3.1), OEMs cannot store their program code in on-chip flash. While it is theoretically possible to store OEM program code in ROM on SoPEC, this would entail OEM-specific ASICs which would be prohibitively expensive. Therefore OEM program code cannot permanently reside on SoPEC.
3989Since OEM program code must be downloadable for SoPEC to execute, it should therefore be possible to update the OEM program code as enhancements to functionality are made and bug fixes are applied.
3990In the worst case, only new printers would receive the new functionality or bug fixes. In the best case, existing SoPEC users can download new embedded code to enable functionality or bug fixes. Ideally, these same users would be obtaining these updates from the OEM website or equivalent, and not require any interaction with Manufacturer/owner.
00002.3.5 Must be Bootable from Activity on USB2
3991SoPEC can be placed in sleep mode to save power when printing is not required. RAM is not preserved in sleep mode. Therefore any program code and data in RAM will be lost. However, SoPEC must be capable of being woken up by the host when it is time to print again.
3992In the case of a single SoPEC system, the host communicates with SoPEC via USB2. From SoPEC's point of view, it is activity on the USB2 device port that signals the time to wake up.
3993In the case of a multi-SoPEC system, the host typically communicates with the Master SoPEC chip (as above), and then the Master relays messages to other Slave SoPECs by sending data out USB2 host port(s) and into the Slave SoPEC's device port. The net result is that the Slave SoPECs and the Master SoPEC all boot as a result of activity on the USB2 device port.
3994Therefore SoPEC must be capable of being woken up by activity on the USB2 device port.
00002.3.6 Must be Bootable from an External ROM to Allow Stand-alone Printer Operation
3995SoPEC must also support the case where the printer is not connected to a PC (or the PC is currently turned off), and a digital camera or equivalent is plugged into the SoPEC-based printer. In this case, the entire printing application needs to be present within the hardware of the printer. Since the Manufacturer/owner program code and OEM program code will vary depending on the application (see Section 2.3.3 and Section 2.3.4), it is not possible to store the program in SoPEC's ROM.
3996Therefore SoPEC requires a means of booting from a non-PC host. It is possible that this could be accomplished by the OEM adding a USB2-host chip to the printer and simulating the effect of a PC, and thereby download the program code. This solution requires the boot operation to be based on USB2 activity (see Section 2.3.5). However this is an unattractive solution since it adds microprocessor complexity and component cost when only a ROM-equivalent was desired.
3997As a result SoPEC should ideally be able to boot from an external ROM of some kind. Note that booting from an external ROM means first booting from the internal ROM, and then downloading and authenticating the startup section of the program from the external ROM. This is not the same as simply running program code in-situ within an external ROM, since one of the security requirements was that OEMs and end-users must not be able to replace or tamper with Manufacturer/owner program code or data, i.e. we never want to blindly run code from an external ROM.
3998As an additional point, if SoPEC is in sleep mode, SoPEC must be capable of instigating the boot process due to activity on a programmable GPIO. e.g. a wake-up button. This would begin addition to the standard power-on booting.
00002.3.7 No Extra Pins to Assign IDs to Slave SoPECs
3999In a single SoPEC system the host only sends data to the single SoPEC. However in a multi-SoPEC system, each of the slaves needs to be uniquely identifiable in order to be able for the host to send data to the correct slave.
4000Since there is no flash on board SoPEC (Section 2.3.1) we are unable to store a slave ID in each SoPEC. Moreover, any ROM in each SoPEC will be identical.
4001It is possible to assign n pins to allow 2<sup>n </sup>combinations of IDs for slave SoPECs. However a design goal of SoPEC is to minimize pins for cost reasons, and this is particularly true of features only used in multi-SoPEC systems.
4002The design constraint requirement is therefore to allow slaves to be IDed via a method that does not require any extra pins. This implies that whatever boot mechanism that satisfies the security requirements of Section 2.1 must also be able to assign IDs to slave SoPECs.
00002.3.8 Cannot Trust the Comms Channel to the QA Chip in the Printer (PRINTER_QA)
4003If the printer operating parameters are stored in the non-volatile memory of the Print Engine's on-board PRINTER_QA chip, both Manufacturer/owner and OEM program code cannot rely on the communication channel being secure. It is possible for an attacker to eavesdrop on communications to the PRINTER_QA chip, replace the PRINTER_QA chip and/or subvert the communications channel. It is also possible for this to be true during manufacture of the circuit board containing the SoPEC and the PRINTER_QA chip.
00002.3.9 Cannot Trust the Comms Channel to the QA Chip in the Ink Cartridges (INK_QA)
4004The amount of ink remaining for a given ink cartridge is stored in the non-volatile memory of that ink cartridge's INK_QA chip. Both Manufacturer/owner and OEM program code cannot rely on the communication channel to the INK_QA being secure. It is possible for an attacker to eavesdrop on communications to the INK_QA chip, to replace the INK_QA chip and/or to subvert the communications channel. It is also possible for this to be true during manufacture of the consumable containing the INK_QA chip.
00002.3.10 Cannot Trust the Inter-SoPEC Comms Channel (USB2)
4005In a multi-SoPEC system, or in a single-SoPEC system that has a non-USB2 connection to the host, a given SoPEC will receive its data over a USB2 host port. It is quite possible for an end-user to insert a chip that eavesdrops on and/or subverts the communications channel (for example performs man-in-the-middle attacks).
00003 Proposed Solution
4006A proposed solution to the requirements of Section 2, can be summarised as: <ul id="ul0392" list-style="none"><li id="ul0392-0001" num="0000"><ul id="ul0393" list-style="none"><li id="ul0393-0001" num="4007">Each SoPEC has a unique id</li><li id="ul0393-0002" num="4008">CPU with user/supervisor mode</li><li id="ul0393-0003" num="4009">Memory Management Unit</li><li id="ul0393-0004" num="4010">The unique id is not cached</li><li id="ul0393-0005" num="4011">Specific entry points in O/S</li><li id="ul0393-0006" num="4012">Boot procedure, including authentication of program code and operating parameters</li><li id="ul0393-0007" num="4013">SoPEC physical identification <br /> 3.1 Each SoPEC Has a Unique ID </li></ul></li></ul>
4014Each SoPEC needs to contains a unique SoPEC_id of minimum size 64-bits. This SoPEC_id is used to form a symmetric key unique to each SoPEC: SoPEC_id_key. On SoPEC we make use of an additional 112-bit ECID<sup>2 </sup>macro that has been programmed with a random number on a per-chip basis. Thus SoPEC_id is the 112-bit macro, and the SoPEC_id_key is a 160-bit result obtained by SHA1(SoPEC_ID). <sup>2</sup>Electronic Chip Id
4015The verification of operating parameters and ink usage depends on SoPEC_id being difficult to determine. Difficult to determine means that someone should not be able to determine the id via software, or by viewing the communications between chips on the board. If the SoPEC_id is available through running a test procedure on specific test pins on the chip, then depending on the ease by which this can be done, it is likely to be acceptable.
4016It is important to note that in the proposed solution, compromise of the SoPEC_id leads only to compromise of the operating parameters and ink usage on this particular SoPEC. It does not compromise any other SoPEC or all inks or operating parameters in general.
4017It is ideal that the SoPEC_id be random, although this is unlikely to occur on standard manufacture processes for ASICs. If the id is within a small range however, it will be able to be broken by brute force. This is why 32-bits is not sufficient protection.
00003.2 CPU with User/Supervisor Mode
4018SoPEC contains a CPU with direct hardware support for user and supervisor modes. At present, the intended CPU is the LEON (a 32-bit processor with an instruction set according to the IEEE-1754 standard. The IEEE1754 standard is compatible with the SPARC V8 instruction set).
4019Manufacturer/owner (operating system) program code will run in supervisor mode, and all OEM program code will run in user mode.
00003.3 Memory Management Unit
4020SoPEC contains a Memory Management Unit (MMU) that limits access to regions of DRAM by defining read, write and execute access permissions for supervisor and user mode. Program code running in user mode is subject to user mode permission settings, and program code running in supervisor mode is subject to supervisor mode settings.
4021A setting of 1 for a permission bit means that type of access (e.g. read, write, execute) is permitted. A setting of 0 for a read permission bit means that that type of access is not permitted.
4022At reset and whenever SoPEC wakes up, the settings for all the permission bits are 1 for all supervisor mode accesses, and 0 for all user mode accesses. This means that supervisor mode program code must explicitly set user mode access to be permitted on a section of DRAM.
4023Access permission to all the non-valid address space should be trapped, regardless of user or supervisor mode, and regardless of the access being read, execute, or write.
4024Access permission to all of the valid non-DRAM address space (for example the PEP blocks) is supervisor read/write access only (no supervisor execute access, and user mode has no acccess at all) with the exception that certain GPIO and Timer registers can also be accessed by user code. These registers will require bitwise access permissions. Each peripheral block will determine how the access is restricted.
4025With respect to the DRAM and PEP subsystems of SoPEC, typically we would set user read/write/execute mode permissions to be 1/1/0 only in the region of memory that is used for OEM program data, 1/0/1 for regions of OEM program code, and 0/0/0 elsewhere (including the trap table). By contrast we would typically set supervisor mode read/write/execute permissions for this memory to be 1/1/0 (to avoid accidentally executing user code in supervisor mode).
4026The SoPEC_id parameter (see Section 3.1) should only be accessible in supervisor mode, and should only be stored and manipulated in a region of memory that has no user mode access.
00003.4 Unique ID is not Cached
4027The unique SoPEC_id needs to be available to supervisor code and not available to user code. This is taken care of by the MMU (Section 3.3).
4028However the SoPEC_id must also not be accessable via the CPU's data cache or register windows. For example, if the user were to cause an interrupt to occur at a particular point in the program execution when the SoPEC_id was being manipulated, it must not be possible for the user program code to turn caching off and then access the SoPEC_id inside the data cache. This would bypass any MMU security.
4029The same must be true of register windows. It must not be possible for user mode program code to read or modify register settings in a supervisor program's register windows.
4030This means that at the least, the SoPEC_id itself must not be cacheable. Likewise, any processed form of the SoPEC_id such as the SoPEC_id key (e.g. read into registers or calculated expected results from a QA_Chip) should not be accessable by user program code.
00003.5 Specific Entry Points in O/S
4031Given that user mode program code cannot even call functions in supervisor code space, the question arises as how OEM programs can access functions, or request services. The implementation for this depends on the CPU.
4032On the LEON processor, the TRAP instruction allows programs to switch between user and supervisor mode in a controlled way. The TRAP switches between user and supervisor register sets, and calls a specific entry point in the supervisor code space in supervisor mode. The TRAP handler dispatches the service request, and then returns to the caller in user mode.
4033Use of a command dispatcher allows the O/S to provide services that filter access—e.g. a generalised print function will set PEP registers appropriately and ensure QA Chip ink updates occur.
4034The LEON also allows supervisor mode code to call user mode code in user mode. There are a number of ways that this functionality can be implemented. It is possible to call the user code without a trap, but to return to supervisor mode requires a trap (and associated latency).
00003.6 Boot Procedure
00003.6.1 Basic Premise
4035The intention is to load the Manufacturer/owner and OEM program code into SoPEC's RAM, where it can be subsequently executed. The basic SoPEC therefore, must be capable of downloading program code. However SoPEC must be able to guarantee that only authorized Manufacturer/owner boot programs can be loaded, otherwise anyone could modify the O/S to do anything, and then load that—thereby bypassing the licensed operating parameters.
4036We perform authentication of program code and data using asymmetric (public-key) digital signatures and without using a QA Chip.
4037Assuming we have already downloaded some data and a 160-bit signature into eDRAM, the boot loader needs to perform the following tasks: <ul id="ul0394" list-style="none"><li id="ul0394-0001" num="0000"><ul id="ul0395" list-style="none"><li id="ul0395-0001" num="4038">perform SHA-1 on the downloaded data to calculate a digest localDigest</li><li id="ul0395-0002" num="4039">perform asymmetric decryption on the downloaded signature (160-bits) using an asymmetric public key to obtain authorizedDigest</li><li id="ul0395-0003" num="4040">If authorizedDigest is the PKCS#1 (patent free) form of localDigest, then the downloaded data is authorized (the signature must have been signed with the asymmetric private key) and control can then be passed to the downloaded data</li></ul></li></ul>
4041Asymmetric decryption is used instead of symmetric decryption because the decrypting key must be held in SoPEC's ROM. If symmetric private keys are used, the ROM can be probed and the security is compromised.
4042The procedure requires the following data item: <ul id="ul0396" list-style="none"><li id="ul0396-0001" num="0000"><ul id="ul0397" list-style="none"><li id="ul0397-0001" num="4043">boot0key=an n-bit asymmetric public key</li></ul></li></ul>
4044The procedure also requires the following two functions: <ul id="ul0398" list-style="none"><li id="ul0398-0001" num="0000"><ul id="ul0399" list-style="none"><li id="ul0399-0001" num="4045">SHA-1=a function that performs SHA-1 on a range of memory and returns a 160-bit digest</li><li id="ul0399-0002" num="4046">decrypt=a function that performs asymmetric decryption of a message using the passed-in key</li></ul></li></ul>
4047<tables id="TABLE-US-00358" num="00358"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>PKCS#1 form of localDigest is 2048-bits formatted as</entry></row><row><entry /><entry>follows: bits 2047–2040 = 0x00, bits 2039–2032 = 0x01,</entry></row><row><entry /><entry>bits 2031–288 = 0xFF . . . 0xFF, bits 287–160 =</entry></row><row><entry /><entry>0x003021300906052B0E03021A05000414, bits 159–0 =</entry></row><row><entry /><entry>localDigest. For more information, see PKCS#1 v2.1 section</entry></row><row><entry /><entry>9.2</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
4048Assuming that all of these are available (e.g. in the boot ROM), boot loader 0 can becode:
4049<tables id="TABLE-US-00359" num="00359"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>bootloader0(data, sig)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>localDigest <img file="US7165824B2_D0013.tif" /> SHA-1(data)</entry></row><row><entry /><entry>authorizedDigest <img file="US7165824B2_D0014.tif" /> decrypt(sig, boot0key)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="28pt" align="left" /><colspec colname="3" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry>expectedDigest</entry><entry>=</entry><entry>0x00|0x01|0xFF..0xFF|</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>0x003021300906052B0E03021A05000414</entry></row><row><entry /><entry>|localDigest) //</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>”|“ = concat</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>If (authorizedDigest = = expectedDigest)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>jump to program code at data-start address//</entry></row><row><entry /><entry>will never</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>// program code is unauthorized</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
4050The length of the key will depend on the asymmetric algorithm chosen. The key must provide the equivalent protection of the entire QA Chip system—if the Manufacturer/owner O/S program code can be bypassed, then it is equivalent to the QA Chip keys being compromised. In fact it is worse because it would compromise Manufacturer/owner operating parameters, OEM operating parameters, and ink authentication by software downloaded off the net (e.g. from some hacker).
4051In the case of RSA, a 2048-bit key is required to match the 160-bit symmetric-key security of the QA Chip. In the case of ECDSA, a key length of 132 bits is likely to suffice. RSA is convenient because the patent (U.S. Pat. No. 4,405,829) expired in September 2000.
4052There is no advantage to storing multiple keys in SoPEC and having the external message choose which key to validate against, because a compromise of any key allows the external user to always select that key.
4053There is also no particular advantage to having the boot mechanism select the key (e.g. one for USB-based booting and one for external ROM booting) a compromise of the external ROM booting key is enough to compromise all the SoPEC systems.
4054However, there are advantages in having multiple keys present in the boot ROM and having a wire-bonding option on the pads select which of the keys is to be used. Ideally, the pads would be connected within the package, and the selection is not available via external means once the die has ben packaged. This means we can have different keys for different application areas (e.g. different uses of the chip), and if any particular SoPEC key is compromised, the die could be kept constant and only the bonding changed. Note that in the worst case of all keys being compromised, it may be economically feasible to change the boot0key value in SoPEC's ROM, since this is only a single mask change, and would be easy to verify and characterize.
4055Therefore the entire security of SoPEC is based on keeping the asymmetric private key paired to boot0key secure. The entire security of SoPEC is also based on keeping the program that signs (i.e. authorizes) datasets using the asymmetric private key paired to boot0key secure.
4056It may therefore be reasonable to have multiple signatures (and hence multiple signature programs) to reduce the chance of a single point of weakness by a rogue employee. Note that the authentication time increases linearly with the number of signatures, and requires a 2048-bit public key in ROM for each signature.
00003.6.2 Hierarchies of Authentication
4057Given that test programs, evaluation programs, and Manufacturer/owner O/S code needs to be written and tested, and OEM program code etc. also needs to be tested, it is not secure to have a single authentication of a monolithic dataset combining Manufacturer/owner O/S, non-O/S, and OEM program code—we certainly don't want OEMs signing Manufacturer/owner program code, and Manufacturer/owner shouldn't have to be involved with the signing of OEM program code.
4058Therefore we require differing levels of authentication and therefore a number of keys, although the procedure for authentication is identical to the first—a section of program code contains the key and procedure for authenticating the next.
4059This method allows for any hierarchy of authentication, based on a root key of boot0key. For example, assume that we have the following entities: <ul id="ul0400" list-style="none"><li id="ul0400-0001" num="0000"><ul id="ul0401" list-style="none"><li id="ul0401-0001" num="4060">QACo, Manufacturer/owner's QA/key company. Knows private version of boot0key, and owner of security concerns.</li><li id="ul0401-0002" num="4061">SoPECCo, Manufacturer/owner's SoPEC hardware/software company. Supplies SoPEC ASICs and SoPEC O/S printing software to a ComCo.</li><li id="ul0401-0003" num="4062">ComCo, a company that assembles Print Engines from SoPECs, Memjet printheads etc, customizing the Print Engine for a given OEM according to a license</li><li id="ul0401-0004" num="4063">OEM, a company that uses a Print Engine to create a printer product to sell to the end-users. The OEM would supply the motor control logic, user interface, and casing.</li></ul></li></ul>
4064The levels of authentication hierarchy are as follows: <ul id="ul0402" list-style="none"><li id="ul0402-0001" num="0000"><ul id="ul0403" list-style="none"><li id="ul0403-0001" num="4065">QACo writes the boot ROM, agenerates dataset1, consisting of a boot loader program that loads and validates dataset2 and QACo's asymmetric public boot1key. QACo signs dataset0 with the asymmetric private boot0key.</li><li id="ul0403-0002" num="4066">SoPECCo generates dataset1, consisting of the print engine security kernel O/S (which incorporates the security-based features of the print engine functionality) and the ComCo's asymmetric public key. Upon a special “formal release” request from SoPECCo, QACo signs dataset0 with QACo's asymmetric private boot0key key. The print engine program code expects to see an operating parameter block signed by the ComCo's asymmetric private key. Note that this is a special “formal release” request to by SoPECCo; the procedure for development versions of the program are described in Section 3.6.3.</li><li id="ul0403-0003" num="4067">The ComCo generates dataSet3, consisting of dataset1 plus dataset2, where dataset2 is an operating parameter block for a given OEM's print engine licence (according to the print engine license arrangement) signed with the ComCo's asymmetric private key. The operating parameter block (dataset2) would contain valid print speed ranges, a PrintEngineLicenseID, and the OEM's asymmetric public key. The ComCo can generate as many of these operating parameter blocks for any number of Print Engine Licenses, but cannot write or sign any supervisor O/S program code.</li><li id="ul0403-0004" num="4068">The OEM would generate dataset5, consisting of dataset3 plus dataset4, where dataset4 is the OEM program code signed with the OEM's asymmetric private key. The OEM can produce as many versions of dataset5 as it likes (e.g. for testing purposes or for updates to drivers etc) and need not involve Manufacturer/owner, QACo, or ComCo in any way.</li></ul></li></ul>
4069The relationship is shown below in <figref idref="DRAWINGS">FIG. 325</figref>.
4070When the end-user uses dataset5, SoPEC itself validates dataset1 via the boot0key mechanism described in Section 3.6.1. Once dataset1 is executing, it validates dataset2, and uses dataset2 data to validate dataset4. The validation hierarchy is shown in <figref idref="DRAWINGS">FIG. 326</figref>.
4071If a key is compromised, it compromises all subsequent authorizations down the hierarchy. In the example from above (and as illustrated in <figref idref="DRAWINGS">FIG. 326</figref>) if the OEM's asymmetric private key is compromised, then O/S program code is not compromised since it is above OEM program code in the authentication hierarchy. However if the ComCo's asymmetric private key is compromised, then the OEM program code is also compromised. A compromise of boot0key compromises everything up to SoPEC itself, and would require a mask ROM change in SoPEC to fix.
4072It is worthwhile repeating that in any hierarchy the security of the entire hierarchy is based on keeping the asymmetric private key paired to boot0key secure. It is also a requirement that the program that signs (i.e. authorizes) datasets using the asymmetric private key paired to boot0key secure.
00003.6.3 Developing Program Code at Manufacturer/Owner
4073The hierarchical boot procedure described in Section 3.6.1 and Section 3.6.2 gives a hierarchy of protection in a final shipped product.
4074It is also desirable to use a hierarchy of protection during software development within Manufacturer/owner.
4075For a program to be downloaded and run on SoPEC during development, it will need to be signed. In addition, we don't want to have to sign each and every Manufacturer/owner development code with the boot0key, as it creates the possibility of any developmental (including buggy or rogue) application being run on any SoPEC.
4076Therefore QACo needs to generate/create a special intermediate boot loader, signed with boot0key, that performs the exact same tasks as the normal boot loader, except that it checks the SoPECid to see if it is a specific SoPECid (or set of SoPECids). If the SoPEC_id is in the valid set, then the developmental boot loader validates dataset2 by means of its length and a SHA-1 digest of the developmental code<sup>3</sup>, and not by a further digital signature. The QACo can give this boot loader to the software development team within Manufacturer/owner. The software team can now write and run any program code, and load the program code using the development boot loader. There is no requirement for the subsequent software program (i.e. the developmental program code) to be signed with any key since the programs can only be run on the particular SoPECs. <sup>3</sup>The SHA-1 digest is to allow the total program load time to simulate the running time of the normal boot loader running on a non-developmental version of the program.
4077If the developmental boot loader (and/or signature generator) were compromised, or any of the developmental programs were compromised, the worst situation is that an attacker could run programs on that particular set of SoPECs, and on no others.
4078This should greatly reduce the possibility of erroneous programs signed with boot0key being available to an attacker (only official releases are signed by boot0key), and therefore reduces the possibility of a Manufacturer/owner employee intentionally or inadvertently creating a back door for attackers.
4079The relationship is shown below in <figref idref="DRAWINGS">FIG. 327</figref>.
4080Theoretically the same kind of hierarchy could also be used to allow OEMs to be assured that their program code will only work on specific SoPECs, but this is unlikely to be necessary, and is probably undesirable.
00003.6.4 Date-limited Loaders
4081It is possible that errors in supervisor program code (e.g. the operating system) could allow attackers to subvert the program in SoPEC and gain supervisor control.
4082To reduce the impact of this kind of attack, it is possible to allocate some bits of the SoPEC_id to form some kind of date. The granularity of the date could be as simple as a single bit that says the date is obtained from the regular IBM ECID, or it could be 6 bits that give 10 years worth of 3-month units.
4083The first step of the program loaded by boot loader 0 could check the SoPEC_id date, and run or refuse to run appropriately. The Manufacturer/owner driver or OS could therefore be limited to run on SoPECs that are manufactured up until a particular date.
4084This means that the OEM would require a new version of the OS for SoPECs after a particular date, but the new driver could be made to work on all previous versions of SoPEC.
4085The function simply requires a form of date, whose granularity for working can be determined by agreement with the OEM.
4086For example, suppose that SoPECs are supplied with 3-month granularity in their date components. Manufacturer/owner could ship a version of the OS that works for any SoPEC of the date (i.e. on any chip), or for all SoPECs manufactured during the year etc. The driver issued the next year could work with all SoPECs up until that years etc. In this way the drivers for a chip will be backwards compatible, but will be deliberately not forwards-compatible. It allows the downloading of a new driver with no problems, but it protects against bugs in one years's driver OS from being used against future SoPECs.
4087Note that the phasing in of a new OS doesn't have to be at the same time as the hardware. For example, the new OS can come in 3 months before the hardware that it supports. However once the new SoPECs are being delivered, the OEM must not ship the older driver with the newer SoPECs, for the old driver will not work on the newer SoPECs. Basically once the OEM has received the new driver, they should use that driver for all SoPEC systems from that point on (old SoPECs will work with the new driver).
4088This date-limiting feature would most likely be using a field in the ComCo specified operating parameters, so it allows the SoPEC to use date-checking in addition to additional QA Chip related parameter checking (such as the OEM's PrintEngineLicenseId etc).
4089A variant on this theme is a date-window, where a start-date and end-date are specified (as relating to SoPEC manufacture, not date of use).
00003.6.5 Authenticating Operating Parameters
4090Operating parameters need to be considered in terms of Manufacturer/owner operating parameters and OEM operating parameters. Both sets of operating parameters are stored on the PRINTER_QA chip (physically located inside the printer). This allows the printer to maintain parameters regardless of being moved to different computers, or a loss/replacement of host O/S drivers etc.
4091On PRINTER_QA, memory vector M<sub>0 </sub>contains the upgradable operating parameters, and memory vectors M<sub>1+</sub> contains any constant (non-upgradable) operating parameters.
4092Considering only Manufacturer/owner operating parameters for the moment, there are actually two problems: <ul id="ul0404" list-style="none"><li id="ul0404-0001" num="4093">a. setting and storing the Manufacturer/owner operating parameters, which should be authorized only by Manufacturer/owner</li><li id="ul0404-0002" num="4094">b. reading the parameters into SoPEC, which is an issue of SoPEC authenticating the data on the PRINTER_QA chip since we don't trust PRINTER_QA.</li></ul>
4095The PRINTER_QA chip therefore contains the following symmetric keys: <ul id="ul0405" list-style="none"><li id="ul0405-0001" num="0000"><ul id="ul0406" list-style="none"><li id="ul0406-0001" num="4096">K<sub>0</sub>=PrintEngineLicense_key. This key is constant for all SoPECs supplied for a given print engine license agreement between an OEM and a Manufacturer/owner ComCo. K<sub>0 </sub>has write permissions to the Manufacturer/owner upgradeable region of M<sub>0 </sub>on PRINTER_QA.</li><li id="ul0406-0002" num="4097">K<sub>1</sub>=SoPEC_id_key. This key is unique for each SoPEC (see Section 3.1), and is known only to the SoPEC and PRINTER_QA. K, does not have write permissions for anything.</li></ul></li></ul>
4098K<sub>0 </sub>is used to solve problem (a). It is only used to authenticate the actual upgrades of the operating parameters. Upgrades are performed using the standard upgrade protocol described in [5], with PRINTER_QA acting as the ChipU, and the external upgrader acting as the ChipS.
4099K<sub>1 </sub>is used by SoPEC to solve problem (b). It is used to authenticate reads of data (i.e. the operating parameters) from PRINTER_QA. The procedure follows the standard authenticated read protocol described in [5], with PRINTER_QA acting as ChipR, and the embedded supervisor software on SoPEC acting as ChipT. The authenticated read protocol [5] requires the use of a 160-bit nonce, which is a pseudo-random number. This creates the problem of introducing pseudo-randomness into SoPEC that is not readily determinable by OEM programs, especially given that SoPEC boots into a known state. One possibility is to use the same random number generator as in the QA Chip (a 160-bit maximal-lengthed linear feedback shift register) with the seed taken from the value in the WatchDogTimer register in SoPEC's timer unit when the first page arrives.
4100Note that the procedure for verifying reads of data from PRINTER_QA does not rely on Manufacturer/owner's key K<sub>0</sub>. This means that precisely the same mechanism can be used to read and authenticate the OEM data also stored in PRINTER_QA. Of course this must be done by Manufacturer/owner supervisor code so that SoPEC_id key is not revealed.
4101If the OEM also requires upgradable parameters, we can add an extra key to PRINTER_QA, where that key is an OEM_key and has write permissions to the OEM part of M<sub>0</sub>.
4102In this way, K<sub>1 </sub>never needs to be known by anyone except the SoPEC and PRINTER_QA.
4103Each printing SoPEC in a multi-SoPEC system need access to a PRINTER_QA chip that contains the appropriate SoPEC_id_key to validate ink useage and operating parameters. This can be accomplished by a separate PRINTER_QA for each SoPEC, or by adding extra keys (multiple SoPEC_id_keys) to a single PRINTER_QA.
4104However, if ink usage is not being validated (e.g. if print speed were the only Manufacturer/owner upgradable parameter) then not all SoPECs require access to a PRINTER_QA chip that contains the appropriate SoPEC_id_key. Assuming that OEM program code controls the physical motor speed (different motors per OEM), then the PHI within the first (or only) front-page SoPEC can be programmed to accept (or generate) line sync pulses no faster than a particular rate. If line syncs arrived faster than the particular rate, the PHI would simply print at the slower rate. If the motor speed was hacked to be fast, the print image will appear stretched.
00003.6.5.1 Floating Operating Parameters and Dongles
4105As described in Section 2.1.2, Manufacturer/owner operating parameters include such items as print speed, print quality etc. and are tied to a license provided to an OEM. These parameters are under Manufacturer/owner control. The licensed Manufacturer/owner operating parameters are typically stored in the PRINTER_QA as described in Section 3.6.5.
4106However there are situations when it is desirable to have a floating upgrade to a license, for use on a printer of the user's choice. For example, OEMs may sell a speed-increase license upgrade that can be plugged into the printer of the user's choice. This form of upgrade can be considered a floating upgrade in that it upgrades whichever printer it is currently plugged into. This dongle is referred to as ADDITIONAL_PRINTER_QA. The software checks for the existence of an ADDITIONAL_PRINTER_QA, and if present the operating parameters are chosen from the values stored on both QA chips.
4107The basic problem of authenticating the additional operating parameters boils down to the problem that we don't trust ADDITIONAL_PRINTER_QA. Therefore we need a system whereby a given SoPEC can perform an authenticated read of the data in ADDITIONAL_PRINTER_QA.
4108We should not write the SoPEC_id_key to a key in the ADDITIONAL_PRINTER_QA because: <ul id="ul0407" list-style="none"><li id="ul0407-0001" num="0000"><ul id="ul0408" list-style="none"><li id="ul0408-0001" num="4109">then it will be tied specifically to that SoPEC, and the primary intention of the ADDITIONAL_PRINTER_QA is that it be floatable;</li><li id="ul0408-0002" num="4110">the ink cartridge would then not work in another printer since the other printer would not know the old SoPEC_id_key (knowledge of the old key is required in order to change the old key to a new one).</li><li id="ul0408-0003" num="4111">updating keys is not power-safe (i.e. if at the user's site, power is removed mid-update, the ADDITIONAL_PRINTER_QA could be rendered useless)</li></ul></li></ul>
4112The proposed solution is to let ADDITIONAL_PRINTER_QA have two keys: <ul id="ul0409" list-style="none"><li id="ul0409-0001" num="0000"><ul id="ul0410" list-style="none"><li id="ul0410-0001" num="4113">K<sub>0</sub>=FloatingPrintEngineLicense_key. This key has the same function as the PrintEngineLicense_key in the PRINTER_QA<sup>4 </sup>in that K<sub>0 </sub>has write permissions to the Manufacturer/owner upgradeable region of M<sub>0 </sub>on ADDITIONAL_PRINTER_QA. <sup>4</sup>This can be identical to PrintEngineLicense_key in the PRINTER_QA if it is desireable (unlikely) that upgraders can function on PRINTER_QAs as well as ADDITIONAL_PRINTER_QAs</li><li id="ul0410-0002" num="4114">K<sub>1</sub>=UseExtParmsLicense_key. This key is constant for all of the ADDITIONAL_PRINTER_QAs for a given license agreement between an OEM and a Manufacturer/owner ComCo (this is not the same key as PrintEngineLicense_key which is stored as K<sub>0 </sub>in PRINTER_QA). K<sub>1 </sub>has no write permissions to anything.</li></ul></li></ul>
4115K<sub>0 </sub>is used to allow writes to the various fields containing operating parameters in the ADDITIONAL_PRINTER_QA. These writes/upgrades are performed using the standard upgrade protocol described in [5], with ADDITIONAL_PRINTER_QA acting as the ChipU, and the external upgrader acting as the ChipS. The upgrader (ChipS) also needs to check the appropriate licensing parameters such as OEM_Id for validity.
4116K<sub>1 </sub>is used to allow SoPEC to authenticate reads of the ink remaining and any other ink data. This is accomplished by having the same UseExtParmsLicense_key within PRINTER_QA (e.g. in K<sub>2</sub>), also with no write permissions. i.e: <ul id="ul0411" list-style="none"><li id="ul0411-0001" num="0000"><ul id="ul0412" list-style="none"><li id="ul0412-0001" num="4117">PRINTER_QA.K<sub>2</sub>=UseExtParmsLicense_key. This key is constant for all of the PRINTER_QAs for a given license agreement between an OEM and a Manufacturer/owner ComCo. K<sub>2 </sub>has no write permissions to anything.</li></ul></li></ul>
4118This means there are two shared keys, with PRINTER_QA sharing both, and thereby acting as a bridge between INK_CA and SoPEC. <ul id="ul0413" list-style="none"><li id="ul0413-0001" num="0000"><ul id="ul0414" list-style="none"><li id="ul0414-0001" num="4119">UseExtParmsLicense_key is shared between PRINTER_QA and ADDITIONAL_PRINTER_QA</li><li id="ul0414-0002" num="4120">SoPEC_id_key is shared between SoPEC and PRINTER_QA</li></ul></li></ul>
4121All SoPEC has to do is do an authenticated read [6] from ADDITIONAL_PRINTER_QA, pass the data/signature to PRINTER_QA, let PRINTER_QA validate the data/signature, and get PRINTER_QA to produce a similar signature based on the shared SoPEC_id_key. It can do so using the Translate function [6]. SoPEC can then compare PRINTER_QA's signature with its own calculated signature (i.e. implement a Test function [6] in software on SoPEC), and if the signatures match, the data from ADDITIONAL_PRINTER_QA must be valid, and can therefore be trusted.
4122Once the data from ADDITIONAL_PRINTER_QA is known to be trusted, the various operating parameters such as OEM_Id can be checked for validity.
4123The actual steps of read authentication as performed by SoPEC are:
4124<tables id="TABLE-US-00360" num="00360"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>R<sub>PRINTER </sub><img file="US7165824B2_D0015.tif" /> PRINTER_QA.random( )</entry></row><row><entry>R<sub>DONGLE</sub>,M<sub>DONGLE</sub>,SIG<sub>DONGLE </sub><img file="US7165824B2_D0016.tif" /> DONGLE_QA.read(K1, R<sub>PRINTER</sub>)</entry></row><row><entry>R<sub>SOPEC </sub><img file="US7165824B2_D0017.tif" /> random( )</entry></row><row><entry>R<sub>PRINTER</sub>, SIG<sub>PRINTER </sub><img file="US7165824B2_D0018.tif" /> PRINTER_QA.translate(K2, R<sub>DONGLE</sub>,</entry></row><row><entry>M<sub>DONGLE</sub>, SIG<sub>DONGLE</sub>, K1, R<sub>SOPEC</sub>)</entry></row><row><entry>SIG<sub>SOPEC </sub><img file="US7165824B2_D0019.tif" /> HMAC_SHA_1(SoPEC_id_key, M<sub>DONGLE </sub>| R<sub>PRINTER </sub>|</entry></row><row><entry>R<sub>SOPEC</sub>)</entry></row><row><entry>If (SIG<sub>PRINTER </sub>= SIG<sub>SOPEC</sub>)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// various parms inside M<sub>DONGLE</sub> (data read from</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>ADDITIONAL_PRINTER_QA) is valid</entry></row><row><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// the data read from ADDITIONAL_PRINTER_QA is not valid and</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>cannot be trusted</entry></row><row><entry>EndIf</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 3.6.5.2 Dongles Tied to a Given SoPEC
4125Section 3.6.5.1 describes floating dongles i.e. dongles that can be used on any SoPEC. Sometimes it is desirable to tie a dongle to a specific SoPEC.
4126Tying a QA_CHIP to be used only on a specific SoPEC can be easily accomplished by writing the PRINTER_QA's chipId (unique serial number) into an appropriate M<sub>0 </sub>field on the ADDITIONAL_PRINTER_QA. The system software can detect the match and function appropriately. If there is no match, the software can ignore the data read from the ADDITIONAL_PRINTER_QA.
4127Although it is also possible to store the SoPEC_id_key in one of the keys within the dongle, this must be done in an environment where power will not be removed partway through the key update process (if power is removed during the key update there is a possibility that the dongle QA Chip may be rendered unusable, although this can be checked for after the power failure).
00003.6.5.3 OEM Assembly-line Test
4128Although an OEM should only be able sell the licensed operating parameters for a given Print Engine, they must be able to assembly-line test<sup>5 </sup>or service/test the Print Engine with a different set of operating parameters e.g. a maximally upgraded Print Engine. <sup>5</sup>This section is referring to assembly-line testing rather than development testing. An OEM can maximally upgrade a given Print Engine to allow developmental testing of their own OEM program code & mechanics.
4129Several different mechanisms can be employed to allow OEMs to test the upgraded capabilities of the Print Engine. At present it is unclear exactly what kind of assembly-line tests would be performed.
4130The simplest solution is to use an ADDITIONAL_PRINTER_QA (i.e. special dongle PRINTER_QA as described in Section 3.6.5.1). The ADDITIONAL_PRINTER_QA would contain the operating parameters that maximally upgrade the printer as long as the dongle is connected to the SoPEC. The exact connection may be directly electrical (e.g. via the standard QA Chip connections) or may be over the USB connection to the printer test host depending on the nature of the test. The exact preferred connection is yet to be determined.
4131In the testing environment, the ADDITIONAL_PRINTER_QA also requires a numberOfImpressions field inside M<sub>0</sub>, which is writeable by K<sub>0</sub>. Before the SoPEC prints a page at the higher speed, it decrements the numberOfImpressions counter, performs an authenticated read to ensure the count was decremented, and then prints the page. In this way, the total number of pages that can be printed at high speed is reduced in the event of someone stealing the ADDITIONAL_PRINTER_QA device. It also means that multiple test machines can make use of the same ADDITIONAL_PRINTER_QA.
00003.6.6 Use of a PrintEngineLicense id
4132Manufacturer/owner O/S program code contains the OEM's asymmetric public key to ensure that the subsequent OEM program code is authentic—i.e. from the OEM. However given that SoPEC only contains a single root key, it is theoretically possible for different OEM's applications to be run identically physical Print Engines i.e. printer driver for OEM, run on an identically physical Print Engine from OEM<sub>2</sub>.
4133To guard against this, the Manufacturer/owner O/S program code contains a PrintEngineLicense_id code (e.g. 16 bits) that matches the same named value stored as a fixed operating parameter in the PRINTER_QA (i.e. in M<sub>1+</sub>). As with all other operating parameters, the value of PrintEngineLicense_id is stored in PRINTER_QA (and any ADDITIONAL_PRINTER_QA devices) at the same time as the other various PRINTER_QA customizations are being applied, before being shipped to the OEM site.
4134In this way, the OEMs can be sure of differentiating themselves through software functionality.
00003.6.7 Authentication of Ink
4135The Manufacturer/owner O/S must perform ink authentication [6] during prints. Ink usage authentication makes use of counters in SoPEC that keep an accurate record of the exact number of dots printed for each ink.
4136The ink amount remaining in a given cartridge is stored in that cartridge's INK QA chip. Other data stored on the INK_QA chip includes ink color, viscosity, Memjet firing pulse profile information, as well as licensing parameters such as OEM_ID, inkType, InkUsageLicense_ID, etc. This information is typically constant, and is therefore likely to be stored in M<sub>1+</sub> within INK_QA.
4137Just as the Print Engine operating parameters are validated by means of PRINTER_QA, a given Print Engine license may only be permitted to function with specifically licensed ink. Therefore the software on SoPEC could contain a valid set of ink types, colors, OEM_Ids, InkUsageLicense_Ids etc. for subsequent matching against the data in the INK_QA.
4138SoPEC must be able to authenticate reads from the INK_QA, both in terms of ink parameters as well as ink remaining.
4139To authenticate ink a number of steps must be taken: <ul id="ul0415" list-style="none"><li id="ul0415-0001" num="0000"><ul id="ul0416" list-style="none"><li id="ul0416-0001" num="4140">restrict access to dot counts</li><li id="ul0416-0002" num="4141">authenticate ink usage and ink parameters via INK_QA and PRINTER_QA</li><li id="ul0416-0003" num="4142">broadcast ink dot usage to all SoPECs in a multi-SoPEC system <br /> 3.6.7.1 Restrict Access to Dot Counts </li></ul></li></ul>
4143Since the dot counts are accessed via the PHI in the PEP section of SoPEC, access to these registers (and more generally all PEP registers) must be only available from supervisor mode, and not by OEM code (running in user mode). Otherwise it might be possible for OEM program code to clear dot counts before authentication has occurred.
00003.6.7.2 Authenticate Ink Usage and Ink Parameters via INK_QA and PRINTER_QA
4144The basic problem of authentication of ink remaining and other ink data boils down to the problem that we don't trust INK_QA. Therefore how can a SoPEC know the initial value of ink (or the ink parameters), and how can a SoPEC know that after a write to the INK_QA, the count has been correctly decremented.
4145Taking the first issue, which is determining the initial ink count or the ink parameters, we need a system whereby a given SoPEC can perform an authenticated read of the data in INK_QA.
4146We cannot write the SoPEC_id_key to the INK_QA for two reasons: <ul id="ul0417" list-style="none"><li id="ul0417-0001" num="0000"><ul id="ul0418" list-style="none"><li id="ul0418-0001" num="4147">updating keys is not power-safe (i.e. if power is removed mid-update, the INK_QA could be rendered useless)</li><li id="ul0418-0002" num="4148">the ink cartridge would then not work in another printer since the other printer would not know the old SoPEC_id_key (knowledge of the old key is required in order to change the old key to a new one).</li></ul></li></ul>
4149The proposed solution is to let INK_QA have two keys: <ul id="ul0419" list-style="none"><li id="ul0419-0001" num="0000"><ul id="ul0420" list-style="none"><li id="ul0420-0001" num="4150">K<sub>0</sub>=SupplyInkLicense_key. This key is constant for all ink cartridges for a given ink supply agreement between an OEM and a Manufacturer/owner ComCo (this is not the same key as PrintEngineLicense_key which is stored as K<sub>0 </sub>in PRINTER_QA). K<sub>0 </sub>has write permissions to the ink remaining regions of M<sub>0 </sub>on INK_QA.</li><li id="ul0420-0002" num="4151">K<sub>1</sub>=UseInkLicense_key. This key is constant for all ink cartridges for a given ink usage agreement between an OEM and a Manufacturer/owner ComCo (this is not the same key as PrintEngineLicense_key which is stored as K<sub>0 </sub>in PRINTER_QA). K<sub>1 </sub>has no write permissions to anything.</li></ul></li></ul>
4152K<sub>0 </sub>is used to authenticate the actual upgrades of the amount of ink remaining (e.g. to fill and refill the amount of ink). Upgrades are performed using the standard upgrade protocol described in [5], with INK_QA acting as the ChipU, and the external upgrader acting as the ChipS. The fill and refill upgrader (ChipS) also needs to check the appropriate ink licensing parameters such as OEM_ID, InkType and InkUsageLicense_Id for validity.
4153K<sub>1 </sub>is used to allow SoPEC to authenticate reads of the ink remaining and any other ink data. This is accomplished by having the same UseInkLicense_key within PRINTER_QA (e.g. in K<sub>2 </sub>or K<sub>3</sub>), also with no write permissions.
4154This means there are two shared keys, with PRINTER_QA sharing both, and thereby acting as a bridge between INK_QA and SoPEC. <ul id="ul0421" list-style="none"><li id="ul0421-0001" num="0000"><ul id="ul0422" list-style="none"><li id="ul0422-0001" num="4155">UseInkLicense_key is shared between INK_QA and PRINTER_QA</li><li id="ul0422-0002" num="4156">SoPEC_id_key is shared between SoPEC and PRINTER_QA</li></ul></li></ul>
4157All SoPEC has to do is do an authenticated read [6] from INK_QA, pass the data/signature to PRINTER_QA, let PRINTER_QA validate the data/signature and get PRINTER_QA to produce a similar signature based on the shared SoPEC id key (i.e. the Translate function [6]). SoPEC can then compare PRINTER_QA's signature with its own calculated signature (i.e. implement a Test function [6] in software on the SoPEC), and if the signatures match, the data from INK_QA must be valid, and can therefore be trusted.
4158Once the data from INK_QA is known to be trusted, the amount of ink remaining can be checked, and the other ink licensing parameters such as OEM_ID, InkType, InkUsageLicense_Id can be checked for validity.
4159The actual steps of read authentication as performed by SoPEC are:
4160<tables id="TABLE-US-00361" num="00361"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>R<sub>PRINTER </sub><img file="US7165824B2_D0020.tif" /> PRINTER_QA.random( )</entry></row><row><entry /><entry>R<sub>INK</sub>, M<sub>INK</sub>, SIG<sub>INK </sub><img file="US7165824B2_D0021.tif" /> INK_QA.read(K1, R<sub>PRINTER</sub>) // read</entry></row><row><entry /><entry>with key1:</entry></row><row><entry /><entry>UseInkLicense_key</entry></row><row><entry /><entry>R<sub>SOPEC </sub><img file="US7165824B2_D0022.tif" /> random( )</entry></row><row><entry /><entry>R<sub>PRINTER</sub>, SIG<sub>PRINTER </sub><img file="US7165824B2_D0023.tif" /> PRINTER_QA.translate (K2, R<sub>INK</sub>,</entry></row><row><entry /><entry>M<sub>INK</sub>, SIG<sub>INK</sub>, K1, R<sub>SOPEC</sub>)</entry></row><row><entry /><entry>SIG<sub>SOPEC </sub><img file="US7165824B2_D0024.tif" /> HMAC_SHA_1(SoPEC_id_key, M<sub>INK </sub>| R<sub>PRINTER </sub>|</entry></row><row><entry /><entry>R<sub>SOPEC</sub>)</entry></row><row><entry /><entry>If (SIG<sub>PRINTER </sub>= SIG<sub>SOPEC</sub>)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>// M<sub>INK </sub>(data read from INK_QA) is valid</entry></row><row><entry /><entry>// M<sub>INK </sub>could be ink parameters, such as</entry></row><row><entry /><entry>InkUsageLicense_Id, or</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ink remaining</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>If (M<sub>INK</sub>.inkRemaining = expectedInkRemaining)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>// all is ok</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>// the ink value is not what we wrote, so don't print</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>anything anymore</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>// the data read from INK_QA is not valid and cannot be</entry></row><row><entry /><entry>trusted</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
4161Strictly speaking, we don't need a nonce (R<sub>SOPEC</sub>) all the time because M<sub>A </sub>(containing the ink remaining) should be decrementing between authentications. However we do need one to retrieve the initial amount of ink and the other ink parameters (at power up). This is why taking a random number from the WatchDogTimer at the receipt of the first page is acceptable.
4162In summary, the SoPEC performs the non-authenticated write [6] of ink remaining to the INK_QA chip, and then performs an authenticated read of the data via the PRINTER_QA as per the pseudocode above. If the value is authenticated, and the INK_QA ink-remaining value matches the expected value, the count was correctly decremented and the printing can continue.
00003.6.7.3 Broadcast Ink Dot Usage to all SoPECs in a Multi-SoPEC System
4163In a multi-SoPEC system, each SoPEC attached to a printhead must broadcast its ink usage to all the SoPECs. In this way, each SoPEC will have its own version of the expected ink usage.
4164In the case of a man-in-the-middle attack, at worst the count in a given SoPEC is only its own count (i.e. all broadcasts are turned into 0 ink usage by the man-in-the-middle). We would also require the broadcast amount to be treated as an unsigned integer to prevent negative amounts from being substituted.
4165A single SoPEC performs the update of ink remaining to the INK_QA chip, and then all SoPECs perform an authenticated read of the data via the appropriate PRINTER_QA (the PRINTER_QA that contains their matching SoPEC_id_key—remember that multiple SoPEC id keys can be stored in a single PRINTER_QA). If the value is authenticated, and the INK_QA value matches the expected value, the count was correctly decremented and the printing can continue.
4166If any of the broadcasts are not received, or have been tampered with, the updated ink counts will not match. The only case this does not cater for is if each SoPEC is tricked (via a USB2 inter-SoPEC-comms man-in-the-middle attack) into a total that is the same, yet not the true total. Apart from the fact that this is not viable for general pages, at worst this is the maximum amount of ink printed by a single SoPEC. We don't care about protecting against this case.
4167Since a typical maximum is 4 printing SoPECs, it requires at most 4 authenticated reads. This should be completed within 0.5 seconds, well within the 1–2 seconds/page print time.
00003.6.8 Example Hierarchy
4168Adding an extra bootloader step to the example from Section 3.6.2, we can break up the contents of program space into logical sections, as shown in Table 227. Note that the ComCo does not provide any program code, merely operating parameters that is used by the O/S.
4169<tables id="TABLE-US-00362" num="00362"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 227</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Sections of Program Space</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="35pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><colspec colname="3" colwidth="98pt" align="left" /><tbody valign="top"><row><entry>section</entry><entry>contents</entry><entry>verifies</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>0</entry><entry>boot loader 0</entry><entry>section 1 via boot0key</entry></row><row><entry>(ROM)</entry><entry>SHA-1 function</entry></row><row><entry /><entry>asymmetric</entry></row><row><entry /><entry>decrypt function</entry></row><row><entry /><entry>boot0key</entry></row><row><entry>1</entry><entry>boot loader 1</entry><entry>section 2 via</entry></row><row><entry /><entry>SoPEC_OS_public_key</entry><entry>SoPEC_OS_public_key</entry></row><row><entry>2</entry><entry>Manufacturer/owner</entry><entry>section 3 via</entry></row><row><entry /><entry>O/S program code</entry><entry>ComCo_public_key</entry></row><row><entry /><entry>function to generate</entry><entry>section 4 via</entry></row><row><entry /><entry>SoPEC_id_key from</entry><entry>OEM_public_key (supplied</entry></row><row><entry /><entry>SoPEC_id Basic Print</entry><entry>in section 3)</entry></row><row><entry /><entry>Engine</entry><entry>PRINTER_QA data, which</entry></row><row><entry /><entry>ComCo_public_key</entry><entry>includes the</entry></row><row><entry /><entry /><entry>PrintEngineLicense_id,</entry></row><row><entry /><entry /><entry>Manufacturer/owner</entry></row><row><entry /><entry /><entry>operating parameters,</entry></row><row><entry /><entry /><entry>and OEM operating</entry></row><row><entry /><entry /><entry>parameters (all</entry></row><row><entry /><entry /><entry>authenticated via</entry></row><row><entry /><entry /><entry>SoPEC_id_key)</entry></row><row><entry>3</entry><entry>ComCo license</entry><entry>Is used by section 2</entry></row><row><entry /><entry>agreement operat-</entry><entry>to verify section 4</entry></row><row><entry /><entry>ing parameter ranges,</entry><entry>and range of</entry></row><row><entry /><entry>including</entry><entry>parameters as found in</entry></row><row><entry /><entry>PrintEngineLicense_id</entry><entry>PRINTER_QA</entry></row><row><entry /><entry>(gets loaded into</entry></row><row><entry /><entry>supervisor mode sec-</entry></row><row><entry /><entry>tion of memory)</entry></row><row><entry /><entry>OEM_public_key</entry></row><row><entry /><entry>(gets loaded into</entry></row><row><entry /><entry>supervisor mode</entry></row><row><entry /><entry>section of memory)</entry></row><row><entry /><entry>Any ComCo written</entry></row><row><entry /><entry>user-mode program</entry></row><row><entry /><entry>code (gets loaded</entry></row><row><entry /><entry>into mode mode</entry></row><row><entry /><entry>section of memory)</entry></row><row><entry>4</entry><entry>OEM specific program</entry><entry>OEM operating</entry></row><row><entry /><entry>code</entry><entry>parameters via calls</entry></row><row><entry /><entry /><entry>to Manufacturer/owner</entry></row><row><entry /><entry /><entry>O/S code</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
4170The verification procedures will be required each time the CPU is woken up, since the RAM is not preserved.
00003.6.9 What if the CPU is Not Fast Enough?
4171In the example of Section 3.6.8, every time the CPU is woken up to print a document it needs to perform: <ul id="ul0423" list-style="none"><li id="ul0423-0001" num="0000"><ul id="ul0424" list-style="none"><li id="ul0424-0001" num="4172">SHA-1 on all program code and program data</li><li id="ul0424-0002" num="4173">4 sets of asymmetric decryption to load the program code and data</li><li id="ul0424-0003" num="4174">1 HMAC-SHA1 generation per 512-bits of Manufacturer/owner and OEM printer and ink operating parameters</li></ul></li></ul>
4175Although the SHA-1 and HMAC process will be fast enough on the embedded CPU (the program code will be executing from ROM), it may be that the asymmetric decryption will be slow. And this becomes more likely with each extra level of authentication. If this is the case (as is likely), hardware acceleration is required.
4176A cheap form of hardware acceleration takes advantage of the fact that in most cases the same program is loaded each time, with the first time likely to be at power-up. The hardware acceleration is simply data storage for the authorizedDigest which means that the boot procedure now is:
4177<tables id="TABLE-US-00363" num="00363"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>slowCPU_bootloader0(data, sig)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>localDigest <img file="US7165824B2_D0025.tif" /> SHA-1(data)</entry></row><row><entry /><entry>If (localDigest = previouslyStoredAuthorizedDigest)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>jump to program code at data-start address// will never</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>authorizedDigest <img file="US7165824B2_D0026.tif" /> decrypt(sig, boot0key)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="28pt" align="left" /><colspec colname="3" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry>expectedDigest</entry><entry>=</entry><entry>0x00 |0x01|0xFF..0xFF|</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>0x003021300906052B0E03021A05000414 |</entry></row><row><entry /><entry>localDigest)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>If (authorizedDigest = = expectedDigest)</entry></row><row><entry /><entry>previouslyStoredAuthorizedDigest <img file="US7165824B2_D0027.tif" /> localDigest</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>jump to program code at data-start address// will</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>never return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row><row><entry /><entry>// program code is unauthorized</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
4178This procedure means that a reboot of the same authorized program code will only require SHA-1 processing. At power-up, or if new program code is loaded (e.g. an upgrade of a driver over the internet), then the full authorization via asymmetric decryption takes place. This is because the stored digest will not match at power-up and whenever a new program is loaded.
4179The question is how much preserved space is required.
4180Each digest requires 160 bits (20 bytes), and this is constant regardless of the asymmetric encryption scheme or the key length. While it is possible to reduce this number of bits, thereby sacrificing security, the cost is small enough to warrant keeping the full digest.
4181However each level of boot loader requires its own digest to be preserved. This gives a maximum of 20 bytes per loader. Digests for operating parameters and ink levels may also be preserved in the same way, although these authentications should be fast enough not to require cached storage.
4182Assuming SoPEC provides for 12 digests (to be generous), this is a total of 240 bytes. These 240 bytes could easily be stored as 60×32-bit registers, or probably more conveniently as a small amount of RAM (eg 0.25–1 Kbyte). Providing something like 1 Kbyte of RAM has the advantage of allowing the CPU to store other useful data, although this is not a requirement.
4183In general, it is useful for the boot ROM to know whether it is being started up due to power-on reset, GPIO activity, or activity on the USB2. In the former case, it can ignore the previously stored values (either 0 for registers or garbage for RAM). In the latter cases, it can use the previously stored values. Even without this, a startup value of 0 (or garbage) means the digest won't match and therefore the authentication will occur implictly.
00003.7 SoPEC Phsyical Identification
4184There must be a mapping of logical to physical since specific SoPECs are responsible for printing on particular physical parts of the page, and/or have particular devices attached to specific pins.
4185The identification process is mostly solved by general USB2 enumeration.
4186Each slave SoPEC will need to verify the boot broadcast messages received over USB2, and only execute the code if the signatures are valid. Several levels of authorization may occur. However, at some stage, this common program code (broadcast to all of the slave SoPECs and signed by the appropriate asymmetric private key) can, among other things, set the slave SoPEC's id relating to the physical location. If there is only 1 slave, the id is easy to determine, but if there is more than 1 slave, the id must be determined in some fashion. For example, physical location/id determination may be: <ul id="ul0425" list-style="none"><li id="ul0425-0001" num="0000"><ul id="ul0426" list-style="none"><li id="ul0426-0001" num="4187">given by the physical USB2 port on the master</li><li id="ul0426-0002" num="4188">related to the physical wiring up of the USB2 interconnects</li><li id="ul0426-0003" num="4189">based on GPIO wiring. On other systems, a particular physical arrangement of SoPECs may exist such that each slave SoPEC will have a different set of connections on GPIOs. For example, one SoPEC maybe in charge of motor control, while another may be driving the LEDs etc. The unused GPIO pins (not necessarily the same on each SoPEC) can be set as inputs and then tied to 0 or 1. As long as the connection settings are mutually exclusive, program code can determine which is which, and the id appropriately set.</li></ul></li></ul>
4190This scheme of slave SoPEC identification does not introduce a security breach. If an attacker rewires the pinouts to confuse identification, at best it will simply cause strange printouts (e.g. swapping of printout data) to occur, while at worst the Print Engine will simply not function.
00003.8 Setting Up QA Chip Keys
4191In use, each INK_QA chip needs the following keys: <ul id="ul0427" list-style="none"><li id="ul0427-0001" num="0000"><ul id="ul0428" list-style="none"><li id="ul0428-0001" num="4192">K<sub>0</sub>=SupplyInkLicense_key</li><li id="ul0428-0002" num="4193">K<sub>1</sub>=UseInkLicense_key</li></ul></li></ul>
4194Each PRINTER_QA chip tied to a specific SoPEC requires the following keys: <ul id="ul0429" list-style="none"><li id="ul0429-0001" num="0000"><ul id="ul0430" list-style="none"><li id="ul0430-0001" num="4195">K<sub>0</sub>=PrintEngineLicense_key</li><li id="ul0430-0002" num="4196">K<sub>1</sub>=SoPEC_id_key</li><li id="ul0430-0003" num="4197">K<sub>2</sub>=UseExtParmsLicense_key</li><li id="ul0430-0004" num="4198">K<sub>3</sub>=UseInkLicense_key</li></ul></li></ul>
4199Note that there may be more than one K<sub>1 </sub>depending on the number of PRINTER_QA chips and SoPECs in a system. These keys need to be appropriately set up in the QA Chips before they will function correctly together.
00003.8.1 Original QA Chips as Received by a ComCo
4200When original QA Chips are shipped from QACo to a specific ComCo their keys are as follows: <ul id="ul0431" list-style="none"><li id="ul0431-0001" num="0000"><ul id="ul0432" list-style="none"><li id="ul0432-0001" num="4201">K<sub>0</sub>=QACo_ComCo_Key0</li><li id="ul0432-0002" num="4202">K<sub>1</sub>=QACo_ComCo_Key1</li><li id="ul0432-0003" num="4203">K<sub>2</sub>=QACo_ComCo_Key2</li><li id="ul0432-0004" num="4204">K<sub>3</sub>=QACo_ComCo_Key3</li></ul></li></ul>
4205All 4 keys are only known to QACo. Note that these keys are different for each QA Chip.
00003.8.2 Steps at the ComCo
4206The ComCo is responsible for making Print Engines out of Memjet printheads, QA Chips, PECs or SoPECs, PCBs etc.
4207In addition, the ComCo must customize the INK_QA chips and PRINTER_QA chip on-board the print engine before shipping to the OEM.
4208There are two stages: <ul id="ul0433" list-style="none"><li id="ul0433-0001" num="0000"><ul id="ul0434" list-style="none"><li id="ul0434-0001" num="4209">replacing the keys in QA Chips with specific keys for the application (i.e. INK_QA and PRINTER_QA)</li><li id="ul0434-0002" num="4210">setting operating parameters as per the license with the OEM <br /> 3.8.2.1 Replacing Keys </li></ul></li></ul>
4211The ComCo is issued QID hardware [4] by QACo that allows programming of the various keys (except for K<sub>1</sub>) in a given QA Chip to the final values, following the standard ChipF/ChipP replace key (indirect version) protocol [6]. The indirect version of the protocol allows each QACo_ComCo_Key to be different for each SoPEC.
4212In the case of programming of PRINTER_QA's K<sub>1 </sub>to be SoPEC_id_key, there is the additional step of transferring an asymmetrically encrypted SoPEC_id_key (by the public-key) along with the nonce (R<sub>P</sub>) used in the replace key protocol to the device that is functioning as a ChipF. The ChipF must decrypt the SoPEC_id_key so it can generate the standard replace key message for PRINTER_QA (functioning as a ChipP in the ChipF/ChipP protocol). The asymmetric key pair held in the ChipF equivalent should be unique to a ComCo (but still known only by QACo) to prevent damage in the case of a compromise.
4213Note that the various keys installed in the QA Chips (both INK_QA and PRINTER_QA) are only known to the QACo. The OEM only uses QIDs and QACo supplied ChipFs. The replace key protocol [6] allows the programming to occur without compromising the old or new key.
00003.8.2.2 Setting Operating Parameters
4214There are two sets of operating parameters stored in PRINTER_QA and INK_QA: <ul id="ul0435" list-style="none"><li id="ul0435-0001" num="0000"><ul id="ul0436" list-style="none"><li id="ul0436-0001" num="4215">fixed</li><li id="ul0436-0002" num="4216">upgradable</li></ul></li></ul>
4217The fixed operating parameters can be written to by means of a non-authenticated writes [6] to M<sub>1+</sub> via a QID [4], and permission bits set such that they are ReadOnly.
4218The upgradable operating parameters can only be written to after the QA Chips have been programmed with the correct keys as per Section 3.8.2.1. Once they contain the correct keys they can be programmed with appropriate operating parameters by means of a QID and an appropriate ChipS (containing matching keys).
0000Authentication Protocols
00001 Introduction
4219The following describes authentication protocols for general authentication applications, but with specific reference to the QA Chip.
4220The intention is to show the broad form of possible protocols for use in different authentication situations, and can be used as a reference when subsequently defining an implementation specification for a particular application. As mentioned earlier, although the protocols are described in relation to a printing environment, many of them have wider application such as, but not limited to, those described at the end of this specification.
00002 Nomenclature
4221The following symbolic nomenclature is used throughout this document:
4222<tables id="TABLE-US-00364" num="00364"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 228</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Summary of symbolic nomenclature</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>Symbol</entry><entry>Description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>F[X]</entry><entry>Function F, taking a single parameter X</entry></row><row><entry>F[X, Y]</entry><entry>Function F, taking two parameters, X and Y</entry></row><row><entry>X | Y</entry><entry>X concatenated with Y</entry></row><row><entry>X <img file="US7165824B2_D0028.tif" /> Y</entry><entry>Bitwise X AND Y</entry></row><row><entry>X <img file="US7165824B2_D0029.tif" /> Y</entry><entry>Bitwise X OR Y (inclusive-OR)</entry></row><row><entry>X ⊕ Y</entry><entry>Bitwise X XOR Y (exclusive-OR)</entry></row><row><entry><img file="US7165824B2_D0030.tif" /> X</entry><entry>Bitwise NOT X (complement)</entry></row><row><entry>X <img file="US7165824B2_D0031.tif" /> Y</entry><entry>X is assigned the value Y</entry></row><row><entry>X <img file="US7165824B2_D0032.tif" /> {Y, Z}</entry><entry>The domain of assignment inputs to X is Y and Z</entry></row><row><entry>X = Y</entry><entry>X is equal to Y</entry></row><row><entry>X ≠ Y</entry><entry>X is not equal to Y</entry></row><row><entry><img file="US7165824B2_D0033.tif" /> X</entry><entry>Decrement X by 1 (floor 0)</entry></row><row><entry><img file="US7165824B2_D0034.tif" /> X</entry><entry>Increment X by 1 (modulo register length)</entry></row><row><entry>Erase X</entry><entry>Erase Flash memory register X</entry></row><row><entry>SetBits[X, Y]</entry><entry>Set the bits of the Flash memory register X based</entry></row><row><entry /><entry>on Y</entry></row><row><entry>Z <img file="US7165824B2_D0035.tif" /> ShiftRight[X, Y]</entry><entry>Shift register X right one bit position, taking input</entry></row><row><entry /><entry>bit from Y and placing the output bit in Z</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 3 Pseudocode <br /> 3.1 Asynchronous
4223The following pseudocode: <ul id="ul0437" list-style="none"><li id="ul0437-0001" num="0000"><ul id="ul0438" list-style="none"><li id="ul0438-0001" num="4224">var=expression <ul id="ul0439" list-style="none"><li id="ul0439-0001" num="4225">means the var signal or output is equal to the evaluation of the expression. <br /> 3.2 Synchronous </li></ul></li></ul></li></ul>
4226The following pseudocode: <ul id="ul0440" list-style="none"><li id="ul0440-0001" num="0000"><ul id="ul0441" list-style="none"><li id="ul0441-0001" num="4227">var←expression <ul id="ul0442" list-style="none"><li id="ul0442-0001" num="4228">means the var register is assigned the result of evaluating the expression during this cycle. <br /> 3.3 Expression </li></ul></li></ul></li></ul>
4229Expressions are defined using the nomenclature in Table 228 above. Therefore: <br /><i>var</i>=(<i>a=b</i>)<br /> is interpreted as the var signal is 1 if a is equal to b, and 0 otherwise. <br /> 4. Intentionally Blank <br /> 5 Basic Protocols <br /> 5.1 Protocol Background
4230This protocol set is a restricted form of a more general case of a multiple key single memory vector protocol. It is a restricted form in that the memory vector M has been optimized for Flash memory utilization: <ul id="ul0443" list-style="none"><li id="ul0443-0001" num="0000"><ul id="ul0444" list-style="none"><li id="ul0444-0001" num="4231">M is broken into multiple memory vectors (semi-fixed and variable components) for the purposes of optimizing flash memory utilization. Typically M contains some parts that are fixed at some stage of the manufacturing process (eg a batch number, serial number etc.), and once set, are not ever updated. This information does not contain the amount of consumable remaining, and therefore is not read or written to with any great frequency.</li><li id="ul0444-0002" num="4232">We therefore define M<sub>0 </sub>to be the M that contains the frequently updated sections, and the remaining Ms to be rarely written to. Authenticated writes only write to M<sub>0</sub>, and non-authenticated writes can be directed to a specific M<sub>n</sub>. This reduces the size of permissions that are stored in the QA Chip (since key-based writes are not required for Ms other than M<sub>0</sub>). It also means that M<sub>0 </sub>and the remaining Ms can be manipulated in different ways, thereby increasing flash memory longevity. <br /> 5.2 Requirements of Protocol </li></ul></li></ul>
4233Each QA Chip contains the following values: <ul id="ul0445" list-style="none"><li id="ul0445-0001" num="4234">N The maximum number of keys known to the chip.</li><li id="ul0445-0002" num="4235">T The number of vectors M is broken into.</li><li id="ul0445-0003" num="4236">K<sub>N </sub>Array of N secret keys used for calculating F<sub>Kn</sub>[X] where K<sub>n </sub>is the nth element of the array.</li><li id="ul0445-0004" num="4237">R Current random number used to ensure time varying messages. Each chip instance must be seeded with a different initial value. Changes for each signature generation.</li><li id="ul0445-0005" num="4238">M<sub>T </sub>Array of T memory vectors. Only M<sub>0 </sub>can be written to with an authorized write, while all Ms can be written to in an unauthorized write. Writes to M<sub>0 </sub>are optimized for Flash usage, while updates to any other M<sub>1+</sub> are expensive with regards to Flash utilization, and are expected to be only performed once per section of M<sub>n</sub>. M<sub>1 </sub>contains T, N and f in ReadOnly form so users of the chip can know these two values.</li><li id="ul0445-0006" num="4239">P<sub>T+N </sub>T+N element array of access permissions for each part of M. Entries n={0 . . . T−1} hold access permissions for non-authenticated writes to M<sub>n </sub>(no key required). Entries n={T to T+N−1}hold access permissions for authenticated writes to M<sub>0 </sub>for K<sub>n</sub>. Permission choices for each part of M are Read Only, Read/Write, and Decrement Only.</li><li id="ul0445-0007" num="4240">C 3 constants used for generating signatures. C<sub>1</sub>, C<sub>2</sub>, and C<sub>3 </sub>are constants that pad out a sub-message to a hashing boundary, and all 3 must be different.</li></ul>
4241Each QA Chip contains the following private function: <ul id="ul0446" list-style="none"><li id="ul0446-0001" num="4242">S<sub>Kn</sub>[N,X] Internal function only. Returns S<sub>Kn</sub>[X], the result of applying a digital signature function S to X based upon the appropriate key K<sub>n</sub>. The digital signature must be long enough to counter the chances of someone generating a random signature. The length depends on the signature scheme chosen, although the scheme chosen for the QA Chip is HMAC-SHA1, and therefore the length of the signature is 160 bits.</li></ul>
4243Additional functions are required in certain QA Chips, but these are described as required.
00005.3 Read protocols
4244The set of read protocols describe the means by which a System reads a specific data vector M<sub>t </sub>from a QA Chip referred to as ChipR.
4245We assume that the communications link to ChipR (and therefore ChipR itself) is not trusted. If it were trusted, the System could simply read the data and there is no issue. Since the communications link to ChipR is not trusted and ChipR cannot be trusted, the System needs a way of authenticating the data as actually being from a real ChipR.
4246Since the read protocol must be capable of being implemented in physical QA Chips, we cannot use asymmetric cryptography (for example the ChipR signs the data with a private key, and System validates the signature using a public key).
4247This document describes two read protocols: <ul id="ul0447" list-style="none"><li id="ul0447-0001" num="0000"><ul id="ul0448" list-style="none"><li id="ul0448-0001" num="4248">direct validation of reads</li><li id="ul0448-0002" num="4249">indirect validation of reads. <br /> 5.3.1 Direct Validation of Reads </li></ul></li></ul>
4250In a direct validation read protocol we require two QA Chips: ChipR is the QA Chip being read, and ChipT is the QA Chip we entrust to tell us whether or not the data read from ChipR is trustworthy. The basic idea is that system asks ChipR for data, and ChipR responds with the data and a signature based on a secret key. System then asks ChipT whether the signature supplied by ChipR is correct. If ChipT responds that it is, then System can trust that data just read from ChipR. Every time data is read from ChipR, the validation procedure must be carried out.
4251Direct validation requires the System to trust the communication line to ChipT. This could be because ChipT is in physical proximity to the System, and both System and ChipT are in a trusted (e.g. Silverbrook secure) environment. However, since we need to validate the read, ChipR by definition must be in a non-trusted environment.
4252Each QA Chip protects its signature generation or verification mechanism by the use of a nonce.
4253The protocol requires the following publicly available functions in ChipT: <ul id="ul0449" list-style="none"><li id="ul0449-0001" num="4254">Random<img file="US7165824B2_D0036.tif" /> Returns R (does not advance R).</li><li id="ul0449-0002" num="4255">Test[n,X, Y, Z] Advances R and returns 1 if S<sub>Kn</sub>[R|X|C<sub>1</sub>|Y]=Z. Otherwise returns 0. The time taken to calculate and compare signatures must be independent of data content.</li></ul>
4256The protocol requires the following publicly available functions in ChipR: <ul id="ul0450" list-style="none"><li id="ul0450-0001" num="4257">Read[n, t, X] Advances R, and returns R, M<sub>t</sub>, S<sub>Kn</sub>[X|R|C<sub>1</sub>|M<sub>t</sub>]. The time taken to calculate the signature must not be based on the contents of X, R, M<sub>t</sub>, or K. If t is invalid, the function assumes t=0.</li></ul>
4258To read ChipR's memory M<sub>t </sub>in a validated way, System performs the following tasks: <ul id="ul0451" list-style="none"><li id="ul0451-0001" num="4259">a. System calls ChipT's Random function;</li><li id="ul0451-0002" num="4260">b. ChipT returns R<sub>T </sub>to System;</li><li id="ul0451-0003" num="4261">c. System calls ChipR's Read function, passing in some key number n1, the desired data vector number t, and R<sub>T </sub>(from b);</li><li id="ul0451-0004" num="4262">d. ChipR updates R<sub>R</sub>, then calculates and returns R<sub>R</sub>, M<sub>Rt</sub>, S<sub>Kn1</sub>[R<sub>T</sub>|R<sub>R</sub>|C<sub>1</sub>|M<sub>Rt</sub>];</li><li id="ul0451-0005" num="4263">e. System calls ChipT's Test function, passing in the key to use for signature verification n2, and the results from d (i.e. R<sub>R</sub>, M<sub>Rt</sub>, S<sub>Kn1</sub>[R<sub>T</sub>|R<sub>R</sub>|C<sub>1</sub>|M<sub>Rt</sub>]);</li><li id="ul0451-0006" num="4264">f. System checks response from ChipT. If the response is 1, then the M<sub>t </sub>read from ChipR is considered to be valid. If 0, then the M<sub>t </sub>read from ChipR is considered to be invalid.</li></ul>
4265The choice of n1 and n2 must be such that ChipR's K<sub>n1</sub>=ChipT's K<sub>n2</sub>.
4266The data flow for this read protocol is shown in <figref idref="DRAWINGS">FIG. 328</figref>.
4267From the System's perspective, the protocol would take on a form like the following pseudocode:
4268<tables id="TABLE-US-00365" num="00365"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>R<sub>T </sub><img file="US7165824B2_D0037.tif" /> ChipT.Random( )</entry></row><row><entry /><entry>R<sub>R</sub>, M<sub>R</sub>, SIG<sub>R </sub><img file="US7165824B2_D0038.tif" /> ChipR.Read(keyNumOnChipR,desiredM, R<sub>T</sub>)</entry></row><row><entry /><entry>ok <img file="US7165824B2_D0039.tif" /> ChipT.Test(keyNumOnChipT, R<sub>R</sub>, M<sub>R</sub>, SIG<sub>R</sub>)</entry></row><row><entry /><entry>If (ok = 1)</entry></row><row><entry /><entry>// M<sub>R </sub>is to be trusted</entry></row><row><entry /><entry>Else</entry></row><row><entry /><entry>// M<sub>R </sub>is not to be trusted</entry></row><row><entry /><entry>EndIf</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
4269With regards to security, if an attacker finds out ChipR's K<sub>n1</sub>, they can replace the ChipR by a fake ChipR because they can create signatures. Likewise, if an attacker finds out ChipT's K<sub>n2</sub>, they can replace the ChipR by a fake ChipR because ChipR's K<sub>n1</sub>=ChipT's K<sub>n2</sub>. Moreover, they can use the ChipRs on any system that shares the same key.
4270The only way of restricting exposure due to key reveals is to restrict the number of systems that match ChipR and ChipT. i.e. vary the key as much as possible. The degree to which this can be done will depend on the application. In the case of a PRINTER_QA acting as a ChipT, and an INK_QA acting as a ChipR, the same key must be used on all systems where the particular INK_QA data must be validated.
4271In all cases, ChipR must contain sufficient information to produce a signature. Knowing (or finding out) this information, whatever form it is in, allows clone ChipRs to be built.
00005.3.2 Indirect Validation of Reads
4272In a direct validation protocol (see Section 5.3.1), the System validates the correctness of data read from ChipR by means of a trusted chip ChipT. This is possible because ChipR and ChipT share some secret information.
4273However, it is possible to extend trust via indirect validation. This is required when we trust ChipT, but ChipT doesn't know how to validate data from ChipR. Instead, ChipT knows how to validate data from ChipI (some intermediate chip) which in turn knows how to validate data from either another ChipI (and so on up a chain) or ChipR. Thus we have a chain of validation.
4274The means of validation chains is translation of signatures. ChipI<sub>n </sub>translates signatures from higher up the chain (either ChipI<sub>n−1 </sub>or from ChipR at the start of the chain) into signatures capable of being passed to the next stage in the chain (either ChipI<sub>n+1 </sub>or to ChipT at the end of the chain). A given ChipI can only translate signatures if it knows the key of the previous stage in the chain as well as the key of the next stage in the chain.
4275The protocol requires the following publicly available functions in ChipI: <ul id="ul0452" list-style="none"><li id="ul0452-0001" num="4276">Random<img file="US7165824B2_D0040.tif" /> Returns R (does not advance R).</li><li id="ul0452-0002" num="4277">Translate[n1,X, Y, Z,n2,A] Returns 1, S<sub>Kn2</sub>[A|R|C<sub>1</sub>|Y] and advances R if Z=S<sub>Kn1</sub>[R|X|C<sub>1</sub>|Y]. Otherwise returns 0, 0. The time taken to calculate and compare signatures must be independent of data content.</li></ul>
4278The data flow for this signature translation protocol is shown in <figref idref="DRAWINGS">FIG. 329</figref>:
4279Note that R<sub>prev </sub>is eventually R<sub>R</sub>, and R<sub>next </sub>is eventually R<sub>T</sub>. In the multiple ChipI case, R<sub>prev </sub>is the R<sub>I </sub>of ChipI<sub>n−1 </sub>and R<sub>next </sub>is R<sub>I </sub>of ChipI<sub>n+1</sub>. The R<sub>prev </sub>of the first ChipI in the chain is R<sub>R</sub>, and the R<sub>next </sub>of the last ChipI in the chain is R<sub>T</sub>.
4280Assuming at least 1 ChipT, the System would need to perform the following tasks in order to read ChipR's memory M<sub>t </sub>in an indirectly validated way: <ul id="ul0453" list-style="none"><li id="ul0453-0001" num="4281">a. System calls ChipI<sub>n</sub>'s Random function;</li><li id="ul0453-0002" num="4282">b. ChipI<sub>0 </sub>returns R<sub>10 </sub>to System;</li><li id="ul0453-0003" num="4283">c. System calls ChipR's Read function, passing in some key number n0, the desired data vector number t, and R<sub>10 </sub>(from b);</li><li id="ul0453-0004" num="4284">d. ChipR updates R<sub>R</sub>, then calculates and returns R<sub>R</sub>, M<sub>Rt</sub>, S<sub>Kn0</sub>[R<sub>In</sub>|R<sub>R</sub>|C<sub>1</sub>|M<sub>Rt</sub>];</li><li id="ul0453-0005" num="4285">e. System assigns R<sub>R </sub>to R<sub>prev </sub>and S<sub>Kn0</sub>[R<sub>In</sub>|R<sub>R</sub>|C<sub>1</sub>|M<sub>Rt</sub>] to SIG<sub>prev </sub></li><li id="ul0453-0006" num="4286">f. System calls the next-chip-in-the-chain's Random function (either ChipI<sub>n+</sub>, or ChipT)</li><li id="ul0453-0007" num="4287">g. The next-chip-in-the-chain will return R<sub>next </sub>to System</li><li id="ul0453-0008" num="4288">h. System calls ChipI<sub>n</sub>'s Translate function, passing in n1<sub>n </sub>(translation input key number), R<sub>prev</sub>, M<sub>Rt</sub>, SIG<sub>prev</sub>), n2<sub>n</sub>, (translation output key number) and the results from g (R<sub>next</sub>);</li><li id="ul0453-0009" num="4289">i. ChipI returns testResult and SIG<sub>1 </sub>to System</li><li id="ul0453-0010" num="4290">j. If testResult=0, then the validation has failed, and the M<sub>t </sub>read from ChipR is considered to be invalid. Exit with failure.</li><li id="ul0453-0011" num="4291">k. If the next chip in the chain is a ChipI, assign SIG<sub>1 </sub>to SIG<sub>prev </sub>and go to step f</li><li id="ul0453-0012" num="4292">l. System calls ChipT's Test function, passing in n<sub>t</sub>, R<sub>prev</sub>, M<sub>Rt</sub>, and SIG<sub>prev</sub>;</li><li id="ul0453-0013" num="4293">m. System calls System checks response from ChipT. If the response is 1, then the M<sub>t </sub>read from ChipR is considered to be valid. If 0, then the M<sub>t </sub>read from ChipR is considered to be invalid.</li></ul>
4294For the Translate function to work, ChipI<sub>n </sub>and ChipI<sub>n+1</sub>, must share a key. The choice of n1 and n2 in the protocol described must be such that ChipI<sub>n</sub>'s K<sub>n2</sub>=ChipI<sub>n+1</sub>'s K<sub>n1</sub>.
4295Note that Translate is essentially a “Test plus resign” function. From an implementation point of view the first part of Translate is identical to Test.
4296Note that the use of ChipIs and the translate function merely allows signatures to be transformed. At the end of the translation chain (if present) will be a ChipT requiring the use of a Test function.
4297There can be any number of ChipIs in the chain to ChipT as long as the Translate function is used to map signatures between ChipI<sub>n </sub>and ChipI<sub>n+1 </sub>and so on until arrival at the final destination (ChipT).
4298From the System's perspective, a read protocol using at least 1 ChipI would take on a form like the following pseudocode:
4299<tables id="TABLE-US-00366" num="00366"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>R<sub>next </sub><img file="US7165824B2_D0041.tif" /> ChipI[0].Random( )</entry></row><row><entry /><entry>R<sub>prev</sub>, M<sub>R</sub>, SIG<sub>prev </sub><img file="US7165824B2_D0042.tif" /> ChipR.Read(keyNumOnChipR, desiredM,</entry></row><row><entry /><entry>R<sub>next</sub>)</entry></row><row><entry /><entry>ok = 1</entry></row><row><entry /><entry>i = 0</entry></row><row><entry /><entry>while ( (i < iMax) AND ok)</entry></row><row><entry /><entry>For i <img file="US7165824B2_D0043.tif" /> 0 to iMax</entry></row><row><entry /><entry>If (i = iMax)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>R<sub>next </sub><img file="US7165824B2_D0044.tif" /> ChipT.Random( )</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>R<sub>next </sub><img file="US7165824B2_D0045.tif" /> ChipI[i+1].Random( )</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>ok, SIG<sub>prev </sub><img file="US7165824B2_D0046.tif" /> ChipI[i].Translate(iKey[i], R<sub>prev</sub>, M<sub>R</sub>,</entry></row><row><entry /><entry>SIG<sub>prev</sub>, oKey[i], R<sub>next</sub>)</entry></row><row><entry /><entry>R<sub>prev </sub>= R<sub>next</sub></entry></row><row><entry /><entry>If (ok = 0)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>// M<sub>R </sub>is not to be trusted</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>EndFor</entry></row><row><entry /><entry>ok <img file="US7165824B2_D0047.tif" /> ChipT.Test(keyNumOnChipT, R<sub>prev</sub>, M<sub>R</sub>, SIG<sub>prev</sub>)</entry></row><row><entry /><entry>If (ok = 1)</entry></row><row><entry /><entry>// M<sub>R </sub>is to be trusted</entry></row><row><entry /><entry>Else</entry></row><row><entry /><entry>// M<sub>R </sub>is not to be trusted</entry></row><row><entry /><entry>EndIf</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 5.3.3 Additional Comments on Reads
4300In the Memjet printing environment, certain implementations will exist where the operating parameters are stored in QA Chips. In this case, the system must read the data from the QA Chip using an appropriate read protocol.
4301If the connection is trusted (e.g. to a virtual QA Chip in software), a generic Read is sufficient. If the connection is not trusted, it is ideal that the System have a trusted ChipT in the form of software (if possible) or hardware (e.g. a QA Chip on board the same silicon package as the microcontroller and firmware). Whether implemented in software or hardware, the QA Chip should contain an appropriate key that is unique per print engine. Such a key setup would allow reads of print engine parameters and also allow indirect reads of consumables (from a consumable QA Chip).
4302If the ChipT is physically separate from System (e.g. ChipT is on a board connected to System) System must also occasionally (based on system clock for example) call ChipT's Test function with bad data, expecting a 0 response. This is to reduce the possibility of someone inserting a fake ChipT into the system that always returns 1 for the Test function.
00005.4 Upgrade Protocols
4303This set of protocols describe the means by which a System upgrades a specific data vector M<sub>t </sub>within a QA Chip (ChipU). The data vector may contain information about the functioning of the device (e.g. the current maximum operating speed) or the amount of a consumable remaining.
4304The updating of M<sub>t </sub>in ChipU falls into two categories: <ul id="ul0454" list-style="none"><li id="ul0454-0001" num="0000"><ul id="ul0455" list-style="none"><li id="ul0455-0001" num="4305">non-authenticated writes, where anyone is able to update the data vector</li><li id="ul0455-0002" num="4306">authenticated writes, where only authorized entities are able to upgrades data vectors <br /> 5.4.1 Non-authenticated Writes </li></ul></li></ul>
4307This is the most frequent type of write, and takes place between the System/consumable during normal everyday operation for M<sub>0</sub>, and during the manufacturing process for M<sub>1+</sub>.
4308In this kind of write, the System wants to change M<sub>t </sub>within ChipU subject to P. For example, the System could be decrementing the amount of consumable remaining. Although System does not need to know and of the K<sub>S </sub>or even have access to a trusted chip to perform the write, the System must follow a non-authenticated write by an authenticated read if it needs to know that the write was successful.
4309The protocol requires ChipU to contain the following publicly available function: <ul id="ul0456" list-style="none"><li id="ul0456-0001" num="4310">Write[t, X] Writes X over those parts of M<sub>t </sub>subject to P<sub>t </sub>and the existing value for M. <ul id="ul0457" list-style="none"><li id="ul0457-0001" num="4311">To authenticate a write of M<sub>new </sub>to ChipA's memory M<sub>new</sub>:</li></ul></li><li id="ul0456-0002" num="4312">a. System calls ChipU's Write function, passing in M<sub>new</sub>;</li><li id="ul0456-0003" num="4313">b. The authentication procedure for a Read is carried out (see Section 5.3 on page 604);</li><li id="ul0456-0004" num="4314">c. If the read succeeds in such a way that M<sub>new</sub>=M returned in b, the write succeeded. If not, it failed.</li></ul>
4315Note that if these parameters are transmitted over an error-prone communications line (as opposed to internally or using an additional error-free transport layer), then an additional checksum would be required to prevent the wrong M from being updated or to prevent the correct M from being updated to the wrong value. For example, SHA-1 [t,X] should be additionally transferred across the communications line and checked (either by a wrapper function around Write or in a variant of Write that takes a hash as an extra parameter).
4316This is the most frequent type of write, and takes place between the System/consumable during normal everyday operation for M<sub>0</sub>, and during the manufacturing process for M<sub>1+</sub>.
00005.4.2 Authenticated Writes
4317In the QA Chip protocols, M<sub>0 </sub>is defined to be the only data vector that can be upgraded in an authenticated way. This decision was made primarily to simplify flash management, although it also helps to reduce the permissions storage requirements.
4318In this kind of write, System wants to change Chip U's M<sub>0 </sub>in an authorized way, without being subject to the permissions that apply during normal operation. For example, a consumable may be at a refilling station and the normally Decrement Only section of M<sub>0 </sub>should be updated to include the new valid consumable. In this case, the chip whose M<sub>0 </sub>is being updated must authenticate the writes being generated by the external System and in addition, apply the appropriate permission for the key to ensure that only the correct parts of M<sub>0 </sub>are updated. Having a different permission for each key is required as when multiple keys are involved, all keys should not necessarily be given open access to M<sub>0</sub>. For example, suppose M<sub>0 </sub>contains printer speed and a counter of money available for franking. A ChipS that updates printer speed should not be capable of updating the amount of money. Since P<sub>0 . . . T−1 </sub>is used for non-authenticated writes, each K<sub>n </sub>has a corresponding permission P<sub>T+n </sub>that determines what can be updated in an authenticated write.
4319The basic principle of the authenticated write (or upgrade) protocol is that the new value for the M<sub>t </sub>must be signed before ChipU accepts it. The QA Chip responsible for generating the signature (ChipS) must first validate that the ChipU is valid by reading the old value for M<sub>t</sub>. Once the old value is seen as valid, a new value can be signed by ChipS and the resultant data plus signature passed to ChipU. Note that both chips distrust each other.
4320There are two forms of authenticated writes. The first form is when both ChipU and ChipS directly store the same key. The second is when both ChipU and ChipS store different versions of the key and a transforming procedure is used on the stored key to generate the required key—i.e. the key is indirectly stored. The second form is slightly more complicated, and only has value when the ChipS is not readily available to an attacker.
00005.4.2.1 Direct Authenticated Writes
4321The direct form of the authenticated write protocol is used when the ChipS and ChipU are equally available to an attacker. For example, suppose that ChipU contains a printer's operating speed. Suppose that the speed can be increased by purchasing a ChipS and inserting it into the printer system. In this case, the ChipS and ChipU are equally available to an attacker. This is different from upgrading the printer over the internet where the effective ChipS is in a remote location, and thereby not as readily available to an attacker.
4322The direct authenticated write protocol requires ChipU to contain the following publicly available functions: <ul id="ul0458" list-style="none"><li id="ul0458-0001" num="4323">Read[n, t, X] Advances R, and returns R, M<sub>t</sub>, S<sub>Kn</sub>[X|R|C<sub>1</sub>|M<sub>t</sub>]. The time taken to calculate the signature must not be based on the contents of X, R, M<sub>t</sub>, or K.</li><li id="ul0458-0002" num="4324">WriteA[n, X, Y, Z] Advances R, replaces M<sub>0 </sub>by Y subject to P<sub>T+n</sub>, and returns 1 only if S<sub>Kn</sub>[R|X|C<sub>1</sub>|Y]=Z. Otherwise returns 0. The time taken to calculate and compare signatures must be independent of data content. This function is identical to ChipT's Test function except that it additionally writes Y subject to P<sub>T+n </sub>to its M when the signature matches.</li></ul>
4325Authenticated writes require that the System has access to a ChipS that is capable of generating appropriate signatures.
4326In its basic form, ChipS requires the following variables and function: <ul id="ul0459" list-style="none"><li id="ul0459-0001" num="4327">SignM[n,V,W,X,Y,Z] Advances R, and returns R, S<sub>Kn</sub>[W|R|C<sub>1</sub>|Z] only if Y=S<sub>Kn</sub>[V|W|C<sub>1</sub>|X]. <ul id="ul0460" list-style="none"><li id="ul0460-0001" num="4328">Otherwise returns all 0s. The time taken to calculate and compare signatures must be independent of data content.</li></ul></li></ul>
4329To update ChipU's M vector: <ul id="ul0461" list-style="none"><li id="ul0461-0001" num="4330">a. System calls ChipU's Read function, passing in n1, 0 (desired vector number) and 0 (the random value, but is a don't-care value) as the input parameters;</li><li id="ul0461-0002" num="4331">b. ChipU produces R<sub>U</sub>, M<sub>U0</sub>, S<sub>Kn1</sub>[0|R<sub>U</sub>|C<sub>1</sub>|M<sub>U0</sub>] and returns these to System;</li><li id="ul0461-0003" num="4332">c. System calls ChipS's SignM function, passing in n2 (the key to be used in ChipS), 0 (the random value as used in a), R<sub>U</sub>, M<sub>U0</sub>, S<sub>Kn1</sub>[0|R<sub>U</sub>|C<sub>1</sub>|M<sub>U0</sub>], and M<sub>D </sub>(the desired vector to be written to ChipU);</li><li id="ul0461-0004" num="4333">d. ChipS produces R<sub>S </sub>and S<sub>Kn2</sub>[R<sub>U</sub>|R<sub>S</sub>|C<sub>1</sub>|M<sub>D</sub>] if the inputs were valid, and 0 for all outputs if the inputs were not valid.</li><li id="ul0461-0005" num="4334">e. If values returned in d are non zero, then ChipU is considered authentic. System can then call ChipU's WriteA function with these values from d.</li><li id="ul0461-0006" num="4335">f. ChipU should return a 1 to indicate success. A 0 should only be returned if the data generated by ChipS is incorrect (e.g. a transmission error).</li></ul>
4336The choice of n1 and n2 must be such that ChipU's K<sub>n1</sub>=ChipS's K<sub>n2</sub>.
4337The data flow for authenticated writes is shown in <figref idref="DRAWINGS">FIG. 330</figref>.
4338Note that this protocol allows ChipS to generate a signature for any desired memory vector M<sub>D</sub>, and therefore a stolen ChipS has the ability to effectively render the particular keys for those parts of M<sub>0 </sub>in ChipU irrelevant.
4339It is therefore not recommended that the basic form of ChipS be ever implemented except in specifically controlled circumstances.
4340It is much more secure to limit the powers of ChipS. The following list covers some of the variants of limiting the power of ChipS: <ul id="ul0462" list-style="none"><li id="ul0462-0001" num="4341">a. the ability to upgrade a limited number of times</li><li id="ul0462-0002" num="4342">b. the ability to upgrade based on a credit value—i.e. the upgrade amount is decremented from the local value, and effectively transferred to the upgraded device</li><li id="ul0462-0003" num="4343">c. the ability to upgrade to a fixed value or from a limited list</li><li id="ul0462-0004" num="4344">d. the ability to upgrade to any value</li><li id="ul0462-0005" num="4345">e. the ability to only upgrade certain data fields within M</li></ul>
4346In many of these variants, the ability to refresh the ChipS in some way (e.g. with a new count or credit value) would be a useful feature.
4347In certain cases, the variant is in ChipS, while ChipU remains the same. It may also be desirable to create a ChipU variant, for example only allowing ChipU to only be upgraded a specific number of times.
00005.4.2.1.1 Variant Example
4348This section details the variant for the ability to upgrade a memory vector to any value a specific number of times, but the upgrade is only allowed to affect certain fields within the memory vector i.e. a combination of (a), (d), and (e) above.
4349In this example, ChipS requires the following variables and function: <ul id="ul0463" list-style="none"><li id="ul0463-0001" num="4350">CountRemaining Part of ChipS's M<sub>0 </sub>that contains the number of signatures that ChipS is allowed to generate. Decrements with each successful call to SignM and SignP. Permissions in ChipS's P<sub>0 . . . T−1 </sub>for this part of M<sub>0 </sub>needs to be ReadOnly once ChipS has been setup. Therefore CountRemaining can only be updated by another ChipS that will perform updates to that part of M<sub>0 </sub>(assuming ChipS's Ps allows that part of M<sub>0 </sub>to be updated).</li><li id="ul0463-0002" num="4351">Q Part of M that contains the write permissions for updating ChipU's M. By adding Q to ChipS we allow different ChipSs that can update different parts of M<sub>U</sub>. Permissions in ChipS's P<sub>0 . . . T−1 </sub>for this part of M needs to be ReadOnly once ChipS has been setup. Therefore Q can only be updated by another ChipS that will perform updates to that part of M.</li><li id="ul0463-0003" num="4352">SignM[n,V,W,X,Y,Z] Advances R, decrements CountRemaining and returns R, Z<sub>QX </sub>(Z applied to X with permissions Q), S<sub>Kn</sub>[W|R|C<sub>1</sub>|Z<sub>QX</sub>] only if Y=S<sub>Kn</sub>[V|W|C<sub>1</sub>|X] and CountRemaining>0. Otherwise returns all 0s. The time taken to calculate and compare signatures must be independent of data content.</li></ul>
4353To update ChipU's M vector: <ul id="ul0464" list-style="none"><li id="ul0464-0001" num="4354">a. System calls ChipU's Read function, passing in n1, 0 (desired vector number) and 0 (the random value, but is a don't-care value) as the input parameters;</li><li id="ul0464-0002" num="4355">b. ChipU produces R<sub>U</sub>, M<sub>U0</sub>, S<sub>Kn1</sub>[0|R<sub>U</sub>|C<sub>1</sub>|M<sub>U0</sub>] and returns these to System;</li><li id="ul0464-0003" num="4356">c. System calls ChipS's SignM function, passing in n2 (the key to be used in ChipS), 0 (as used in a), R<sub>U</sub>, M<sub>U0</sub>, S<sub>Kn1</sub>[0|R<sub>U</sub>|C<sub>1</sub>|M<sub>U0</sub>], and M<sub>D </sub>(the desired vector to be written to ChipU);</li><li id="ul0464-0004" num="4357">d. ChipS produces R<sub>S</sub>, M<sub>QD </sub>(processed by running M<sub>D </sub>against M<sub>U0 </sub>using Q) and S<sub>Kn2</sub>[R<sub>U</sub>|R<sub>S</sub>|C<sub>1</sub>|M<sub>QD</sub>] if the inputs were valid, and 0 for all outputs if the inputs were not valid.</li><li id="ul0464-0005" num="4358">e. If values returned in d are non zero, then ChipU is considered authentic. System can then call ChipU's WriteA function with these values from d.</li><li id="ul0464-0006" num="4359">f. ChipU should return a 1 to indicate success. A 0 should only be returned if the data generated by ChipS is incorrect (e.g. a transmission error).</li></ul>
4360The choice of n1 and n2 must be such that ChipU's K<sub>n1</sub>=ChipS's K<sub>n2</sub>.
4361The data flow for this variant of authenticated writes is shown in <figref idref="DRAWINGS">FIG. 331</figref>.
4362Note that Q in ChipS is part of ChipS's M. This allows a user to set up ChipS with a permission set for upgrades. This should be done to ChipS and that part of M designated by P<sub>0 . . . T−1 </sub>set to ReadOnly before ChipS is programmed with K<sub>U</sub>. If K<sub>S </sub>is programmed with K<sub>U </sub>first, there is a risk of someone obtaining a half-setup ChipS and changing all of M<sub>U </sub>instead of only the sections specified by Q.
4363In addition, CountRemaining in ChipS needs to be setup (including making it ReadOnly in P<sub>S</sub>) before ChipS is programmed with K<sub>U</sub>. ChipS should therefore be programmed to only perform a limited number of SignM operations (thereby limiting compromise exposure if a ChipS is stolen). Thus ChipS would itself need to be upgraded with a new CountRemaining every so often.
00005.4.2.2 Indirect Authenticated Writes
4364This section describes an alternative authenticated write protocol when ChipU is more readily available to an attacker and ChipS is less available to an attacker. We can store different keys on ChipU and ChipS, and implement a mapping between them in such a way that if the attacker is able to obtain a key from a given ChipU, they cannot upgrade all ChipUs.
4365In the general case, this is accomplished by storing key K<sub>S </sub>on ChipS, and K<sub>U </sub>and f on ChipU. The relationship is f(K<sub>S</sub>)=K<sub>U </sub>such that knowledge of K<sub>U </sub>and f does not make it easy to determine K<sub>S</sub>. This implies that a one-way function is desirable for f.
4366In the QA Chip domain, we define f as a number (e.g. 32-bits) such that SHA1(K<sub>S</sub>|f)=K<sub>U</sub>. The value of f (random between chips) can be stored in a known location within M<sub>1 </sub>as a constant for the life of the QA Chip. It is possible to use the same f for multiple relationships if desired, since f is public and the protection lies in the fact that f varies between QA Chips (preferably in a non-predictable way).
4367The indirect protocol is the same as the direct protocol with the exception that f is additionally passed in to the SignM function so that ChipS is able to generate the correct key. The System obtains f by performing a Read of M<sub>1</sub>. Note that all other functions, including the WriteA function in ChipU, are identical to their direct authentication counterparts. <ul id="ul0465" list-style="none"><li id="ul0465-0001" num="4368">SignM[f,n,V,W,X,Y,Z] Advances R, and returns R, S<sub>f(Kn)</sub>[W|R|C<sub>1</sub>|Z] only if Y=S<sub>f(Kn)</sub>[V|W|C<sub>1</sub>|X] and CountRemaining>0. Otherwise returns all 0s. The time taken to calculate and compare signatures must be independent of data content.</li></ul>
4369Before reading ChipU's memory M<sub>0 </sub>(the pre-upgrade value), the System must extract f from ChipU by performing the following tasks: <ul id="ul0466" list-style="none"><li id="ul0466-0001" num="4370">a. System calls ChipU's Read function, passing in (dontCare, 1, dontCare)</li><li id="ul0466-0002" num="4371">b. ChipU returns M<sub>1</sub>, from which System can extract f<sub>U </sub></li><li id="ul0466-0003" num="4372">c. System stores f<sub>U </sub>for future use</li></ul>
4373To update ChipU's M vector, the protocol is identical to that described in the basic authenticated write protocol with the exception of steps c and d: <ul id="ul0467" list-style="none"><li id="ul0467-0001" num="4374">c. System calls ChipS's SignM function, passing in f<sub>U</sub>, n2 (the key to be used in ChipS), 0 (as used in a), R<sub>U</sub>, M<sub>U0</sub>, S<sub>Kn1</sub>[0|R<sub>U</sub>|C<sub>1</sub>|M<sub>U0</sub>], and M<sub>D </sub>(the desired vector to be written to ChipU);</li><li id="ul0467-0002" num="4375">d. ChipS produces R<sub>S </sub>and S<sub>fU(Kn2)</sub>[R<sub>U</sub>|R<sub>S</sub>|C<sub>1</sub>|M<sub>D</sub>] if the inputs were valid, and 0 for all outputs if the inputs were not valid.</li></ul>
4376In addition, the choice of n1 and n2 must be such that ChipU's K<sub>n1</sub>=ChipS's f<sub>U</sub>(K<sub>n2</sub>).
4377Note that f<sub>U </sub>is obtained from M<sub>1 </sub>without validation. This is because there is nothing to be gained by subverting the value of f<sub>U</sub>, (because then the signatures won't match).
4378From the System's perspective, the protocol would take on a form like the following pseudocode:
4379<tables id="TABLE-US-00367" num="00367"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>dontCare, M<sub>R</sub>, dontCare <img file="US7165824B2_D0048.tif" /> ChipR.Read(dontCare,1, dontCare)</entry></row><row><entry>f<sub>R </sub>= extract from M<sub>R</sub></entry></row><row><entry>. . .</entry></row><row><entry>R<sub>U</sub>, M<sub>U</sub>, SIG<sub>U </sub><img file="US7165824B2_D0049.tif" /> ChipU.Read(keyNumOnChipU,0, 0)</entry></row><row><entry>R<sub>S</sub>, SIG<sub>S </sub>= ChipS.SignM2(f<sub>R</sub>, keyNumOnChipS, 0, R<sub>U</sub>, M<sub>U</sub>, SIG<sub>U</sub>, M<sub>D</sub>)</entry></row><row><entry>If (R<sub>S </sub>= SIG<sub>S </sub>= 0)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// ChipU and therefore M<sub>U </sub>is not to be trusted</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>// ChipU and therefore M<sub>U </sub>can be trusted</entry></row><row><entry /><entry>ok = ChipU.WriteA(keyNumOnChipU, R<sub>S</sub>, M<sub>D</sub>, SIG<sub>S</sub>)</entry></row><row><entry /><entry>If (ok)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>// updating of data in ChipU was successful</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>// transmission error during WriteA</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 5.4.2.2.1 Variant Example
4380The indirect form of the example from Section 5.4.2.1.1 is shown here. <ul id="ul0468" list-style="none"><li id="ul0468-0001" num="4381">SignM[f,n,V,W,X,Y,Z] Advances R, decrements CountRemaining and returns R, Z<sub>QX </sub>(Z applied to X with permissions Q), S<sub>f(Kn)</sub>[W|R|C<sub>1</sub>|Z<sub>QX</sub>] only if Y=S<sub>f(Kn)</sub>[V|W|C<sub>1</sub>X] and CountRemaining>0. Otherwise returns all 0s. The time taken to calculate and compare signatures must be independent of data content.</li></ul>
4382Before reading ChipU's memory M<sub>0 </sub>(the pre-upgrade value), the System must extract f from ChipU by performing the following tasks: <ul id="ul0469" list-style="none"><li id="ul0469-0001" num="4383">a. System calls ChipU's Read function, passing in (dontCare, 1, dontCare)</li><li id="ul0469-0002" num="4384">b. ChipU returns M<sub>1</sub>, from which System can extract f<sub>U </sub></li><li id="ul0469-0003" num="4385">c. System stores f<sub>U </sub>for future use</li></ul>
4386To update ChipU's M vector, the protocol is identical to that described in the basic authenticated write protocol with the exception of steps c and d: <ul id="ul0470" list-style="none"><li id="ul0470-0001" num="4387">c. System calls ChipS's SignM function, passing in f<sub>U</sub>, n2 (the key to be used in ChipS), 0 (as used in a), R<sub>U</sub>, M<sub>U0</sub>, S<sub>Kn1</sub>[0|R<sub>U</sub>|C<sub>1</sub>|M<sub>U0</sub>], and M<sub>D </sub>(the desired vector to be written to ChipU);</li><li id="ul0470-0002" num="4388">d. ChipS produces R<sub>S</sub>, M<sub>QD </sub>(processed by running M<sub>D </sub>against M<sub>U0 </sub>using Q) and S<sub>fU(Kn2)</sub>[R<sub>U</sub>|R<sub>S</sub>|C<sub>1</sub>|M<sub>QD</sub>] if the inputs were valid, and 0 for all outputs if the inputs were not valid.</li></ul>
4389In addition, the choice of n1 and n2 must be such that ChipU's K<sub>n1</sub>=ChipS's f<sub>U</sub>(K<sub>n2</sub>).
4390Note that f<sub>U </sub>is obtained from M<sub>1 </sub>without validation. This is because there is nothing to be gained by subverting the value of f<sub>U</sub>, (because then the signatures won't match).
4391From the System's perspective, the protocol would take on a form like the following pseudocode:
4392<tables id="TABLE-US-00368" num="00368"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>dontCare, M<sub>R</sub>, dontCare <img file="US7165824B2_D0050.tif" /> ChipR.Read(dontCare,1, dontCare)</entry></row><row><entry /><entry>f<sub>R </sub>= extract from M<sub>R</sub></entry></row><row><entry /><entry>. . .</entry></row><row><entry /><entry>R<sub>U</sub>, M<sub>U</sub>, SIG<sub>U </sub><img file="US7165824B2_D0051.tif" /> ChipU.Read(keyNumOnChipU,0, 0)</entry></row><row><entry /><entry>R<sub>S</sub>, M<sub>QD</sub>, SIG<sub>S </sub>= ChipS.SignM2(f<sub>R</sub>, keyNumOnChipS, 0, R<sub>U</sub>, M<sub>U</sub>,</entry></row><row><entry /><entry>SIG<sub>U</sub>, M<sub>D</sub>)</entry></row><row><entry /><entry>If (R<sub>S </sub>= M<sub>QD </sub>= SIG<sub>S </sub>= 0)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>// ChipU and therefore M<sub>U </sub>is not to be trusted</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>// ChipU and therefore M<sub>U </sub>can be trusted</entry></row><row><entry /><entry>ok = ChipU.WriteA(keyNumOnChipU, R<sub>S</sub>, M<sub>QD</sub>, SIG<sub>S</sub>)</entry></row><row><entry /><entry>If (ok)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>// updating of data in ChipU was successful</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>// transmission error during WriteA</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 5.4.3 Updating Permissions for Future Writes
4393In order to reduce exposure to accidental and malicious attacks on P (and certain parts of M), only authorized users are allowed to update P. Writes to P are the same as authorized writes to M, except that they update P<sub>n </sub>instead of M. Initially (at manufacture), P is set to be Read/Write for all M. As different processes fill up different parts of M, they can be sealed against future change by updating the permissions. Updating a chip's P<sub>0 . . . T−1 </sub>changes permissions for unauthorized writes to M<sub>n</sub>, and updating P<sub>T . . . T+N−1 </sub>changes permissions for authorized writes with key K<sub>n</sub>.
4394P<sub>n </sub>is only allowed to change to be a more restrictive form of itself. For example, initially all parts of M have permissions of Read/Write. A permission of Read/Write can be updated to Decrement Only or Read Only. A permission of Decrement Only can be updated to become Read Only. A Read Only permission cannot be further restricted.
4395In this transaction protocol, the System's chip is referred to as ChipS, and the chip being updated is referred to as ChipU. Each chip distrusts the other.
4396The protocol requires the following publicly available functions in ChipU: <ul id="ul0471" list-style="none"><li id="ul0471-0001" num="4397">Random<img file="US7165824B2_D0052.tif" /> Returns R (does not advance R).</li><li id="ul0471-0002" num="4398">SetPermission[n,p,X,Y,Z] Advances R, and updates P<sub>p </sub>according to Y and returns 1 followed by the resultant P<sub>p </sub>only if S<sub>Kn</sub>[R|X|Y|C<sub>2</sub>]=Z. Otherwise returns 0. P<sub>p </sub>can only become more restricted. Passing in 0 for any permission leaves it unchanged (passing in Y=0 returns the current P<sub>p</sub>).</li></ul>
4399Authenticated writes of permissions require that the System has access to a ChipS that is capable of generating appropriate signatures. ChipS requires the following variable: <ul id="ul0472" list-style="none"><li id="ul0472-0001" num="4400">CountRemaining Part of ChipS's M<sub>0 </sub>that contains the number of signatures that ChipS is allowed to generate. Decrements with each successful call to SignM and SignP. Permissions in ChipS's P<sub>0 . . . T−1 </sub>for this part of M<sub>0 </sub>needs to be ReadOnly once ChipS has been setup. Therefore CountRemaining can only be updated by another ChipS that will perform updates to that part of M<sub>0 </sub>(assuming ChipS's P<sub>n </sub>allows that part of M<sub>0 </sub>to be updated).</li></ul>
4401In addition, ChipS requires either of the following two SignP functions depending on whether direct or indirect key storage is used (see direct vs indirect authenticated write protocols in Section 5.4.2): <ul id="ul0473" list-style="none"><li id="ul0473-0001" num="4402">SignP[n,X,Y] Used when the same key is directly stored in both ChipS and ChipU. Advances R, decrements CountRemaining and returns R and S<sub>Kn</sub>[X|R|Y|C<sub>2</sub>] only if CountRemaining>0. Otherwise returns all 0s. The time taken to calculate and compare signatures must be independent of data content.</li><li id="ul0473-0002" num="4403">SignP[f,n,X,Y] Used when the same key is not directly stored in both ChipS and ChipU. In this case ChipU's K<sub>n1</sub>=ChipS's f(K<sub>n2</sub>). The function is identical to the direct form of SignP, except that it additionally accepts f and returns S<sub>f(Kn)</sub>[X|R|Y|C<sub>2</sub>] instead of S<sub>Kn</sub>[X|R|Y|C<sub>2</sub>]. <br /> 5.4.3.1 Direct Form of SignP </li></ul>
4404When the direct form of SignP is used, ChipU's P<sub>n </sub>is updated as follows: <ul id="ul0474" list-style="none"><li id="ul0474-0001" num="4405">a. System calls ChipU's Random function;</li><li id="ul0474-0002" num="4406">b. ChipU returns R<sub>U </sub>to System;</li><li id="ul0474-0003" num="4407">c. System calls ChipS's SignP function, passing in n2, R<sub>U </sub>and P<sub>D </sub>(the desired P to be written to ChipU);</li><li id="ul0474-0004" num="4408">d. ChipS produces R<sub>S </sub>and S<sub>Kn2</sub>[R<sub>U</sub>|R<sub>S</sub>|P<sub>D</sub>|C<sub>2</sub>] if it is still permitted to produce signatures.</li><li id="ul0474-0005" num="4409">e. If values returned in d are non zero, then System can then call ChipU's SetPermission function with n1, the desired permission entry p, R<sub>S</sub>, P<sub>D </sub>and S<sub>Kn2</sub>[R<sub>U</sub>|R<sub>S</sub>|P<sub>D</sub>|C<sub>2</sub>].</li><li id="ul0474-0006" num="4410">f. ChipU verifies the received signature against its own generated signature S<sub>Kn1</sub>[R<sub>U</sub>|R<sub>S</sub>|P<sub>D</sub>|C<sub>2</sub>] and applies P<sub>D </sub>to P<sub>n </sub>if the signature matches</li><li id="ul0474-0007" num="4411">g. System checks 1 st output parameter. 1=success, 0=failure.</li></ul>
4412The choice of n1 and n2 must be such that ChipU's K<sub>n1</sub>=ChipS's K<sub>n2</sub>.
4413The data flow for basic authenticated writes to permissions is shown in <figref idref="DRAWINGS">FIG. 332</figref>.
00005.4.3.2 Indirect Form of SignP
4414When the indirect form of SignP is used in ChipS, the System must extract f from ChipU (so it knows how to generate the correct key) by performing the following tasks: <ul id="ul0475" list-style="none"><li id="ul0475-0001" num="4415">a. System calls ChipU's Read function, passing in (dontCare, 1, dontCare)</li><li id="ul0475-0002" num="4416">b. ChipU returns M<sub>1</sub>, from which System can extract f<sub>U </sub></li><li id="ul0475-0003" num="4417">c. System stores f<sub>U </sub>for future use</li></ul>
4418ChipU's P<sub>n </sub>is updated as follows: <ul id="ul0476" list-style="none"><li id="ul0476-0001" num="4419">a. System calls ChipU's Random function;</li><li id="ul0476-0002" num="4420">b. ChipU returns R<sub>U </sub>to System;</li><li id="ul0476-0003" num="4421">c. System calls ChipS's SignP function, passing in f<sub>U</sub>, n2, R<sub>U </sub>and P<sub>D </sub>(the desired P to be written to ChipU);</li><li id="ul0476-0004" num="4422">d. ChipS produces R<sub>S </sub>and S<sub>fU(K</sub><sub>n2)</sub>[R<sub>U</sub>|R<sub>S</sub>|P<sub>D</sub>|C<sub>2</sub>] if it is still permitted to produce signatures.</li><li id="ul0476-0005" num="4423">e. If values returned in d are non zero, then System can then call ChipU's SetPermission function with n1, the desired permission entry p, R<sub>S</sub>, P<sub>D </sub>and S<sub>fU(Kn2)</sub>[R<sub>U</sub>|R<sub>S</sub>|P<sub>D</sub>|C<sub>2</sub>].</li><li id="ul0476-0006" num="4424">f. ChipU verifies the received signature against S<sub>Kn1</sub>[R<sub>U</sub>|R<sub>S</sub>|P<sub>D</sub>|C<sub>2</sub>] and applies P<sub>D </sub>to P<sub>n </sub>if the signature matches</li><li id="ul0476-0007" num="4425">g. System checks 1 st output parameter. 1=success, 0=failure.</li></ul>
4426In addition, the choice of n1 and n2 must be such that ChipU's K<sub>n1</sub>=ChipS's f<sub>U</sub>(K<sub>n2</sub>).
00005.4.4 Protecting Memory Vectors
4427To protect the appropriate part of M<sub>n </sub>against unauthorized writes, call SetPermissions[n] for n=0 to T−1. To protect the appropriate part of M<sub>0 </sub>against authorized writes with key n, call SetPermissions[T+n] for n=0 to N−1.
4428Note that only M<sub>0 </sub>can be written in an authenticated fashion.
4429Note that the SetPermission function must be called after the part of M has been set to the desired value.
4430For example, if adding a serial number to an area of M<sub>1 </sub>that is currently ReadWrite so that noone is permitted to update the number again: <ul id="ul0477" list-style="none"><li id="ul0477-0001" num="0000"><ul id="ul0478" list-style="none"><li id="ul0478-0001" num="4431">the Write function is called to write the serial number to M<sub>1 </sub></li><li id="ul0478-0002" num="4432">SetPermission(1) is called for to set that part of M to be ReadOnly for non-authorized writes.</li></ul></li></ul>
4433If adding a consumable value to M<sub>0 </sub>such that only keys 1–2 can update it, and keys 0, and 3−N cannot: <ul id="ul0479" list-style="none"><li id="ul0479-0001" num="0000"><ul id="ul0480" list-style="none"><li id="ul0480-0001" num="4434">the Write function is called to write the amount of consumable to M<sub>1 </sub></li><li id="ul0480-0002" num="4435">SetPermission is called for 0 to set that part of M<sub>0 </sub>to be DecrementOnly for non-authorized writes. This allows the amount of consumable to decrement.</li><li id="ul0480-0003" num="4436">SetPermission is called for n={T, T+3, T+4 . . . , T+N−1} to set that part of M<sub>0 </sub>to be ReadOnly for authorized writes using all but keys 1 and 2. This leaves keys 1 and 2 with ReadWrite permissions to M<sub>0</sub>.</li></ul></li></ul>
4437It is possible for someone who knows a key to further restrict other keys, but it is not in anyone's interest to do so.
00005.5 Programming K
4438In this case, we have a factory chip (ChipF) connected to a System. The System wants to program the key in another chip (ChipP). System wants to avoid passing the new key to ChipP in the clear, and also wants to avoid the possibility of the key-upgrade message being replayed on another ChipP (even if the user doesn't know the key).
4439The protocol assumes that ChipF and ChipP already share (directly or indirectly) a secret key K<sub>old</sub>. This key is used to ensure that only a chip that knows K<sub>old </sub>can set K<sub>new</sub>.
4440Although the example shows a ChipF that is only allowed to program a specific number of ChipPs, the key-upgrade protocol can be easily altered (similar to the way the write protocols have variants) to provide other means of limiting the ability to update ChipPs.
4441The protocol requires the following publicly available functions in ChipP: <ul id="ul0481" list-style="none"><li id="ul0481-0001" num="4442">Random<img file="US7165824B2_D0053.tif" /> Returns R (does not advance R). <ul id="ul0482" list-style="none"><li id="ul0482-0001" num="4443">ReplaceKey[n, X, Y, Z] Replaces K<sub>n </sub>by S<sub>Kn</sub>[R|X|C<sub>3</sub>]⊕Y, advances R, and returns 1 only if S<sub>Kn</sub>[X|Y|C<sub>3</sub>]=Z. Otherwise returns 0. The time taken to calculate signatures and compare values must be identical for all inputs.</li></ul></li></ul>
4444And the following data and functions in ChipF: <ul id="ul0483" list-style="none"><li id="ul0483-0001" num="4445">CountRemaining Part of M<sub>0 </sub>with contains the number of signatures that ChipF is allowed to generate. Decrements with each successful call to GetProgramKey. Permissions in P for this part of M<sub>0 </sub>needs to be ReadOnly once ChipF has been setup. Therefore can only be updated by a ChipS that has authority to perform updates to that part of M<sub>0</sub>.</li><li id="ul0483-0002" num="4446">K<sub>new </sub>The new key to be transferred from ChipF to ChipP. Must not be visible. After manufacture, K<sub>new </sub>is 0.</li></ul>
4447SetPartialKey[X] Updates K<sub>new </sub>to be K<sub>new</sub>⊕X. This function allows K<sub>new </sub>to be programmed in any number of steps, thereby allowing different people or systems to know different parts of the key (but not the whole K<sub>new</sub>). K<sub>new </sub>is stored in ChipF's flash memory.
4448In addition, ChipF requires either of the following GetProgramKey functions depending on whether direct or indirect key storage is used on the input key and/or output key (see direct vs indirect authenticated write protocols in Section 5.4.2): <ul id="ul0484" list-style="none"><li id="ul0484-0001" num="4449">GetProgramKey1[n, X] Direct to direct. Used when the same key (K<sub>n</sub>) is directly stored in both ChipF and ChipP and we want to store K<sub>new </sub>in ChipP. Advances R<sub>F</sub>, decrements CountRemaining, outputs R<sub>F</sub>, the encrypted key S<sub>Kn</sub>[X|R<sub>F</sub>|C<sub>3</sub>]⊕K<sub>new </sub>and a signature of the first two outputs plus C<sub>3 </sub>if CountRemaining>0. Otherwise outputs 0. The time to calculate the encrypted key & signature must be identical for all inputs.</li><li id="ul0484-0002" num="4450">GetProgramKey2[f, n, X] Direct to indirect. Used when the same key (K<sub>n</sub>) is directly stored in both ChipF and ChipP but we want to store f<sub>P</sub>(K<sub>new</sub>) in ChipP instead of simply K<sub>new </sub>(i.e. we want to keep the key in ChipP to be different in all ChipPs). In this case ChipP's K<sub>n1</sub>=ChipF's f<sub>P</sub>(K<sub>n2</sub>). The function is identical to GetProgramKey1, except that it additionally accepts f<sub>P</sub>, and returns S<sub>Kn</sub>[X|R<sub>F</sub>|C<sub>3</sub>]⊕f<sub>P</sub>(K<sub>new</sub>) instead of S<sub>Kn</sub>[X|R<sub>F</sub>|C<sub>3</sub>]⊕K<sub>new</sub>. Note that the produced signature is produced using K<sub>n </sub>since that is what is already stored in ChipP.</li><li id="ul0484-0003" num="4451">GetProgramKey3[f, n, X] Indirect to direct. Used when the same key is not directly stored in both ChipF and ChipP but we want to store K<sub>new </sub>in ChipP. In this case ChipP's K<sub>n1</sub>=ChipF's f<sub>P</sub>(K<sub>n2</sub>). The function is identical to GetProgramKey1, except that it additionally accepts f<sub>P</sub>, and returns S<sub>fP(Kn)</sub>[X|R<sub>F</sub>|C<sub>3</sub>]⊕K<sub>new </sub>instead of S<sub>Kn</sub>[X|R<sub>F</sub>|C<sub>3</sub>]⊕K<sub>new</sub>. The produced signature is produced using f<sub>P</sub>(Kn) instead of K<sub>n </sub>since that is what is already stored in ChipP.</li><li id="ul0484-0004" num="4452">GetProgramKey4[f, n, X] Indirect to indirect. Used when the same key is not directly stored in both ChipF and ChipP but we want to store f<sub>P</sub>(K<sub>new</sub>) in ChipP instead of simply K<sub>new </sub>(i.e. we want to keep the key in ChipP to be different in all ChipPs). In this case ChipP's K<sub>n1</sub>=ChipF's f<sub>P</sub>(K<sub>n2</sub>). The function is identical to GetProgramKey3, except that it returns S<sub>fP(Kn)</sub>[X|R<sub>F</sub>|C<sub>3</sub>]⊕f<sub>P</sub>(K<sub>new</sub>) instead of S<sub>fP(Kn)</sub>[X|R<sub>F</sub>|C<sub>3</sub>]⊕K<sub>new</sub>. The produced signature is produced using f<sub>P</sub>(K<sub>n</sub>) since that is what is already stored in ChipP.</li></ul>
4453Since there are likely to be few ChipFs, and many ChipPs, the indirect forms of GetProgramKey can be usefully employed.
00005.5.1 GetProgramKey1—Direct to Direct
4454With the “old key=direct, new key=direct” form of GetProgramKey, to update P's key: <ul id="ul0485" list-style="none"><li id="ul0485-0001" num="4455">a. System calls ChipP's Random function;</li><li id="ul0485-0002" num="4456">b. ChipP returns R<sub>P </sub>to System;</li><li id="ul0485-0003" num="4457">c. System calls ChipF's GetProgramKey function, passing in n2 (the desired key to use) and the result from b;</li><li id="ul0485-0004" num="4458">d. ChipF updates R<sub>F</sub>, then calculates and returns R<sub>F</sub>, S<sub>Kn2</sub>[R<sub>P</sub>|R<sub>F</sub>|C<sub>3</sub>]⊕K<sub>new</sub>, and S<sub>Kn2</sub>[R<sub>F</sub>|S<sub>Kn2</sub>[R<sub>P</sub>|R<sub>F</sub>|C<sub>3</sub>|⊕K<sub>new</sub>⊕C<sub>3</sub>];</li><li id="ul0485-0005" num="4459">e. If the response from d is not 0, System calls ChipP's ReplaceKey function, passing in n1 (the key to use in ChipP) and the response from d;</li><li id="ul0485-0006" num="4460">f. System checks response from ChipP. If the response is 1, then ChipP's K<sub>n1 </sub>has been correctly updated to K<sub>new</sub>. If the response is 0, ChipP's K<sub>n1 </sub>has not been updated.</li></ul>
4461The choice of n1 and n2 must be such that ChipP's K<sub>n1</sub>=ChipF's K<sub>n2</sub>.
4462The data flow for key updates is shown in <figref idref="DRAWINGS">FIG. 333</figref>:
4463Note that K<sub>new </sub>is never passed in the open. An attacker could send its own R<sub>P</sub>, but cannot produce S<sub>Kn2</sub>[R<sub>P</sub>|R<sub>F</sub>|C<sub>3</sub>] without K<sub>n2</sub>. The signature based on K<sub>new </sub>is sent to ensure that ChipP will be able to determine if either of the first two parameters have been changed en route.
4464CountRemaining needs to be setup in M<sub>F0 </sub>(including making it ReadOnly in P) before ChipF is programmed with K<sub>P</sub>. ChipF should therefore be programmed to only perform a limited number of GetProgramKey operations (thereby limiting compromise exposure if a ChipF is stolen). An authorized ChipS can be used to update this counter if necessary (see Section 5.4.2 on page 610).
00005.5.2 GetProgramKey2—Direct to Indirect
4465With the “old key=direct, new key=indirect” form of GetProgramKey, to update P's key, the System must extract f from ChipP (so it can tell ChipF how to generate the correct key) by performing the following tasks: <ul id="ul0486" list-style="none"><li id="ul0486-0001" num="4466">a. System calls ChipP's Read function, passing in (dontCare, 1, dontCare)</li><li id="ul0486-0002" num="4467">b. ChipP returns M<sub>1</sub>, from which System can extract f<sub>P </sub></li><li id="ul0486-0003" num="4468">c. System stores f<sub>P </sub>for future use</li></ul>
4469ChipP's key is updated as follows: <ul id="ul0487" list-style="none"><li id="ul0487-0001" num="4470">a. System calls ChipP's Random function;</li><li id="ul0487-0002" num="4471">b. ChipP returns R<sub>P </sub>to System;</li><li id="ul0487-0003" num="4472">c. System calls ChipF's GetProgramKey function, passing in f<sub>P</sub>, n2 (the desired key to use) and the result from b;</li><li id="ul0487-0004" num="4473">d. ChipF updates R<sub>F</sub>, then calculates and returns R<sub>F</sub>, S<sub>Kn2</sub>[R<sub>P</sub>|R<sub>F</sub>|C<sub>3</sub>]⊕f<sub>P</sub>(K<sub>new</sub>), and S<sub>Kn2</sub>[R<sub>F</sub>|S<sub>Kn2</sub>[R<sub>P</sub>|R<sub>F</sub>|C<sub>3</sub>]⊕f<sub>P</sub>(K<sub>new</sub>)|C<sub>3</sub>];</li><li id="ul0487-0005" num="4474">e. If the response from d is not 0, System calls ChipP's ReplaceKey function, passing in n1 (the key to use in ChipP) and the response from d;</li><li id="ul0487-0006" num="4475">f. System checks response from ChipP. If the response is 1, then ChipP's K<sub>n1 </sub>has been correctly updated to f<sub>P</sub>(K<sub>new</sub>). If the response is 0, ChipP's K<sub>n1 </sub>has not been updated.</li></ul>
4476The choice of n1 and n2 must be such that ChipP's K<sub>n1</sub>=ChipF's K<sub>n2</sub>.
00005.5.3 GetProgramKey3—Indirect to Direct
4477With the “old key=indirect, new key=direct” form of GetProgramKey, to update P's key, the System must extract f from ChipP (so it can tell ChipF how to generate the correct key) by performing the following tasks: <ul id="ul0488" list-style="none"><li id="ul0488-0001" num="4478">a. System calls ChipP's Read function, passing in (dontCare, 1, dontCare)</li><li id="ul0488-0002" num="4479">b. ChipP returns M<sub>1</sub>, from which System can extract f<sub>P </sub></li><li id="ul0488-0003" num="4480">c. System stores f<sub>P </sub>for future use</li></ul>
4481ChipP's key is updated as follows: <ul id="ul0489" list-style="none"><li id="ul0489-0001" num="4482">a. System calls ChipP's Random function;</li><li id="ul0489-0002" num="4483">b. ChipP returns R<sub>P </sub>to System;</li><li id="ul0489-0003" num="4484">c. System calls ChipF's GetProgramKey function, passing in f<sub>P</sub>, n2 (the desired key to use) and the result from b;</li><li id="ul0489-0004" num="4485">d. ChipF updates R<sub>F</sub>, then calculates and returns R<sub>F</sub>, S<sub>fP(Kn2)</sub>[R<sub>P</sub>|R<sub>F</sub>|C<sub>3</sub>]⊕K<sub>new</sub>, and S<sub>fP(Kn2)</sub>[R<sub>F</sub>|S<sub>fP(Kn2)</sub>[R<sub>P</sub>|R<sub>F</sub>|C<sub>3</sub>]⊕K<sub>new</sub>|C<sub>3</sub>];</li><li id="ul0489-0005" num="4486">e. If the response from d is not 0, System calls ChipP's ReplaceKey function, passing in n1 (the key to use in ChipP) and the response from d;</li><li id="ul0489-0006" num="4487">f. System checks response from ChipP. If the response is 1, then ChipP's K<sub>n1 </sub>has been correctly updated to K<sub>new</sub>. If the response is 0, ChipP's K<sub>n1 </sub>has not been updated.</li></ul>
4488The choice of n1 and n2 must be such that ChipP's K<sub>n1</sub>=ChipF's f<sub>P</sub>(K<sub>n2</sub>).
00005.5.4 GetProgramKey4—Indirect to Indirect
4489With the “old key=indirect, new key=indirect” form of GetProgramKey, to update P's key, the System must extract f from ChipP (so it can tell ChipF how to generate the correct key) by performing the following tasks: <ul id="ul0490" list-style="none"><li id="ul0490-0001" num="4490">a. System calls ChipP's Read function, passing in (dontCare, 1, dontCare)</li><li id="ul0490-0002" num="4491">b. ChipP returns M<sub>1</sub>, from which System can extract f<sub>P </sub></li><li id="ul0490-0003" num="4492">c. System stores f<sub>P </sub>for future use</li></ul>
4493ChipP's key is updated as follows: <ul id="ul0491" list-style="none"><li id="ul0491-0001" num="4494">a. System calls ChipP's Random function;</li><li id="ul0491-0002" num="4495">b. ChipP returns R<sub>P </sub>to System;</li><li id="ul0491-0003" num="4496">c. System calls ChipF's GetProgramKey function, passing in f<sub>P</sub>, n2 (the desired key to use) and the result from b;</li><li id="ul0491-0004" num="4497">d. ChipF updates R<sub>F</sub>, then calculates and returns R<sub>F</sub>, S<sub>fP(Kn2)</sub>[R<sub>P</sub>|R<sub>F</sub>|C<sub>3</sub>]⊕f<sub>P</sub>(K<sub>new</sub>), and S<sub>fP(Kn2)</sub>[R<sub>F</sub>|S<sub>fP(Kn2)</sub>[R<sub>P</sub>|R<sub>F</sub>|C<sub>3</sub>]⊕f<sub>P</sub>(K<sub>new</sub>)|C<sub>3</sub>];</li><li id="ul0491-0005" num="4498">e. If the response from d is not 0, System calls ChipP's ReplaceKey function, passing in n1 (the key to use in ChipP) and the response from d;</li><li id="ul0491-0006" num="4499">f. System checks response from ChipP. If the response is 1, then ChipP's K<sub>n1 </sub>has been correctly updated to f<sub>P</sub>(K<sub>new</sub>). If the response is 0, ChipP's K<sub>n1 </sub>has not been updated.</li></ul>
4500The choice of n1 and n2 must be such that ChipP's K<sub>n1</sub>=ChipF's f<sub>P</sub>(K<sub>n2</sub>).
00005.5.5 Chicken and Egg
4501The Program Key protocol requires both ChipF and ChipP to know K<sub>old </sub>(either directly or indirectly). Obviously both chips had to be programmed in some way with K<sub>old</sub>, and thus K<sub>old </sub>can be thought of as an older K<sub>new</sub>: K<sub>old </sub>can be placed in chips if another ChipF knows K<sub>older</sub>, and so on.
4502Although this process allows a chain of reprogramming of keys, with each stage secure, at some stage the very first key (K<sub>first</sub>) must be placed in the chips. K<sub>first </sub>is in fact programmed with the chip's microcode at the manufacturing test station as the last step in manufacturing test. K<sub>first </sub>can be a manufacturing batch key, changed for each batch or for each customer etc., and can have as short a life as desired. Compromising K<sub>first </sub>need not result in a complete compromise of the chain of Ks. This is especially true if K<sub>first </sub>is indirectly stored in ChipPs (i.e. each ChipP holds an f and f(K<sub>first</sub>) instead of K<sub>first </sub>directly). One example is where K<sub>first </sub>(the key stored in each chip after manufacture/test) is a batch key, and can be different per chip. K<sub>first </sub>may advance to a ComCo specific K<sub>seond </sub>etc. but still remain indirect. A direct form (e.g. K<sub>fianal</sub>) only needs to go in if it is actually required at the end of the programming chain.
4503Depending on reprogramming requirements, K<sub>first </sub>can be the same or different for all K<sub>n</sub>.
00006 Memjet Forms of Protocols
4504Physical QA Chips are used in Memjet printer systems to store printer operating parameters as well as consumable parameters.
00006.1 PRINTER_QA
4505A PRINTER_QA is stored within each print engine to perform two primary tasks: <ul id="ul0492" list-style="none"><li id="ul0492-0001" num="0000"><ul id="ul0493" list-style="none"><li id="ul0493-0001" num="4506">storage and protection of operating parameters</li><li id="ul0493-0002" num="4507">a means of indirect read validation of other QA Chip data vectors</li></ul></li></ul>
4508Each PRINTER_QA contains the following keys:
4509<tables id="TABLE-US-00369" num="00369"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 229</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Keys in PrinterQA</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="70pt" align="left" /><colspec colname="3" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>Key</entry><entry>Contents</entry><entry>Comments</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>0</entry><entry>Upgrade Key</entry><entry>Used to upgrade the operating</entry></row><row><entry /><entry /><entry>parameters. Should be indirect form</entry></row><row><entry /><entry /><entry>of key (i.e. a different key for each</entry></row><row><entry /><entry /><entry>PRINTER_QA) so that an indirect</entry></row><row><entry /><entry /><entry>form of the write is required.</entry></row><row><entry>1</entry><entry>Consumable Read</entry><entry>Used to indirectly read the data from</entry></row><row><entry /><entry>Validation Key</entry><entry>an CONSUMABLE_QA chip using</entry></row><row><entry /><entry /><entry>indirect authenticated read protocol</entry></row><row><entry /><entry /><entry>(Section 5.3.2 on page 606).</entry></row><row><entry>2</entry><entry>PrintEngineController</entry><entry>When reading data from the</entry></row><row><entry /><entry>Read Validation Key</entry><entry>PRINTER_QA, the system can either</entry></row><row><entry /><entry /><entry>trust the data, or must use this key</entry></row><row><entry /><entry /><entry>to perform the authenticated read</entry></row><row><entry /><entry /><entry>protocol (see Section 5.3 on page</entry></row><row><entry /><entry /><entry>604).</entry></row><row><entry>3–n</entry><entry>(reserved)</entry><entry>Currently unused.</entry></row><row><entry /><entry /><entry>Could be used to provide a means to</entry></row><row><entry /><entry /><entry>indirectly read additional print engine</entry></row><row><entry /><entry /><entry>operating parameters ala K1, or</entry></row><row><entry /><entry /><entry>provide additional Print Engine</entry></row><row><entry /><entry /><entry>validation ala K2.</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
4510Note that if multiple Print Engine Controllers are used (e.g. a multiple SoPEC system), then multiple PrintEngineController Read Validation Keys are required. These keys can be stored within a single PRINTER_QA (e.g. in K<sub>3 </sub>and beyond), or can be stored in separate PRINTER_QAs (for example each SoPEC (or group of SoPECs) has an individual PRINTER_QA).
4511The functions required in the PRINTER_QA are: <ul id="ul0494" list-style="none"><li id="ul0494-0001" num="0000"><ul id="ul0495" list-style="none"><li id="ul0495-0001" num="4512">Random, ReplaceKey, to allow key programming & substitution</li><li id="ul0495-0002" num="4513">Read, to allow reads of data</li><li id="ul0495-0003" num="4514">Write, to allow updates of M<sub>1+</sub> during manufacture</li><li id="ul0495-0004" num="4515">WriteAuth, to provide a means of updating the M<sub>0 </sub>data (operating parameters)</li><li id="ul0495-0005" num="4516">SetPermissions, to provide a means of updating write permissions</li><li id="ul0495-0006" num="4517">Test, to provide a means of checking if consumable reads are valid</li><li id="ul0495-0007" num="4518">Translate, to provide a means of indirect reading of consumable data <br /> 6.2 CONSUMABLE_QA </li></ul></li></ul>
4519A CONSUMABLE_QA is stored with each consumable (e.g. ink cartridge) to perform two primary tasks: <ul id="ul0496" list-style="none"><li id="ul0496-0001" num="0000"><ul id="ul0497" list-style="none"><li id="ul0497-0001" num="4520">storage of consumable related data</li><li id="ul0497-0002" num="4521">protection of consumable amount remaining</li></ul></li></ul>
4522Each CONSUMABLE_QA contains the following keys:
4523<tables id="TABLE-US-00370" num="00370"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 230</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Keys in CONSUMABLE_QA</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>Key</entry><entry>Contents</entry><entry>Comments</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>0</entry><entry>Upgrade Key</entry><entry>Used to upgrade the consumable</entry></row><row><entry /><entry /><entry>parameters. Should be stored as</entry></row><row><entry /><entry /><entry>the indirect form of the key</entry></row><row><entry /><entry /><entry>(i.e. a different key for each</entry></row><row><entry /><entry /><entry>CONSUMABLE_QA) so that an</entry></row><row><entry /><entry /><entry>indirect form of the write is</entry></row><row><entry /><entry /><entry>required.</entry></row><row><entry>1</entry><entry>Consumable Read</entry><entry>When reading data from the</entry></row><row><entry /><entry>Validation Key</entry><entry>CONSUMABLE_QA, the system can</entry></row><row><entry /><entry /><entry>either trust the data, or must</entry></row><row><entry /><entry /><entry>use this key to perform either</entry></row><row><entry /><entry /><entry>the direct or indirect</entry></row><row><entry /><entry /><entry>authenticated read protocol</entry></row><row><entry /><entry /><entry>(see Section 5.3 on page 604).</entry></row><row><entry>2</entry><entry>(reserved)</entry><entry>Currently unused.</entry></row><row><entry>3–n</entry><entry>(reserved)</entry><entry>Currently unused.</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
4524The functions required in the CONSUMABLE_QA are: <ul id="ul0498" list-style="none"><li id="ul0498-0001" num="0000"><ul id="ul0499" list-style="none"><li id="ul0499-0001" num="4525">Random, ReplaceKey, to allow key programming & substitution</li><li id="ul0499-0002" num="4526">Read, to allow reads of data.</li><li id="ul0499-0003" num="4527">Write, to allow updates of M<sub>1+</sub> during manufacture</li><li id="ul0499-0004" num="4528">WriteAuth, to provide a means of updating the M<sub>0 </sub>data (consumable remaining)</li><li id="ul0499-0005" num="4529">SetPermissions, to provide a means of updating write permissions <br /> Authentication of Consumables <br /> 1 Introduction </li></ul></li></ul>
4530Manufacturers of systems that require consumables (such as a laser printer that requires toner cartridges) have struggled with the problem of authenticating consumables, to varying levels of success. Most have resorted to specialized packaging that involves a patent. However this does not stop home refill operations or clone manufacture in countries with weak industrial property protection. The prevention of copying is important to prevent poorly manufactured substitute consumables from damaging the base system. For example, poorly filtered ink may clog print nozzles in an ink jet printer, causing the consumer to blame the system manufacturer and not admit the use of non-authorized consumables.
4531To solve the authentication problem, this document describes an QA Chip that contains authentication keys and circuitry specially designed to prevent copying. The chip is manufactured using the standard Flash memory manufacturing process, and is low cost enough to be included in consumables such as ink and toner cartridges. The implementation is approximately 1 mm<sup>2 </sup>in a 0.25 micron flash process, and has an expected manufacturing cost of approximately 10 cents in 2003.
2 NSA
4532Once programmed, the QA Chips as described here are compliant with the NSA export guidelines since they do not constitute a strong encryption device. They can therefore be practically manufactured in the USA (and exported) or anywhere else in the world.
00003 Nomenclature
4533The following symbolic nomenclature is used throughout this document:
4534<tables id="TABLE-US-00371" num="00371"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 231</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Summary of symbolic nomenclature</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>Symbol</entry><entry>Description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>F[X]</entry><entry>Function F, taking a single parameter X</entry></row><row><entry>F[X, Y]</entry><entry>Function F, taking two parameters, X and Y</entry></row><row><entry>X | Y</entry><entry>X concatenated with Y</entry></row><row><entry>X <img file="US7165824B2_D0054.tif" /> Y</entry><entry>Bitwise X AND Y</entry></row><row><entry>X <img file="US7165824B2_D0055.tif" /> Y</entry><entry>Bitwise X OR Y (inclusive-OR)</entry></row><row><entry>X ⊕ Y</entry><entry>Bitwise X XOR Y (exclusive-OR)</entry></row><row><entry><img file="US7165824B2_D0056.tif" /> X</entry><entry>Bitwise NOT X (complement)</entry></row><row><entry>X <img file="US7165824B2_D0057.tif" /> Y</entry><entry>X is assigned the value Y</entry></row><row><entry>X <img file="US7165824B2_D0058.tif" /> {Y, Z}</entry><entry>The domain of assignment inputs to X is Y and Z</entry></row><row><entry>X = Y</entry><entry>X is equal to Y</entry></row><row><entry>X ≠ Y</entry><entry>X is not equal to Y</entry></row><row><entry><img file="US7165824B2_D0059.tif" /> X</entry><entry>Decrement X by 1 (floor 0)</entry></row><row><entry><img file="US7165824B2_D0060.tif" /> X</entry><entry>Increment X by 1 (modulo register length)</entry></row><row><entry>Erase X</entry><entry>Erase Flash memory register X</entry></row><row><entry>SetBits[X, Y]</entry><entry>Set the bits of the Flash memory register X based</entry></row><row><entry /><entry>on Y</entry></row><row><entry>Z <img file="US7165824B2_D0061.tif" /> ShiftRight[X, Y]</entry><entry>Shift register X right one bit position, taking input</entry></row><row><entry /><entry>bit from Y and placing the output bit in Z</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 4 Pseudocode <br /> 4.1.1 Asynchronous
4535The following pseudocode: <ul id="ul0500" list-style="none"><li id="ul0500-0001" num="0000"><ul id="ul0501" list-style="none"><li id="ul0501-0001" num="4536">var=expression <br /> means the var signal or output is equal to the evaluation of the expression. <br /> 4.1.2 Synchronous </li></ul></li></ul>
4537The following pseudocode: <ul id="ul0502" list-style="none"><li id="ul0502-0001" num="0000"><ul id="ul0503" list-style="none"><li id="ul0503-0001" num="4538">var←expression <br /> means the var register is assigned the result of evaluating the expression during this cycle. <br /> 4.1.3 Expression </li></ul></li></ul>
4539Expressions are defined using the nomenclature in Table 231 above. Therefore: <br /><i>var</i>=(<i>a=b</i>)<br /> is interpreted as the var signal is 1 if a is equal to b, and 0 otherwise. <br /> 4.2 Diagrams
4540Black is used to denote data, and red to denote 1-bit control-signal lines.
00004.3 QA Chip Terminology
4541This document refers to QA Chips by their function in particular protocols: <ul id="ul0504" list-style="none"><li id="ul0504-0001" num="0000"><ul id="ul0505" list-style="none"><li id="ul0505-0001" num="4542">For authenticated reads, ChipA is the QA Chip being authenticated, and ChipT is the QA Chip that is trusted.</li><li id="ul0505-0002" num="4543">For replacement of keys, ChipP is the QA Chip being programmed with the new key, and ChipF is the factory QA Chip that generates the message to program the new key.</li><li id="ul0505-0003" num="4544">For upgrades of data in a QA Chip, ChipU is the QA Chip being upgraded, and ChipS is the QA Chip that signs the upgrade value.</li></ul></li></ul>
4545Any given physical QA Chip will contain functionality that allows it to operate as an entity in some number of these protocols.
4546Therefore, wherever the terms ChipA, ChipT, ChipP, ChipF, ChipU and ChipS are used in this document, they are referring to logical entities involved in an authentication protocol as defined in subsequent sections.
4547Physical QA Chips are referred to by their location. For example, each ink cartridge may contain a QA Chip referred to as an INK_QA, with all INK_QA chips being on the same physical bus. In the same way, the QA Chip inside a printer is referred to as PRINTER_QA, and will be on a separate bus to the INK_QA chips.
00005 Concepts and Terms
4548This chapter provides a background to the problem of authenticating consumables. For more in-depth introductory texts, see [12], [78], and [56].
00005.1 Basic Terms
4549A message, denoted by M, is plaintext. The process of transforming M into ciphertext C, where the substance of M is hidden, is called encryption. The process of transforming C back into M is called decryption. Referring to the encryption function as E, and the decryption function as D, we have the following identities: <br />E[M]=C<br />D[C]=M
4550Therefore the following identity is true: <br />D[E[M]]=M<br /> 5.2 Symmetric Cryptography
4551A symmetric encryption algorithm is one where: <ul id="ul0506" list-style="none"><li id="ul0506-0001" num="0000"><ul id="ul0507" list-style="none"><li id="ul0507-0001" num="4552">the encryption function E relies on key K<sub>1</sub>,</li><li id="ul0507-0002" num="4553">the decryption function D relies on key K<sub>2</sub>,</li><li id="ul0507-0003" num="4554">K<sub>2 </sub>can be derived from K<sub>1</sub>, and</li><li id="ul0507-0004" num="4555">K<sub>1 </sub>can be derived from K<sub>2</sub>.</li></ul></li></ul>
4556In most symmetric algorithms, K<sub>1 </sub>equals K<sub>2</sub>. However, even if K<sub>1 </sub>does not equal K<sub>2</sub>, given that one key can be derived from the other, a single key K can suffice for the mathematical definition. Thus: <br />E<sub>K</sub>[M]=C<br />D<sub>K</sub>[C]=M
4557The security of these algorithms rests very much in the key K. Knowledge of K allows anyone to encrypt or decrypt. Consequently K must remain a secret for the duration of the value of M. For example, M may be a wartime message “My current position is grid position 123–456”. Once the war is over the value of M is greatly reduced, and if K is made public, the knowledge of the combat unit's position may be of no relevance whatsoever. Of course if it is politically sensitive for the combat unit's position to be known even after the war, K may have to remain secret for a very long time.
4558An enormous variety of symmetric algorithms exist, from the textbooks of ancient history through to sophisticated modern algorithms. Many of these are insecure, in that modern cryptanalysis techniques (see Section 5.7 on page 646) can successfully attack the algorithm to the extent that K can be derived.
4559The security of the particular symmetric algorithm is a function of two things: the strength of the algorithm and the length of the key [78].
4560The strength of an algorithm is difficult to quantify, relying on its resistance to cryptographic attacks (see Section 5.7 on page 646). In addition, the longer that an algorithm has remained in the public eye, and yet remained unbroken in the midst of intense scrutiny, the more secure the algorithm is likely to be. By contrast, a secret algorithm that has not been scrutinized by cryptographic experts is unlikely to be secure.
4561Even if the algorithm is “perfectly” strong (the only way to break it is to try every key—see Section 5.7.1.5 on page 647), eventually the right key will be found. However, the more keys there are, the more keys have to be tried. If there are N keys, it will take a maximum of N tries. If the key is N bits long, it will take a maximum of 2<sup>N </sup>tries, with a 50% chance of finding the key after only half the attempts (2<sup>N−1</sup>). The longer N becomes, the longer it will take to find the key, and hence the more secure it is. What makes a good key length depends on the value of the secret and the time for which the secret must remain secret as well as available computing resources.
4562In 1996, an ad hoc group of world-renowned cryptographers and computer scientists released a report [9] describing minimal key lengths for symmetric ciphers to provide adequate commercial security. They suggest an absolute minimum key length of 90 bits in order to protect data for 20 years, and stress that increasingly, as cryptosystems succumb to smarter attacks than brute-force key search, even more bits may be required to account for future surprises in cryptanalysis techniques.
4563We will ignore most historical symmetric algorithms on the grounds that they are insecure, especially given modern computing technology. Instead, we will discuss the following algorithms: <ul id="ul0508" list-style="none"><li id="ul0508-0001" num="0000"><ul id="ul0509" list-style="none"><li id="ul0509-0001" num="4564">DES</li><li id="ul0509-0002" num="4565">Blowfish</li><li id="ul0509-0003" num="4566">RC5</li><li id="ul0509-0004" num="4567">IDEA <br /> 5.2.1 DES </li></ul></li></ul>
4568DES (Data Encryption Standard) [26] is a US and international standard, where the same key is used to encrypt and decrypt. The key length is 56 bits. It has been implemented in hardware and software, although the original design was for hardware only. The original algorithm used in DES was patented in 1976 (U.S. Pat. No. 3,962,539) and has since expired.
4569During the design of DES, the NSA (National Security Agency) provided secret S-boxes to perform the key-dependent nonlinear transformations of the data block. After differential cryptanalysis was discovered outside the NSA, it was revealed that the DES S-boxes were specifically designed to be resistant to differential cryptanalysis.
4570As described in [95], using 1993 technology, a 56-bit DES key can be recovered by a custom-designed $1 million machine performing a brute force attack in only 35 minutes. For $10 million, the key can be recovered in only 3.5 minutes. DES is clearly not secure now, and will become less so in the future.
4571A variant of DES, called triple-DES is more secure, but requires 3 keys: K<sub>1</sub>, K<sub>2</sub>, and K<sub>3</sub>. The keys are used in the following manner: <br />E<sub>K3</sub>[D<sub>K2</sub>[E<sub>K1</sub>[M]]]=C<br />D<sub>K3</sub>[E<sub>K2</sub>[D<sub>K1</sub>[C]]]=M
4572The main advantage of triple-DES is that existing DES implementations can be used to give more security than single key DES. Specifically, triple-DES gives protection of equivalent key length of 112 bits [78]. Triple-DES does not give the equivalent protection of a 168-bit key (3×56) as one might naively expect.
4573Equipment that performs triple-DES decoding and/or encoding cannot be exported from the United States.
00005.2.2 Blowfish
4574Blowfish is a symmetric block cipher first presented by Schneier in 1994 [76]. It takes a variable length key, from 32 bits to 448 bits, is unpatented, and is both license and royalty free. In addition, it is much faster than DES.
4575The Blowfish algorithm consists of two parts: a key-expansion part and a data-encryption part. Key expansion converts a key of at most 448 bits into several subkey arrays totaling 4168 bytes. Data encryption occurs via a 16-round Feistel network. All operations are XORs and additions on 32-bit words, with four index array lookups per round.
4576It should be noted that decryption is the same as encryption except that the subkey arrays are used in the reverse order. Complexity of implementation is therefore reduced compared to other algorithms that do not have such symmetry.
4577[77] describes the published attacks which have been mounted on Blowfish, although the algorithm remains secure as of February 1998 [79]. The major finding with these attacks has been the discovery of certain weak keys. These weak keys can be tested for during key generation. For more information, refer to [77] and [79].
5.2.3 RC5
4578Designed by Ron Rivest in 1995, RC5 [74] has a variable block size, key size, and number of rounds. Typically, however, it uses a 64-bit block size and a 128-bit key.
4579The RC5 algorithm consists of two parts: a key-expansion part and a data-encryption part. Key expansion converts a key into 2r+2 subkeys (where r=the number of rounds), each subkey being w bits. For a 64-bit blocksize with 16 rounds (w=32, r=16), the subkey arrays total 136 bytes. Data encryption uses addition mod 2<sup>w</sup>, XOR and bitwise rotation.
4580An initial examination by Kaliski and Yin [43] suggested that standard linear and differential cryptanalysis appeared impractical for the 64-bit blocksize version of the algorithm. Their differential attacks on 9 and 12 round RC5 require 2<sup>45 </sup>and 2<sup>62 </sup>chosen plaintexts respectively, while the linear attacks on 4, 5, and 6 round RC5 requires 2<sup>37</sup>, 2<sup>47 </sup>and 2<sup>57 </sup>known plaintexts). These two attacks are independent of key size.
4581More recently however, Knudsen and Meier [47] described a new type of differential attack on RC5 that improved the earlier results by a factor of 128, showing that RC5 has certain weak keys.
4582RC5 is protected by multiple patents owned by RSA Laboratories. A license must be obtained to use it.
5.2.4 IDEA
4583Developed in 1990 by Lai and Massey [53], the first incarnation of the IDEA cipher was called PES. After differential cryptanalysis was discovered by Biham and Shamir in 1991, the algorithm was strengthened, with the result being published in 1992 as IDEA [52].
4584IDEA uses 128-bit keys to operate on 64-bit plaintext blocks. The same algorithm is used for encryption and decryption. It is generally regarded as the most secure block algorithm available today [78][78].
4585The biggest drawback of IDEA is the fact that it is patented (U.S. Pat. No. 5,214,703, issued in 1993), and a license must be obtained from Ascom Tech AG (Bern) to use it.
00005.3 Asymmetric Cryptography
4586An asymmetric encryption algorithm is one where: <ul id="ul0510" list-style="none"><li id="ul0510-0001" num="0000"><ul id="ul0511" list-style="none"><li id="ul0511-0001" num="4587">the encryption function E relies on key K<sub>1</sub>,</li><li id="ul0511-0002" num="4588">the decryption function D relies on key K<sub>2</sub>,</li><li id="ul0511-0003" num="4589">K<sub>2 </sub>cannot be derived from K<sub>1 </sub>in a reasonable amount of time, and</li><li id="ul0511-0004" num="4590">K<sub>1 </sub>cannot be derived from K<sub>2 </sub>in a reasonable amount of time.</li></ul></li></ul>
4591Thus: <br />E<sub>K1</sub>[M]=C<br />D<sub>K2</sub>[C]=M
4592These algorithms are also called public-key because one key K<sub>1 </sub>can be made public. Thus anyone can encrypt a message (using K<sub>1</sub>) but only the person with the corresponding decryption key (K<sub>2</sub>) can decrypt and thus read the message.
4593In most cases, the following identity also holds: <br />E<sub>K2</sub>[M]=C<br />D<sub>K1</sub>[C]=M
4594This identity is very important because it implies that anyone with the public key K<sub>1 </sub>can see M and know that it came from the owner of K<sub>2</sub>. No-one else could have generated C because to do so would imply knowledge of K<sub>2</sub>. This gives rise to a different application, unrelated to encryption—digital signatures.
4595The property of not being able to derive K<sub>1 </sub>from K<sub>2 </sub>and vice versa in a reasonable time is of course clouded by the concept of reasonable time. What has been demonstrated time after time, is that a calculation that was thought to require a long time has been made possible by the introduction of faster computers, new algorithms etc. The security of asymmetric algorithms is based on the difficulty of one of two problems: factoring large numbers (more specifically large numbers that are the product of two large primes), and the difficulty of calculating discrete logarithms in a finite field. Factoring large numbers is conjectured to be a hard problem given today's understanding of mathematics. The problem however, is that factoring is getting easier much faster than anticipated. Ron Rivest in 1977 said that factoring a 125-digit number would take 40 quadrillion years [30]. In 1994 a 129-digit number was factored (3]. According to Schneier, you need a 1024-bit number to get the level of security today that you got from a 512-bit number in the 1980s [78]. If the key is to last for some years then 1024 bits may not even be enough. Rivest revised his key length estimates in 1990: he suggests 1628 bits for high security lasting until 2005, and 1884 bits for high security lasting until 2015 [69]. Schneier suggests 2048 bits are required in order to protect against corporations and governments until 2015 [80].
4596Public key cryptography was invented in 1976 by Diffie and Hellman [15][15], and independently by Merkle [57]. Although Diffie, Hellman and Merkle patented the concepts (U.S. Pat. Nos. 4,200,770 and 4,218,582), these patents expired in 1997.
4597A number of public key cryptographic algorithms exist. Most are impractical to implement, and many generate a very large C for a given M or require enormous keys. Still others, while secure, are far too slow to be practical for several years. Because of this, many public key systems are hybrid—a public key mechanism is used to transmit a symmetric session key, and then the session key is used for the actual messages.
4598All of the algorithms have a problem in terms of key selection. A random number is simply not secure enough. The two large primes p and q must be chosen carefully—there are certain weak combinations that can be factored more easily (some of the weak keys can be tested for). But nonetheless, key selection is not a simple matter of randomly selecting 1024 bits for example. Consequently the key selection process must also be secure.
4599Of the practical algorithms in use under public scrutiny, the following are discussed: <ul id="ul0512" list-style="none"><li id="ul0512-0001" num="0000"><ul id="ul0513" list-style="none"><li id="ul0513-0001" num="4600">RSA</li><li id="ul0513-0002" num="4601">DSA</li><li id="ul0513-0003" num="4602">EIGamal <br /> 5.3.1 RSA </li></ul></li></ul>
4603The RSA cryptosystem [75], named after Rivest, Shamir, and Adleman, is the most widely used public key cryptosystem, and is a de facto standard in much of the world [78].
4604The security of RSA depends on the conjectured difficulty of factoring large numbers that are the product of two primes (p and q). There are a number of restrictions on the generation of p and q. They should both be large, with a similar number of bits, yet not be close to one another (otherwise p≡q≡√pq). In addition, many authors have suggested that p and q should be strong primes [56]. The Hellman-Bach patent (U.S. Pat. No. 4,633,036) covers a method for generating strong RSA primes p and q such that n=pq and factoring n is believed to be computationally infeasible. The RSA algorithm patent was issued in 1983 (U.S. Pat. No. 4,405,829). The patent expires on Sep. 20, 2000.
5.3.2 DSA
4605DSA (Digital Signature Algorithm) is an algorithm designed as part of the Digital Signature Standard (DSS) [29]. As defined, it cannot be used for generalized encryption. In addition, compared to RSA, DSA is 10 to 40 times slower for signature verification [40]. DSA explicitly uses the SHA-1 hashing algorithm (see Section 5.5.3.3 on page 640).
4606DSA key generation relies on finding two primes p and q such that q divides p−1. According to Schneier [78], a 1024-bit p value is required for long term DSA security. However the DSA standard [29] does not permit values of p larger than 1024 bits (p must also be a multiple of 64 bits).
4607The US Government owns the DSA algorithm and has at least one relevant patent (U.S. Pat. No. 5,231,688 granted in 1993). However, according to NIST [61]: <ul id="ul0514" list-style="none"><li id="ul0514-0001" num="0000"><ul id="ul0515" list-style="none"><li id="ul0515-0001" num="4608">“The DSA patent and any foreign counterparts that may issue are available for use without any written permission from or any payment of royalties to the U.S. government.”</li></ul></li></ul>
4609In a much stronger declaration, NIST states in the same document [61] that DSA does not infringe third party's rights: <ul id="ul0516" list-style="none"><li id="ul0516-0001" num="0000"><ul id="ul0517" list-style="none"><li id="ul0517-0001" num="4610">“NIST reviewed all of the asserted patents and concluded that none of them would be infringed by DSS. Extra protection will be written into the PK1 pilot project that will prevent an organization or individual from suing anyone except the government for patent infringement during the course of the project.”</li></ul></li></ul>
4611It must however, be noted that the Schnorr authentication algorithm [81] (U.S. Pat. No. 4,995,082) patent holder claims that DSA infringes his patent. The Schnorr patent is not due to expire until 2008.
00005.3.3 EIGamal
4612The EIGamal scheme [22][22] is used for both encryption and digital signatures. The security is based on the conjectured difficulty of calculating discrete logarithms in a finite field.
4613Key selection involves the selection of a prime p, and two random numbers g and x such that both g and x are less than p. Then calculate y=gx mod p. The public key is y, g, and p. The private key is x.
4614EIGamal is unpatented. Although it uses the patented Diffie-Hellman public key algorithm [15][15], those patents expired in 1997. EIGamal public key encryption and digital signatures can now be safely used without infringing third party patents.
00005.4 Cryptographic Challenge-response Protocols and Zero Knowledge Proofs
4615The general principle of a challenge-response protocol is to provide identity authentication. The simplest form of challenge-response takes the form of a secret password. A asks B for the secret password, and if B responds with the correct password, A declares B authentic.
4616There are three main problems with this kind of simplistic protocol. Firstly, once B has responded with the password, any observer C will know what the password is. Secondly, A must know the password in order to verify it. Thirdly, if C impersonates A, then B will give the password to C (thinking C was A), thus compromising the password.
4617Using a copyright text (such as a haiku) as the password is not sufficient, because we are assuming that anyone is able to copy the password (for example in a country where intellectual property is not respected).
4618The idea of cryptographic challenge-response protocols is that one entity (the claimant) proves its identity to another (the verifier) by demonstrating knowledge of a secret known to be associated with that entity, without revealing the secret itself to the verifier during the protocol [56]. In the generalized case of cryptographic challenge-response protocols, with some schemes the verifier knows the secret, while in others the secret is not even known by the verifier. A good overview of these protocols can be found in [25], [78], and [56].
4619Since this documentation specifically concerns Authentication, the actual cryptographic challenge-response protocols used for authentication are detailed in the appropriate sections. However the concept of Zero Knowledge Proofs bears mentioning here.
4620The Zero Knowledge Proof protocol, first described by Feige, Fiat and Shamir in [24] is extensively used in Smart Cards for the purpose of authentication [34][34][34]. The protocol's effectiveness is based on the assumption that it is computationally infeasible to compute square roots modulo a large composite integer with unknown factorization. This is provably equivalent to the assumption that factoring large integers is difficult.
4621It should be noted that there is no need for the claimant to have significant computing power. Smart cards implement this kind of authentication using only a few modulo multiplications [34][34].
4622Finally, it should be noted that the Zero Knowledge Proof protocol is patented [82] (U.S. Pat. No. 4,748,668, issued May 31, 1988).
00005.5 One-way Functions
4623A one-way function F operates on an input X, and returns F[X] such that X cannot be determined from F[X]. When there is no restriction on the format of X, and F[X] contains fewer bits than X, then collisions must exist. A collision is defined as two different X input values producing the same F[X] value—i.e. X<sub>1 </sub>and X<sub>2 </sub>exist such that X<sub>1</sub>≠X<sub>2 </sub>yet F[X<sub>1</sub>]=F[X<sub>2</sub>].
4624When X contains more bits than F[X], the input must be compressed in some way to create the output. In many cases, X is broken into blocks of a particular size, and compressed over a number of rounds, with the output of one round being the input to the next. The output of the hash function is the last output once X has been consumed. A pseudo-collision of the compression function CF is defined as two different initial values V<sub>1 </sub>and V<sub>2 </sub>and two inputs X<sub>1 </sub>and X<sub>2 </sub>(possibly identical) are given such that CF(V<sub>1</sub>, X<sub>1</sub>)=CF(V<sub>2</sub>, X<sub>2</sub>). Note that the existence of a pseudo-collision does not mean that it is easy to compute an X<sub>2 </sub>for a given X<sub>1</sub>.
4625We are only interested in one-way functions that are fast to compute. In addition, we are only interested in deterministic one-way functions that are repeatable in different implementations.
4626Consider an example F where F[X] is the time between calls to F. For a given F([X] X cannot be determined because X is not even used by F. However the output from F will be different for different implementations. This kind of F is therefore not of interest.
4627In the scope of this document, we are interested in the following forms of one-way functions: <ul id="ul0518" list-style="none"><li id="ul0518-0001" num="0000"><ul id="ul0519" list-style="none"><li id="ul0519-0001" num="4628">Encryption using an unknown key</li><li id="ul0519-0002" num="4629">Random number sequences</li><li id="ul0519-0003" num="4630">Hash Functions</li><li id="ul0519-0004" num="4631">Message Authentication Codes <br /> 5.5.1 Encryption Using an Unknown Key </li></ul></li></ul>
4632When a message is encrypted using an unknown key K<sub>1 </sub>the encryption function E is effectively one-way. Without the key, it is computationally infeasible to obtain M from EK[M] without K. An encryption function is only one-way for as long as the key remains hidden.
4633An encryption algorithm does not create collisions, since E creates EK[M] such that it is possible to reconstruct M using function D. Consequently F[X] contains at least as many bits as X (no information is lost) if the one-way function F is E.
4634Symmetric encryption algorithms (see Section 5.2 on page 629) have the advantage over asymmetric algorithms (see Section 5.3 on page 632) for producing one-way functions based on encryption for the following reasons: <ul id="ul0520" list-style="none"><li id="ul0520-0001" num="0000"><ul id="ul0521" list-style="none"><li id="ul0521-0001" num="4635">The key for a given strength encryption algorithm is shorter for a symmetric algorithm than an asymmetric algorithm</li><li id="ul0521-0002" num="4636">Symmetric algorithms are faster to compute and require less software or silicon</li></ul></li></ul>
4637Note however, that the selection of a good key depends on the encryption algorithm chosen. Certain keys are not strong for particular encryption algorithms, so any key needs to be tested for strength. The more tests that need to be performed for key selection, the less likely the key will remain hidden.
00005.5.2 Random Number Sequences
4638Consider a random number sequence R<sub>0</sub>, R<sub>1</sub>, . . . , R<sub>i</sub>, R<sub>i+1</sub>. We define the one-way function F such that F[X] returns the X<sup>th </sup>random number in the random sequence. However we must ensure that F[X] is repeatable for a given X on different implementations. The random number sequence therefore cannot be truly random. Instead, it must be pseudo-random, with the generator making use of a specific seed.
4639There are a large number of issues concerned with defining good random number generators. Knuth, in [48] describes what makes a generator “good” (including statistical tests), and the general problems associated with constructing them. Moreau gives a high level survey of the current state of the field in [60].
4640The majority of random number generators produce the i<sup>th </sup>random number from the i−<b>1</b><sup>th </sup>state—the only way to determine the i<sup>th </sup>number is to iterate from the 0<sup>th </sup>number to the i<sup>th</sup>. If i is large, it may not be practical to wait for i iterations.
4641However there is a type of random number generator that does allow random access. In [10], Blum, Blum and Shub define the ideal generator as follows: “ . . . we would like a pseudo-random sequence generator to quickly produce, from short seeds, long sequences (of bits) that appear in every way to be generated by successive flips of a fair coin”. They defined the x<sup>2 </sup>mod n generator [10], more commonly referred to as the BBS generator. They showed that given certain assumptions upon which modern cryptography relies, a BBS generator passes extremely stringent statistical tests.
4642The BBS generator relies on selecting n which is a Blum integer (n=pq where p and q are large prime numbers, p≠q, p mod 4=3, and q mod 4=3). The initial state of the generator is given by x<sub>0 </sub>where x<sub>0</sub>=x<sup>2 </sup>mod n, and x is a random integer relatively prime to n. The i<sup>th </sup>pseudo-random bit is the least significant bit of x<sub>i </sub>where: <br /><i>x</i><sub>i</sub><i>=x</i><sub>i−1</sub><sup>2</sup>mod <i>n</i>
4643As an extra property, knowledge of p and q allows a direct calculation of the i<sup>th </sup>number in the sequence as follows: <br /><i>x</i><sub>i</sub><i>=x</i><sub>0</sub><sup>y</sup>mod <i>n </i>where <i>y</i>=2<sup>i</sup>mod((<i>p</i>−1)(<i>q</i>−1))
4644Without knowledge of p and q, the generator must iterate (the security of calculation relies on the conjectured difficulty of factoring large numbers).
4645When first defined, the primary problem with the BBS generator was the amount of work required for a single output bit. The algorithm was considered too slow for most applications. However the advent of Montgomery reduction arithmetic [58] has given rise to more practical implementations, such as [59]. In addition, Vazirani and Vazirani have shown in [93] that depending on the size of n, more bits can safely be taken from x<sub>i </sub>without compromising the security of the generator.
4646Assuming we only take 1 bit per x<sub>i</sub>, N bits (and hence N iterations of the bit generator function) are needed in order to generate an N-bit random number. To the outside observer, given a particular set of bits, there is no way to determine the next bit other than a 50/50 probability. If the x, p and q are hidden, they act as a key, and it is computationally infeasible to take an output bit stream and compute x, p, and q. It is also computationally infeasible to determine the value of i used to generate a given set of pseudo-random bits. This last feature makes the generator one-way.
4647Different values of i can produce identical bit sequences of a given length (e.g. 32 bits of random bits). Even if x, p and q are known, for a given F[i], i can only be derived as a set of possibilities, not as a certain value (of course if the domain of i is known, then the set of possibilities is reduced further).
4648However, there are problems in selecting a good p and q, and a good seed x. In particular, Ritter in [68] describes a problem in selecting x. The nature of the problem is that a BBS generator does not create a single cycle of known length. Instead, it creates cycles of various lengths, including degenerate (zero-length) cycles. Thus a BBS generator cannot be initialized with a random state—it might be on a short cycle. Specific algorithms exist in section 9 of [10] to determine the length of the period for a given seed given certain strenuous conditions for n.
00005.5.3 Hash Functions
4649Special one-way functions, known as Hash functions, map arbitrary length messages to fixed-length hash values. Hash functions are referred to as H[M]. Since the input is of arbitrary length, a hash function has a compression component in order to produce a fixed length output. Hash functions also have an obfuscation component in order to make it difficult to find collisions and to determine information about M from H[M].
4650Because collisions do exist, most applications require that the hash algorithm is preimage resistant, in that for a given X<sub>1 </sub>it is difficult to find X<sub>2 </sub>such that H[X<sub>1</sub>]=H[X<sub>2</sub>]. In addition, most applications also require the hash algorithm to be collision resistant (i.e. it should be hard to find two messages X<sub>1 </sub>and X<sub>2 </sub>such that H[X<sub>1</sub>]=H[X<sub>2</sub>]). However, as described in [20], it is an open problem whether a collision-resistant hash function, in the ideal sense, can exist at all.
4651The primary application for hash functions is in the reduction of an input message into a digital “fingerprint” before the application of a digital signature algorithm. One problem of collisions with digital signatures can be seen in the following example. <ul id="ul0522" list-style="none"><li id="ul0522-0001" num="0000"><ul id="ul0523" list-style="none"><li id="ul0523-0001" num="4652">A has a long message M<sub>1 </sub>that says “I owe B $10”. A signs H[M<sub>1</sub>] using his private key. B, being greedy, then searches for a collision message M<sub>2 </sub>where H[M<sub>2</sub>]=H[M<sub>1</sub>] but where M<sub>2 </sub>is favorable to B, for example “I owe B $1 million”. Clearly it is in A's interest to ensure that it is difficult to find such an M<sub>2</sub>.</li></ul></li></ul>
4653Examples of collision resistant one-way hash functions are SHA-1 [28], MD5 [73] and RIPEMD-160 [66], all derived from MD4 [70][70].
5.5.3.1 MD4
4654Ron Rivest introduced MD4 [70][70] in 1990. It is only mentioned here because all other one-way hash functions are derived in some way from MD4.
4655MD4 is now considered completely broken [18][18] in that collisions can be calculated instead of searched for. In the example above, B could trivially generate a substitute message M<sub>2 </sub>with the same hash value as the original message M<sub>1</sub>.
5.5.3.2 MD5
4656Ron Rivest introduced MD5 [73] in 1991 as a more secure MD4. Like MD4, MD5 produces a 128-bit hash value. MD5 is not patented [80].
4657Dobbertin describes the status of MD5 after recent attacks [20]. He describes how pseudo-collisions have been found in MD5, indicating a weakness in the compression function, and more recently, collisions have been found. This means that MD5 should not be used for compression in digital signature schemes where the existence of collisions may have dire consequences. However MD5 can still be used as a one-way function. In addition, the HMAC-MD5 construct (see Section 5.5.4.1 on page 643) is not affected by these recent attacks.
5.5.3.3 SHA-1
4658SHA-1 [28] is very similar to MD5, but has a 160-bit hash value (MD5 only has 128 bits of hash value). SHA-1 was designed and introduced by the NIST and NSA for use in the Digital Signature Standard (DSS). The original published description was called SHA [27], but very soon afterwards, was revised to become SHA-1 [28], supposedly to correct a security flaw in SHA (although the NSA has not released the mathematical reasoning behind the change).
4659There are no known cryptographic attacks against SHA-1 [78]. It is also more resistant to brute force attacks than MD4 or MD5 simply because of the longer hash result.
4660The US Government owns the SHA-1 and DSA algorithms (a digital signature authentication algorithm defined as part of DSS [29]) and has at least one relevant patent (U.S. Pat. No. 5,231,688 granted in 1993). However, according to NIST [61]: <ul id="ul0524" list-style="none"><li id="ul0524-0001" num="0000"><ul id="ul0525" list-style="none"><li id="ul0525-0001" num="4661">“The DSA patent and any foreign counterparts that may issue are available for use without any written permission from or any payment of royalties to the U.S. government.”</li></ul></li></ul>
4662In a much stronger declaration, NIST states in the same document [61] that DSA and SHA-1 do not infringe third party's rights: <ul id="ul0526" list-style="none"><li id="ul0526-0001" num="0000"><ul id="ul0527" list-style="none"><li id="ul0527-0001" num="4663">“NIST reviewed all of the asserted patents and concluded that none of them would be infringed by DSS. Extra protection will be written into the PK1 pilot project that will prevent an organization or individual from suing anyone except the government for patent infringement during the course of the project.”</li></ul></li></ul>
4664It must however, be noted that the Schnorr authentication algorithm [81] (U.S. Pat. No. 4,995,082) patent holder claims that DSA infringes his patent. The Schnorr patent is not due to expire until 2008. Fortunately this does not affect SHA-1.
5.5.3.4 RIPEMD-160
4665RIPEMD-160 [66] is a hash function derived from its predecessor RIPEMD [11] (developed for the European Community's RIPE project in 1992). As its name suggests, RIPEMD-160 produces a 160-bit hash result. Tuned for software implementations on 32-bit architectures, RIPEMD-160 is intended to provide a high level of security for 10 years or more.
4666Although there have been no successful attacks on RIPEMD-160, it is comparatively new and has not been extensively cryptanalyzed. The original RIPEMD algorithm [11] was specifically designed to resist known cryptographic attacks on MD4. The recent attacks on MD5 (detailed in [20]) showed similar weaknesses in the RIPEMD 128-bit hash function. Although the attacks showed only theoretical weaknesses, Dobbertin, Preneel and Bosselaers further strengthened RIPEMD into a new algorithm RIPEMD-160.
4667RIPEMD-160 is in the public domain, and requires no licensing or royalty payments.
00005.5.4 Message Authentication Codes
4668The problem of message authentication can be summed up as follows: <ul id="ul0528" list-style="none"><li id="ul0528-0001" num="0000"><ul id="ul0529" list-style="none"><li id="ul0529-0001" num="4669">How can A be sure that a message supposedly from B is in fact from B?</li></ul></li></ul>
4670Message authentication is different from entity authentication (described in the section on cryptographic challenge-response protocols). With entity authentication, one entity (the claimant) proves its identity to another (the verifier). With message authentication, we are concerned with making sure that a given message is from who we think it is from i.e. it has not been tampered with en route from the source to its destination. While this section has a brief overview of message authentication, a more detailed survey can be found in [88].
4671A one-way hash function is not sufficient protection for a message. Hash functions such as MD5 rely on generating a hash value that is representative of the original input, and the original input cannot be derived from the hash value. A simple attack by E, who is in-between A and B, is to intercept the message from B, and substitute his own. Even if A also sends a hash of the original message, E can simply substitute the hash of his new message. Using a one-way hash function alone, A has no way of knowing that B's message has been changed.
4672One solution to the problem of message authentication is the Message Authentication Code, or MAC.
4673When B sends message M, it also sends MAC(M] so that the receiver will know that M is actually from B. For this to be possible, only B must be able to produce a MAC of M, and in addition, A should be able to verify M against MAC[M]. Notice that this is different from encryption of M−MACs are useful when M does not have to be secret.
4674The simplest method of constructing a MAC from a hash function is to encrypt the hash value with a symmetric algorithm: <ul id="ul0530" list-style="none"><li id="ul0530-0001" num="4675">1. Hash the input message H[M]</li><li id="ul0530-0002" num="4676">2. Encrypt the hash E<sub>K</sub>[H[M]]</li></ul>
4677This is more secure than first encrypting the message and then hashing the encrypted message. Any symmetric or asymmetric cryptographic function can be used, with the appropriate advantages and disadvantage of each type described in Section 5.2 on page 629 and Section 5.3 on page 632.
4678However, there are advantages to using a key-dependent one-way hash function instead of techniques that use encryption (such as that shown above): <ul id="ul0531" list-style="none"><li id="ul0531-0001" num="0000"><ul id="ul0532" list-style="none"><li id="ul0532-0001" num="4679">Speed, because one-way hash functions in general work much faster than encryption;</li><li id="ul0532-0002" num="4680">Message size, because E<sub>K</sub>[M] is at least the same size as M, while H[M] is a fixed size (usually considerably smaller than M);</li><li id="ul0532-0003" num="4681">Hardware/software requirements—keyed one-way hash functions are typically far less complex than their encryption-based counterparts; and</li><li id="ul0532-0004" num="4682">One-way hash function implementations are not considered to be encryption or decryption devices and therefore are not subject to US export controls.</li></ul></li></ul>
4683It should be noted that hash functions were never originally designed to contain a key or to support message authentication. As a result, some ad hoc methods of using hash functions to perform message authentication, including various functions that concatenate messages with secret prefixes, suffixes, or both have been proposed [56][56]. Most of these ad hoc methods have been successfully attacked by sophisticated means [42][42][42]. Additional MACs have been suggested based on XOR schemes [8] and Toeplitz matrices [49] (including the special case of LFSR-based (Linear Feed Shift Register) constructions).
5.5.4.1 HMAC
4684The HMAC construction [6][6] in particular is gaining acceptance as a solution for Internet message authentication security protocols. The HMAC construction acts as a wrapper, using the underlying hash function in a black-box way. Replacement of the hash function is straightforward if desired due to security or performance reasons. However, the major advantage of the HMAC construct is that it can be proven secure provided the underlying hash function has some reasonable cryptographic strengths—that is, HMAC's strengths are directly connected to the strength of the hash function [6].
4685Since the HMAC construct is a wrapper, any iterative hash function can be used in an HMAC. Examples include HMAC-MD5, HMAC-SHA1, HMAC-RIPEMD160 etc.
4686Given the following definitions: <ul id="ul0533" list-style="none"><li id="ul0533-0001" num="0000"><ul id="ul0534" list-style="none"><li id="ul0534-0001" num="4687">H=the hash function (e.g. MD5 or SHA-1)</li><li id="ul0534-0002" num="4688">n=number of bits output from H (e.g. 160 for SHA-1, 128 bits for MD5)</li><li id="ul0534-0003" num="4689">M=the data to which the MAC function is to be applied</li><li id="ul0534-0004" num="4690">K=the secret key shared by the two parties</li><li id="ul0534-0005" num="4691">ipad=0x36 repeated 64 times</li><li id="ul0534-0006" num="4692">opad=0x5C repeated 64 times</li></ul></li></ul>
4693The HMAC algorithm is as follows: <ul id="ul0535" list-style="none"><li id="ul0535-0001" num="4694">1. Extend K to 64 bytes by appending 0x00 bytes to the end of K</li><li id="ul0535-0002" num="4695">2. XOR the 64 byte string created in (1) with ipad</li><li id="ul0535-0003" num="4696">3. append data stream M to the 64 byte string created in (2)</li><li id="ul0535-0004" num="4697">4. Apply H to the stream generated in (3)</li><li id="ul0535-0005" num="4698">5. XOR the 64 byte string created in (1) with opad</li><li id="ul0535-0006" num="4699">6. Append the H result from (4) to the 64 byte string resulting from (5)</li><li id="ul0535-0007" num="4700">7. Apply H to the output of (6) and output the result</li></ul>
4701Thus: <br /><i>HMAC[M]=H</i>[(<i>K⊕opad</i>)|<i>H</i>[(<i>K⊕ipad</i>)|<i>M]]</i>
4702The recommended key length is at least n bits, although it should not be longer than 64 bytes (the length of the hashing block). A key longer than n bits does not add to the security of the function.
4703HMAC optionally allows truncation of the final output e.g. truncation to 128 bits from 160 bits.
4704The HMAC designers' Request for Comments [51] was issued in 1997, one year after the algorithm was first introduced. The designers claimed that the strongest known attack against HMAC is based on the frequency of collisions for the hash function H (see Section 14.10 on page 700), and is totally impractical for minimally reasonable hash functions: <ul id="ul0536" list-style="none"><li id="ul0536-0001" num="0000"><ul id="ul0537" list-style="none"><li id="ul0537-0001" num="4705">As an example, if we consider a hash function like MD5 where the output length is 128 bits, the attacker needs to acquire the correct message authentication tags computed (with the same secret key K) on about 2<sup>64 </sup>known plaintexts. This would require the processing of at least 2<sup>64 </sup>blocks under H, an impossible task in any realistic scenario (for a block length of 64 bytes this would take 250,000 years in a continuous 1 Gbps link, and without changing the secret key K all this time). This attack could become realistic only if serious flaws in the collision behavior of the function H are discovered (e.g. Collisions found after 2<sup>30 </sup>messages). Such a discovery would determine the immediate replacement of function H (the effects of such a failure would be far more severe for the traditional uses of H in the context of digital signatures, public key certificates etc).</li></ul></li></ul>
4706Of course, if a 160-bit hash function is used, then 2<sup>64 </sup>should be replaced with 2<sup>80</sup>.
4707This should be contrasted with a regular collision attack on cryptographic hash functions where no secret key is involved and 2<sup>64 </sup>off-line parallelizable operations suffice to find collisions.
4708More recently, HMAC protocols with replay prevention components [62] have been defined in order to prevent the capture and replay of any M, HMAC[M] combination within a given time period.
4709Finally, it should be noted that HMAC is in the public domain [50], and incurs no licensing fees. There are no known patents infringed by HMAC.
00005.6 Random Numbers and Time Varying Messages
4710The use of a random number generator as a one-way function has already been examined. However, random number generator theory is very much intertwined with cryptography, security, and authentication.
4711There are a large number of issues concerned with defining good random number generators. Knuth, in [48] describes what makes a generator good (including statistical tests), and the general problems associated with constructing them. Moreau gives a high level survey of the current state of the field in [60].
4712One of the uses for random numbers is to ensure that messages vary over time. Consider a system where A encrypts commands and sends them to B. If the encryption algorithm produces the same output for a given input, an attacker could simply record the messages and play them back to fool B. There is no need for the attacker to crack the encryption mechanism other than to know which message to play to B (while pretending to be A). Consequently messages often include a random number and a time stamp to ensure that the message (and hence its encrypted counterpart) varies each time.
4713Random number generators are also often used to generate keys. Although Klapper has recently shown [45] that a family of secure feedback registers for the purposes of building key-streams does exist, he does not give any practical construction. It is therefore best to say at the moment that all generators are insecure for this purpose. For example, the Berlekamp-Massey algorithm [54], is a classic attack on an LFSR random number generator. If the LFSR is of length n, then only 2n bits of the sequence suffice to determine the LFSR, compromising the key generator.
4714If, however, the only role of the random number generator is to make sure that messages vary over time, the security of the generator and seed is not as important as it is for session key generation. If however, the random number seed generator is compromised, and an attacker is able to calculate future “random” numbers, it can leave some protocols open to attack. Any new protocol should be examined with respect to this situation.
4715The actual type of random number generator required will depend upon the implementation and the purposes for which the generator is used. Generators include Blum, Blum, and Shub [10], stream ciphers such as RC4 by Ron Rivest [71], hash functions such as SHA-1 [28] and RIPEMD-160 [66], and traditional generators such LFSRs (Linear Feedback Shift Registers) [48] and their more recent counterpart FCSRs (Feedback with Carry Shift Registers) [44].
00005.7 Attacks
4716This section describes the various types of attacks that can be undertaken to break an authentication cryptosystem. The attacks are grouped into physical and logical attacks.
4717Logical attacks work on the protocols or algorithms rather than their physical implementation, and attempt to do one of three things: <ul id="ul0538" list-style="none"><li id="ul0538-0001" num="0000"><ul id="ul0539" list-style="none"><li id="ul0539-0001" num="4718">Bypass the authentication process altogether</li><li id="ul0539-0002" num="4719">Obtain the secret key by force or deduction, so that any question can be answered</li><li id="ul0539-0003" num="4720">Find enough about the nature of the authenticating questions and answers in order to, without the key, give the right answer to each question.</li></ul></li></ul>
4721Regardless of the algorithms and protocol used by a security chip, the circuitry of the authentication part of the chip can come under physical attack. Physical attacks come in four main ways, although the form of the attack can vary: <ul id="ul0540" list-style="none"><li id="ul0540-0001" num="0000"><ul id="ul0541" list-style="none"><li id="ul0541-0001" num="4722">Bypassing the security chip altogether</li><li id="ul0541-0002" num="4723">Physical examination of the chip while in operation (destructive and non-destructive)</li><li id="ul0541-0003" num="4724">Physical decomposition of chip</li><li id="ul0541-0004" num="4725">Physical alteration of chip</li></ul></li></ul>
4726The attack styles and the forms they take are detailed below.
4727This section does not suggest solutions to these attacks. It merely describes each attack type. The examination is restricted to the context of an authentication chip (as opposed to some other kind of system, such as Internet authentication) attached to some System.
00005.7.1 Logical Attacks
4728These attacks are those which do not depend on the physical implementation of the cryptosystem. They work against the protocols and the security of the algorithms and random number generators.
00005.7.1.1 Ciphertext Only Attack
4729This is where an attacker has one or more encrypted messages, all encrypted using the same algorithm. The aim of the attacker is to obtain the plaintext messages from the encrypted messages. Ideally, the key can be recovered so that all messages in the future can also be recovered.
00005.7.1.2 Known Plaintext Attack
4730This is where an attacker has both the plaintext and the encrypted form of the plaintext. In the case of an authentication chip, a known-plaintext attack is one where the attacker can see the data flow between the system and the authentication chip. The inputs and outputs are observed (not chosen by the attacker), and can be analyzed for weaknesses (such as birthday attacks or by a search for differentially interesting input/output pairs).
4731A known plaintext attack can be carried out by connecting a logic analyzer to the connection between the system and the authentication chip.
00005.7.1.3 Chosen Plaintext Attacks
4732A chosen plaintext attack describes one where a cryptanalyst has the ability to send any chosen message to the cryptosystem, and observe the response. If the cryptanalyst knows the algorithm, there may be a relationship between inputs and outputs that can be exploited by feeding a specific output to the input of another function.
4733The chosen plaintext attack is much stronger than the known plaintext attack since the attacker can choose the messages rather than simply observe the data flow.
4734On a system using an embedded authentication chip, it is generally very difficult to prevent chosen plaintext attacks since the cryptanalyst can logically pretend he/she is the system, and thus send any chosen bit-pattern streams to the authentication chip.
00005.7.1.4 Adaptive Chosen Plaintext Attacks
4735This type of attack is similar to the chosen plaintext attacks except that the attacker has the added ability to modify subsequent chosen plaintexts based upon the results of previous experiments. This is certainly the case with any system/authentication chip scenario described for consumables such as photocopiers and toner cartridges, especially since both systems and consumables are made available to the public.
00005.7.1.5 Brute Force Attack
4736A guaranteed way to break any key-based cryptosystem algorithm is simply to try every key. Eventually the right one will be found. This is known as a brute force attack. However, the more key possibilities there are, the more keys must be tried, and hence the longer it takes (on average) to find the right one. If there are N keys, it will take a maximum of N tries. If the key is N bits long, it will take a maximum of 2<sup>N </sup>tries, with a 50% chance of finding the key after only half the attempts (2<sup>N−1</sup>). The longer N becomes, the longer it will take to find the key, and hence the more secure the key is. Of course, an attack may guess the key on the first try, but this is more unlikely the longer the key is.
4737Consider a key length of 56 bits. In the worst case, all 2<sup>56 </sup>tests (7.2×10<sup>16 </sup>tests) must be made to find the key. In 1977, Diffie and Hellman described a specialized machine for cracking DES, consisting of one million processors, each capable of running one million tests per second [17]. Such a machine would take 20 hours to break any DES code.
4738Consider a key length of 128 bits. In the worst case, all 2<sup>128 </sup>tests (3.4×10<sup>38 </sup>tests) must be made to find the key. This would take ten billion years on an array of a trillion processors each running 1 billion tests per second.
4739With a long enough key length, a brute force attack takes too long to be worth the attacker's efforts.
00005.7.1.6 Guessing Attack
4740This type of attack is where an attacker attempts to simply “guess” the key. As an attack it is identical to the brute force attack (see Section 5.7.1.5 on page 647) where the odds of success depend on the length of the key.
00005.7.1.7 Quantum Computer Attack
4741To break an n-bit key, a quantum computer [83] (NMR, Optical, or Caged Atom) containing n qubits embedded in an appropriate algorithm must be built. The quantum computer effectively exists in 2<sup>n </sup>simultaneous coherent states. The trick is to extract the right coherent state without causing any decoherence. To date this has been achieved with a 2 qubit system (which exists in 4 coherent states). It is thought possible to extend this to 6 qubits (with 64 simultaneous coherent states) within a few years.
4742Unfortunately, every additional qubit halves the relative strength of the signal representing the key. This rapidly becomes a serious impediment to key retrieval, especially with the long keys. used in cryptographically secure systems.
4743As a result, attacks on a cryptographically secure key (e.g. 160 bits) using a Quantum Computer are likely not to be feasible and it is extremely unlikely that quantum computers will have achieved more than 50 or so qubits within the commercial lifetime of the authentication chips. Even using a 50 qubit quantum computer, 2<sup>110 </sup>tests are required to crack a 160 bit key.
00005.7.1.8 Purposeful Error Attack
4744With certain algorithms, attackers can gather valuable information from the results of a bad input. This can range from the error message text to the time taken for the error to be generated.
4745A simple example is that of a userid/password scheme. If the error message usually says “Bad userid”, then when an attacker gets a message saying “Bad password” instead, then they know that the userid is correct. If the message always says “Bad userid/password” then much less information is given to the attacker. A more complex example is that of the recent published method of cracking encryption codes from secure web sites [41]. The attack involves sending particular messages to a server and observing the error message responses. The responses give enough information to learn the keys—even the lack of a response gives some information.
4746An example of algorithmic time can be seen with an algorithm that returns an error as soon as an erroneous bit is detected in the input message. Depending on hardware implementation, it may be a simple method for the attacker to time the response and alter each bit one by one depending on the time taken for the error response, and thus obtain the key. Certainly in a chip implementation the time taken can be observed with far greater accuracy than over the Internet.
00005.7.1.9 Birthday Attack
4747This attack is named after the famous “birthday paradox” (which is not actually a paradox at all). The odds of one person sharing a birthday with another, is 1 in 365 (not counting leap years). Therefore there must be 183 people in a room for the odds to be more than 50% that one of them shares your birthday. However, there only needs to be 23 people in a room for there to be more than a 50% chance that any two share a birthday, as shown in the following relation:
4748<maths id="MATH-US-00002" num="00002"><math overflow="scroll"><mrow><mi>Prob</mi><mo>=</mo><mrow><mrow><mn>1</mn><mo>-</mo><mfrac><mrow><mi>n</mi><mo></mo><mstyle><mspace width="0.3em" height="0.3ex" /></mstyle><mo></mo><mi>P</mi><mo></mo><mstyle><mspace width="0.3em" height="0.3ex" /></mstyle><mo></mo><mi>r</mi></mrow><msup><mi>n</mi><mi>r</mi></msup></mfrac></mrow><mo>=</mo><mrow><mrow><mn>1</mn><mo>-</mo><mfrac><mrow><mn>365</mn><mo></mo><mi>P23</mi></mrow><msup><mn>365</mn><mn>23</mn></msup></mfrac></mrow><mo>≈</mo><mn>0.507</mn></mrow></mrow></mrow></math></maths>
4749Birthday attacks are common attacks against hashing algorithms, especially those algorithms that combine hashing with digital signatures.
4750If a message has been generated and already signed, an attacker must search for a collision message that hashes to the same value (analogous to finding one person who shares your birthday). However, if the attacker can generate the message, the birthday attack comes into play. The attacker searches for two messages that share the same hash value (analogous to any two people sharing a birthday), only one message is acceptable to the person signing it, and the other is beneficial for the attacker. Once the person has signed the original message the attacker simply claims now that the person signed the alternative message—mathematically there is no way to tell which message was the original, since they both hash to the same value.
4751Assuming a brute force attack is the only way to determine a match, the weakening of an n-bit key by the birthday attack is 2<sup>n/2</sup>. A key length of 128 bits that is susceptible to the birthday attack has an effective length of only 64 bits.
00005.7.1.10 Chaining Attack
4752These are attacks made against the chaining nature of hash functions. They focus on the compression function of a hash function. The idea is based on the fact that a hash function generally takes arbitrary length input and produces a constant length output by processing the input n bits at a time. The output from one block is used as the chaining variable set into the next block. Rather than finding a collision against an entire input, the idea is that given an input chaining variable set, to find a substitute block that will result in the same output chaining variables as the proper message.
4753The number of choices for a particular block is based on the length of the block. If the chaining variable is c bits, the hashing function behaves like a random mapping, and the block length is b bits, the number of such b-bit blocks is approximately 2<sup>b</sup>/2<sup>c</sup>. The challenge for finding a substitution block is that such blocks are a sparse subset of all possible blocks.
4754For SHA-1, the number of 512 bit blocks is approximately 2<sup>512</sup>/2<sup>160</sup>, or 2<sup>352</sup>. The chance of finding a block by brute force search is about 1 in 2<sup>160</sup>.
00005.7.1.11 Substitution with a Complete Lookup Table
4755If the number of potential messages sent to the chip is small, then there is no need for a clone manufacturer to crack the key. Instead, the clone manufacturer could incorporate a ROM in their chip that had a record of all of the responses from a genuine chip to the codes sent by the system. The larger the key, and the larger the response, the more space is required for such a lookup table.
00005.7.1.12 Substitution with a Sparse Lookup Table
4756If the messages sent to the chip are somehow predictable, rather than effectively random, then the clone manufacturer need not provide a complete lookup table. For example: <ul id="ul0542" list-style="none"><li id="ul0542-0001" num="0000"><ul id="ul0543" list-style="none"><li id="ul0543-0001" num="4757">If the message is simply a serial number, the clone manufacturer need simply provide a lookup table that contains values for past and predicted future serial numbers. There are unlikely to be more than 10<sup>9 </sup>of these.</li><li id="ul0543-0002" num="4758">If the test code is simply the date, then the clone manufacturer can produce a lookup table using the date as the address.</li><li id="ul0543-0003" num="4759">If the test code is a pseudo-random number using either the serial number or the date as a seed, then the clone manufacturer just needs to crack the pseudo-random number generator in the system. This is probably not difficult, as they have access to the object code of the system. The clone manufacturer would then produce a content addressable memory (or other sparse array lookup) using these codes to access stored authentication codes. <br /> 5.7.1.13 Differential Cryptanalysis </li></ul></li></ul>
4760Differential cryptanalysis describes an attack where pairs of input streams are generated with known differences, and the differences in the encoded streams are analyzed.
4761Existing differential attacks are heavily dependent on the structure of S boxes, as used in DES and other similar algorithms. Although other algorithms such as HMAC-SHA1 have no S boxes, an attacker can undertake a differential-like attack by undertaking statistical analysis of: <ul id="ul0544" list-style="none"><li id="ul0544-0001" num="0000"><ul id="ul0545" list-style="none"><li id="ul0545-0001" num="4762">Minimal-difference inputs, and their corresponding outputs</li><li id="ul0545-0002" num="4763">Minimal-difference outputs, and their corresponding inputs</li></ul></li></ul>
4764Most algorithms were strengthened against differential cryptanalysis once the process was described. This is covered in the specific sections devoted to each cryptographic algorithm. However some recent algorithms developed in secret have been broken because the developers had not considered certain styles of differential attacks [94] and did not subject their algorithms to public scrutiny.
00005.7.1.14 Message Substitution Attacks
4765In certain protocols, a man-in-the-middle can substitute part or all of a message. This is where a real authentication chip is plugged into a reusable clone chip within the consumable. The clone chip intercepts all messages between the system and the authentication chip, and can perform a number of substitution attacks.
4766Consider a message containing a header followed by content. An attacker may not be able to generate a valid header, but may be able to substitute their own content, especially if the valid response is something along the lines of “Yes, I received your message”. Even if the return message is “Yes, I received the following message . . . ”, the attacker may be able to substitute the original message before sending the acknowledgment back to the original sender.
4767Message Authentication Codes were developed to combat message substitution attacks.
00005.7.1.15 Reverse Engineering the Key Generator
4768If a pseudo-random number generator is used to generate keys, there is the potential for a clone manufacture to obtain the generator program or to deduce the random seed used. This was the way in which the security layer of the Netscape browser program was initially broken [33].
00005.7.1.16 Bypassing the Authentication Process
4769It may be that there are problems in the authentication protocols that can allow a bypass of the authentication process altogether. With these kinds of attacks the key is completely irrelevant, and the attacker has no need to recover it or deduce it.
4770Consider an example of a system that authenticates at power-up, but does not authenticate at any other time. A reusable consumable with a clone authentication chip may make use of a real authentication chip. The clone authentication chip uses the real chip for the authentication call, and then simulates the real authentication chip's state data after that.
4771Another example of bypassing authentication is if the system authenticates only after the consumable has been used. A clone authentication chip can accomplish a simple authentication bypass by simulating a loss of connection after the use of the consumable but before the authentication protocol has completed (or even started).
4772One infamous attack known as the “Kentucky Fried Chip” hack [2] involved replacing a microcontroller chip for a satellite TV system. When a subscriber stopped paying the subscription fee, the system would send out a “disable” message. However the new micro-controller would simply detect this message and not pass it on to the consumer's satellite TV system.
00005.7.1.17 Garrote/Bribe Attack
4773If people know the key, there is the possibility that they could tell someone else. The telling may be due to coercion (bribe, garrote etc.), revenge (e.g. a disgruntled employee), or simply for principle. These attacks are usually cheaper and easier than other efforts at deducing the key. As an example, a number of people claiming to be involved with the development of the (now defunct) Divx standard for DVD claimed (before the standard was rejected by consumers) that they would like to help develop Divx specific cracking devices—out of principle.
00005.7.2 Physical Attacks
4774The following attacks assume implementation of an authentication mechanism in a silicon chip that the attacker has physical access to. The first attack, Reading ROM, describes an attack when keys are stored in ROM, while the remaining attacks assume that a secret key is stored in Flash memory.
00005.7.2.1 Reading ROM
4775If a key is stored in ROM it can be read directly. A ROM can thus be safely used to hold a public key (for use in asymmetric cryptography), but not to hold a private key. In symmetric cryptography, a ROM is completely insecure. Using a copyright text (such as a haiku) as the key is not sufficient, because we are assuming that the cloning of the chip is occurring in a country where intellectual property is not respected.
00005.7.2.2 Reverse Engineering of Chip
4776Reverse engineering of the chip is where an attacker opens the chip and analyzes the circuitry. Once the circuitry has been analyzed the inner workings of the chip's algorithm can be recovered. Lucent Technologies have developed an active method [4] known as TOBIC (Two photon OBIC, where OBIC stands for Optical Beam Induced Current), to image circuits. Developed primarily for static RAM analysis, the process involves removing any back materials, polishing the back surface to a mirror finish, and then focusing light on the surface. The excitation wavelength is specifically chosen not to induce a current in the IC.
4777A Kerckhoffs in the nineteenth century made a fundamental assumption about cryptanalysis: if the algorithm's inner workings are the sole secret of the scheme, the scheme is as good as broken [39]. He stipulated that the secrecy must reside entirely in the key. As a result, the best way to protect against reverse engineering of the chip is to make the inner workings irrelevant.
00005.7.2.3 Usurping the Authentication Process
4778It must be assumed that any clone manufacturer has access to both the system and consumable designs.
4779If the same channel is used for communication between the system and a trusted system authentication chip, and a non-trusted consumable authentication chip, it may be possible for the non-trusted chip to interrogate a trusted authentication chip in order to obtain the “correct answer”. If this is so, a clone manufacturer would not have to determine the key. They would only have to trick the system into using the responses from the system authentication chip.
4780The alternative method of usurping the authentication process follows the same method as the logical attack described in Section 5.7.1.16 on page 652, involving simulated loss of contact with the system whenever authentication processes take place, simulating power-down etc.
00005.7.2.4 Modification of System
4781This kind of attack is where the system itself is modified to accept clone consumables. The attack may be a change of system ROM, a rewiring of the consumable, or, taken to the extreme case, a completely clone system.
4782Note that this kind of attack requires each individual system to be modified, and would most likely require the owner's consent. There would usually have to be a clear advantage for the consumer to undertake such a modification, since it would typically void warranty and would most likely be costly. An example of such a modification with a clear advantage to the consumer is a software patch to change fixed-region DVD players into region-free DVD players (although it should be noted that this is not to use clone consumables, but rather originals from the same companies simply targeted for sale in other countries).
00005.7.2.5 Direct Viewing of Chip Operation by Conventional Probing
4783If chip operation could be directly viewed using an STM (Scanning Tunnelling Microscope) or an electron beam, the keys could be recorded as they are read from the internal non-volatile memory and loaded into work registers.
4784These forms of conventional probing require direct access to the top or front sides of the IC while it is powered.
00005.7.2.6 Direct Viewing of the Non-volatile Memory
4785If the chip were sliced so that the floating gates of the Flash memory were exposed, without discharging them, then the key could probably be viewed directly using an STM or SKM (Scanning Kelvin Microscope).
4786However, slicing the chip to this level without discharging the gates is probably impossible. Using wet etching, plasma etching, ion milling (focused ion beam etching), or chemical mechanical polishing will almost certainly discharge the small charges present on the floating gates.
00005.7.2.7 Viewing the Light Bursts Caused by State Changes
4787Whenever a gate changes state, a small amount of infrared energy is emitted. Since silicon is transparent to infrared, these changes can be observed by looking at the circuitry from the underside of a chip. While the emission process is weak, it is bright enough to be detected by highly sensitive equipment developed for use in astronomy. The technique [92], developed by IBM, is called PICA (Picosecond Imaging Circuit Analyzer). If the state of a register is known at time t, then watching that register change over time will reveal the exact value at time t+n, and if the data is part of the key, then that part is compromised.
00005.7.2.8 Viewing the Keys Using an SEPM
4788A non-invasive testing device, known as a Scanning Electric Potential Microscope (SEPM), allows the direct viewing of charges within a chip [37]. The SEPM has a tungsten probe that is placed a few micrometers above the chip, with the probe and circuit forming a capacitor. Any AC signal flowing beneath the probe causes displacement current to flow through this capacitor. Since the value of the current change depends on the amplitude and phase of the AC signal, the signal can be imaged. If the signal is part of the key, then that part is compromised.
00005.7.2.9 Monitoring EMI
4789Whenever electronic circuitry operates, faint electromagnetic signals are given off. Relatively inexpensive equipment can monitor these signals and could give enough information to allow an attacker to deduce the keys.
00005.7.2.10 Viewing I<sub>dd </sub>Fluctuations
4790Even if keys cannot be viewed, there is a fluctuation in current whenever registers change state. If there is a high enough signal to noise ratio, an attacker can monitor the difference in I<sub>dd </sub>that may occur when programming over either a high or a low bit. The change in I<sub>dd </sub>can reveal information about the key. Attacks such as these have already been used to break smart cards [46].
00005.7.2.11 Differential Fault Analysis
4791This attack assumes introduction of a bit error by ionization, microwave radiation, or environmental stress. In most cases such an error is more likely to adversely affect the chip (e.g. cause the program code to crash) rather than cause beneficial changes which would reveal the key. Targeted faults such as ROM overwrite, gate destruction etc. are far more likely to produce useful results.
00005.7.2.12 Clock Glitch Attacks
4792Chips are typically designed to properly operate within a certain clock speed range. Some attackers attempt to introduce faults in logic by running the chip at extremely high clock speeds or introduce a clock glitch at a particular time for a particular duration [1]. The idea is to create race conditions where the circuitry does not function properly. An example could be an AND gate that (because of race conditions) gates through Input<sub>1 </sub>all the time instead of the AND of Input, and Input<sub>2</sub>.
4793If an attacker knows the internal structure of the chip, they can attempt to introduce race conditions at the correct moment in the algorithm execution, thereby revealing information about the key (or in the worst case, the key itself).
00005.7.2.13 Power Supply Attacks
4794Instead of creating a glitch in the clock signal, attackers can also produce glitches in the power supply where the power is increased or decreased to be outside the working operating voltage range. The net effect is the same as a clock glitch—introduction of error in the execution of a particular instruction. The idea is to stop the CPU from XORing the key, or from shifting the data one bit-position etc. Specific instructions are targeted so that information about the key is revealed.
00005.7.2.14 Overwriting ROM
4795Single bits in a ROM can be overwritten using a laser cutter microscope [1], to either 1 or 0 depending on the sense of the logic. If the ROM contains instructions, it may be a simple matter for an attacker to change a conditional jump to a non-conditional jump, or perhaps change the destination of a register transfer. If the target instruction is chosen carefully, it may result in the key being revealed.
00005.7.2.15 Modifying EEPROM/Flash
4796These attacks fall into two categories: <ul id="ul0546" list-style="none"><li id="ul0546-0001" num="0000"><ul id="ul0547" list-style="none"><li id="ul0547-0001" num="4797">those similar to the ROM attacks except that the laser cutter microscope technique can be used to both set and reset individual bits. This gives much greater scope in terms of modification of algorithms.</li><li id="ul0547-0002" num="4798">Electron beam programming of floating gates. As described in [89] and [32], a focused electron beam can change a gate by depositing electrons onto it. Damage to the rest of the circuit can be avoided, as described in [31]. <br /> 5.7.2.16 Gate Destruction </li></ul></li></ul>
4799Anderson and Kuhn described the rump session of the 1997 workshop on Fast Software Encryption ([1], where Biham and Shamir presented an attack on DES. The attack was to use a laser cutter to destroy an individual gate in the hardware implementation of a known block cipher (DES). The net effect of the attack was to force a particular bit of a register to be “stuck”. Biham and Shamir described the effect of forcing a particular register to be affected in this way—the least significant bit of the output from the round function is set to 0. Comparing the 6 least significant bits of the left half and the right half can recover several bits of the key. Damaging a number of chips in this way can reveal enough information about the key to make complete key recovery easy.
4800An encryption chip modified in this way will have the property that encryption and decryption will no longer be inverses.
00005.7.2.17 Overwrite Attacks
4801Instead of trying to read the Flash memory, an attacker may simply set a single bit by use of a laser cutter microscope. Although the attacker doesn't know the previous value, they know the new value. If the chip still works, the bit's original state must be the same as the new state. If the chip doesn't work any longer, the bit's original state must be the logical NOT of the current state. An attacker can perform this attack on each bit of the key and obtain the n-bit key using at most n chips (if the new bit matched the old bit, a new chip is not required for determining the next bit).
00005.7.2.18 Test Circuitry Attack
4802Most chips contain test circuitry specifically designed to check for manufacturing defects. This includes BIST (Built In Self Test) and scan paths. Quite often the scan paths and test circuitry includes access and readout mechanisms for all the embedded latches. In some cases the test circuitry could potentially be used to give information about the contents of particular registers.
4803Test circuitry is often disabled once the chip has passed all manufacturing tests, in some cases by blowing a specific connection within the chip. A determined attacker, however, can reconnect the test circuitry and hence enable it.
00005.7.2.19 Memory Remnants
4804Values remain in RAM long after the power has been removed [35], although they do not remain long enough to be considered non-volatile. An attacker can remove power once sensitive information has been moved into RAM (for example working registers), and then attempt to read the value from RAM. This attack is most useful against security systems that have regular RAM chips. A classic example is cited by [1], where a security system was designed with an automatic power-shut-off that is triggered when the computer case is opened. The attacker was able to simply open the case, remove the RAM chips, and retrieve the key because the values persisted.
00005.7.2.20 Chip Theft Attack
4805If there are a number of stages in the lifetime of an authentication chip, each of these stages must be examined in terms of ramifications for security should chips be stolen. For example, if information is programmed into the chip in stages, theft of a chip between stages may allow an attacker to have access to key information or reduced efforts for attack. Similarly, if a chip is stolen directly after manufacture but before programming, does it give an attacker any logical or physical advantage?
00005.7.2.21 Trojan Horse Attack
4806At some stage the authentication chips must be programmed with a secret key. Suppose an attacker builds a clone authentication chip and adds it to the pile of chips to be programmed. The attacker has especially built the clone chip so that it looks and behaves just like a real authentication chip, but will give the key out to the attacker when a special attacker-known command is issued to the chip. Of course the attacker must have access to the chip after the programming has taken place, as well as physical access to add the Trojan horse authentication chip to the genuine chips.
00006 Requirements
4807Existing solutions to the problem of authenticating consumables have typically relied on patents covering physical packaging. However this does not stop home refill operations or clone manufacture in countries with weak industrial property protection. Consequently a much higher level of protection is required.
4808The authentication mechanism is therefore built into an authentication chip that is embedded in the consumable and allows a system to authenticate that consumable securely and easily. Limiting ourselves to the system authenticating consumables (we don't consider the consumable authenticating the system), two levels of protection can be considered:
0000Presence Only Authentication:
0000<ul id="ul0548" list-style="none"><li id="ul0548-0001" num="0000"><ul id="ul0549" list-style="none"><li id="ul0549-0001" num="4809">This is where only the presence of an authentication chip is tested. The authentication chip can be removed and used in other consumables as long as be used indefinitely. <br /> Consumable Lifetime Authentication: </li><li id="ul0549-0002" num="4810">This is where not only is the presence of the authentication chip tested for, but also the authentication chip must only last the lifetime of the consumable. For the chip to be re-used it must be completely erased and reprogrammed.</li></ul></li></ul>
4811The two levels of protection address different requirements. We are primarily concerned with Consumable Lifetime authentication in order to prevent cloned versions of high volume consumables. In this case, each chip should hold secure state information about the consumable being authenticated. It should be noted that a Consumable Lifetime authentication chip could be used in any situation requiring a Presence Only authentication chip.
4812Requirements for authentication, data storage integrity and manufacture are considered separately. The following sections summarize requirements of each.
00006.1 Authentication
4813The authentication requirements for both Presence Only and Consumable Lifetime authentication are restricted to the case of a system authenticating a consumable. We do not consider bi-directional authentication where the consumable also authenticates the system. For example, it is not necessary for a valid toner cartridge to ensure it is being used in a valid photocopier.
4814For Presence Only authentication, we must be assured that an authentication chip is physically present. For Consumable Lifetime authentication we also need to be assured that state data actually came from the authentication chip, and that it has not been altered en route. These issues cannot be separated—data that has been altered has a new source, and if the source cannot be determined, the question of alteration cannot be settled.
4815It is not enough to provide an authentication method that is secret, relying on a home-brew security method that has not been scrutinized by security experts. The primary requirement therefore is to provide authentication by means that have withstood the scrutiny of experts.
4816The authentication scheme used by the authentication chip should be resistant to defeat by logical means. Logical types of attack are extensive, and attempt to do one of three things: <ul id="ul0550" list-style="none"><li id="ul0550-0001" num="0000"><ul id="ul0551" list-style="none"><li id="ul0551-0001" num="4817">Bypass the authentication process altogether</li><li id="ul0551-0002" num="4818">Obtain the secret key by force or deduction, so that any question can be answered</li><li id="ul0551-0003" num="4819">Find enough about the nature of the authenticating questions and answers in order to, without the key, give the right answer to each question.</li></ul></li></ul>
4820The logical attack styles and the forms they take are detailed in Section 5.7.1 on page 646.
4821The algorithm should have a flat keyspace, allowing any random bit string of the required length to be a possible key. There should be no weak keys.
00006.2 Data Storage Integrity
4822Although authentication protocols take care of ensuring data integrity in communicated messages, data storage integrity is also required. Two kinds of data must be stored within the authentication chip: <ul id="ul0552" list-style="none"><li id="ul0552-0001" num="0000"><ul id="ul0553" list-style="none"><li id="ul0553-0001" num="4823">Authentication data, such as secret keys</li><li id="ul0553-0002" num="4824">Consumable state data, such as serial numbers, and media remaining etc.</li></ul></li></ul>
4825The access requirements of these two data types differ greatly. The authentication chip therefore requires a storage/access control mechanism that allows for the integrity requirements of each type.
00006.2.1 Authentication Data
4826Authentication data must remain confidential. It needs to be stored in the chip during a manufacturing/programming stage of the chip's life, but from then on must not be permitted to leave the chip. It must be resistant to being read from non-volatile memory. The authentication scheme is responsible for ensuring the key cannot be obtained by deduction, and the manufacturing process is responsible for ensuring that the key cannot be obtained by physical means.
4827The size of the authentication data memory area must be large enough to hold the necessary keys and secret information as mandated by the authentication protocols.
00006.2.2 Consumable State Data
4828Consumable state data can be divided into the following types. Depending on the application, there will be different numbers of each of these types of data items. <ul id="ul0554" list-style="none"><li id="ul0554-0001" num="0000"><ul id="ul0555" list-style="none"><li id="ul0555-0001" num="4829">Read Only</li><li id="ul0555-0002" num="4830">ReadWrite</li><li id="ul0555-0003" num="4831">Decrement Only</li></ul></li><li id="ul0554-0002" num="4832">Read Only data needs to be stored in the chip during a manufacturing/programming stage of the chip's life, but from then on should not be allowed to change. Examples of Read Only data items are consumable batch numbers and serial numbers.</li><li id="ul0554-0003" num="4833">ReadWrite data is changeable state information, for example, the last time the particular consumable was used. ReadWrite data items can be read and written an unlimited number of times during the lifetime of the consumable. They can be used to store any state information about the consumable. The only requirement for this data is that it needs to be kept in non-volatile memory. Since an attacker can obtain access to a system (which can write to ReadWrite data), any attacker can potentially change data fields of this type. This data type should not be used for secret information, and must be considered insecure.</li><li id="ul0554-0004" num="4834">Decrement Only data is used to count down the availability of consumable resources. A photocopier's toner cartridge, for example, may store the amount of toner remaining as a Decrement Only data item. An ink cartridge for a color printer may store the amount of each ink color as a Decrement Only data item, requiring 3 (one for each of Cyan, Magenta, and Yellow), or even as many as 5 or 6 Decrement Only data items. The requirement for this kind of data item is that once programmed with an initial value at the manufacturing/programming stage, it can only reduce in value. Once it reaches the minimum value, it cannot decrement any further. The Decrement Only data item is only required by Consumable Lifetime authentication.</li></ul>
4835Note that the size of the consumable state data storage required is only for that information required to be authenticated. Information which would be of no use to an attacker, such as ink color-curve characteristics or ink viscosity do not have to be stored in the secure state data memory area of the authentication chip.
00006.3 Manufacture
4836The authentication chip must have a low manufacturing cost in order to be included as the authentication mechanism for low cost consumables.
4837The authentication chip should use a standard manufacturing process, such as Flash. This is necessary to: <ul id="ul0556" list-style="none"><li id="ul0556-0001" num="0000"><ul id="ul0557" list-style="none"><li id="ul0557-0001" num="4838">Allow a great range of manufacturing location options</li><li id="ul0557-0002" num="4839">Use well-defined and well-behaved technology</li><li id="ul0557-0003" num="4840">Reduce cost</li></ul></li></ul>
4841Regardless of the authentication scheme used, the circuitry of the authentication part of the chip must be resistant to physical attack. Physical attack comes in four main ways, although the form of the attack can vary: <ul id="ul0558" list-style="none"><li id="ul0558-0001" num="0000"><ul id="ul0559" list-style="none"><li id="ul0559-0001" num="4842">Bypassing the authentication chip altogether</li><li id="ul0559-0002" num="4843">Physical examination of chip while in operation (destructive and non-destructive)</li><li id="ul0559-0003" num="4844">Physical decomposition of chip</li><li id="ul0559-0004" num="4845">Physical alteration of chip</li></ul></li></ul>
4846The physical attack styles and the forms they take are detailed in Section 5.7.2 on page 652. Ideally, the chip should be exportable from the USA, so it should not be possible to use an authentication chip as a secure encryption device. This is low priority requirement since there are many companies in other countries able to manufacture the authentication chips. In any case, the export restrictions from the USA may change.
0000Authentication
00007 Introduction
4847Existing solutions to the problem of authenticating consumables have typically relied on physical patents on packaging. However this does not stop home refill operations or clone manufacture in countries with weak industrial property protection. Consequently a much higher level of protection is required.
4848It is not enough to provide an authentication method that is secret, relying on a home-brew security method that has not been scrutinized by security experts. Security systems such as Netscape's original proprietary system and the GSM Fraud Prevention Network used by cellular phones are examples where design secrecy caused the vulnerability of the security [33][33]. Both security systems were broken by conventional means that would have been detected if the companies had followed an open design process. The solution is to provide authentication by means that have withstood the scrutiny of experts.
4849In this section, we examine a number of protocols that can be used for consumables authentication. We only use security methods that are publicly described, using known behaviors in this new way. Readers should be familiar with the concepts and terms described in Section 5 on page 629. We avoid the Zero Knowledge Proof protocol since it is patented.
4850For all protocols, the security of the scheme relies on a secret key, not a secret algorithm. In the nineteenth century, A Kerckhoffs made a fundamental assumption about cryptanalysis: if the algorithm's inner workings are the sole secret of the scheme, the scheme is as good as broken [39]. He stipulated that the secrecy must reside entirely in the key. As a result, the best way to protect against reverse engineering of any authentication chip is to make the algorithmic inner workings irrelevant (the algorithm of the inner workings must still be must be valid, but not the actual secret).
4851The QA Chip is a programmable device, and can therefore be setup with an application-specific program together with an application-specific set of protocols. This section describes the following sets of protocols: <ul id="ul0560" list-style="none"><li id="ul0560-0001" num="0000"><ul id="ul0561" list-style="none"><li id="ul0561-0001" num="4852">single key single memory vector</li><li id="ul0561-0002" num="4853">multiple key single memory vector</li><li id="ul0561-0003" num="4854">multiple key multiple memory vector</li></ul></li></ul>
4855These protocols refer to the number of valid keys that an QA Chip knows about, and the size of data required to be stored in the chip.
4856From these protocols it is straightforward to construct protocol sets for the single key multiple memory vector case (of course the multiple memory vector can be considered to be. and multiple key single memory vector. Other protocol sets can also be defined as necessary. Of course multiple memory vector can be conveniently
4857All the protocols rely on a time-variant challenge (i.e. the challenge is different each time), where the response depends on the challenge and the secret. The challenge involves a random number so that any observer will not be able to gather useful information about a subsequent identification.
00008 Single Key Single Memory Vector
00008.1 Protocol Background
4858This protocol set is provided for two reasons: <ul id="ul0562" list-style="none"><li id="ul0562-0001" num="0000"><ul id="ul0563" list-style="none"><li id="ul0563-0001" num="4859">the other protocol sets defined in this document are simply extensions of this one; and</li><li id="ul0563-0002" num="4860">it is useful in its own right</li></ul></li></ul>
4861The single key protocol set is useful for applications where only a single key is required. Note that there can be many consumables and systems, but there is only a single key that connects them all. Examples include: <ul id="ul0564" list-style="none"><li id="ul0564-0001" num="0000"><ul id="ul0565" list-style="none"><li id="ul0565-0001" num="4862">car and keys. A car and the car-key share a single key. There can be multiple sets of car-keys, each effectively cut to the same key. A company could have a set of cars, each with the same key. Any of the car-keys could then be used to drive any of the cars.</li><li id="ul0565-0002" num="4863">printer and ink cartridge. All printers of a certain model use the same ink cartridge, with printer and cartridge sharing only a single key. Note that to introduce a new printer model that accepts the old ink cartridge the new model would need the same key as the old model. See the multiple-key protocols for alternative solutions to this problem. <br /> 8.2 Requirements of Protocol </li></ul></li></ul>
4864Each QA Chip contains the following values: <ul id="ul0566" list-style="none"><li id="ul0566-0001" num="0000"><ul id="ul0567" list-style="none"><li id="ul0567-0001" num="4865">K The secret key for calculating F<sub>K</sub>[X]. K must not be stored directly in the QA Chip. Instead, each chip needs to store a random number R<sub>K </sub>(different for each chip), K⊕R<sub>K</sub>, and <img file="US7165824B2_D0062.tif" />K⊕R<sub>K</sub>. The stored K⊕R<sub>K </sub>can be XORed with R<sub>K </sub>to obtain the real K. Although <img file="US7165824B2_D0063.tif" />KβR<sub>K </sub>must be stored to protect against differential attacks, it is not used.</li><li id="ul0567-0002" num="4866">R Current random number used to ensure time varying messages. Each chip instance must be seeded with a different initial value. Changes for each signature generation.</li><li id="ul0567-0003" num="4867">M Memory vector of QA Chip.</li><li id="ul0567-0004" num="4868">P 2 element array of access permissions for each part of M. Entry 0 holds access permissions for non-authenticated writes to M (no key required). Entry 1 holds access permissions for authenticated writes to M (key required). Permission choices for each part of M are Read Only, Read/Write, and Decrement Only.</li><li id="ul0567-0005" num="4869">C 3 constants used for generating signatures. C<sub>1</sub>, C<sub>2</sub>, and C<sub>3 </sub>are constants that pad out a submessage to a hashing boundary, and all 3 must be different. <ul id="ul0568" list-style="none"><li id="ul0568-0001" num="4870">Each QA Chip contains the following private function:</li></ul></li><li id="ul0567-0006" num="4871">S<sub>K</sub>[X] Internal function only. Returns S<sub>K</sub>[X], the result of applying a digital signature function S to X based upon key K. The digital signature must be long enough to counter the chances of someone generating a random signature. The length depends on the signature scheme chosen, although the scheme chosen for the QA Chip is HMAC-SHA1 (see Section 13 on page 691), and therefore the length of the signature is 160 bits.</li></ul></li></ul>
4872Additional functions are required in certain QA Chips, but these are described as required.
00008.3 Reads of M
4873In this case, we have a trusted chip (ChipT) connected to a System. The System wants to authenticate an object that contains a non-trusted chip (ChipA). In effect, the System wants to know that it can securely read a memory vector (M) from ChipA: to be sure that ChipA is valid and that M has not been altered.
4874The protocol requires the following publicly available function in ChipA: <ul id="ul0569" list-style="none"><li id="ul0569-0001" num="0000"><ul id="ul0570" list-style="none"><li id="ul0570-0001" num="4875">Read[X] Advances R, and returns R, M, S<sub>K</sub>[X|R|C<sub>1</sub>|M]. The time taken to calculate the signature must not be based on the contents of X, R, M, or K.</li></ul></li></ul>
4876The protocol requires the following publicly available functions in ChipT: <ul id="ul0571" list-style="none"><li id="ul0571-0001" num="0000"><ul id="ul0572" list-style="none"><li id="ul0572-0001" num="4877">Random<img file="US7165824B2_D0064.tif" /> Returns R (does not advance R).</li><li id="ul0572-0002" num="4878">Test[X, Y, Z] Advances R and returns 1 if S<sub>K</sub>[R|X|C<sub>1</sub>|Y]=Z. Otherwise returns 0. The time taken to calculate and compare signatures must be independent of data content.</li></ul></li></ul>
4879To authenticate ChipA and read ChipA's memory M: <ul id="ul0573" list-style="none"><li id="ul0573-0001" num="4880">a. System calls ChipT's Random function;</li><li id="ul0573-0002" num="4881">b. ChipT returns R<sub>T </sub>to System;</li><li id="ul0573-0003" num="4882">c. System calls ChipA's Read function, passing in the result from b;</li><li id="ul0573-0004" num="4883">d. ChipA updates R<sub>A</sub>, then calculates and returns R<sub>A</sub>, M<sub>A</sub>, S<sub>K</sub>[R<sub>T</sub>|R<sub>A</sub>|C<sub>1</sub>|M<sub>A</sub>];</li><li id="ul0573-0005" num="4884">e. System calls ChipT's Test function, passing in R<sub>A</sub>, M<sub>A</sub>, S<sub>K</sub>[R<sub>T</sub>|R<sub>A</sub>|C<sub>1</sub>|M<sub>A</sub>];</li><li id="ul0573-0006" num="4885">f. System checks response from ChipT. If the response is 1, then ChipA is considered authentic. If 0, ChipA is considered invalid.</li></ul>
4886The data flow for read authentication is shown in <figref idref="DRAWINGS">FIG. 334</figref>.
4887The protocol allows System to simply pass data from one chip to another, with no special processing. The protection relies on ChipT being trusted, even though System does not know K.
4888When ChipT is physically separate from System (eg is chip on a board connected to System) System must also occassionally (based on system clock for example) call ChipT's Test function with bad data, expecting a 0 response. This is to prevent someone from inserting a fake ChipT into the system that always returns 1 for the Test function.
00008.4 Writes
4889In this case, the System wants to update M in some chip referred to as ChipU. This can be non-authenticated (for example, anyone is allowed to count down the amount of consumable remaining), or authenticated (for example, replenishing the amount of consumable remaining).
00008.4.1 Non-authenticated Writes
4890This is the most frequent type of write, and takes place between the System/consumable during normal everyday operation. In this kind of write, System wants to change M in a way that doesn't require special authorization. For example, the System could be decrementing the amount of consumable remaining. Although System does not need to know K or even have access to a trusted chip, System must follow a non-authenticated write by an authenticated read if it needs to know that the write was successful.
4891The protocol requires the following publicly available function: <ul id="ul0574" list-style="none"><li id="ul0574-0001" num="0000"><ul id="ul0575" list-style="none"><li id="ul0575-0001" num="4892">Write[X] Writes X over those parts of M subject to P<sub>0 </sub>and the existing value for M.</li></ul></li></ul>
4893To authenticate a write of M<sub>new </sub>to ChipA's memory M: <ul id="ul0576" list-style="none"><li id="ul0576-0001" num="4894">a. System calls ChipU's Write function, passing in M<sub>new</sub>;</li><li id="ul0576-0002" num="4895">b. The authentication procedure for a Read is carried out (see Section 8.3 on page 664);</li><li id="ul0576-0003" num="4896">c. If ChipU is authentic and M<sub>new</sub>=M returned in b, the write succeeded. If not, it failed. <br /> 8.4.2 Authenticated Writes </li></ul>
4897In this kind of write, System wants to change Chip U's M in an authorized way, without being subject to the permissions that apply during normal operation (P<sub>0</sub>). For example, the consumable may be at a refilling station and the normally Decrement Only section of M should be updated to include the new valid consumable. In this case, the chip whose M is being updated must authenticate the writes being generated by the external System and in addition, apply permissions P<sub>1 </sub>to ensure that only the correct parts of M are updated.
4898In this transaction protocol, the System's chip is referred to as ChipS, and the chip being updated is referred to as ChipU. Each chip distrusts the other.
4899The protocol requires the following publicly available functions in ChipU: <ul id="ul0577" list-style="none"><li id="ul0577-0001" num="0000"><ul id="ul0578" list-style="none"><li id="ul0578-0001" num="4900">Read[X] Advances R, and returns R, M, S<sub>K</sub>[X|R|C<sub>1</sub>|M]. The time taken to calculate the signature must be identical for all inputs.</li><li id="ul0578-0002" num="4901">WriteA[X, Y, Z]Returns 1, advances R, and replaces M by Y subject to P<sub>1 </sub>only if S<sub>K</sub>[R|X|C<sub>1</sub>|Y]=Z. Otherwise returns 0. The time taken to calculate and compare signatures must be independent of data content. This function is identical to ChipT's Test function except that it additionally writes Y over those parts of M subject to P<sub>1 </sub>when the signature matches.</li></ul></li></ul>
4902Authenticated writes require that the System has access to a ChipS that is capable of generating appropriate signatures. ChipS requires the following variables and function: <ul id="ul0579" list-style="none"><li id="ul0579-0001" num="0000"><ul id="ul0580" list-style="none"><li id="ul0580-0001" num="4903">CountRemaining Part of M that contains the number of signatures that ChipS is allowed to generate. Decrements with each successful call to SignM and SignP. Permissions in ChipS's P<sub>0 </sub>for this part of M needs to be ReadOnly once ChipS has been setup. Therefore CountRemaining can only be updated by another ChipS that will perform updates to that part of M (assuming ChipS's P<sub>1 </sub>allows that part of M to be updated).</li><li id="ul0580-0002" num="4904">Q Part of M that contains the write permissions for updating ChipU's M. By adding Q to ChipS we allow different ChipSs that can update different parts of M<sub>U</sub>. Permissions in ChipS's P<sub>0 </sub>for this part of M needs to be ReadOnly once ChipS has been setup. Therefore Q can only be updated by another ChipS that will perform updates to that part of M.</li><li id="ul0580-0003" num="4905">SignM[V,W,X,Y,Z] Advances R, decrements CountRemaining and returns R, Z<sub>QX </sub>(Z applied to X with permissions Q), followed by S<sub>K</sub>[W|R|C<sub>1</sub>|Z<sub>QX</sub>] only if S<sub>K</sub>[V|W|C<sub>1</sub>|X]=Y and CountRemaining>0. Otherwise returns all 0s. The time taken to calculate and compare signatures must be independent of data content.</li></ul></li></ul>
4906To update ChipU's M vector: <ul id="ul0581" list-style="none"><li id="ul0581-0001" num="4907">a. System calls ChipU's Read function, passing in 0 as the input parameter;</li><li id="ul0581-0002" num="4908">b. ChipU produces R<sub>U</sub>, M<sub>U</sub>, S<sub>K</sub>[0|R<sub>U</sub>|C<sub>1</sub>|M<sub>U</sub>] and returns these to System;</li><li id="ul0581-0003" num="4909">c. System calls ChipS's SignM function, passing in 0 (as used in a), R<sub>U</sub>, M<sub>U</sub>, S<sub>K</sub>[0|R<sub>U</sub>|C<sub>1</sub>|M<sub>U</sub>], and M<sub>D </sub>(the desired vector to be written to ChipU);</li><li id="ul0581-0004" num="4910">d. ChipS produces R<sub>S</sub>, M<sub>QD </sub>(processed by running M<sub>D </sub>against M<sub>U </sub>using Q) and S<sub>K</sub>[R<sub>U</sub>|R<sub>S</sub>|C<sub>1</sub>|M<sub>QD</sub>] if the inputs were valid, and 0 for all outputs if the inputs were not valid.</li><li id="ul0581-0005" num="4911">e. If values returned in d are non zero, then ChipU is considered authentic. System can then call ChipU's WriteA function with these values.</li><li id="ul0581-0006" num="4912">f. ChipU should return a 1 to indicate success. A 0 should only be returned if the data generated by ChipS is incorrect (e.g. a transmission error).</li></ul>
4913The data flow for authenticated writes is shown in <figref idref="DRAWINGS">FIG. 335</figref>.
4914Note that Q in ChipS is part of ChipS's M. This allows a user to set up ChipS with a permission set for upgrades. This should be done to ChipS and that part of M designated by P<sub>0 </sub>set to ReadOnly before ChipS is programmed with K<sub>U</sub>. If K<sub>S </sub>is programmed with K<sub>U </sub>first, there is a risk of someone obtaining a half-setup ChipS and changing all of M<sub>U </sub>instead of only the sections specified by Q.
4915The same is true of CountRemaining. The CountRemaining value needs to be setup (including making it ReadOnly in P<sub>0</sub>) before ChipS is programmed with K<sub>U</sub>. ChipS is therefore programmed to only perform a limited number of SignM operations (thereby limiting compromise exposure if a ChipS is stolen). Thus ChipS would itself need to be upgraded with a new CountRemaining every so often.
00008.4.3 Updating Permissions for Future Writes
4916In order to reduce exposure to accidental and malicious attacks on P and certain parts of M, only authorized users are allowed to update P. Writes to P are the same as authorized writes to M, except that they update P<sub>n </sub>instead of M. Initially (at manufacture), P is set to be Read/Write for all parts of M. As different processes fill up different parts of M, they can be sealed against future change by updating the permissions. Updating a chip's P<sub>0 </sub>changes permissions for unauthorized writes, and updating P<sub>1 </sub>changes permissions for authorized writes.
4917P<sub>n </sub>is only allowed to change to be a more restrictive form of itself. For example, initially all parts of M have permissions of Read/Write. A permission of Read/Write can be updated to Decrement Only or Read Only. A permission of Decrement Only can be updated to become Read Only. A Read Only permission cannot be further restricted.
4918In this transaction protocol, the System's chip is referred to as ChipS, and the chip being updated is referred to as ChipU. Each chip distrusts the other.
4919The protocol requires the following publicly available functions in ChipU: <ul id="ul0582" list-style="none"><li id="ul0582-0001" num="0000"><ul id="ul0583" list-style="none"><li id="ul0583-0001" num="4920">Random<img file="US7165824B2_D0065.tif" /> Returns R (does not advance R).</li><li id="ul0583-0002" num="4921">SetPermission[n,X,Y,Z] Advances R, and updates P<sub>n </sub>according to Y and returns 1 followed by the resultant P<sub>n </sub>only if S<sub>K</sub>[R|X|Y|C<sub>2</sub>]=Z. Otherwise returns 0. P<sub>n </sub>can only become more restricted. Passing in 0 for any permission leaves it unchanged (passing in Y=0 returns the current P<sub>n</sub>).</li></ul></li></ul>
4922Authenticated writes of permissions require that the System has access to a ChipS that is capable of generating appropriate signatures. ChipS requires the following variables and function: <ul id="ul0584" list-style="none"><li id="ul0584-0001" num="0000"><ul id="ul0585" list-style="none"><li id="ul0585-0001" num="4923">CountRemaining Part of M that contains the number of signatures that ChipS is allowed to generate. Decrements with each successful call to SignM and SignP. Permissions in ChipS's P<sub>0 </sub>for this part of M needs to be ReadOnly once ChipS has been setup. Therefore CountRemaining can only be updated by another ChipS that will perform updates to that part of M (assuming ChipS's P<sub>1 </sub>allows that part of M to be updated).</li><li id="ul0585-0002" num="4924">SignP[X,Y] Advances R, decrements CountRemaining and returns R and S<sub>K</sub>[X|R|Y|C<sub>2</sub>] only if CountRemaining>0. Otherwise returns all 0s. The time taken to calculate and compare signatures must be independent of data content.</li></ul></li></ul>
4925To update ChipU's P<sub>n</sub>: <ul id="ul0586" list-style="none"><li id="ul0586-0001" num="4926">a. System calls ChipU's Random function;</li><li id="ul0586-0002" num="4927">b. ChipU returns R<sub>U </sub>to System;</li><li id="ul0586-0003" num="4928">c. System calls ChipS's SignP function, passing in R<sub>U </sub>and P<sub>D </sub>(the desired P to be written to ChipU);</li><li id="ul0586-0004" num="4929">d. ChipS produces R<sub>S </sub>and S<sub>K</sub>[R<sub>U</sub>|R<sub>S</sub>|P<sub>D</sub>|C<sub>2</sub>] if it is still permitted to produce signatures.</li><li id="ul0586-0005" num="4930">e. If values returned in d are non zero, then System can then call ChipU's SetPermission function with the desired n, R<sub>S</sub>, P<sub>D </sub>and S<sub>K</sub>[R<sub>U</sub>|R<sub>S</sub>|P<sub>D</sub>|C<sub>2</sub>].</li><li id="ul0586-0006" num="4931">f. ChipU verifies the received signature against S<sub>K</sub>[R<sub>U</sub>|R<sub>S</sub>|P<sub>D</sub>|C<sub>2</sub>] and applies P<sub>D </sub>to P<sub>n </sub>if the signature matches</li><li id="ul0586-0007" num="4932">g. System checks 1st output parameter. 1=success, 0=failure.</li></ul>
4933The data flow for authenticated writes to permissions is shown in <figref idref="DRAWINGS">FIG. 336</figref> below.
00008.5 Programming K
4934In this case, we have a factory chip (ChipF) connected to a System. The System wants to program the key in another chip (ChipP). System wants to avoid passing the new key to ChipP in the clear, and also wants to avoid the possibility of the key-upgrade message being replayed on another ChipP (even if the user doesn't know the key).
4935The protocol assumes that ChipF and ChipP already share a secret key K<sub>old</sub>. This key is used to ensure that only a chip that knows K<sub>old </sub>can set K<sub>new</sub>.
4936The protocol requires the following publicly available functions in ChipP: <ul id="ul0587" list-style="none"><li id="ul0587-0001" num="0000"><ul id="ul0588" list-style="none"><li id="ul0588-0001" num="4937">Random<img file="US7165824B2_D0066.tif" /> Returns R (does not advance R).</li><li id="ul0588-0002" num="4938">ReplaceKey[X, Y, Z] Replaces K by S<sub>Kold</sub>[R|X|C<sub>3</sub>]⊕Y, advances R, and returns 1 only if S<sub>Kold</sub>[X|Y|C<sub>3</sub>]=Z. Otherwise returns 0. The time taken to calculate signatures and compare values must be identical for all inputs.</li></ul></li></ul>
4939And the following data and function in ChipF: <ul id="ul0589" list-style="none"><li id="ul0589-0001" num="0000"><ul id="ul0590" list-style="none"><li id="ul0590-0001" num="4940">CountRemaining Part of M with contains the number of signatures that ChipF is allowed to generate. Decrements with each successful call to GetProgramKey. Permissions in P for this part of M needs to be ReadOnly once ChipF has been setup. Therefore can only be updated by a ChipS that has authority to perform updates to that part of M.</li><li id="ul0590-0002" num="4941">K<sub>new </sub>The new key to be transferred from ChipF to ChipP. Must not be visible.</li><li id="ul0590-0003" num="4942">SetPartialKey[X,Y] If word X of K<sub>new </sub>has not yet been set, set word X of K<sub>new </sub>to Y and return 1. Otherwise return 0. This function allows K<sub>new </sub>to be programmed in multiple steps, thereby allowing different people or systems to know different parts of the key (but not the whole K<sub>new</sub>). K<sub>new </sub>is stored in ChipF's flash memory. Since there is a small number of ChipFs, it is theoretically not necessary to store the inverse of Knew, but it is stronger protection to do so.</li><li id="ul0590-0004" num="4943">GetProgramKey[X] Advances R<sub>F</sub>, decrements CountRemaining, outputs R<sub>F</sub>, the encrypted key S<sub>Kold</sub>[X|R<sub>F</sub>|C<sub>3</sub>]⊕K<sub>new </sub>and a signature of the first two outputs plus C<sub>3 </sub>if CountRemaining>0. Otherwise outputs 0. The time to calculate the encrypted key & signature must be identical for all inputs.</li></ul></li></ul>
4944To update P's key: <ul id="ul0591" list-style="none"><li id="ul0591-0001" num="4945">a. System calls ChipP's Random function;</li><li id="ul0591-0002" num="4946">b. ChipP returns R<sub>P </sub>to System;</li><li id="ul0591-0003" num="4947">c. System calls ChipF's GetProgramKey function, passing in the result from b;</li><li id="ul0591-0004" num="4948">d. ChipF updates R<sub>F</sub>, then calculates and returns R<sub>F</sub>, S<sub>Kold</sub>[R<sub>P</sub>|R<sub>F</sub>|C<sub>3</sub>]⊕K<sub>new</sub>, and S<sub>Kold</sub>[R<sub>F</sub>|S<sub>Kold</sub>[R<sub>P</sub>|R<sub>F</sub>|C<sub>3</sub>]⊕K<sub>new</sub>|C<sub>3</sub>];</li><li id="ul0591-0005" num="4949">e. If the response from d is not 0, System calls ChipP's ReplaceKey function, passing in the response from d;</li><li id="ul0591-0006" num="4950">f. System checks response from ChipP. If the response is 1, then K<sub>P </sub>has been correctly updated to K<sub>new</sub>. If the response is 0, K<sub>P </sub>has not been updated.</li></ul>
4951The data flow for key updates is shown in <figref idref="DRAWINGS">FIG. 337</figref>.
4952Note that K<sub>new </sub>is never passed in the open. An attacker could send its own R<sub>P</sub>, but cannot produce S<sub>Kold</sub>[R<sub>P</sub>|R<sub>F</sub>|C<sub>3</sub>] without K<sub>old</sub>. The third parameter, a signature, is sent to ensure that ChipP can determine if either of the first two parameters have been changed en route.
4953CountRemaining needs to be setup in M<sub>F </sub>(including making it ReadOnly in P) before ChipF is programmed with K<sub>P</sub>. ChipF should therefore be programmed to only perform a limited number of GetProgramKey operations (thereby limiting compromise exposure if a ChipF is stolen). An authorized ChipS can be used to update this counter if neccesary (see Section 8.4 on page 665).
00008.5.1 Chicken and Egg
4954Of course, for the Program Key protocol to work, both ChipF and ChipP must both know K<sub>old</sub>. Obviously both chips had to be programmed with K<sub>old</sub>, and thus K<sub>old </sub>can be thought of as an older K<sub>new</sub>:K<sub>old </sub>can be placed in chips if another ChipF knows K<sub>older</sub>, and so on.
4955Although this process allows a chain of reprogramming of keys, with each stage secure, at some stage the very first key (K<sub>first</sub>) must be placed in the chips. K<sub>first </sub>is in fact programmed with the chip's microcode at the manufacturing test station as the last step in manufacturing test. K<sub>first </sub>can be a manufacturing batch key, changed for each batch or for each customer etc, and can have as short a life as desired. Compromising K<sub>first </sub>need not result in a complete compromise of the chain of K<sub>S</sub>.
00009 Multiple Key Single Memory Vector
00009.1 Protocol Background
4956This protocol set is an extension to the single key single memory vector protocol set, and is provided for two reasons: <ul id="ul0592" list-style="none"><li id="ul0592-0001" num="0000"><ul id="ul0593" list-style="none"><li id="ul0593-0001" num="4957">the multiple key multiple memory vector protocol set defined in this document is simply extensions of this one; and</li><li id="ul0593-0002" num="4958">it is useful in its own right</li></ul></li></ul>
4959The multiple key protocol set is typically useful for applications where there are multiple types of systems and consumables, and they need to work with each other in various ways. This is typically in the following situations: <ul id="ul0594" list-style="none"><li id="ul0594-0001" num="0000"><ul id="ul0595" list-style="none"><li id="ul0595-0001" num="4960">when different systems want to share some consumables, but not others. For example printer models may share some ink cartridges and not share others.</li><li id="ul0595-0002" num="4961">when there are different owners of data in M. Part of the memory vector may be owned by one company (eg the speed of the printer) and another may be owned by another (eg the serial number of the chip). In this case a given key K<sub>n </sub>needs to be able to write to a given part of M, and other keys K<sub>n </sub>need to be disallowed from writing to these same areas. <br /> 9.2 Requirements of Protocol </li></ul></li></ul>
4962Each QA Chip contains the following values: <ul id="ul0596" list-style="none"><li id="ul0596-0001" num="4963">N The maximum number of keys known to the chip.</li><li id="ul0596-0002" num="4964">K<sub>N </sub>Array of N secret keys used for calculating F<sub>Kn</sub>[X] where K<sub>n </sub>is the nth element of the array. Each K<sub>n </sub>must not be stored directly in the QA Chip. Instead, each chip needs to store a single random number R<sub>K </sub>(different for each chip), K<sub>n</sub>⊕R<sub>K</sub>, and <img file="US7165824B2_D0067.tif" />K<sub>n</sub>⊕R<sub>K</sub>. The stored K<sub>n</sub>⊕R<sub>K </sub>can be XORed with R<sub>K </sub>to obtain the real K<sub>n</sub>. Although <img file="US7165824B2_D0068.tif" />K<sub>n</sub>⊕R<sub>K </sub>must be stored to protect against differential attacks, it is not used.</li><li id="ul0596-0003" num="4965">R Current random number used to ensure time varying messages. Each chip instance must be seeded with a different initial value. Changes for each signature generation.</li><li id="ul0596-0004" num="4966">M Memory vector of QA Chip. A fixed part of M contains N in ReadOnly form so users of the chip can know the number of keys known by the chip.</li><li id="ul0596-0005" num="4967">P N+1 element array of access permissions for each part of M. Entry 0 holds access permissions for non-authenticated writes to M (no key required). Entries 1 to N+1 hold access permissions for authenticated writes to M, one for each K. Permission choices for each part of M are Read Only, Read/Write, and Decrement Only.</li><li id="ul0596-0006" num="4968">C 3 constants used for generating signatures. C<sub>1</sub>, C<sub>2</sub>, and C<sub>3 </sub>are constants that pad out a submessage to a hashing boundary, and all 3 must be different.</li></ul>
4969Each QA Chip contains the following private function: <ul id="ul0597" list-style="none"><li id="ul0597-0001" num="4970">S<sub>Kn</sub>[N,X] Internal function only. Returns S<sub>Kn</sub>[X], the result of applying a digital signature function S to X based upon the appropriate key K<sub>n</sub>. The digital signature must be long enough to counter the chances of someone generating a random signature. The length depends on the signature scheme chosen, although the scheme chosen for the QA Chip is HMAC-SHA1 (see Section 13 on page 691), and therefore the length of the signature is 160 bits.</li></ul>
4971Additional functions are required in certain QA Chips, but these are described as required.
00009.3 Reads
4972As with the single key scenario, we have a trusted chip (ChipT) connected to a System. The System wants to authenticate an object that contains a non-trusted chip (ChipA). In effect, the System wants to know that it can securely read a memory vector (M) from ChipA: to be sure that ChipA is valid and that M has not been altered.
4973The protocol requires the following publicly available functions: <ul id="ul0598" list-style="none"><li id="ul0598-0001" num="0000"><ul id="ul0599" list-style="none"><li id="ul0599-0001" num="4974">Random<img file="US7165824B2_D0069.tif" /> Returns R (does not advance R).</li><li id="ul0599-0002" num="4975">Read[n, X] Advances R, and returns R, M, S<sub>Kn</sub>[X|R|C<sub>1</sub>|M]. The time taken to calculate the signature must not be based on the contents of X, R, M, or K.</li><li id="ul0599-0003" num="4976">Test[n,X, Y, Z] Advances R and returns 1 if S<sub>Kn</sub>[R|X|C<sub>1</sub>|Y]=Z. Otherwise returns 0. The time taken to calculate and compare signatures must be independent of data content.</li></ul></li></ul>
4977To authenticate ChipA and read ChipA's memory M: <ul id="ul0600" list-style="none"><li id="ul0600-0001" num="4978">a. System calls ChipT's Random function;</li><li id="ul0600-0002" num="4979">b. ChipT returns R<sub>T </sub>to System;</li><li id="ul0600-0003" num="4980">c. System calls ChipA's Read function, passing in some key number n1 and the result from b;</li><li id="ul0600-0004" num="4981">d. ChipA updates R<sub>A</sub>, then calculates and returns R<sub>A</sub>, M<sub>A</sub>, S<sub>KAn1</sub>[R<sub>T</sub>|R<sub>A</sub>|C<sub>1</sub>|M<sub>A</sub>];</li><li id="ul0600-0005" num="4982">e. System calls ChipT's Test function, passing in n2, R<sub>A</sub>, M<sub>A</sub>, S<sub>KAn1</sub>[R<sub>T</sub>|R<sub>A</sub>|C<sub>1</sub>|M<sub>A</sub>];</li><li id="ul0600-0006" num="4983">f. System checks response from ChipT. If the response is 1, then ChipA is considered authentic. If 0, ChipA is considered invalid.</li></ul>
4984The choice of n1 and n2 must be such that ChipA's K<sub>n1</sub>=ChipT's K<sub>n2</sub>.
4985The data flow for read authentication is shown in <figref idref="DRAWINGS">FIG. 338</figref>.
4986The protocol allows System to simply pass data from one chip to another, with no special processing. The protection relies on ChipT being trusted, even though System does not know K.
4987When ChipT is physically separate from System (eg is chip on a board connected to System) System must also occassionally (based on system clock for example) call ChipT's Test function with bad data, expecting a 0 response. This is to prevent someone from inserting a fake ChipT into the system that always returns 1 for the Test function.
4988It is important that n1 is chosen by System. Otherwise ChipA would need to return N<sub>A </sub>sets of signatures for each read, since ChipA does not know which of the keys will satisfy ChipT. Similarly, system must also choose n2, so it can potentially restrict the number of keys in ChipT that are matched against (otherwise ChipT would have to match against all its keys). This is important in order to restrict how different keys are used. For example, say that ChipT contains 6 keys, keys 0–2 are for various printer-related upgrades, and keys 3–6 are for inks. ChipA contains say 4 keys, one key for each printer model. At power-up, System goes through each of chipA's keys 0–3, trying each out against ChipT's keys 3–6. System doesn't try to match against ChipT's keys 0–2. Otherwise knowledge of a speed-upgrade key could be used to provide ink QA Chip chips. This matching needs to be done only once (eg at power up). Once matching keys are found, System can continue to use those key numbers.
4989Since System needs to know N<sub>T </sub>and N<sub>A</sub>, part of M is used to hold N (eg in Read Only form), and the system can obtain it by calling the Read function, passing in key 0.
00009.4 Writes
4990As with the single key scenario, the System wants to update M in ChipU. As before, this can be done in a non-authenticated and authenticated way.
00009.4.1 Non-authenticated Writes
4991This is the most frequent type of write, and takes place between the System/consumable during normal everyday operation. In this kind of write, System wants to change M subject to P. For example, the System could be decrementing the amount of consumable remaining. Although System does not need to know any of the K<sub>S </sub>or even have access to a trusted chip to perform the write, System must follow a non-authenticated write by an authenticated read if it needs to know that the write was successful.
4992The protocol requires the following publicly available function: <ul id="ul0601" list-style="none"><li id="ul0601-0001" num="4993">Write[X] Writes X over those parts of M subject to P<sub>0 </sub>and the existing value for M.</li></ul>
4994To authenticate a write of M<sub>new </sub>to ChipA's memory M: <ul id="ul0602" list-style="none"><li id="ul0602-0001" num="4995">a. System calls ChipU's Write function, passing in M<sub>new</sub>;</li><li id="ul0602-0002" num="4996">b. The authentication procedure for a Read is carried out (see Section 9.3 on page 671);</li><li id="ul0602-0003" num="4997">c. If ChipU is authentic and M<sub>new</sub>=M returned in b, the write succeeded. If not, it failed. <br /> 9.4.2 Authenticated Writes </li></ul>
4998In this kind of write, System wants to change Chip U's M in an authorized way, without being subject to the permissions that apply during normal operation (P<sub>0</sub>). For example, the consumable may be at a refilling station and the normally Decrement Only section of M should be updated to include the new valid consumable. In this case, the chip whose M is being updated must authenticate the writes being generated by the external System and in addition, apply the appropriate permission for the key to ensure that only the correct parts of M are updated. Having a different permission for each key is required as when multiple keys are involved, all keys should not necessarily be given open access to M. For example, suppose M contains printer speed and a counter of money available for franking. A ChipS that updates printer speed should not be capable of updating the amount of money. Since P<sub>0 </sub>is used for non-authenticated writes, each K<sub>n </sub>has a corresponding permission P<sub>n+1 </sub>that determines what can be updated in an authenticated write.
4999In this transaction protocol, the System's chip is referred to as ChipS, and the chip being updated is referred to as ChipU. Each chip distrusts the other.
5000The protocol requires the following publicly available functions in ChipU: <ul id="ul0603" list-style="none"><li id="ul0603-0001" num="0000"><ul id="ul0604" list-style="none"><li id="ul0604-0001" num="5001">Read[n, X] Advances R, and returns R, M, S<sub>Kn</sub>[X|R|C<sub>1</sub>|M]. The time taken to calculate the signature must not be based on the contents of X, R, M, or K.</li><li id="ul0604-0002" num="5002">WriteA[n, X, Y, Z] Advances R, replaces M by Y subject to P<sub>n+1</sub>, and returns 1 only if S<sub>Kn</sub>[R|X|C<sub>1</sub>|Y]=Z. Otherwise returns 0. The time taken to calculate and compare signatures must be independent of data content. This function is identical to ChipT's Test function except that it additionally writes Y subject to P<sub>n+1 </sub>to its M when the signature matches.</li></ul></li></ul>
5003Authenticated writes require that the System has access to a ChipS that is capable of generating appropriate signatures. ChipS requires the following variables and function: <ul id="ul0605" list-style="none"><li id="ul0605-0001" num="5004">CountRemaining Part of M that contains the number of signatures that ChipS is allowed to generate. Decrements with each successful call to SignM and SignP. Permissions in ChipS's P<sub>0 </sub>for this part of M needs to be ReadOnly once ChipS has been setup. Therefore CountRemaining can only be updated by another ChipS that will perform updates to that part of M (assuming ChipS's P allows that part of M to be updated).</li><li id="ul0605-0002" num="5005">Q Part of M that contains the write permissions for updating ChipU's M. By adding Q to ChipS we allow different ChipSs that can update different parts of M<sub>U</sub>. Permissions in ChipS's P<sub>0 </sub>for this part of M needs to be ReadOnly once ChipS has been setup. Therefore Q can only be updated by another ChipS that will perform updates to that part of M.</li><li id="ul0605-0003" num="5006">SignM[n,V,W,X,Y,Z] Advances R, decrements CountRemaining and returns R, Z<sub>QX </sub>(Z applied to X with permissions Q), S<sub>Kn</sub>[W|R|C<sub>1</sub>|Z<sub>QX</sub>] only if Y=S<sub>Kn</sub>[V|W|C<sub>1</sub>|X] and CountRemaining>0. Otherwise returns all 0s. The time taken to calculate and compare signatures must be independent of data content.</li></ul>
5007To update ChipU's M vector: <ul id="ul0606" list-style="none"><li id="ul0606-0001" num="5008">a. System calls ChipU's Read function, passing in n1 and 0 as the input parameters;</li><li id="ul0606-0002" num="5009">b. ChipU produces R<sub>U</sub>, M<sub>U</sub>, S<sub>Kn1</sub>[0|R<sub>U</sub>|C<sub>1</sub>|M<sub>U</sub>] and returns these to System;</li><li id="ul0606-0003" num="5010">c. System calls ChipS's SignM function, passing in n2 (the key to be used in ChipS), 0 (as used in a), R<sub>U</sub>, M<sub>U</sub>, S<sub>Kn1</sub>[0|R<sub>U</sub>|C<sub>1</sub>|M<sub>U</sub>], and M<sub>D </sub>(the desired vector to be written to ChipU);</li><li id="ul0606-0004" num="5011">d. ChipS produces R<sub>S</sub>, M<sub>QD </sub>(processed by running M<sub>D </sub>against M<sub>U </sub>using Q) and S<sub>Kn2</sub>[R<sub>U</sub>|R<sub>S</sub>|C<sub>1</sub>|M<sub>QD</sub>] if the inputs were valid, and 0 for all outputs if the inputs were not valid.</li><li id="ul0606-0005" num="5012">e. If values returned in d are non zero, then ChipU is considered authentic. System can then call ChipU's WriteA function with these values from d.</li><li id="ul0606-0006" num="5013">f. ChipU should return a 1 to indicate success. A 0 should only be returned if the data generated by ChipS is incorrect (e.g. a transmission error).</li></ul>
5014The choice of n1 and n2 must be such that ChipU's K<sub>n1</sub>=ChipS's K<sub>n2</sub>.
5015The data flow for authenticated writes is shown in <figref idref="DRAWINGS">FIG. 339</figref> below.
5016Note that Q in ChipS is part of ChipS's M. This allows a user to set up ChipS with a permission set for upgrades. This should be done to ChipS and that part of M designated by P<sub>0 </sub>set to ReadOnly before ChipS is programmed with K<sub>U</sub>. If K<sub>S </sub>is programmed with K<sub>U </sub>first, there is a risk of someone obtaining a half-setup ChipS and changing all of M<sub>U </sub>instead of only the sections specified by Q.
5017In addition, CountRemaining in ChipS needs to be setup (including making it ReadOnly in P<sub>S</sub>) before ChipS is programmed with K<sub>U</sub>. ChipS should therefore be programmed to only perform a limited number of SignM operations (thereby limiting compromise exposure if a ChipS is stolen). Thus ChipS would itself need to be upgraded with a new CountRemaining every so often.
00009.4.3 Updating Permissions for Future Writes
5018In order to reduce exposure to accidental and malicious attacks on P (and certain parts of M), only authorized users are allowed to update P. Writes to P are the same as authorized writes to M, except that they update P<sub>n </sub>instead of M. Initially (at manufacture), P is set to be Read/Write for all parts of M. As different processes fill up different parts of M, they can be sealed against future change by updating the permissions. Updating a chip's P<sub>0 </sub>changes permissions for unauthorized writes, and updating P<sub>n+1 </sub>changes permissions for authorized writes with key K<sub>n</sub>.
5019P<sub>n </sub>is only allowed to change to be a more restrictive form of itself. For example, initially all parts of M have permissions of Read/Write. A permission of Read/Write can be updated to Decrement Only or Read Only. A permission of Decrement Only can be updated to become Read Only. A Read Only permission cannot be further restricted.
5020In this transaction protocol, the System's chip is referred to as ChipS, and the chip being updated is referred to as ChipU. Each chip distrusts the other.
5021The protocol requires the following publicly available functions in ChipU: <ul id="ul0607" list-style="none"><li id="ul0607-0001" num="5022">Random<img file="US7165824B2_D0070.tif" /> Returns R (does not advance R).</li><li id="ul0607-0002" num="5023">SetPermission[n,p,X,Y,Z] Advances R, and updates P<sub>p </sub>according to Y and returns 1 followed by the resultant P<sub>p </sub>only if S<sub>Kn</sub>[R|X|Y|C<sub>2</sub>]=Z. Otherwise returns 0. P<sub>p </sub>can only become more restricted. Passing in 0 for any permission leaves it unchanged (passing in Y=0 returns the current P<sub>p</sub>).</li></ul>
5024Authenticated writes of permissions require that the System has access to a ChipS that is capable of generating appropriate signatures. ChipS requires th following variables and function: <ul id="ul0608" list-style="none"><li id="ul0608-0001" num="5025">CountRemaining Part of M that contains the number of signatures that ChipS is allowed to generate. Decrements with each successful call to SignM and SignP. Permissions in ChipS's P<sub>0 </sub>for this part of M needs to be ReadOnly once ChipS has been setup. Therefore CountRemaining can only be updated by another ChipS that will perform updates to that part of M (assuming ChipS's P<sub>n </sub>allows that part of M to be updated).</li><li id="ul0608-0002" num="5026">SignP[n,X,Y] Advances R, decrements CountRemaining and returns R and S<sub>Kn</sub>[X|R|Y|C<sub>2</sub>] only if CountRemaining>0. Otherwise returns all 0s. The time taken to calculate and compare signatures must be independent of data content.</li></ul>
5027To update ChipU's P<sub>n</sub>: <ul id="ul0609" list-style="none"><li id="ul0609-0001" num="5028">a. System calls ChipU's Random function;</li><li id="ul0609-0002" num="5029">b. ChipU returns R<sub>U </sub>to System;</li><li id="ul0609-0003" num="5030">c. System calls ChipS's SignP function, passing in n1, R<sub>U </sub>and P<sub>D </sub>(the desired P to be written to ChipU);</li><li id="ul0609-0004" num="5031">d. ChipS produces R<sub>S </sub>and S<sub>Kn1</sub>[R<sub>U</sub>|R<sub>S</sub>|P<sub>D</sub>|C<sub>2</sub>] if it is still permitted to produce signatures.</li><li id="ul0609-0005" num="5032">e. If values returned in d are non zero, then System can then call ChipU's SetPermission function with n2, the desired permission entry p, R<sub>S</sub>, P<sub>D </sub>and S<sub>Kn1</sub>[R<sub>U</sub>|R<sub>S</sub>|P<sub>D</sub>|C<sub>2</sub>].</li><li id="ul0609-0006" num="5033">f. ChipU verifies the received signature against S<sub>Kn2</sub>[R<sub>U</sub>|R<sub>S</sub>|P<sub>D</sub>|C<sub>2</sub>] and applies P<sub>D </sub>to P<sub>n </sub>if the signature matches</li><li id="ul0609-0007" num="5034">g. System checks 1st output parameter. 1=success, 0=failure.</li></ul>
5035The choice of n1 and n2 must be such that ChipU's K<sub>n1</sub>=ChipS's K<sub>n2</sub>.
5036The data flow for authenticated writes to permissions is shown in <figref idref="DRAWINGS">FIG. 340</figref> below.
00009.4.4 Protecting M in a Multiple Key System
5037To protect the appropriate part of M, the SetPermission function must be called after the part of M has been set to the desired value.
5038For example, if adding a serial number to an area of M that is currently ReadWrite so that noone is permitted to update the number again: <ul id="ul0610" list-style="none"><li id="ul0610-0001" num="0000"><ul id="ul0611" list-style="none"><li id="ul0611-0001" num="5039">the Write function is called to write the serial number to M</li><li id="ul0611-0002" num="5040">SetPermission is called for n={1, . . . , N} to set that part of M to be ReadOnly for authorized writes using key n−1.</li><li id="ul0611-0003" num="5041">SetPermission is called for 0 to set that part of M to be ReadOnly for non-authorized writes</li></ul></li></ul>
5042For example, adding a consumable value to M such that only keys 1–2 can update it, and keys 0, and 3-N cannot: <ul id="ul0612" list-style="none"><li id="ul0612-0001" num="0000"><ul id="ul0613" list-style="none"><li id="ul0613-0001" num="5043">the Write function is called to write the amount of consumable to M</li><li id="ul0613-0002" num="5044">SetPermission is called for n={1, 4, 5, . . . , N−1} to set that part of M to be ReadOnly for authorized writes using key n−1. This leaves keys 1 and 2 with ReadWrite permissions.</li><li id="ul0613-0003" num="5045">SetPermission is called for 0 to set that part of M to be DecrementOnly for non-authorized writes. This allows the amount of consumable to decrement.</li></ul></li></ul>
5046It is possible for someone who knows a key to further restrict other keys, but it is not in anyone's interest to do so.
00009.5 Programming K
5047In this case, we have a factory chip (ChipF) connected to a System. The System wants to program the key in another chip (ChipP). System wants to avoid passing the new key to ChipP in the clear, and also wants to avoid the possibility of the key-upgrade message being replayed on another ChipP (even if the user doesn't know the key).
5048The protocol is a simple extension of the single key protocol in that it assumes that ChipF and ChipP already share a secret key K<sub>old</sub>. This key is used to ensure that only a chip that knows K<sub>old </sub>can set K<sub>new</sub>.
5049The protocol requires the following publicly available functions in ChipP: <ul id="ul0614" list-style="none"><li id="ul0614-0001" num="0000"><ul id="ul0615" list-style="none"><li id="ul0615-0001" num="5050">Random<img file="US7165824B2_D0071.tif" /> Returns R (does not advance R).</li><li id="ul0615-0002" num="5051">ReplaceKey[n, X, Y, Z] Replaces K<sub>n </sub>by S<sub>Kn</sub>[R|X|C<sub>3</sub>]⊕Y, advances R, and returns 1 only if S<sub>Kn</sub>[X|Y|C<sub>3</sub>]=Z. Otherwise returns 0. The time taken to calculate signatures and compare values must be identical for all inputs.</li></ul></li></ul>
5052And the following data and functions in ChipF: <ul id="ul0616" list-style="none"><li id="ul0616-0001" num="0000"><ul id="ul0617" list-style="none"><li id="ul0617-0001" num="5053">CountRemaining Part of M with contains the number of signatures that ChipF is allowed to generate. Decrements with each successful call to GetProgramKey. Permissions in P for this part of M needs to be ReadOnly once ChipF has been setup. Therefore can only be updated by a ChipS that has authority to perform updates to that part of M.</li><li id="ul0617-0002" num="5054">K<sub>new </sub>The new key to be transferred from ChipF to ChipP. Must not be visible.</li><li id="ul0617-0003" num="5055">SetPartialKey[X,Y] If word X of K<sub>new </sub>has not yet been set, set word X of K<sub>new </sub>to Y and return 1. Otherwise return 0. This function allows K<sub>new </sub>to be programmed in multiple steps, thereby allowing different people or systems to know different parts of the key (but not the whole K<sub>new</sub>). K<sub>new </sub>is stored in ChipF's flash memory. Since there is a small number of ChipFs, it is theoretically not necessary to store the inverse of K<sub>new</sub>, but it is stronger protection to do so.</li><li id="ul0617-0004" num="5056">GetProgramKey[n, X] Advances R<sub>F</sub>, decrements CountRemaining, outputs R<sub>F</sub>, the encrypted key S<sub>Kn</sub>[X|R<sub>F</sub>|C<sub>3</sub>]⊕K<sub>new </sub>and a signature of the first two outputs plus C<sub>3 </sub>if CountRemaining>0. Otherwise outputs 0. The time to calculate the encrypted key & signature must be identical for all inputs.</li></ul></li></ul>
5057To update P's key: <ul id="ul0618" list-style="none"><li id="ul0618-0001" num="5058">a. System calls ChipP's Random function;</li><li id="ul0618-0002" num="5059">b. ChipP returns R<sub>P </sub>to System;</li><li id="ul0618-0003" num="5060">c. System calls ChipF's GetProgramKey function, passing in n1 (the desired key to use) and the result from b;</li><li id="ul0618-0004" num="5061">d. ChipF updates R<sub>F</sub>, then calculates and returns R<sub>F</sub>, S<sub>Kn1</sub>[R<sub>P</sub>|R<sub>F</sub>|C<sub>3</sub>]⊕K<sub>new</sub>, and S<sub>Kn1</sub>[R<sub>F</sub>|S<sub>Kn1</sub>[R<sub>P</sub>|R<sub>F</sub>|C<sub>3</sub>]⊕K<sub>new</sub>|C<sub>3</sub>];</li><li id="ul0618-0005" num="5062">e. If the response from d is not 0, System calls ChipP's ReplaceKey function, passing in n2 (the key to use in ChipP) and the response from d;</li><li id="ul0618-0006" num="5063">f. System checks response from ChipP. If the response is 1, then K<sub>Pn2 </sub>has been correctly updated to K<sub>new</sub>. If the response is 0, K<sub>Pn2 </sub>has not been updated.</li></ul>
5064The choice of n1 and n2 must be such that ChipF's K<sub>n1</sub>=ChipP's K<sub>n2</sub>.
5065The data flow for key updates is shown in <figref idref="DRAWINGS">FIG. 341</figref> below.
5066Note that K<sub>new </sub>is never passed in the open. An attacker could send its own R<sub>P</sub>, but cannot produce S<sub>Kn1</sub>[R<sub>P</sub>|R<sub>F</sub>|C<sub>3</sub>] without K<sub>n1</sub>. The signature based on K<sub>new </sub>is sent to ensure that ChipP will be able to determine if either of the first two parameters have been changed en route.
5067CountRemaining needs to be setup in M<sub>F </sub>(including making it ReadOnly in P) before ChipF is programmed with K<sub>P</sub>. ChipF should therefore be programmed to only perform a limited number of GetProgramKey operations (thereby limiting compromise exposure if a ChipF is stolen). An authorized ChipS can be used to update this counter if neccesary (see Section 9.4 on page 673).
00009.5.1 Chicken and Egg
5068As with the single key protocol, for the Program Key protocol to work, both ChipF and ChipP must both know K<sub>old</sub>. Obviously both chips had to be programmed with K<sub>old</sub>, and thus K<sub>old </sub>can be thought of as an older K<sub>new</sub>:K<sub>old </sub>can be placed in chips if another ChipF knows K<sub>older</sub>, and so on.
5069Although this process allows a chain of reprogramming of keys, with each stage secure, at some stage the very first key (K<sub>first</sub>) must be placed in the chips. K<sub>first </sub>is in fact programmed with the chip's microcode at the manufacturing test station as the last step in manufacturing test. K<sub>first </sub>can be a manufacturing batch key, changed for each batch or for each customer etc, and can have as short a life as desired. Compromising K<sub>first </sub>need not result in a complete compromise of the chain of Ks.
5070Depending on the reprogramming requirements, K<sub>first </sub>can be the same or different for all K<sub>n</sub>.
000010 Multiple Keys Multiple Memory Vectors
000010.1 Protocol Background
5071This protocol set is a slight restriction of the multiple key single memory vector protocol set, and is the expected protocol. It is a restriction in that M has been optimized for Flash memory utilization.
5072M is broken into multiple memory vectors (semi-fixed and variable components) for the purposes of optimizing flash memory utilization. Typically M contains some parts that are fixed at some stage of the manufacturing process (eg a batch number, serial number etc), and once set, are not ever updated. This information does not contain the amount of consumable remaining, and therefore is not read or written to with any great frequency.
5073We therefore define M<sub>0 </sub>to be the M that contains the frequently updated sections, and the remaining Ms to be rarely written to. Authenticated writes only write to M<sub>0</sub>, and non-authenticated writes can be directed to a specific M<sub>n</sub>. This reduces the size of permissions that are stored in the QA Chip (since key-based writes are not required for Ms other than M<sub>0</sub>). It also means that M<sub>0 </sub>and the remaining Ms can be manipulated in different ways, thereby increasing flash memory longevity.
000010.2 Requirements of Protocol
5074Each QA Chip contains the following values: <ul id="ul0619" list-style="none"><li id="ul0619-0001" num="5075">N The maximum number of keys known to the chip.</li><li id="ul0619-0002" num="5076">T The number of vectors M is broken into.</li><li id="ul0619-0003" num="5077">K<sub>N </sub>Array of N secret keys used for calculating F<sub>Kn</sub>[X] where K<sub>n </sub>is the nth element of the array. Each K<sub>n </sub>must not be stored directly in the QA Chip. Instead, each chip needs to store a single random number R<sub>K </sub>(different for each chip), K<sub>n</sub>⊕R<sub>K</sub>, and <img file="US7165824B2_D0072.tif" />K<sub>n</sub>⊕R<sub>K</sub>. The stored K<sub>n</sub>⊕R<sub>K </sub>can be XORed with R<sub>K </sub>to obtain the real K<sub>n</sub>. Although <img file="US7165824B2_D0073.tif" />K<sub>n</sub>⊕R<sub>K </sub>must be stored to protect against differential attacks, it is not used.</li><li id="ul0619-0004" num="5078">R Current random number used to ensure time varying messages. Each chip instance must be seeded with a different initial value. Changes for each signature generation.</li><li id="ul0619-0005" num="5079">M<sub>T </sub>Array of T memory vectors. Only M<sub>0 </sub>can be written to with an authorized write, while all Ms can be written to in an unauthorized write. Writes to M<sub>0 </sub>are optimized for Flash usage, while updates to any other M<sub>n </sub>are expensive with regards to Flash utilization, and are expected to be only performed once per section of M<sub>n</sub>. M<sub>1 </sub>contains T and N in ReadOnly form so users of the chip can know these two values.</li><li id="ul0619-0006" num="5080">P<sub>T+N </sub>T+N element array of access permissions for each part of M. Entries n={0 . . . T−1} hold access permissions for non-authenticated writes to M<sub>n </sub>(no key required). Entries n={T to T+N−1}hold access permissions for authenticated writes to M<sub>0 </sub>for K<sub>n</sub>. Permission choices for each part of M are Read Only, Read/Write, and Decrement Only.</li><li id="ul0619-0007" num="5081">C 3 constants used for generating signatures. C<sub>1</sub>, C<sub>2</sub>, and C<sub>3 </sub>are constants that pad out a submessage to a hashing boundary, and all 3 must be different.</li></ul>
5082Each QA Chip contains the following private function: <ul id="ul0620" list-style="none"><li id="ul0620-0001" num="5083">S<sub>Kn</sub>[N,X] Internal function only. Returns S<sub>Kn</sub>[X], the result of applying a digital signature function S to X based upon the appropriate key K<sub>n</sub>. The digital signature must be long enough to counter the chances of someone generating a random signature. The length depends on the signature scheme chosen, although the scheme chosen for the QA Chip is HMAC-SHA1, and therefore the length of the signature is 160 bits.</li></ul>
5084Additional functions are required in certain QA Chips, but these are described as required.
000010.3 Reads
5085As with the previous scenarios, we have a trusted chip (ChipT) connected to a System. The System wants to authenticate an object that contains a non-trusted chip (ChipA). In effect, the System wants to know that it can securely read a memory vector (M<sub>t</sub>) from ChipA: to be sure that ChipA is valid and that M has not been altered.
5086The protocol requires the following publicly available functions: <ul id="ul0621" list-style="none"><li id="ul0621-0001" num="0000"><ul id="ul0622" list-style="none"><li id="ul0622-0001" num="5087">Random<img file="US7165824B2_D0074.tif" /> Returns R (does not advance R).</li><li id="ul0622-0002" num="5088">Read[n, t, X] Advances R, and returns R, M<sub>t</sub>, S<sub>Kn</sub>[X|R|C<sub>1</sub>|M<sub>t</sub>]. The time taken to calculate the signature must not be based on the contents of X, R, M<sub>t</sub>, or K. If t is invalid, the function assumes t=0.</li><li id="ul0622-0003" num="5089">Test[n,X, Y, Z] Advances R and returns 1 if S<sub>Kn</sub>[R|X|C<sub>1</sub>|Y]=Z. Otherwise returns 0. The time taken to calculate and compare signatures must be independent of data content.</li></ul></li></ul>
5090To authenticate ChipA and read ChipA's memory M: <ul id="ul0623" list-style="none"><li id="ul0623-0001" num="5091">a. System calls ChipT's Random function;</li><li id="ul0623-0002" num="5092">b. ChipT returns R<sub>T </sub>to System;</li><li id="ul0623-0003" num="5093">c. System calls ChipA's Read function, passing in some key number n1, the desired M number t, and the result from b;</li><li id="ul0623-0004" num="5094">d. ChipA updates R<sub>A</sub>, then calculates and returns R<sub>A</sub>, M<sub>At</sub>, S<sub>KAn1</sub>[R<sub>T</sub>|R<sub>A</sub>|C<sub>1</sub>|M<sub>At</sub>];</li><li id="ul0623-0005" num="5095">e. System calls ChipT's Test function, passing in n2, R<sub>A</sub>, M<sub>At</sub>, S<sub>KAn1</sub>[R<sub>T</sub>|R<sub>A</sub>|C<sub>1</sub>|M<sub>At</sub>];</li><li id="ul0623-0006" num="5096">f. System checks response from ChipT. If the response is 1, then ChipA is considered authentic. If 0, ChipA is considered invalid.</li></ul>
5097The choice of n1 and n2 must be such that ChipA's K<sub>n1</sub>=ChipT's K<sub>n2</sub>.
5098The data flow for read authentication is shown in <figref idref="DRAWINGS">FIG. 342</figref> below.
5099The protocol allows System to simply pass data from one chip to another, with no special processing. The protection relies on ChipT being trusted, even though System does not know K.
5100When ChipT is physically separate from System (eg is chip on a board connected to System) System must also occassionally (based on system clock for example) call ChipT's Test function with bad data, expecting a 0 response. This is to prevent someone from inserting a fake ChipT into the system that always returns 1 for the Test function.
5101It is important that n1 is chosen by System. Otherwise ChipA would need to return NA sets of signatures for each read, since ChipA does not know which of the keys will satisfy ChipT. Similarly, system must also choose n2, so it can potentially restrict the number of keys in ChipT that are matched against (otherwise ChipT would have to match against all its keys). This is important in order to restrict how different keys are used. For example, say that ChipT contains 6 keys, keys 0–2 are for various printer-related upgrades, and keys 3–6 are for inks. ChipA contains say 4 keys, one key for each printer model. At power-up, System goes through each of chipA's keys 0–3, trying each out against ChipT's keys 3–6. System doesn't try to match against ChipT's keys 0–2. Otherwise knowledge of a speed-upgrade key could be used to provide ink QA Chip chips. This matching needs to be done only once (eg at power up). Once matching keys are found, System can continue to use those key numbers.
5102Since System needs to know N<sub>T</sub>, N<sub>A</sub>, and T<sub>A</sub>, part of M<sub>1 </sub>is used to hold N (eg in Read Only form), and the system can obtain it by calling the Read function, passing in key 0 and t=1.
000010.4 Writes
5103As with the previous scenarios, the System wants to update M<sub>t </sub>in ChipU. As before, this can be done in a non-authenticated and authenticated way.
000010.4.1 Non-authenticated Writes
5104This is the most frequent type of write, and takes place between the System/consumable during normal everyday operation for M<sub>0</sub>, and during the manufacturing process for M<sub>t</sub>.
5105In this kind of write, System wants to change M subject to P. For example, the System could be decrementing the amount of consumable remaining. Although System does not need to know and of the Ks or even have access to a trusted chip to perform the write, System must follow a non-authenticated write by an authenticated read if it needs to know that the write was successful.
5106The protocol requires the following publicly available function: <ul id="ul0624" list-style="none"><li id="ul0624-0001" num="0000"><ul id="ul0625" list-style="none"><li id="ul0625-0001" num="5107">Write[t, X] Writes X over those parts of M<sub>t </sub>subject to P<sub>t </sub>and the existing value for M.</li></ul></li></ul>
5108To authenticate a write of M<sub>new </sub>to ChipA's memory M: <ul id="ul0626" list-style="none"><li id="ul0626-0001" num="5109">a. System calls ChipU's Write function, passing in M<sub>new</sub>;</li><li id="ul0626-0002" num="5110">b. The authentication procedure for a Read is carried out (see Section 9.3 on page 671);</li><li id="ul0626-0003" num="5111">c. If ChipU is authentic and M<sub>new</sub>=M returned in b, the write succeeded. If not, it failed. <br /> 10.4.2 Authenticated Writes </li></ul>
5112In the multiple memory vectors protocol, only M<sub>0 </sub>can be written to an an authenticated way. This is because only M<sub>0 </sub>is considered to have components that need to be upgraded.
5113In this kind of write, System wants to change Chip U's M<sub>0 </sub>in an authorized way, without being subject to the permissions that apply during normal operation. For example, the consumable may be at a refilling-station and the normally Decrement Only section of M<sub>0 </sub>should be updated to include the new valid consumable. In this case, the chip whose M<sub>0 </sub>is being updated must authenticate the writes being generated by the external System and in addition, apply the appropriate permission for the key to ensure that only the correct parts of M<sub>0 </sub>are updated. Having a different permission for each key is required as when multiple keys are involved, all keys should not necessarily be given open access to M<sub>0</sub>. For example, suppose M<sub>0 </sub>contains printer speed and a counter of money available for franking. A ChipS that updates printer speed should not be capable of updating the amount of money. Since P<sub>0 . . . T−1 </sub>is used for non-authenticated writes, each K<sub>n </sub>has a corresponding permission P<sub>T+n </sub>that determines what can be updated in an authenticated write.
5114In this transaction protocol, the System's chip is referred to as ChipS, and the chip being updated is referred to as ChipU. Each chip distrusts the other.
5115The protocol requires the following publicly available functions in ChipU: <ul id="ul0627" list-style="none"><li id="ul0627-0001" num="0000"><ul id="ul0628" list-style="none"><li id="ul0628-0001" num="5116">Read[n, t, X] Advances R, and returns R, M<sub>t</sub>, S<sub>Kn</sub>[X|R|C<sub>1</sub>|M<sub>t</sub>]. The time taken to calculate the signature must not be based on the contents of X, R, M<sub>t</sub>, or K.</li><li id="ul0628-0002" num="5117">WriteA[n, X, Y, Z] Advances R, replaces M<sub>0 </sub>by Y subject to P<sub>T+n</sub>, and returns 1 only if S<sub>Kn</sub>[R|X|C<sub>1</sub>|Y]=Z. Otherwise returns 0. The time taken to calculate and compare signatures must be independent of data content. This function is identical to ChipT's Test function except that it additionally writes Y subject to P<sub>T+n </sub>to its M when the signature matches.</li></ul></li></ul>
5118Authenticated writes require that the System has access to a ChipS that is capable of generating appropriate signatures. ChipS requires the following variables and function: <ul id="ul0629" list-style="none"><li id="ul0629-0001" num="0000"><ul id="ul0630" list-style="none"><li id="ul0630-0001" num="5119">CountRemaining Part of M that contains the number of signatures that ChipS is allowed to generate. Decrements with each successful call to SignM and SignP. Permissions in ChipS's P<sub>0 . . . T−1 </sub>for this part of M needs to be ReadOnly once ChipS has been setup. Therefore CountRemaining can only be updated by another ChipS that will perform updates to that part of M (assuming ChipS's P allows that part of M to be updated).</li><li id="ul0630-0002" num="5120">Q Part of M that contains the write permissions for updating ChipU's M. By adding Q to ChipS we allow different ChipSs that can update different parts of M<sub>U</sub>. Permissions in ChipS's P<sub>0 . . . T−1 </sub>for this part of M needs to be ReadOnly once ChipS has been setup. Therefore Q can only be updated by another ChipS that will perform updates to that part of M.</li><li id="ul0630-0003" num="5121">SignM[n,V,W,X,Y,Z] Advances R, decrements CountRemaining and returns R, Z<sub>QX </sub>(Z applied to X with permissions Q), S<sub>Kn</sub>[W|R|C<sub>1</sub>|Z<sub>QX </sub>only if Y=S<sub>Kn</sub>[V|W|C<sub>1</sub>|X] and CountRemaining>0. Otherwise returns all 0s. The time taken to calculate and compare signatures must be independent of data content.</li></ul></li></ul>
5122To update ChipU's M vector: <ul id="ul0631" list-style="none"><li id="ul0631-0001" num="5123">a. System calls ChipU's Read function, passing in n1, 0 and 0 as the input parameters;</li><li id="ul0631-0002" num="5124">b. ChipU produces R<sub>U</sub>, M<sub>U0</sub>, S<sub>Kn1</sub>[0|R<sub>U</sub>|C<sub>1</sub>|M<sub>U0</sub>] and returns these to System;</li><li id="ul0631-0003" num="5125">c. System calls ChipS's SignM function, passing in n2 (the key to be used in ChipS), 0 (as used in a), R<sub>U</sub>, M<sub>U0</sub>, S<sub>Kn1</sub>[0|R<sub>U</sub>|C<sub>1</sub>|M<sub>U0</sub>], and M<sub>D </sub>(the desired vector to be written to ChipU);</li><li id="ul0631-0004" num="5126">d. ChipS produces R<sub>S</sub>, M<sub>QD </sub>(processed by running M<sub>D </sub>against M<sub>U0 </sub>using Q) and S<sub>Kn2</sub>[R<sub>U</sub>|R<sub>S</sub>|C<sub>1</sub>|M<sub>QD</sub>] if the inputs were valid, and 0 for all outputs if the inputs were not valid.</li><li id="ul0631-0005" num="5127">e. If values returned in d are non zero, then ChipU is considered authentic. System can then call ChipU's WriteA function with these values from d.</li><li id="ul0631-0006" num="5128">f. ChipU should return a 1 to indicate success. A 0 should only be returned if the data generated by ChipS is incorrect (e.g. a transmission error).</li></ul>
5129The choice of n1 and n2 must be such that ChipU's K<sub>n1</sub>=ChipS's K<sub>n2</sub>.
5130The data flow for authenticated writes is shown in <figref idref="DRAWINGS">FIG. 343</figref> below.
5131Note that Q in ChipS is part of ChipS's M. This allows a user to set up ChipS with a permission set for upgrades. This should be done to ChipS and that part of M designated by P<sub>0 . . . T−1 </sub>set to ReadOnly before ChipS is programmed with K<sub>U</sub>. If K<sub>S </sub>is programmed with K<sub>U </sub>first, there is a risk of someone obtaining a half-setup ChipS and changing all of M<sub>U </sub>instead of only the sections specified by Q.
5132In addition, CountRemaining in ChipS needs to be setup (including making it ReadOnly in P<sub>S</sub>) before ChipS is programmed with K<sub>U</sub>. ChipS should therefore be programmed to only perform a limited number of SignM operations (thereby limiting compromise exposure if a ChipS is stolen). Thus ChipS would itself need to be upgraded with a new CountRemaining every so often.
000010.4.3 Updating Permissions for Future Writes
5133In order to reduce exposure to accidental and malicious attacks on P (and certain parts of M), only authorized users are allowed to update P. Writes to P are the same as authorized writes to M, except that they update P<sub>n </sub>instead of M. Initially (at manufacture), P is set to be Read/Write for all M. As different processes fill up different parts of M, they can be sealed against future change by updating the permissions. Updating a chip's P<sub>0 . . . T−1 </sub>changes permissions for unauthorized writes to M<sub>n</sub>, and updating P<sub>T . . . T+N−1 </sub>changes permissions for authorized writes with key K<sub>n</sub>.
5134P<sub>n </sub>is only allowed to change to be a more restrictive form of itself. For example, initially all parts of M have permissions of Read/Write. A permission of Read/Write can be updated to Decrement Only or Read Only. A permission of Decrement Only can be updated to become Read Only. A Read Only permission cannot be further restricted.
5135In this transaction protocol, the System's chip is referred to as ChipS, and the chip being updated is referred to as ChipU. Each chip distrusts the other.
5136The protocol requires the following publicly available functions in ChipU: <ul id="ul0632" list-style="none"><li id="ul0632-0001" num="0000"><ul id="ul0633" list-style="none"><li id="ul0633-0001" num="5137">Random<img file="US7165824B2_D0075.tif" /> Returns R (does not advance R).</li><li id="ul0633-0002" num="5138">SetPermission[n,p,X,Y,Z] Advances R, and updates P<sub>p </sub>according to Y and returns 1 followed by the resultant P<sub>p </sub>only if S<sub>Kn</sub>[R|X|Y|C<sub>2</sub>]=Z. Otherwise returns 0. P<sub>p </sub>can only become more restricted. Passing in 0 for any permission leaves it unchanged (passing in Y=0 returns the current P<sub>p</sub>).</li></ul></li></ul>
5139Authenticated writes of permissions require that the System has access to a ChipS that is capable of generating appropriate signatures. ChipS requires the following variables and function: <ul id="ul0634" list-style="none"><li id="ul0634-0001" num="0000"><ul id="ul0635" list-style="none"><li id="ul0635-0001" num="5140">CountRemaining Part of ChipS's M<sub>0 </sub>that contains the number of signatures that ChipS is allowed to generate. Decrements with each successful call to SignM and SignP. Permissions in ChipS's P<sub>0 . . . T−1 </sub>for this part of M<sub>0 </sub>needs to be ReadOnly once ChipS has been setup. Therefore CountRemaining can only be updated by another ChipS that will perform updates to that part of M<sub>0 </sub>(assuming ChipS's P<sub>n </sub>allows that part of M<sub>0 </sub>to be updated).</li><li id="ul0635-0002" num="5141">SignP[n,X,Y] Advances R, decrements CountRemaining and returns R and S<sub>Kn</sub>[X|R|Y|C<sub>2</sub>] only if CountRemaining>0. Otherwise returns all 0s. The time taken to calculate and compare signatures must be independent of data content.</li></ul></li></ul>
5142To update ChipU's P<sub>n</sub>: <ul id="ul0636" list-style="none"><li id="ul0636-0001" num="5143">a. System calls ChipU's Random function;</li><li id="ul0636-0002" num="5144">b. ChipU returns R<sub>U </sub>to System;</li><li id="ul0636-0003" num="5145">c. System calls ChipS's SignP function, passing in n1, R<sub>U </sub>and P<sub>D </sub>(the desired P to be written to ChipU);</li><li id="ul0636-0004" num="5146">d. ChipS produces R<sub>S </sub>and S<sub>Kn1</sub>[R<sub>U</sub>|R<sub>S</sub>|P<sub>D</sub>|C<sub>2</sub>] if it is still permitted to produce signatures.</li><li id="ul0636-0005" num="5147">e. If values returned in d are non zero, then System can then call ChipU's SetPermission function with n2, the desired permission entry p, R<sub>S</sub>, P<sub>D </sub>and S<sub>Kn1</sub>[R<sub>U</sub>|R<sub>S</sub>|P<sub>D</sub>|C<sub>2</sub>].</li><li id="ul0636-0006" num="5148">f. ChipU verifies the received signature against S<sub>Kn2</sub>[R<sub>U</sub>|R<sub>S</sub>|P<sub>D</sub>|C<sub>2</sub>] and applies P<sub>D </sub>to P<sub>n </sub>if the signature matches</li><li id="ul0636-0007" num="5149">g. System checks 1 st output parameter. 1=success, 0=failure.</li></ul>
5150The choice of n1 and n2 must be such that ChipU's K<sub>n1</sub>=ChipS's K<sub>n2</sub>.
5151The data flow for authenticated writes to permissions is shown in <figref idref="DRAWINGS">FIG. 344</figref> below.
000010.4.4 Protecting M in a Multiple Key Multiple M System
5152To protect the appropriate part of M<sub>n </sub>against unauthorized writes, call SetPermissions[n] for n=0 to T−1. To protect the appropriate part of M<sub>0 </sub>against authorized writes with key n, call SetPermissions[T+n] for n=0 to N−1.
5153Note that only M<sub>0 </sub>can be written in an authenticated fashion.
5154Note that the SetPermission function must be called after the part of M has been set to the desired value.
5155For example, if adding a serial number to an area of M<sub>1 </sub>that is currently ReadWrite so that noone is permitted to update the number again: <ul id="ul0637" list-style="none"><li id="ul0637-0001" num="0000"><ul id="ul0638" list-style="none"><li id="ul0638-0001" num="5156">the Write function is called to write the serial number to M<sub>1 </sub></li><li id="ul0638-0002" num="5157">SetPermission(1) is called for to set that part of M to be ReadOnly for non-authorized writes.</li></ul></li></ul>
5158If adding a consumable value to M<sub>0 </sub>such that only keys 1–2 can update it, and keys 0, and 3-N cannot: <ul id="ul0639" list-style="none"><li id="ul0639-0001" num="0000"><ul id="ul0640" list-style="none"><li id="ul0640-0001" num="5159">the Write function is called to write the amount of consumable to M</li><li id="ul0640-0002" num="5160">SetPermission is called for 0 to set that part of M<sub>0 </sub>to be DecrementOnly for non-authorized writes. This allows the amount of consumable to decrement.</li><li id="ul0640-0003" num="5161">SetPermission is called for n={T, T+3, T+4 . . . , T+N−1} to set that part of M<sub>0 </sub>to be ReadOnly for authorized writes using all but keys 1 and 2. This leaves keys 1 and 2 with ReadWrite permissions to M<sub>0</sub>.</li></ul></li></ul>
5162It is possible for someone who knows a key to further restrict other keys, but it is not in anyone's interest to do so.
000010.5 Programming K
5163This section is identical to the multiple key single memory vector (Section 9.5 on page 677). It is repeated here with mention to M<sub>0 </sub>instead of M for CountRemaining.
5164In this case, we have a factory chip (ChipF) connected to a System. The System wants to program the key in another chip (ChipP). System wants to avoid passing the new key to ChipP in the clear, and also wants to avoid the possibility of the key-upgrade message being replayed on another ChipP (even if the user doesn't know the key).
5165The protocol is a simple extension of the single key protocol in that it assumes that ChipF and ChipP already share a secret key K<sub>old</sub>. This key is used to ensure that only a chip that knows K<sub>old </sub>can set K<sub>new</sub>.
5166The protocol requires the following publicly available functions in ChipP: <ul id="ul0641" list-style="none"><li id="ul0641-0001" num="0000"><ul id="ul0642" list-style="none"><li id="ul0642-0001" num="5167">Random<img file="US7165824B2_D0076.tif" /> Returns R (does not advance R).</li><li id="ul0642-0002" num="5168">ReplaceKey[n, X, Y, Z] Replaces K<sub>n </sub>by S<sub>Kn</sub>[R|X|C<sub>3</sub>]⊕Y, advances R, and returns 1 only if S<sub>Kn</sub>[X|Y|C<sub>3</sub>]=Z. Otherwise returns 0. The time taken to calculate signatures and compare values must be identical for all inputs.</li></ul></li></ul>
5169And the following data and functions in ChipF: <ul id="ul0643" list-style="none"><li id="ul0643-0001" num="0000"><ul id="ul0644" list-style="none"><li id="ul0644-0001" num="5170">CountRemaining Part of M<sub>0 </sub>with contains the number of signatures that ChipF is allowed to generate. Decrements with each successful call to GetProgramKey. Permissions in P for this part of M<sub>0 </sub>needs to be ReadOnly once ChipF has been setup. Therefore can only be updated by a ChipS that has authority to perform updates to that part of M<sub>0</sub>.</li><li id="ul0644-0002" num="5171">K<sub>new </sub>The new key to be transferred from ChipF to ChipP. Must not be visible.</li><li id="ul0644-0003" num="5172">SetPartialKey[X,Y] If word X of K<sub>new </sub>has not yet been set, set word X of K<sub>new </sub>to Y and return 1. Otherwise return 0. This function allows K<sub>new </sub>to be programmed in multiple steps, thereby allowing different people or systems to know different parts of the key (but not the whole K<sub>new</sub>). K<sub>new </sub>is stored in ChipF's flash memory. Since there is a small number of ChipFs, it is theoretically not necessary to store the inverse of K<sub>new</sub>, but it is stronger protection to do so.</li><li id="ul0644-0004" num="5173">GetProgramKey[n, X] Advances R<sub>F</sub>, decrements CountRemaining, outputs R<sub>F</sub>, the encrypted key S<sub>Kn</sub>[X|R<sub>F</sub>|C<sub>3</sub>]⊕K<sub>new </sub>and a signature of the first two outputs plus C<sub>3 </sub>if CountRemaining>0. Otherwise outputs 0. The time to calculate the encrypted key & signature must be identical for all inputs.</li></ul></li></ul>
5174To update P's key: <ul id="ul0645" list-style="none"><li id="ul0645-0001" num="5175">a. System calls ChipP's Random function;</li><li id="ul0645-0002" num="5176">b. ChipP returns R<sub>P </sub>to System;</li><li id="ul0645-0003" num="5177">c. System calls ChipF's GetProgramKey function, passing in n1 (the desired key to use) and the result from b;</li><li id="ul0645-0004" num="5178">d. ChipF updates R<sub>F</sub>, then calculates and returns R<sub>F</sub>, S<sub>Kn1</sub>[R<sub>P</sub>|R<sub>F</sub>|C<sub>3</sub>]⊕K<sub>new</sub>, and S<sub>Kn1</sub>[R<sub>F</sub>|S<sub>Kn1</sub>[R<sub>P</sub>|R<sub>F</sub>|C<sub>3</sub>]⊕K<sub>new</sub>|C<sub>3</sub>];</li><li id="ul0645-0005" num="5179">e. If the response from d is not 0, System calls ChipP's ReplaceKey function, passing in n2 (the key to use in ChipP) and the response from d;</li><li id="ul0645-0006" num="5180">f. System checks response from ChipP. If the response is 1, then K<sub>Pn2 </sub>has been correctly updated to K<sub>new</sub>. If the response is 0, K<sub>Pn2 </sub>has not been updated.</li></ul>
5181The choice of n1 and n2 must be such that ChipF's K<sub>n1</sub>=ChipP's K<sub>n2</sub>.
5182The data flow for key updates is shown in <figref idref="DRAWINGS">FIG. 345</figref> below.
5183Note that K<sub>new </sub>is never passed in the open. An attacker could send its own R<sub>P</sub>, but cannot produce S<sub>Kn1</sub>[R<sub>P</sub>|R<sub>F</sub>|C<sub>3</sub>] without K<sub>n1</sub>. The signature based on K<sub>new </sub>is sent to ensure that ChipP will be able to determine if either of the first two parameters have been changed en route.
5184CountRemaining needs to be setup in M<sub>F0 </sub>(including making it ReadOnly in P) before ChipF is programmed with K<sub>P</sub>. ChipF should therefore be programmed to only perform a limited number of GetProgramKey operations (thereby limiting compromise exposure if a ChipF is stolen). An authorized ChipS can be used to update this counter if neccesary (see Section 9.4 on page 673).
000010.5.1 Chicken and Egg
5185As with the single key protocol, for the Program Key protocol to work, both ChipF and ChipP must both know K<sub>old</sub>. Obviously both chips had to be programmed with K<sub>old</sub>, and thus K<sub>old </sub>can be thought of as an older K<sub>new</sub>:K<sub>old </sub>can be placed in chips if another ChipF knows K<sub>older</sub>, and so on.
5186Although this process allows a chain of reprogramming of keys, with each stage secure, at some stage the very first key (K<sub>first</sub>) must be placed in the chips. K<sub>first </sub>is in fact programmed with the chip's microcode at the manufacturing test station as the last step in manufacturing test. K<sub>first </sub>can be a manufacturing batch key, changed for each batch or for each customer etc, and can have as short a life as desired. Compromising K<sub>first </sub>need not result in a complete compromise of the chain of Ks. Depending on reprogramming requirements, K<sub>first </sub>can be the same or different for all K<sub>n</sub>.
000010.5.2 Security Note
5187Different ChipFs should have different R<sub>F </sub>values to prevent K<sub>new </sub>from being determined as follows: The attacker needs 2 ChipFs, both with the same R<sub>F </sub>and K<sub>n </sub>but different values for K<sub>new</sub>. By knowing K<sub>new1 </sub>the attacker can determine K<sub>new2</sub>. The size of R<sub>F </sub>is 2<sup>160</sup>, and assuming a lifespan of approximately 2<sup>32 </sup>Rs, an attacker needs about 2<sup>60 </sup>ChipFs with the same K<sub>n </sub>to locate the correct chip. Given that there are likely to be only hundreds of ChipFs with the same K<sub>n</sub>, this is not a likely attack. The attack can be eliminated completely by making C<sub>3 </sub>different per chip and transmitting it with the new signature.
000011 Summary of Functions for All Protocols
5188All protocol sets, whether single key, multiple key, single M or multiple M, all rely on the same set of functions. The function set is listed here:
000011.1 All Chips
5189Since every chip must act as ChipP, ChipA and potentially ChipU, all chips require the following functions: <ul id="ul0646" list-style="none"><li id="ul0646-0001" num="0000"><ul id="ul0647" list-style="none"><li id="ul0647-0001" num="5190">Random</li><li id="ul0647-0002" num="5191">ReplaceKey</li><li id="ul0647-0003" num="5192">Read</li><li id="ul0647-0004" num="5193">Write</li><li id="ul0647-0005" num="5194">WriteA</li><li id="ul0647-0006" num="5195">SetPermissions <br /> 11.2 ChipT </li></ul></li></ul>
5196Chips that are to be used as ChipT also require: <ul id="ul0648" list-style="none"><li id="ul0648-0001" num="0000"><ul id="ul0649" list-style="none"><li id="ul0649-0001" num="5197">Test <br /> 11.3 ChipS </li></ul></li></ul>
5198Chips that are to be used as ChipS also require either or both of: <ul id="ul0650" list-style="none"><li id="ul0650-0001" num="0000"><ul id="ul0651" list-style="none"><li id="ul0651-0001" num="5199">SignM</li><li id="ul0651-0002" num="5200">SignP <br /> 11.4 ChipF </li></ul></li></ul>
5201Chips that are to be used as ChipF also require: <ul id="ul0652" list-style="none"><li id="ul0652-0001" num="0000"><ul id="ul0653" list-style="none"><li id="ul0653-0001" num="5202">SetPartialKey</li><li id="ul0653-0002" num="5203">GetProgramKey <br /> 12 Remote Upgrades <br /> 12.1 Basic Remote Upgrades </li></ul></li></ul>
5204Regardless of the number of keys and the number of memory vectors, the use of authenticated reads and writes, and of replacing a new key without revealing K<sub>new </sub>or K<sub>old </sub>allows the possibility of remote upgrades of ChipU and ChipP. The upgrade typically involves a remote server and follows two basic steps: <ul id="ul0654" list-style="none"><li id="ul0654-0001" num="5205">a. During the first stage of the upgrade, the remote system authenticates the user's system to ensure the user's system has the setup that it claims to have.</li><li id="ul0654-0002" num="5206">b. During the second stage of the upgrade, the user's system authenticates the remote system to ensure that the upgrade is from a trusted source. <br /> 12.1.1 User Requests Upgrade </li></ul>
5207The user requests that he wants to upgrade. This can be done by running a specific upgrade application on the user's computer, or by visiting a specific website.
000012.1.2 Remote System Gathers Info Securely About User's Current Setup
5208In this step, the remote system determines the current setup for the user. The current setup must be authenticated, to ensure that the user truly has the setup that is claimed. Traditionally, this has been by checking the existence of files, generating checksums from those files, or by getting a serial number from a hardware dongle, although these traditional methods have difficulties since they can be generated locally by “hacked” software.
5209The authenticated read protocol described in Section 8.3 on page 664 can be used to accomplish this step. The use of random numbers has the advantage that the local user cannot capture a successful transaction and play it back on another computer system to fool the remote system.
000012.1.3 Remote System Gives User Choice of Upgrade Possibilities & User Chooses
5210If there is more than one upgrade possibility, the various upgrade options are now presented to the user. The upgrade options could vary based on a number of factors, including, but not limited to: <ul id="ul0655" list-style="none"><li id="ul0655-0001" num="0000"><ul id="ul0656" list-style="none"><li id="ul0656-0001" num="5211">current user setup</li><li id="ul0656-0002" num="5212">user's preference for payment schemes (e.g. single payment vs. multiple payment)</li><li id="ul0656-0003" num="5213">number of other products owned by user</li></ul></li></ul>
5214The user selects an appropriate upgrade and pays if necessary (by some scheme such as via a secure web site). What is important to note here is that the user chooses a specific upgrade and commences the upgrade operation.
000012.1.4 Remote System Sends Upgrade Request to Local System
5215The remote system now instructs the local system to perform the upgrade. However, the local system can only accept an upgrade from the remote system if the remote system is also authenticated. This is effectively an authenticated write. The use of R<sub>U </sub>in the signature prevents the upgrade message from being replayed on another ChipU.
5216If multiple keys are used, and each chip has a unique key, the remote system can use a serial number obtained from the current setup (authenticated by a common key) to lookup the unique key for use in the upgrade. Although the random number provides time varying messages, use of an unknown K that is different for each chip means that collection and examination of messages and their signatures is made even more difficult.
000012.2 OEM Upgrades
5217OEM upgrades are effectively the same as remote upgrades, except that the user interacts with an OEM server for upgrade selection. The OEM server may send sub-requests to the manufacturer's remote server to provide authentication, upgrade availability lists, and base-level pricing information.
5218An additional level of authentication may be incorporated into the protocol to ensure that upgrade requests are coming from the OEM server, and not from a 3rd party. This can readily be incorporated into both authentication steps.
000013 Choice of Signature Function
5219Given that all protocols make use of keyed signature functions, the choice of function is examined here.
5220Table 232 outlines the attributes of the applicable choices (see Section 5.2 on page 629 and Section 5.5 on page 636 for more information). The attributes are phrased so that the attribute is seen as an advantage.
5221<tables id="TABLE-US-00372" num="00372"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="273pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 232</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Attributes of Applicable Signature Functions</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="9"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="28pt" align="center" /><colspec colname="2" colwidth="28pt" align="center" /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="21pt" align="center" /><colspec colname="5" colwidth="35pt" align="center" /><colspec colname="6" colwidth="28pt" align="center" /><colspec colname="7" colwidth="28pt" align="center" /><colspec colname="8" colwidth="28pt" align="center" /><tbody valign="top"><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>HMAC-</entry></row><row><entry /><entry>Triple</entry><entry>Blow-</entry><entry /><entry /><entry>Random</entry><entry>HMAC-</entry><entry>HMAC-</entry><entry>RIPEM</entry></row><row><entry /><entry>DES</entry><entry>fish</entry><entry>RC5</entry><entry>IDEA</entry><entry>Sequences</entry><entry>MD5</entry><entry>SHA1</entry><entry>D160</entry></row><row><entry /><entry namest="offset" nameend="8" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="9"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="28pt" align="center" /><colspec colname="3" colwidth="28pt" align="center" /><colspec colname="4" colwidth="21pt" align="char" char="." /><colspec colname="5" colwidth="21pt" align="char" char="." /><colspec colname="6" colwidth="35pt" align="center" /><colspec colname="7" colwidth="28pt" align="center" /><colspec colname="8" colwidth="28pt" align="center" /><colspec colname="9" colwidth="28pt" align="center" /><tbody valign="top"><row><entry>Free of patents</entry><entry>•</entry><entry>•</entry><entry /><entry /><entry>•</entry><entry>•</entry><entry>•</entry><entry>•</entry></row><row><entry>Random key</entry><entry /><entry /><entry /><entry /><entry /><entry>•</entry><entry>•</entry><entry>•</entry></row><row><entry>generation</entry></row><row><entry>Can be exported</entry><entry /><entry /><entry /><entry /><entry>•</entry><entry>•</entry><entry>•</entry><entry>•</entry></row><row><entry>from the USA</entry></row><row><entry>Fast</entry><entry /><entry>•</entry><entry /><entry /><entry /><entry>•</entry><entry>•</entry><entry>•</entry></row><row><entry>Preferred Key</entry><entry>168<sup>1</sup></entry><entry>128</entry><entry>128</entry><entry>128</entry><entry>512</entry><entry>128</entry><entry>160</entry><entry>160</entry></row><row><entry>Size (bits) for</entry></row><row><entry>use in this</entry></row><row><entry>application</entry></row><row><entry>Block size (bits)</entry><entry> 64<sup> </sup></entry><entry>64</entry><entry>64</entry><entry>64</entry><entry>256</entry><entry>512</entry><entry>512</entry><entry>512</entry></row><row><entry>Cryptanalysis</entry><entry>•</entry><entry>•</entry><entry /><entry /><entry>•</entry><entry /><entry>•</entry><entry>•</entry></row><row><entry>Attack-Free</entry></row><row><entry>(apart from</entry></row><row><entry>weak keys)</entry></row><row><entry>Output size given</entry><entry>≧N</entry><entry>≧N</entry><entry>≧N</entry><entry>≧N</entry><entry>128</entry><entry>128</entry><entry>160</entry><entry>160</entry></row><row><entry>input size N</entry></row><row><entry>Low storage</entry><entry /><entry /><entry /><entry /><entry>•</entry><entry>•</entry><entry>•</entry><entry>•</entry></row><row><entry>requirements</entry></row><row><entry>Low silicon</entry><entry /><entry /><entry /><entry /><entry>•</entry><entry>•</entry><entry>•</entry><entry>•</entry></row><row><entry>complexity</entry></row><row><entry>NSA designed</entry><entry>•</entry><entry /><entry /><entry /><entry /><entry /><entry>•</entry></row><row><entry namest="1" nameend="9" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
5222An examination of Table 232 shows that the choice is effectively between the 3 HMAC constructs and the Random Sequence. The problem of key size and key generation eliminates the Random Sequence. Given that a number of attacks have already been carried out on MD5 and since the hash result is only 128 bits, HMAC-MD5 is also eliminated. The choice is therefore between HMAC-SHA1 and HMAC-RIPEMD160. Of these, SHA-1 is the preferred function, since: <ul id="ul0657" list-style="none"><li id="ul0657-0001" num="0000"><ul id="ul0658" list-style="none"><li id="ul0658-0001" num="5223">SHA-1 has been more extensively cryptanalyzed without being broken;</li><li id="ul0658-0002" num="5224">SHA-1 requires slightly less intermediate storage than RIPE-MD-160;</li><li id="ul0658-0003" num="5225">SHA-1 is algorithmically less complex than RIPE-MD-160;</li></ul></li></ul>
5226Although SHA-1 is slightly faster than RIPE-MD-160, this was not a reason for choosing SHA-1.
13.1 HMAC-SHA1
5227The mechanism for authentication is the HMAC-SHA1 algorithm. This section examines the HMAC-SHA1 algorithm in greater detail than covered so far, and describes an optimization of the algorithm that requires fewer memory resources than the original definition.
13.1.1 HMAC
5228Given the following definitions: <ul id="ul0659" list-style="none"><li id="ul0659-0001" num="0000"><ul id="ul0660" list-style="none"><li id="ul0660-0001" num="5229">H=the hash function (e.g. MD5 or SHA-1)</li><li id="ul0660-0002" num="5230">n=number of bits output from H (e.g. 160 for SHA-1, 128 bits for MD5)</li><li id="ul0660-0003" num="5231">M=the data to which the MAC function is to be applied</li><li id="ul0660-0004" num="5232">K=the secret key shared by the two parties</li><li id="ul0660-0005" num="5233">ipad=0x36 repeated 64 times</li><li id="ul0660-0006" num="5234">opad=0x5C repeated 64 times</li></ul></li></ul>
5235The HMAC algorithm is as follows: <ul id="ul0661" list-style="none"><li id="ul0661-0001" num="5236">a. Extend K to 64 bytes by appending 0×00 bytes to the end of K</li><li id="ul0661-0002" num="5237">b. XOR the 64 byte string created in (1) with ipad</li><li id="ul0661-0003" num="5238">c. append data stream M to the 64 byte string created in (2)</li><li id="ul0661-0004" num="5239">d. Apply H to the stream generated in (3)</li><li id="ul0661-0005" num="5240">e. XOR the 64 byte string created in (1) with opad</li><li id="ul0661-0006" num="5241">f. Append the H result from (4) to the 64 byte string resulting from (5)</li><li id="ul0661-0007" num="5242">g. Apply H to the output of (6) and output the result</li></ul>
5243Thus: <br /><i>HMAC[M]=H</i>[(<i>K⊕opad</i>)|<i>H</i>[(<i>K⊕ipad</i>)|<i>M]]</i><ul id="ul0662" list-style="none"><li id="ul0662-0001" num="0000"><ul id="ul0663" list-style="none"><li id="ul0663-0001" num="5244">The HMAC-SHA1 algorithm is simply HMAC with H=SHA-1. <br /> 13.1.2 SHA-1 </li></ul></li></ul>
5245The SHA1 hashing algorithm is described in the context of other hashing algorithms in Section 5.5.3.3 on page 640, and completely defined in [28]. The algorithm is summarized here.
5246Nine 32-bit constants are defined in Table 233. There are 5 constants used to initialize the chaining variables, and there are 4 additive constants.
5247<tables id="TABLE-US-00373" num="00373"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 233</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Constants used in SHA-1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="91pt" align="center" /><colspec colname="2" colwidth="14pt" align="center" /><colspec colname="3" colwidth="84pt" align="center" /><colspec colname="4" colwidth="14pt" align="center" /><tbody valign="top"><row><entry /><entry>Initial Chaining Values</entry><entry /><entry>Additive Constants</entry><entry /></row><row><entry /><entry namest="offset" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="35pt" align="left" /><colspec colname="4" colwidth="63pt" align="left" /><tbody valign="top"><row><entry /><entry>h<sub>1</sub></entry><entry>0x67452301</entry><entry>y<sub>1</sub></entry><entry>0x5A827999</entry></row><row><entry /><entry>h<sub>2</sub></entry><entry>0xEFCDAB89</entry><entry>y<sub>2</sub></entry><entry>0x6ED9EBA1</entry></row><row><entry /><entry>h<sub>3</sub></entry><entry>0x98BADCFE</entry><entry>y<sub>3</sub></entry><entry>0x8F1BBCDC</entry></row><row><entry /><entry>h<sub>4</sub></entry><entry>0x10325476</entry><entry>y<sub>4</sub></entry><entry>0xCA62C1D6</entry></row><row><entry /><entry>h<sub>5</sub></entry><entry>0xC3D2E1F0</entry></row><row><entry /><entry namest="offset" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
5248Non-optimized SHA-1 requires a total of 2912 bits of data storage: <ul id="ul0664" list-style="none"><li id="ul0664-0001" num="0000"><ul id="ul0665" list-style="none"><li id="ul0665-0001" num="5249">Five 32-bit chaining variables are defined: H<sub>1</sub>, H<sub>2</sub>, H<sub>3</sub>, H<sub>4 </sub>and H<sub>5</sub>.</li><li id="ul0665-0002" num="5250">Five 32-bit working variables are defined: A, B, C, D, and E.</li><li id="ul0665-0003" num="5251">One 32-bit temporary variable is defined: t.</li><li id="ul0665-0004" num="5252">Eighty 32-bit temporary registers are defined: X<sub>0-79</sub>.</li></ul></li></ul>
5253The following functions are defined for SHA-1:
5254<tables id="TABLE-US-00374" num="00374"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 234</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Functions used in SHA-1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>Symbolic</entry><entry /></row><row><entry /><entry>Nomenclature</entry><entry>Description</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>+</entry><entry>Addition modulo 2<sup>32</sup></entry></row><row><entry /><entry>X <img file="US7165824B2_D0077.tif" /> Y</entry><entry>Result of rotating X left through Y bit positions</entry></row><row><entry /><entry>f(X, Y, Z)</entry><entry>(X <img file="US7165824B2_D0078.tif" /> Y) <img file="US7165824B2_D0079.tif" /> (<img file="US7165824B2_D0080.tif" /> X <img file="US7165824B2_D0081.tif" /> Z)</entry></row><row><entry /><entry>g(X, Y, Z)</entry><entry>(X <img file="US7165824B2_D0082.tif" /> Y) <img file="US7165824B2_D0083.tif" /> (X <img file="US7165824B2_D0084.tif" /> Z) <img file="US7165824B2_D0085.tif" /> (Y <img file="US7165824B2_D0086.tif" /> Z)</entry></row><row><entry /><entry>h(X, Y, Z)</entry><entry>X ⊕ Y ⊕ Z</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
5255The hashing algorithm consists of firstly padding the input message to be a multiple of 512 bits and initializing the chaining variables H<sub>1-5 </sub>with h<sub>1-5</sub>. The padded message is then processed in 512-bit chunks, with the output hash value being the final 160-bit value given by the concatenation of the chaining variables: H<sub>1</sub>|H<sub>2</sub>|H<sub>3</sub>|H<sub>4</sub>|H<sub>5</sub>.
5256The steps of the SHA-1 algorithm are now examined in greater detail.
000013.1.2.1 Step 1. Preprocessing
5257The first step of SHA-1 is to pad the input message to be a multiple of 512 bits as follows and to initialize the chaining variables.
5258<tables id="TABLE-US-00375" num="00375"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 235</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Steps to follow to preprocess the input message</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="140pt" align="left" /><tbody valign="top"><row><entry>Pad the input message</entry><entry>Append a 1 bit to the message</entry></row><row><entry /><entry>Append 0 bits such that the length of the</entry></row><row><entry /><entry>padded message is 64-bits short of a multiple</entry></row><row><entry /><entry>of 512 bits.</entry></row><row><entry /><entry>Append a 64-bit value containing the length in</entry></row><row><entry /><entry>bits of the original input message. Store the</entry></row><row><entry /><entry>length as most significant bit through to least</entry></row><row><entry /><entry>significant bit.</entry></row><row><entry>Initialize the chaining</entry><entry>H<sub>1 </sub><img file="US7165824B2_D0087.tif" /> h<sub>1</sub>, H<sub>2 </sub><img file="US7165824B2_D0088.tif" /> h<sub>2</sub>, H<sub>3 </sub><img file="US7165824B2_D0089.tif" /> h<sub>3</sub>, H<sub>4 </sub><img file="US7165824B2_D0090.tif" /> h<sub>4</sub>,</entry></row><row><entry>variables</entry><entry>H<sub>5 </sub><img file="US7165824B2_D0091.tif" /> h<sub>5</sub></entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 13.1.2.2 Step 2. Processing
5259The padded input message is processed in 512-bit blocks. Each 512-bit block is in the form of 16×32-bit words, referred to as InputWord<sub>0-15</sub>.
5260<tables id="TABLE-US-00376" num="00376"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 236</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Steps to follow for each 512 bit block (InputWord<sub>0–15</sub>)</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>Copy the 512</entry><entry>For j = 0 to 15</entry></row><row><entry /><entry>input bits</entry><entry>X<sub>j </sub>= InputWord<sub>j</sub></entry></row><row><entry /><entry>into X<sub>0–15</sub></entry></row><row><entry /><entry>Expand X<sub>0–15</sub></entry><entry>For j = 16 to 79</entry></row><row><entry /><entry>into X<sub>16–79</sub></entry><entry>X<sub>j </sub><img file="US7165824B2_D0092.tif" /> ((X<sub>j−3 </sub>⊕ X<sub>j−8 </sub>⊕ X<sub>j−14 </sub>⊕ X<sub>j−16</sub>) <img file="US7165824B2_D0093.tif" /> 1)</entry></row><row><entry /><entry>Initialize</entry><entry>A <img file="US7165824B2_D0094.tif" /> H<sub>1</sub>, B <img file="US7165824B2_D0095.tif" /> H<sub>2</sub>, C <img file="US7165824B2_D0096.tif" /> H<sub>3</sub>, D <img file="US7165824B2_D0097.tif" /> H<sub>4</sub>,</entry></row><row><entry /><entry>working</entry><entry>E <img file="US7165824B2_D0098.tif" /> H<sub>5</sub></entry></row><row><entry /><entry>variables</entry></row><row><entry /><entry>Round 1</entry><entry>For j = 0 to 19</entry></row><row><entry /><entry /><entry>t <img file="US7165824B2_D0099.tif" /> ((A <img file="US7165824B2_D0100.tif" /> 5) + f(B, C, D) + E + Xj + y<sub>1</sub>)</entry></row><row><entry /><entry /><entry>E <img file="US7165824B2_D0101.tif" /> D, D <img file="US7165824B2_D0102.tif" /> C, C <img file="US7165824B2_D0103.tif" /> (B <img file="US7165824B2_D0104.tif" /> 30), B <img file="US7165824B2_D0105.tif" /> A,</entry></row><row><entry /><entry /><entry>A <img file="US7165824B2_D0106.tif" /> t</entry></row><row><entry /><entry>Round 2</entry><entry>For j = 20 to 39</entry></row><row><entry /><entry /><entry>t <img file="US7165824B2_D0107.tif" /> ((A <img file="US7165824B2_D0108.tif" /> 5) + h(B, C, D) + E + Xj + y<sub>2</sub>)</entry></row><row><entry /><entry /><entry>E <img file="US7165824B2_D0109.tif" /> D, D <img file="US7165824B2_D0110.tif" /> C, C <img file="US7165824B2_D0111.tif" /> (B <img file="US7165824B2_D0112.tif" /> 30), B <img file="US7165824B2_D0113.tif" /> A,</entry></row><row><entry /><entry /><entry>A <img file="US7165824B2_D0114.tif" /> t</entry></row><row><entry /><entry>Round 3</entry><entry>For j = 40 to 59</entry></row><row><entry /><entry /><entry>t <img file="US7165824B2_D0115.tif" /> ((A <img file="US7165824B2_D0116.tif" /> 5) + g(B, C, D) + E + Xj + y<sub>3</sub>)</entry></row><row><entry /><entry /><entry>E <img file="US7165824B2_D0117.tif" /> D, D <img file="US7165824B2_D0118.tif" /> C, C <img file="US7165824B2_D0119.tif" /> (B <img file="US7165824B2_D0120.tif" /> 30), B <img file="US7165824B2_D0121.tif" /> A,</entry></row><row><entry /><entry /><entry>A <img file="US7165824B2_D0122.tif" /> t</entry></row><row><entry /><entry>Round 4</entry><entry>For j = 60 to 79</entry></row><row><entry /><entry /><entry>t <img file="US7165824B2_D0123.tif" /> ((A <img file="US7165824B2_D0124.tif" /> 5) + h(B, C, D) + E + Xj + y<sub>4</sub>)</entry></row><row><entry /><entry /><entry>E <img file="US7165824B2_D0125.tif" /> D, D <img file="US7165824B2_D0126.tif" /> C, C <img file="US7165824B2_D0127.tif" /> (B <img file="US7165824B2_D0128.tif" /> 30), B <img file="US7165824B2_D0129.tif" /> A,</entry></row><row><entry /><entry /><entry>A <img file="US7165824B2_D0130.tif" /> t</entry></row><row><entry /><entry>Update chaining</entry><entry>H<sub>1 </sub><img file="US7165824B2_D0131.tif" /> H<sub>1 </sub>+ A, H<sub>2 </sub><img file="US7165824B2_D0132.tif" /> H<sub>2 </sub>+ B,</entry></row><row><entry /><entry>variables</entry><entry>H<sub>3 </sub><img file="US7165824B2_D0133.tif" /> H<sub>3 </sub>+ C, H<sub>4 </sub><img file="US7165824B2_D0134.tif" /> H<sub>4 </sub>+ D,</entry></row><row><entry /><entry /><entry>H<sub>5 </sub><img file="US7165824B2_D0135.tif" /> H<sub>5 </sub>+ E</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
5261The bold text is to emphasize the differences between each round.
000013.1.2.3 Step 3. Completion
5262After all the 512-bit blocks of the padded input message have been processed, the output hash value is the final 160-bit value given by: H<sub>1</sub>|H<sub>2</sub>|H<sub>3</sub>|H<sub>4</sub>|H<sub>5</sub>.
000013.1.2.4 Optimization for Hardware Implementation
5263The SHA-1 Step 2 procedure is not optimized for hardware. In particular, the 80 temporary 32-bit registers use up valuable silicon on a hardware implementation. This section describes an optimization to the SHA-1 algorithm that only uses 16 temporary registers. The reduction in silicon is from 2560 bits down to 512 bits, a saving of over 2000 bits. It may not be important in some applications, but in the QA Chip storage space must be reduced where possible.
5264The optimization is based on the fact that although the original 16-word message block is expanded into an 80-word message block, the 80 words are not updated during the algorithm. In addition, the words rely on the previous 16 words only, and hence the expanded words can be calculated on-the-fly during processing, as long as we keep 16 words for the backward references. We require rotating counters to keep track of which register we are up to using, but the effect is to save a large amount of storage.
5265Rather than index X by a single value j, we use a 5 bit counter to count through the iterations. This can be achieved by initializing a 5-bit register with either 16 or 20, and decrementing it until it reaches 0. In order to update the 16 temporary variables as if they were 80, we require 4 indexes, each a 4-bit register. All 4 indexes increment (with wraparound) during the course of the algorithm.
5266<tables id="TABLE-US-00377" num="00377"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 237</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Optimised Steps to follow for each 512 bit block (InputWord<sub>0–15</sub>)</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>Initialize working</entry><entry>A <img file="US7165824B2_D0136.tif" /> H<sub>1</sub>, B <img file="US7165824B2_D0137.tif" /> H<sub>2</sub>, C <img file="US7165824B2_D0138.tif" /> H<sub>3</sub>, D <img file="US7165824B2_D0139.tif" /> H<sub>4</sub>,</entry></row><row><entry /><entry>variables</entry><entry>E <img file="US7165824B2_D0140.tif" /> H<sub>5</sub></entry></row><row><entry /><entry /><entry>N<sub>1 </sub><img file="US7165824B2_D0141.tif" /> 13, N<sub>2 </sub><img file="US7165824B2_D0142.tif" /> 8, N<sub>3 </sub><img file="US7165824B2_D0143.tif" /> 2, N<sub>4 </sub><img file="US7165824B2_D0144.tif" /> 0</entry></row><row><entry /><entry>Round 0</entry><entry>Do 16 times</entry></row><row><entry /><entry>Copy the 512</entry><entry>X<sub>N4 </sub>= InputWord<sub>N4</sub></entry></row><row><entry /><entry>input bits into</entry><entry>[<img file="US7165824B2_D0145.tif" /> N<sub>1</sub>, <img file="US7165824B2_D0146.tif" /> N<sub>2</sub>, <img file="US7165824B2_D0147.tif" /> N<sub>3</sub>]<sub>optional </sub><img file="US7165824B2_D0148.tif" /> N<sub>4</sub></entry></row><row><entry /><entry>X<sub>0–15</sub></entry></row><row><entry /><entry>Round 1A</entry><entry>Do 16 times</entry></row><row><entry /><entry /><entry>t <img file="US7165824B2_D0149.tif" /> ((A <img file="US7165824B2_D0150.tif" /> 5) + f(B, C, D) + E + X<sub>N4 </sub>+ y<sub>1</sub>)</entry></row><row><entry /><entry /><entry>[<img file="US7165824B2_D0151.tif" /> N<sub>1</sub>, <img file="US7165824B2_D0152.tif" /> N<sub>2</sub>, <img file="US7165824B2_D0153.tif" /> N<sub>3</sub>]<sub>optional </sub><img file="US7165824B2_D0154.tif" /> N<sub>4</sub></entry></row><row><entry /><entry /><entry>E <img file="US7165824B2_D0155.tif" /> D, D <img file="US7165824B2_D0156.tif" /> C, C <img file="US7165824B2_D0157.tif" /> (B <img file="US7165824B2_D0158.tif" /> 30), B <img file="US7165824B2_D0159.tif" /> A,</entry></row><row><entry /><entry /><entry>A <img file="US7165824B2_D0160.tif" /> t</entry></row><row><entry /><entry>Round 1B</entry><entry>Do 4 times</entry></row><row><entry /><entry /><entry>X<sub>N4 </sub><img file="US7165824B2_D0161.tif" /> ((X<sub>N1 </sub>⊕ X<sub>N2 </sub>⊕ X<sub>N3 </sub>⊕ X<sub>N4</sub>) <img file="US7165824B2_D0162.tif" /> 1)</entry></row><row><entry /><entry /><entry>t <img file="US7165824B2_D0163.tif" /> ((A <img file="US7165824B2_D0164.tif" /> 5) + f(B, C, D) + E + X<sub>N4 </sub>+ y<sub>1</sub>)</entry></row><row><entry /><entry /><entry><img file="US7165824B2_D0165.tif" /> N<sub>1</sub>, <img file="US7165824B2_D0166.tif" /> N<sub>2</sub>, <img file="US7165824B2_D0167.tif" /> N<sub>3</sub>, <img file="US7165824B2_D0168.tif" /> N<sub>4</sub></entry></row><row><entry /><entry /><entry>E <img file="US7165824B2_D0169.tif" /> D, D <img file="US7165824B2_D0170.tif" /> C, C <img file="US7165824B2_D0171.tif" /> (B <img file="US7165824B2_D0172.tif" /> 30), B <img file="US7165824B2_D0173.tif" /> A,</entry></row><row><entry /><entry /><entry>A <img file="US7165824B2_D0174.tif" /> t</entry></row><row><entry /><entry>Round 2</entry><entry>Do 20 times</entry></row><row><entry /><entry /><entry>X<sub>N4 </sub><img file="US7165824B2_D0175.tif" /> ((X<sub>N1 </sub>⊕ X<sub>N2 </sub>⊕ X<sub>N3 </sub>⊕ X<sub>N4</sub>) <img file="US7165824B2_D0176.tif" /> 1)</entry></row><row><entry /><entry /><entry>t <img file="US7165824B2_D0177.tif" /> ((A <img file="US7165824B2_D0178.tif" /> 5) + h(B, C, D) + E + X<sub>N4 </sub>+ y<sub>2</sub>)</entry></row><row><entry /><entry /><entry><img file="US7165824B2_D0179.tif" /> N<sub>1</sub>, <img file="US7165824B2_D0180.tif" /> N<sub>2</sub>, <img file="US7165824B2_D0181.tif" /> N<sub>3</sub>, <img file="US7165824B2_D0182.tif" /> N<sub>4</sub></entry></row><row><entry /><entry /><entry>E <img file="US7165824B2_D0183.tif" /> D, D <img file="US7165824B2_D0184.tif" /> C, C <img file="US7165824B2_D0185.tif" /> (B <img file="US7165824B2_D0186.tif" /> 30), B <img file="US7165824B2_D0187.tif" /> A,</entry></row><row><entry /><entry /><entry>A <img file="US7165824B2_D0188.tif" /> t</entry></row><row><entry /><entry>Round 3</entry><entry>Do 20 times</entry></row><row><entry /><entry /><entry>X<sub>N4 </sub><img file="US7165824B2_D0189.tif" /> ((X<sub>N1 </sub>⊕ X<sub>N2 </sub>⊕ X<sub>N3 </sub>⊕ X<sub>N4</sub>) <img file="US7165824B2_D0190.tif" /> 1)</entry></row><row><entry /><entry /><entry>t <img file="US7165824B2_D0191.tif" /> ((A <img file="US7165824B2_D0192.tif" /> 5) + g(B, C, D) + E + X<sub>N4 </sub>+ y<sub>3</sub>)</entry></row><row><entry /><entry /><entry><img file="US7165824B2_D0193.tif" /> N<sub>1</sub>, <img file="US7165824B2_D0194.tif" /> N<sub>2</sub>, <img file="US7165824B2_D0195.tif" /> N<sub>3</sub>, <img file="US7165824B2_D0196.tif" /> N<sub>4</sub></entry></row><row><entry /><entry /><entry>E <img file="US7165824B2_D0197.tif" /> D, D <img file="US7165824B2_D0198.tif" /> C, C <img file="US7165824B2_D0199.tif" /> (B <img file="US7165824B2_D0200.tif" /> 30), B <img file="US7165824B2_D0201.tif" /> A,</entry></row><row><entry /><entry /><entry>A <img file="US7165824B2_D0202.tif" /> t</entry></row><row><entry /><entry>Round 4</entry><entry>Do 20 times</entry></row><row><entry /><entry /><entry>X<sub>N4 </sub><img file="US7165824B2_D0203.tif" /> ((X<sub>N1 </sub>⊕ X<sub>N2 </sub>⊕ X<sub>N3 </sub>⊕ X<sub>N4</sub>) <img file="US7165824B2_D0204.tif" /> 1)</entry></row><row><entry /><entry /><entry>t <img file="US7165824B2_D0205.tif" /> ((A <img file="US7165824B2_D0206.tif" /> 5) + h(B, C, D) + E + X<sub>N4 </sub>+ y<sub>4</sub>)</entry></row><row><entry /><entry /><entry><img file="US7165824B2_D0207.tif" /> N<sub>1</sub>, <img file="US7165824B2_D0208.tif" /> N<sub>2</sub>, <img file="US7165824B2_D0209.tif" /> N<sub>3</sub>, <img file="US7165824B2_D0210.tif" /> N<sub>4</sub></entry></row><row><entry /><entry /><entry>E <img file="US7165824B2_D0211.tif" /> D, D <img file="US7165824B2_D0212.tif" /> C, C <img file="US7165824B2_D0213.tif" /> (B <img file="US7165824B2_D0214.tif" /> 30), B <img file="US7165824B2_D0215.tif" /> A,</entry></row><row><entry /><entry /><entry>A <img file="US7165824B2_D0216.tif" /> t</entry></row><row><entry /><entry>Update chaining</entry><entry>H<sub>1 </sub><img file="US7165824B2_D0217.tif" /> H<sub>1 </sub>+ A, H<sub>2 </sub><img file="US7165824B2_D0218.tif" /> H<sub>2 </sub>+ B,</entry></row><row><entry /><entry>variables</entry><entry>H<sub>3 </sub><img file="US7165824B2_D0219.tif" /> H<sub>3 </sub>+ C, H<sub>4 </sub><img file="US7165824B2_D0220.tif" /> H<sub>4 </sub>+ D,</entry></row><row><entry /><entry /><entry>H<sub>5 </sub><img file="US7165824B2_D0221.tif" /> H<sub>5 </sub>+ E</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
5267The bold text is to emphasize the differences between each round.
5268The incrementing of N<sub>1</sub>, N<sub>2</sub>, and N<sub>3 </sub>during Rounds 0 and 1A is optional. A software implementation would not increment them, since it takes time, and at the end of the 16 times through the loop, all 4 counters will be their original values. Designers of hardware may wish to increment all 4 counters together to save on control logic.
5269Round 0 can be completely omitted if the caller loads the 512 bits of X<sub>0-15</sub>.
000014 Holding Out Against Attacks
5270The authentication protocols described in Section 7 on page 661 onward should be resistant to defeat by logical means. This section details each type of attack in turn with reference to the Read Authentication protocol.
000014.1 Brute Force Attack
5271A brute force attack is guaranteed to break any protocol. However the length of the key means that the time for an attacker to perform a brute force attack is too long to be worth the effort.
5272An attacker only needs to break K to build a clone authentication chip. A brute force attack on K must therefore break a 160-bit key.
5273An attack against K requires a maximum of 2<sup>160 </sup>attempts, with a 50% chance of finding the key after only 2<sup>159 </sup>attempts. Assuming an array of a trillion processors, each running one million tests per second, 2<sup>159 </sup>(7.3×10<sup>47</sup>) tests takes 2.3×10<sup>22 </sup>years, which is longer than the total lifetime of the universe. There are around 100 million personal computers in the world. Even if these were all connected in an attack (e.g. via the Internet), this number is still 10,000 times smaller than the trillion-processor attack described. Further, if the manufacture of one trillion processors becomes a possibility in the age of nanocomputers, the time taken to obtain the key is still longer than the total lifetime of the universe.
000014.2 Guessing the Key Attack
5274It is theoretically possible that an attacker can simply “guess the key”. In fact, given enough time, and trying every possible number, an attacker will obtain the key. This is identical to the brute force attack described above, where 2<sup>159 </sup>attempts must be made before a 50% chance of success is obtained.
5275The chances of someone simply guessing the key on the first try is 2<sup>160</sup>. For comparison, the chance of someone winning the top prize in a U.S. state lottery and being killed by lightning in the same day is only 1 in 2<sup>61 </sup>78]. The chance of someone guessing the authentication chip key on the first go is 1 in 2<sup>160</sup>, which is comparable to two people choosing exactly the same atoms from a choice of all the atoms in the Earth i.e. extremely unlikely.
000014.3 Quantum Computer Attack
5276To break K, a quantum computer containing 160 qubits embedded in an appropriate algorithm must be built. As described in Section 5.7.1.7 on page 648, an attack against a 160-bit key is not feasible. An outside estimate of the possibility of quantum computers is that 50 qubits may be achievable within 50 years. Even using a 50 qubit quantum computer, 2<sup>110 </sup>tests are required to crack a 160 bit key. Assuming an array of 1 billion 50 qubit quantum computers, each able to try 2<sup>50 </sup>keys in 1 microsecond (beyond the current wildest estimates) finding the key would take an average of 18 billion years.
000014.4 Ciphertext Only Attack
5277An attacker can launch a ciphertext only attack on K by monitoring calls to Random and Read. However, given that all these calls also reveal the plaintext as well as the hashed form of the plaintext, the attack would be transformed into a stronger form of attack—a known plaintext attack.
000014.5 Known Plaintext Attack
5278It is easy to connect a logic analyzer to the connection between the System and the authentication chip, and thereby monitor the flow of data. This flow of data results in known plaintext and the hashed form of the plaintext, which can therefore be used to launch a known plaintext attack against K.
5279To launch an attack against K, multiple calls to Random and Test must be made (with the call to Test being successful, and therefore requiring a call to Read on a valid chip). This is straightforward, requiring the attacker to have both a system authentication chip and a consumable authentication chip. For each set of calls, an X, S<sub>K</sub>[X] pair is revealed. The attacker must collect these pairs for further analysis.
5280The question arises of how many pairs must be collected for a meaningful attack to be launched with this data. An example of an attack that requires collection of data for statistical analysis is differential cryptanalysis (see Section 14.13 on page 703). However, there are no known attacks against SHA-1 or HMAC-SHA1 [7][7][7], so there is no use for the collected data at this time.
000014.6 Chosen Plaintext Attacks
5281The golden rule for the QA Chip is that it never signs something that is simply given to it—i.e. it never lets the user choose the message that is signed.
5282Although the attacker can choose both R<sub>T </sub>and possibly M, ChipA advances its random number R<sub>A </sub>with each call to Read. The resultant message X therefore contains 160 bits of changing data each call that are not chosen by the attacker.
5283To launch a chosen text attack the attacker would need to locate a chip whose R was the desired R. This makes the search effectively impossible.
000014.7 Adaptive Chosen Plaintext Attacks
5284The HMAC construct provides security against all forms of chosen plaintext attacks [7]. This is primarily because the HMAC construct has 2 secret input variables (the result of the original hash, and the secret key). Thus finding collisions in the hash function itself when the input variable is secret is even harder than finding collisions in the plain hash function. This is because the former requires direct access to SHA-1 in order to generate pairs of input/output from SHA-1.
5285Since R changes with each call to Read, the user cannot choose the complete message. The only value that can be collected by an attacker is HMAC[R<sub>1</sub>|R<sub>2</sub>|M<sub>2</sub>]. These are not attacks against the SHA-1 hash function itself, and reduce the attack to a differential cryptanalysis attack (see Section 14.13 on page 703), examining statistical differences between collected data. Given that there is no differential cryptanalysis attack known against SHA-1 or HMAC, the protocols are resistant to the adaptive chosen plaintext attacks.
000014.8 Purposeful Error Attack
5286An attacker can only launch a purposeful error attack on the Test function, since this is the only function in the Read protocol that validates input against the keys.
5287With the Test function, a 0 value is produced if an error is found in the input—no further information is given. In addition, the time taken to produce the 0 result is independent of the input, giving the attacker no information about which bit(s) were wrong.
5288A purposeful error attack is therefore fruitless.
000014.9 Chaining Attack
5289Any form of chaining attack assumes that the message to be hashed is over several blocks, or the input variables can somehow be set. The HMAC-SHA1 algorithm used by Protocol C1 only ever hashes one or two 512-bit blocks. Chaining attacks are not possible when only one block is used, and are extremely limited when two blocks are used.
000014.10 Birthday Attack
5290The strongest attack known against HMAC is the birthday attack, based on the frequency of collisions for the hash function [7][7]. However this is totally impractical for minimally reasonable hash functions such as SHA-1. And the birthday attack is only possible when the attacker has control over the message that is hashed.
5291Since in the protocols described for the QA Chip, the message to be signed is never chosen by the attacker (at least one 160-bit R value is chosen by the chip doing the signing), the attacker has no control over the message that is hashed. An attacker must instead search for a collision message that hashes to the same value (analogous to finding one person who shares your birthday).
5292The clone chip must therefore attempt to find a new value R<sub>2 </sub>such that the hash of R<sub>1</sub>, R<sub>2 </sub>and a chosen M<sub>2 </sub>yields the same hash value as H[R<sub>1</sub>|R<sub>2</sub>|M]. However ChipT does not reveal the correct hash value (the Test function only returns 1 or 0 depending on whether the hash value is correct). Therefore the only way of finding out the correct hash value (in order to find a collision) is to interrogate a real ChipA. But to find the correct value means to update M, and since the decrement-only parts of M are one-way, and the read-only parts of M cannot be changed, a clone consumable would have to update a real consumable before attempting to find a collision. The alternative is a brute force attack search on the Test function to find a success (requiring each clone consumable to have access to a System consumable). A brute force search, as described above, takes longer than the lifetime of the universe, in this case, per authentication.
5293There is no point for a clone consumable to launch this kind of attack.
000014.11 Substitution with a Complete Lookup Table
5294The random number seed in each System is 160 bits. The best case situation for an attacker is that no state data has been changed. Assuming also that the clone consumable does not advance its R, there is a constant value returned as M. A clone chip must therefore return S<sub>K</sub>[R|c] (where c is a constant), which is a 160 bit value.
5295Assuming a 160-bit lookup of a 160-bit result, this requires 2.9×10<sup>49 </sup>bytes, or 2.6×10<sup>37 </sup>terabytes, certainly more space than is feasible for the near future. This of course does not even take into account the method of collecting the values for the ROM. A complete lookup table is therefore completely impossible.
000014.12 Substitution with a Sparse Lookup Table
5296A sparse lookup table is only feasible if the messages sent to the authentication chip are somehow predictable, rather than effectively random.
5297The random number R is seeded with an unknown random number, gathered from a naturally System authentication chip's Random function, and iterating some random event. There is no possibility for a clone manufacturer to know what the possible range of R is for all Systems, since each bit has an unrelated chance of being 1 or 0.
5298Since the range of R in all systems is unknown, it is not possible to build a sparse lookup table that can be used in all systems. The general sparse lookup table is therefore not a possible attack.
5299However, it is possible for a clone manufacturer to know what the range of R is for a given System. This can be accomplished by loading a LFSR with the current result from a call to a specific number of times into the future. If this is done, a special ROM can be built which will only contain the responses for that particular range of R, i.e. a ROM specifically for the consumables of that particular System. But the attacker still needs to place correct information in the ROM. The attacker will therefore need to find a valid authentication chip and call it for each of the values in R. Suppose the clone authentication chip reports a full consumable, and then allows a single use before simulating loss of connection and insertion of a new full consumable. The clone consumable would therefore need to contain responses for authentication of a full consumable and authentication of a partially used consumable. The worst case ROM contains entries for full and partially used consumables for R over the lifetime of System. However, a valid authentication chip must be used to generate the information, and be partially used in the process. If a given System only produces n R-values, the sparse lookup-ROM required is 20n bytes (20=160/8) multiplied by the number of different values for M. The time taken to build the ROM depends on the amount of time enforced between calls to Read.
5300After all this, the clone manufacturer must rely on the consumer returning for a refill, since the cost of building the ROM in the first place consumes a single consumable. The clone manufacturer's business in such a situation is consequently in the refills.
5301The time and cost then, depends on the size of R and the number of different values for M that must be incorporated in the lookup. In addition, a custom clone consumable ROM must be built to match each and every System, and a different valid authentication chip must be used for each System (in order to provide the full and partially used data). The use of an authentication chip in a System must therefore be examined to determine whether or not this kind of attack is worthwhile for a clone manufacturer.
5302As an example, of a camera system that has about 10,000 prints in its lifetime. Assume it has a single Decrement Only value (number of prints remaining), and a delay of 1 second between calls to Read. In such a system, the sparse table will take about 3 hours to build, and consumes 100K. Remember that the construction of the ROM requires the consumption of a valid authentication chip, so any money charged must be worth more than a single consumable and the clone consumable combined. Thus it is not cost effective to perform this function for a single consumable (unless the clone consumable somehow contained the equivalent of multiple authentic consumables).
5303If a clone manufacturer is going to go to the trouble of building a custom ROM for each owner of a System, an easier approach would be to update System to completely ignore the authentication chip.
5304Consequently, this attack is possible as a per-System attack, and a decision must be made about the chance of this occurring for a given System/Consumable combination. The chance will depend on the cost of the consumable and authentication chips, the longevity of the consumable, the profit margin on the consumable, the time taken to generate the ROM, the size of the resultant ROM, and whether customers will come back to the clone manufacturer for refills that use the same clone chip etc.
000014.13 Differential Cryptanalysis
5305Existing differential attacks are heavily dependent on the structure of S boxes, as used in DES and other similar algorithms. Although HMAC-SHA1 has no S boxes, an attacker can undertake a differential-like attack by undertaking statistical analysis of: <ul id="ul0666" list-style="none"><li id="ul0666-0001" num="0000"><ul id="ul0667" list-style="none"><li id="ul0667-0001" num="5306">Minimal-difference inputs, and their corresponding outputs</li><li id="ul0667-0002" num="5307">Minimal-difference outputs, and their corresponding inputs</li></ul></li></ul>
5308To launch an attack of this nature, sets of input/output pairs must be collected. The collection can be via known plaintext, or from a partially adaptive chosen plaintext attack. Obviously the latter, being chosen, will be more useful.
5309Hashing algorithms in general are designed to be resistant to differential analysis. SHA-1 in particular has been specifically strengthened, especially by the 80 word expansion so that minimal differences in input will still produce outputs that vary in a larger number of bit positions (compared to 128 bit hash functions). In addition, the information collected is not a direct SHA-1 input/output set, due to the nature of the HMAC algorithm. The HMAC algorithm hashes a known value with an unknown value (the key), and the result of this hash is then rehashed with a separate unknown value. Since the attacker does not know the secret value, nor the result of the first hash, the inputs and outputs from SHA-1 are not known, making any differential attack extremely difficult.
5310There are no known differential attacks against SHA-1 or HMAC-SHA-1 [56][56].
5311The following is a more detailed discussion of minimally different inputs and outputs from the QA Chip.
000014.13.1 Minimal Difference Inputs
5312This is where an attacker takes a set of X, S<sub>K</sub>[X] values where the X values are minimally different, and examines the statistical differences between the outputs S<sub>K</sub>[X]. The attack relies on X values that only differ by a minimal number of bits. The question then arises as to how to obtain minimally different X values in order to compare the S<sub>K</sub>[X] values.
5313Although the attacker can choose both R<sub>T </sub>and possibly M, ChipA advances its random number R<sub>A </sub>with each call to Read. The resultant X therefore contains 160 bits of changing data each call, and is therefore not minimally different.
000014.13.2 Minimal Difference Outputs
5314This is where an attacker takes a set of X, S<sub>K</sub>[X] values where the S<sub>K</sub>[X] values are minimally different, and examines the statistical differences between the X values. The attack relies on S<sub>K</sub>[X] values that only differ by a minimal number of bits.
5315There is no way for an attacker to generate an X value for a given S<sub>K</sub>[X]. To do so would violate the fact that S is a one-way function (HMAC-SHA1). Consequently the only way for an attacker to mount an attack of this nature is to record all observed X, S<sub>K</sub>[X] pairs in a table. A search must then be made through the observed values for enough minimally different S<sub>K</sub>[X] values to undertake a statistical analysis of the X values.
000014.14 Message Substitution Attacks
5316In order for this kind of attack to be carried out, a clone consumable must contain a real authentication chip, but one that is effectively reusable since it never gets decremented. The clone authentication chip would intercept messages, and substitute its own. However this attack does not give success to the attacker.
5317A clone authentication chip may choose not to pass on a Write command to the real authentication chip. However the subsequent Read command must return the correct response (as if the Write had succeeded). To return the correct response, the hash value must be known for the specific R and M. An attacker can only determine the hash value by actually updating M in a real Chip, which the attacker does not want to do. Even changing the R sent by System does not help since the System authentication chip must match the R during a subsequent Test.
5318A message substitution attack would therefore be unsuccessful. This is only true if System updates the amount of consumable remaining before it is used.
000014.15 Reverse Engineering the Key Generator
5319If a pseudo-random number generator is used to generate keys, there is the potential for a clone manufacture to obtain the generator program or to deduce the random seed used. This was the way in which the security layer of the Netscape browser was initially broken [33].
000014.16 Bypassing the Authentication Process
5320The System should ideally update the consumable state data before the consumable is used, and follow every write by a read (to authenticate the write). Thus each use of the consumable requires an authentication. If the System adheres to these two simple rules, a clone manufacturer will have to simulate authentication via a method above (such as sparse ROM lookup).
000014.17 Reuse of Authentication Chips
5321Each use of the consumable requires an authentication. If a consumable has been used up, then its authentication chip will have had the appropriate state-data values decremented to 0. The chip can therefore not be used in another consumable.
5322Note that this only holds true for authentication chips that hold Decrement-Only data items. If there is no state data decremented with each usage, there is nothing stopping the reuse of the chip. This is the basic difference between Presence-Only authentication and Consumable Lifetime authentication. All described protocols allow both.
5323The bottom line is that if a consumable has Decrement Only data items that are used by the System, the authentication chip cannot be reused without being completely reprogrammed by a valid programming station that has knowledge of the secret key (e.g. an authorized refill station).
000014.18 Management Decision to Omit Authentication to Save Costs
5324Although not strictly an external attack, a decision to omit authentication in future Systems in order to save costs will have widely varying effects on different markets.
5325In the case of high volume consumables, it is essential to remember that it is very difficult to introduce authentication after the market has started, as systems requiring authenticated consumables will not work with older consumables still in circulation. Likewise, it is impractical to discontinue authentication at any stage, as older Systems will not work with the new, unauthenticated, consumables. In the second case, older Systems can be individually altered by replacing the System program code.
5326Without any form of protection, illegal cloning of high volume consumables is almost certain. However, with the patent and copyright protection, the probability of illegal cloning may be, say 50%. However, this is not the only loss possible. If a clone manufacturer were to introduce clone consumables which caused damage to the System (e.g. clogged nozzles in a printer due to poor quality ink), then the loss in market acceptance, and the expense of warranty repairs, may be significant.
5327In the case of a specialized pairing, such as a car/car-keys, or door/door-key, or some other similar situation, the omission of authentication in future systems is trivial and without repercussions. This is because the consumer is sold the entire set of System and Consumable authentication chips at the one time.
000014.19 Garrote/Bribe Attack
5328If humans do not know the key, there is no amount of force or bribery that can reveal them. The use of ChipF and the ReplaceKey protocol is specifically designed to avoid the requirement of the programming station having to know the new key. However ChipF must be told the new key at some stage, and therefore it is the person(s) who enter the new key into ChipF that are at risk.
5329The level of security against this kind of attack is ultimately a decision for the System/Consumable owner, to be made according to the desired level of service.
5330For example, a car company may wish to keep a record of all keys manufactured, so that a person can request a new key to be made for their car. However this allows the potential compromise of the entire key database, allowing an attacker to make keys for any of the manufacturer's existing cars. It does not allow an attacker to make keys for any new cars. Of course, the key database itself may also be encrypted with a further key that requires a certain number of people to combine their key portions together for access. If no record is kept of which key is used in a particular car, there is no way to make additional keys should one become lost. Thus an owner will have to replace his car's authentication chip and all his car-keys. This is not necessarily a bad situation.
5331By contrast, in a consumable such as a printer ink cartridge, the one key combination is used for all Systems and all consumables. Certainly if no backup of the keys is kept, there is no human with knowledge of the key, and therefore no attack is possible. However, a no-backup situation is not desirable for a consumable such as ink cartridges, since if the key is lost no more consumables can be made. The manufacturer should therefore keep a backup of the key information in several parts, where a certain number of people must together combine their portions to reveal the full key information. This may be required if case the chip programming station needs to be reloaded.
5332In any case, none of these attacks are against the authenticated read protocol, since no humans are involved in the authentication process.
0000Logical Interface
000015 Introduction
5333The QA Chip has a physical and a logical external interface. The physical interface defines how the QA Chip can be connected to a physical System, while the logical interface determines how that System can communicate with the QA Chip. This section deals with the logical interface.
000015.1 Operating Modes
5334The QA Chip has four operating modes—Idle Mode, Program Mode, Trim Mode and Active Mode. <ul id="ul0668" list-style="none"><li id="ul0668-0001" num="0000"><ul id="ul0669" list-style="none"><li id="ul0669-0001" num="5335">Idle Mode is used to allow the chip to wait for the next instruction from the System.</li><li id="ul0669-0002" num="5336">Trim Mode is used to determine the clock speed of the chip and to trim the frequency during the initial programming stage of the chip (when Flash memory is garbage). The clock frequency must be trimmed via Trim Mode before Program Mode is used to store the program code.</li><li id="ul0669-0003" num="5337">Program Mode is used to load up the operating program code, and is required because the operating program code is stored in Flash memory instead of ROM (for security reasons).</li><li id="ul0669-0004" num="5338">Active Mode is used to execute the specific authentication command specified by the System. Program code is executed in Active Mode. When the results of the command have been returned to the System, the chip enters Idle Mode to wait for the next instruction. <br /> 15.1.1 Idle Mode </li></ul></li></ul>
5339The QA Chip starts up in Idle Mode. When the Chip is in Idle Mode, it waits for a command from the master by watching the primary id on the serial line. <ul id="ul0670" list-style="none"><li id="ul0670-0001" num="0000"><ul id="ul0671" list-style="none"><li id="ul0671-0001" num="5340">If the primary id matches the global id (0x00, common to all QA Chips), and the following byte from the master is the Trim Mode id byte, the QA Chip enters Trim Mode and starts counting the number of internal clock cycles until the next byte is received.</li><li id="ul0671-0002" num="5341">If the primary id matches the global id (0x00, common to all QA Chips), and the following byte from the master is the Program Mode id byte, the QA Chip enters Program Mode.</li><li id="ul0671-0003" num="5342">If the primary id matches the global id (0x00, common to all QA Chips), and the following byte from the master is the Active Mode id byte, the QA Chip enters Active Mode and executes startup code, allowing the chip to set itself into a state to receive authentication commands (includes setting a local ID).</li><li id="ul0671-0004" num="5343">If the primary id matches the chip's local ID, and the following byte is a valid command code, the QA Chip enters Active Mode, allowing the command to be executed.</li></ul></li></ul>
5344The valid 8-bit serial mode values sent after a global id are as shown in Table 238. They are specified to minimize the chances of them occurring by error after a global id (e.g. 0xFF and 0x00 are not used):
5345<tables id="TABLE-US-00378" num="00378"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 238</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Id byte values to place chip in specific mode</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="98pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry>Value</entry><entry>Interpretation</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>10100101 (0xA5)</entry><entry>Trim Mode</entry></row><row><entry /><entry>10001110 (0x8E)</entry><entry>Program Mode</entry></row><row><entry /><entry>01111000 (0x78)</entry><entry>Active Mode</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 15.1.2 Trim Mode
5346Trim Mode is enabled by sending a global id byte (0x00) followed by the Trim Mode command byte. The purpose of Trim Mode is to set the trim value (an internal register setting) of the internal ring oscillator so that Flash erasures and writes are of the correct duration. This is necessary due to the variation of the clock speed due to process variations. If writes an erasures are too long, the Flash memory will wear out faster than desired, and in some cases can even be damaged.
5347Trim Mode works by measuring the number of system clock cycles that occur inside the chip from the receipt of the Trim Mode command byte until the receipt of a data byte. When the data byte is received, the data byte is copied to the trim register and the current value of the count is transmitted to the outside world.
5348Once the count has been transmitted, the QA Chip returns to Idle Mode.
5349At reset, the internal trim register setting is set to a known value r. The external user can now perform the following operations: <ul id="ul0672" list-style="none"><li id="ul0672-0001" num="0000"><ul id="ul0673" list-style="none"><li id="ul0673-0001" num="5350">send the global id+write followed by the Trim Mode command byte</li><li id="ul0673-0002" num="5351">send the 8-bit value v over a specified time t</li><li id="ul0673-0003" num="5352">send a stop bit to signify no more data</li><li id="ul0673-0004" num="5353">send the global id+read followed by the Trim Mode command byte</li><li id="ul0673-0005" num="5354">receive the count c</li><li id="ul0673-0006" num="5355">send a stop bit to signify no more data</li></ul></li></ul>
5356Writes to M<sub>1</sub>[n] only succeed when all of M<sub>1</sub>[0 . . . n−1] have already written to (i.e. previous fields are defined) i.e. calculated.
5357The Trim Mode procedure can be repeated a number of times, varying both t and v in known ways, measuring the resultant c. At the end of the process, the final value for v is established (and stored in the trim register for subsequent use in Program Mode). This value v must also be written to the flash for later use (every time the chip is placed in Active Mode for the first time after power-up).
000015.1.3 Program Mode
5358Program Mode is enabled by sending a global id byte (0x00) followed by the Program Mode command byte.
5359The QA Chip determines whether or not the internal fuse has been blown (by reading 32-bit word 0 of the information block of flash memory).
5360If the fuse has been blown the Program Mode command is ignored, and the QA Chip returns to Idle Mode.
5361If the fuse is still intact, the chip enters Program Mode and erases the entire contents of Flash memory. The QA Chip then validates the erasure. If the erasure was successful, the QA Chip receives up to 4096 bytes of data corresponding to the new program code and variable data. The bytes are transferred in order byte<sub>0 </sub>to byte<sub>4095</sub>.
5362Once all bytes of data have been loaded into Flash, the QA Chip returns to Idle Mode.
5363Note that Trim Mode functionality must be performed before a chip enters Program Mode for the first time.
5364Once the desired number of bytes have been downloaded in Program Mode, the LSS Master must wait for 80 μs (the time taken to write two bytes to flash at nybble rates) before sending the new transaction (eg Active Mode). Otherwise the last nybbles may not be written to flash.
000015.1.4 Active Mode
5365Active Mode is entered either by receiving a global id byte (0x00) followed by the Active Mode command byte, or by sending a local id byte followed by a command opcode byte and an appropriate number of data bytes representing the required input parameters for that opcode.
5366In both cases, Active Mode causes execution of program code previously stored in the flash memory via Program Mode. As a result, we never enter Active Mode after Trim Mode, without a Program Mode in between. However once programmed via Program Mode, a chip is allowed to enter Active Mode after power-up, since valid data will be in flash.
5367If Active Mode is entered by the global id mechanism, the QA Chip executes specific reset startup code, typically setting up the local id and other IO specific data.
5368If Active Mode is entered by the local id mechanism, the QA Chip executes specific code depending on the following byte, which functions as an opcode. The opcode command byte format is shown in Table 239:
5369<tables id="TABLE-US-00379" num="00379"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 239</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Command byte</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="98pt" align="center" /><colspec colname="2" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>bits</entry><entry>Description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>2–0</entry><entry>Opcode</entry></row><row><entry>5–3</entry><entry><img file="US7165824B2_D0222.tif" /> opcode</entry></row><row><entry>7–6</entry><entry>count of number of bits set in</entry></row><row><entry /><entry>opcode (0 to 3)</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
5370The interpretation of the 3-bit opcode is shown in Table 240:
5371<tables id="TABLE-US-00380" num="00380"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 240</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>QA Chip opcodes</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><colspec colname="3" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>Op<sup>2</sup></entry><entry>Mn<sup>3</sup></entry><entry>Description</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row><row><entry /><entry>000</entry><entry>RST</entry><entry>Reset</entry></row><row><entry /><entry>001</entry><entry>RND</entry><entry>Random</entry></row><row><entry /><entry>010</entry><entry>RDM</entry><entry>Read M</entry></row><row><entry /><entry>011</entry><entry>TST</entry><entry>Test</entry></row><row><entry /><entry>100</entry><entry>WRM</entry><entry>Write M with no authentication</entry></row><row><entry /><entry>101</entry><entry>WRA</entry><entry>Write with Authentication (to M, P, or K)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>110</entry><entry>chip specific - reserved for ChipF, ChipS etc</entry></row><row><entry /><entry>111</entry><entry>chip specific - reserved for ChipF, ChipS etc</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry namest="offset" nameend="2" align="left" id="FOO-00043"><sup>2</sup>Opcode</entry></row><row><entry /><entry namest="offset" nameend="2" align="left" id="FOO-00044"><sup>3</sup>Mnemonic</entry></row></tbody></tgroup></table></tables>
5372The command byte is designed to ensure that errors in transmission are detected. Regular QA Chip commands are therefore comprised of an opcode plus any associated parameters. The commands are listed in Table 241:
5373<tables id="TABLE-US-00381" num="00381"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 241</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>QA Chip commands</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="112pt" align="center" /><colspec colname="2" colwidth="49pt" align="left" /><tbody valign="top"><row><entry /><entry>Input</entry><entry>Output</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><colspec colname="3" colwidth="77pt" align="left" /><colspec colname="4" colwidth="49pt" align="left" /><tbody valign="top"><row><entry>Command</entry><entry>opcode</entry><entry>Additional parms</entry><entry>Return value</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>Reset</entry><entry>RST</entry><entry>—</entry><entry>—</entry></row><row><entry>Random</entry><entry>RND</entry><entry>—</entry><entry>[20]</entry></row><row><entry>Read</entry><entry>RDM</entry><entry>[1, 1, 20]</entry><entry>[20, 64, 20]<sup>4</sup></entry></row><row><entry>Test</entry><entry>TST</entry><entry>[1, 20, 64, 20]</entry><entry>89<sup>5 </sup>if</entry></row><row><entry /><entry /><entry /><entry>successful,</entry></row><row><entry /><entry /><entry /><entry>76 if not</entry></row><row><entry>Write</entry><entry>WRM</entry><entry>[1, 64, 20]</entry><entry>89 if</entry></row><row><entry /><entry /><entry /><entry>successful,</entry></row><row><entry /><entry /><entry /><entry>76 if not</entry></row><row><entry>WriteAuth</entry><entry>WRA</entry><entry>76 [20, 64, 20]</entry><entry>89 if</entry></row><row><entry /><entry /><entry /><entry>successful,</entry></row><row><entry /><entry /><entry /><entry>76 if not</entry></row><row><entry>ReplaceKey</entry><entry>WRA</entry><entry>89 76 [1, 20, 20, 20]</entry><entry>89 if</entry></row><row><entry /><entry /><entry /><entry>successful,</entry></row><row><entry /><entry /><entry /><entry>76 if not</entry></row><row><entry>SetPermissions</entry><entry>WRA</entry><entry>89 89 [1, 1, 20, 4, 20]</entry><entry>[4]</entry></row><row><entry>SignM<sup>6</sup></entry><entry>ChipS</entry><entry>[1, 20, 20, 64, 20, 64]</entry><entry>[20, 64, 20]</entry></row><row><entry /><entry>only</entry></row><row><entry>SignP<sup>7</sup></entry><entry>ChipS</entry><entry>[1, 20, 20, 4, 20, 4]</entry><entry>[20, 64, 20]</entry></row><row><entry /><entry>only</entry></row><row><entry>GetProgKey</entry><entry>ChipF</entry><entry>[1, 20]</entry><entry>[20, 20, 20]</entry></row><row><entry /><entry>only</entry></row><row><entry>SetPartialKey</entry><entry>ChipF</entry><entry>[1, 4]</entry><entry>89 if</entry></row><row><entry /><entry>only</entry><entry /><entry>successful,</entry></row><row><entry /><entry /><entry /><entry>76 if not</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry namest="1" nameend="4" align="left" id="FOO-00045"><sup>4</sup>[n, m] = list of parameters where n bytes for first parameter, and m bytes for the second etc.</entry></row><row><entry namest="1" nameend="4" align="left" id="FOO-00046"><sup>5</sup>n = actual byte pattern required (in hex). The bytes 0x76 and 0x89 were chosen as the boolean values 0 and 1 as they are inverses of each other, and should not be generated accidentally.</entry></row><row><entry namest="1" nameend="4" align="left" id="FOO-00047"><sup>6</sup>It is expected that most QA Chips will implement SignM as a function that returns 0x00. Only a limited number of chips will be programmed to allow SignM functionality. It is included here as an example of how signatures can be generated for authenticated writes.</entry></row><row><entry namest="1" nameend="4" align="left" id="FOO-00048"><sup>7</sup>It is expected that most QA Chips will implement SignP as a function that returns 0x00. Only a limited number of chips will be programmed to allow SignP functionality. It is included here as an example of how signatures can be generated for authenticated writes.</entry></row></tbody></tgroup></table></tables>
5374Apart from the Reset command, the next four commands are the commands most likely to be used during regular operation. The next three commands are used to provide authenticated writes (which are expected to be uncommon). The final set of commands (including SignM), are expected to be specially implemented on ChipS and ChipF QA Chips only.
5375The input parameters are sent in the specified order, with each parameter being sent least significant byte first and most significant byte last.
5376Return (output) values are read in the same way—least significant byte first and most significant byte last. The client must know how many bytes to retrieve. The QA Chip will time out and return to Idle Mode if an incorrect number of bytes is provided or read.
5377In most cases, the output bytes from one chip's command (the return values) can be fed directly as the input bytes to another chip's command. An example of this is the RND and RD commands. The output data from a call to RND on a trusted QA Chip does not have to be kept by the System. Instead, the System can transfer the output bytes directly to the input of the non-trusted QA Chip's RD command. The description of each command points out where this is so.
5378Each of the commands is examined in detail in the subsequent sections. Note that some algorithms are specifically designed because flash memory is assumed for the implementation of non-volatile variables.
000015.1.5 Non Volatile Variables
5379The memory within the QA Chip contains some non-volatile (Flash) memory to store the variables required by the authentication protocol. Table 242 summarizes the variables.
5380<tables id="TABLE-US-00382" num="00382"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 242</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Non volatile variables required by the authentication protocol</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="56pt" align="center" /><colspec colname="3" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>Name</entry><entry>Size (bits)</entry><entry>Description</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="21pt" align="right" /><colspec colname="3" colwidth="35pt" align="left" /><colspec colname="4" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>N</entry><entry>8</entry><entry /><entry>Number of keys known to the chip</entry></row><row><entry>T</entry><entry>8</entry><entry /><entry>Number of vectors M is broken into</entry></row><row><entry>K<sub>n</sub></entry><entry>160</entry><entry>per key,</entry><entry>Array of N secret keys used for</entry></row><row><entry>R<sub>K</sub></entry><entry>160</entry><entry>for R<sub>K</sub></entry><entry>calculating F<sub>Kn</sub>[X] where K<sub>n </sub>is</entry></row><row><entry /><entry /><entry /><entry>the nth element of the array. Each K<sub>n</sub></entry></row><row><entry /><entry /><entry /><entry>must not be stored directly in the QA</entry></row><row><entry /><entry /><entry /><entry>Chip. Instead, each chip needs to</entry></row><row><entry /><entry /><entry /><entry>store a single random number R<sub>K</sub></entry></row><row><entry /><entry /><entry /><entry>(different for each chip), K<sub>n</sub>⊕R<sub>K</sub>,</entry></row><row><entry /><entry /><entry /><entry>and <img file="US7165824B2_D0223.tif" /> K<sub>n</sub>⊕R<sub>K</sub>. The stored K<sub>n</sub>⊕R<sub>K</sub></entry></row><row><entry /><entry /><entry /><entry>can be XORed with R<sub>K </sub>to obtain the</entry></row><row><entry /><entry /><entry /><entry>real K<sub>n</sub>. Although <img file="US7165824B2_D0224.tif" /> K<sub>n</sub>⊕R<sub>K </sub>must be</entry></row><row><entry /><entry /><entry /><entry>stored to protect against differential</entry></row><row><entry /><entry /><entry /><entry>attacks, it is not used.</entry></row><row><entry>R</entry><entry>160</entry><entry /><entry>Current random number used to ensure</entry></row><row><entry /><entry /><entry /><entry>time varying messages. Each chip</entry></row><row><entry /><entry /><entry /><entry>instance must be seeded with a</entry></row><row><entry /><entry /><entry /><entry>different initial value. Changes for</entry></row><row><entry /><entry /><entry /><entry>each signature generation.</entry></row><row><entry>M<sub>T</sub></entry><entry>512</entry><entry>per M</entry><entry>Array of T memory vectors. Only M<sub>0</sub></entry></row><row><entry /><entry /><entry /><entry>can be written to with an authorized</entry></row><row><entry /><entry /><entry /><entry>write, while all Ms can be written</entry></row><row><entry /><entry /><entry /><entry>to in an unauthorized write. Writes</entry></row><row><entry /><entry /><entry /><entry>to M<sub>0 </sub>are optimized for Flash usage,</entry></row><row><entry /><entry /><entry /><entry>while updates to any other M<sub>n </sub>are</entry></row><row><entry /><entry /><entry /><entry>expensive with regards to Flash</entry></row><row><entry /><entry /><entry /><entry>utilization, and are expected to</entry></row><row><entry /><entry /><entry /><entry>be only performed once per section</entry></row><row><entry /><entry /><entry /><entry>of M<sub>n</sub>. M<sub>1 </sub>contains T and N in</entry></row><row><entry /><entry /><entry /><entry>ReadOnly form so users of the chip</entry></row><row><entry /><entry /><entry /><entry>can know these two values.</entry></row><row><entry>P<sub>T+N</sub></entry><entry>32</entry><entry>per P</entry><entry>T + N element array of access</entry></row><row><entry /><entry /><entry /><entry>permissions for each part of M.</entry></row><row><entry /><entry /><entry /><entry>Entries n = {0 . . . T − 1}</entry></row><row><entry /><entry /><entry /><entry>hold access permissions for non-</entry></row><row><entry /><entry /><entry /><entry>authenticated writes to M<sub>n </sub>(no key</entry></row><row><entry /><entry /><entry /><entry>required). Entries n = {T to</entry></row><row><entry /><entry /><entry /><entry>T + N − 1} hold access</entry></row><row><entry /><entry /><entry /><entry>permissions for authenticated</entry></row><row><entry /><entry /><entry /><entry>writes to M<sub>0 </sub>for K<sub>n</sub>. Permission</entry></row><row><entry /><entry /><entry /><entry>choices for each part of M are Read</entry></row><row><entry /><entry /><entry /><entry>Only, Read/Write, and Decrement Only</entry></row><row><entry>MinTicks</entry><entry>32</entry><entry /><entry>The minimum number of clock ticks</entry></row><row><entry /><entry /><entry /><entry>between calls to key-based functions.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
5381Note that since these variables are in Flash memory, writes should be minimized. The it is not a simple matter to write a new value to replace the old. Care must be taken with flash endurance, and speed of access. This has an effect on the algorithms used to change Flash memory based registers. For example, Flash memory should not be used as a shift register.
5382A reset of the QA Chip has no effect on the non-volatile variables.
000015.1.5.1 M and P
5383M<sub>n </sub>contains application specific state data, such as serial numbers, batch numbers, and amount of consumable remaining. M<sub>n </sub>can be read using the Read command and written to via the Write and WriteA commands.
5384M<sub>0 </sub>is expected to be updated frequently, while each part of M<sub>1-n </sub>should only be written to once. Only M<sub>0 </sub>can be written to via the WriteA command.
5385M<sub>1 </sub>contains the operating parameters of the chip as shown in Table 243, and M<sub>2-n</sub>, are application specific.
5386<tables id="TABLE-US-00383" num="00383"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 243</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Interpretation of M<sub>1</sub></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="28pt" align="center" /><colspec colname="2" colwidth="63pt" align="center" /><colspec colname="3" colwidth="112pt" align="left" /><tbody valign="top"><row><entry /><entry>Length</entry><entry>Bits</entry><entry>interpretation</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="28pt" align="char" char="." /><colspec colname="2" colwidth="63pt" align="center" /><colspec colname="3" colwidth="112pt" align="left" /><tbody valign="top"><row><entry /><entry>8</entry><entry>7–0</entry><entry>Number of available keys</entry></row><row><entry /><entry>8</entry><entry>15–8 </entry><entry>Number of available M vectors</entry></row><row><entry /><entry>16</entry><entry>31–16</entry><entry>Revision of chip</entry></row><row><entry /><entry>96</entry><entry>127–32 </entry><entry>Manufacture id information</entry></row><row><entry /><entry>128</entry><entry>255–128</entry><entry>Serial number</entry></row><row><entry /><entry>8</entry><entry>263–256</entry><entry>Local id of chip</entry></row><row><entry /><entry>248</entry><entry>511–264</entry><entry>reserved</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
5387Each M<sub>n </sub>is 512 bits in length, and is interpreted as a set of 16×32-bit words. Although M<sub>n </sub>may contain a number of different elements, each 32-bit word differs only in write permissions. Each 32-bit word can always be read. Once in client memory, the 512 bits can be interpreted in any way chosen by the client. The different write permissions for each P are outlined in Table 244:
5388<tables id="TABLE-US-00384" num="00384"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 244</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Write permissions</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="154pt" align="left" /><tbody valign="top"><row><entry /><entry>Data type</entry><entry>permission description</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>Read Only</entry><entry>Can never be written to</entry></row><row><entry /><entry>ReadWrite</entry><entry>Can always be written to</entry></row><row><entry /><entry>Decrement</entry><entry>Can only be written to if the new value is less</entry></row><row><entry /><entry>Only</entry><entry>than the old value. Decrement Only values can</entry></row><row><entry /><entry /><entry>be any multiple of 32 bits.</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
5389To accomplish the protection required for writing, a 2-bit permission value P is defined for each of the 32-bit words. Table 245 defines the interpretation of the 2-bit permission bit-pattern:
5390<tables id="TABLE-US-00385" num="00385"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 245</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Permission bit interpretation</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="28pt" align="center" /><colspec colname="2" colwidth="28pt" align="left" /><colspec colname="3" colwidth="49pt" align="left" /><colspec colname="4" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>Bits</entry><entry>Op</entry><entry>Interpretation</entry><entry>Action taken during Write command</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>00</entry><entry>RW</entry><entry>ReadWrite</entry><entry>The new 32-bit value is always</entry></row><row><entry /><entry /><entry /><entry>written to M[n].</entry></row><row><entry>01</entry><entry>MSR</entry><entry>Decrement</entry><entry>The new 32-bit value is only</entry></row><row><entry /><entry /><entry>Only (Most</entry><entry>written to M[n] if it is</entry></row><row><entry /><entry /><entry>Significant</entry><entry>less than the value currently</entry></row><row><entry /><entry /><entry>Region)</entry><entry>in M[n]. This is used for</entry></row><row><entry /><entry /><entry /><entry>access to the Most Significant</entry></row><row><entry /><entry /><entry /><entry>16 bits of a Decrement Only</entry></row><row><entry /><entry /><entry /><entry>number.</entry></row><row><entry>10</entry><entry>NMSR</entry><entry>Decrement</entry><entry>The new 32-bit value is only</entry></row><row><entry /><entry /><entry>Only (Not</entry><entry>written to M[n] if M[n − 1]</entry></row><row><entry /><entry /><entry>the Most</entry><entry>could also be written. The</entry></row><row><entry /><entry /><entry>Significant</entry><entry>NMSR access mode allows multiple</entry></row><row><entry /><entry /><entry>Region)</entry><entry>precision values of 32 bits and</entry></row><row><entry /><entry /><entry /><entry>more (multiples of 32 bits) to</entry></row><row><entry /><entry /><entry /><entry>decrement.</entry></row><row><entry>11</entry><entry>RO</entry><entry>Read Only</entry><entry>The new 32-bit value is ignored.</entry></row><row><entry /><entry /><entry /><entry>M[n] is left unchanged.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
5391The 16 sets of permission bits for each 512 bits of M are gathered together in a single 32-bit variable P, where bits <b>2</b><i>n </i>and <b>2</b><i>n</i>+1 of P correspond to word n of M as follows:
5392Each 2-bit value is stored as a pair with the msb in bit <b>1</b>, and the lsb in bit <b>0</b>. Consequently, if words 0 to 5 of M had permission MSR, with words 6–15 of M permission RO, the 32-bit P variable would be 0xFFFFF555:
000011-11-11-11-11-11-11-11-11-11-01-01-01-01-01-01
5393During execution of a Write and WriteA command, the appropriate Permissions[n] is examined for each M[n] starting from n=15 (msw of M) to n=0 (lsw of M), and a decision made as to whether the ne M[n] value will replace the old. Note that it is important to process the M[n] from msw to lsw to correctly interpret the access permissions.
5394Permissions are set and read using the QA Chip's SetPermissions command. The default for P is all 0s (RW) with the exception of certain parts of M<sub>1</sub>.
5395Note that the Decrement Only comparison is unsigned, so any Decrement Only values that require negative ranges must be shifted into a positive range. For example, a consumable with a Decrement Only data item range of −50 to 50 must have the range shifted to be 0 to 100. The System must then interpret the range 0 to 100 as being −50 to 50. Note that most instances of Decrement Only ranges are N to 0, so there is no range shift required.
5396For Decrement Only data items, arrange the data in order from most significant to least significant 32-bit quantities from M[n] onward. The access mode for the most significant 32 bits (stored in M[n]) should be set to MSR. The remaining 32-bit entries for the data should have their permissions set to NMSR.
5397If erroneously set to NMSR, with no associated MSR region, each NMSR region will be considered independently instead of being a multi-precision comparison.
5398Examples of allocating M and Permission bits can be found in [86].
000015.1.5.2 K and R<sub>K </sub>
5399K is the 160-bit secret key used to protect M and to ensure that the contents of M are valid (when M is read from a non trusted chip). K is initially programmed after manufacture, and from that point on, K can only be updated to a new value if the old K is known. Since K must be kept secret, there is no command to directly read it.
5400K is used in the keyed one-way hash function HMAC-SHA1. As such it should be programmed with a physically generated random number, gathered from a physically random phenomenon. K must NOT be generated with a computer-run random number generator. The security of the QA Chips depends on K being generated in a way that is not deterministic.
5401Each K<sub>n </sub>must not be stored directly in the QA Chip. Instead, each chip needs to store a single random number R<sub>K </sub>(different for each chip), K<sub>n</sub>⊕R<sub>K</sub>, and <img file="US7165824B2_D0225.tif" />K<sub>n</sub>⊕R<sub>K</sub>. The stored K<sub>n</sub>⊕R<sub>K </sub>can be XORed with R<sub>K </sub>to obtain the real K<sub>n</sub>. Although <img file="US7165824B2_D0226.tif" />K<sub>n</sub>R<sub>K </sub>must be stored to protect against differential attacks, it is not used.
15.1.5.3 R
5402R is a 160-bit random number seed that is set up after manufacture (when the chip is programmed) and from that point on, cannot be changed. R is used to ensure that each signed item contains time varying information (not chosen by an attacker), and each chip's R is unrelated from one chip to the next.
5403R is used during the Test command to ensure that the R from the previous call to Random was used as the session key in generating the signature during Read. Likewise, R is used during the WriteAuth command to ensure that the R from the previous call to Read was used as the session key during generation of the signature in the remote Authenticated chip.
5404The only invalid value for R is 0. This is because R is changed via a 160-bit maximal period LFSR (Linear Feedback Shift Register) with taps on bits <b>0</b>, <b>2</b>, <b>3</b>, and <b>5</b>, and is changed only by a successful call to a signature generating function (e.g. Test, WriteAuth).
5405The logical security of the QA Chip relies not only upon the randomness of K and the strength of the HMAC-SHA1 algorithm. To prevent an attacker from building a sparse lookup table, the security of the QA Chip also depends on the range of R over the lifetime of all Systems. What this means is that an attacker must not be able to deduce what values of R there are in produced and future Systems. Ideally, R should be programmed with a physically generated random number, gathered from a physically random phenomenon (must not be deterministic). R must NOT be generated with a computer-run random number generator.
000015.1.5.4 MinTicks
5406There are two mechanisms for preventing an attacker from generating multiple calls to key-based functions in a short period of time. The first is an internal ring oscillator that is temperature-filtered. The second mechanism is the 32-bit MinTicks variable, which is used to specify the minimum number of QA Chip clock ticks that must elapse between calls to key-based functions.
5407The MinTicks variable is set to a fixed value when the QA Chip is programmed. It could possibly be stored in M<sub>1</sub>.
5408The effective value of MinTicks depends on the operating clock speed and the notion of what constitutes a reasonable time between key-based function calls (application specific). The duration of a single tick depends on the operating clock speed. This is the fastest speed of the ring oscillator generated clock (i.e. at the lowest valid operating temperature).
5409Once the duration of a tick is known, the MinTicks value can to be set. The value for MinTicks will be the minimum number of ticks required to pass between calls to the key-based functions (there is no need to protect Random as this produces the same output each time it is called multiple times in a row). The value is a real-time number, and divided by the length of an operating tick.
5410It should be noted that the MinTicks variable only slows down an attacker and causes the attack to cost more since it does not stop an attacker using multiple System chips in parallel.
000015.1.6 GetProgramKey
0000<ul id="ul0674" list-style="none"><li id="ul0674-0001" num="5411">Input: n, R<sub>E</sub>=[1 byte, 20 bytes]</li><li id="ul0674-0002" num="5412">Output: R<sub>L</sub>, E<sub>Kx</sub>[S<sub>Kn</sub>[R<sub>E</sub>|R<sub>L</sub>|C<sub>3</sub>]], S<sub>Kx</sub>[R<sub>L</sub>|E<sub>Kx</sub>[S<sub>Kn</sub>[R<sub>E</sub>|R<sub>L</sub>|C<sub>3</sub>]|C<sub>3</sub>]=[20, 20, 20]</li><li id="ul0674-0003" num="5413">Changes: R<sub>L </sub></li></ul>
5414Note: The GetProgramKey command is only implemented in ChipF, and not in all QA Chips. The GetProgramKey command is used to produce the bytestream required for updating a specified key in ChipP. Only an QA Chip programmed with the correct values of the old K<sub>n </sub>can respond correctly to the GetProgramKey request. The output bytestream from the Random command can be fed as the input bytestream to the ReplaceKey command on the QA Chip being programmed (ChipP).
5415The input bytestream consists of the appropriate opcode followed by the desired key to generate the signature, followed by 20 bytes of R<sub>E </sub>(representing the random number read in from ChipP).
5416The local random number R<sub>L </sub>is advanced, and signed in combination with R<sub>E </sub>and C<sub>3 </sub>by the chosen key to generate a time varying secret number known to both ChipF and ChipP. This signature is then XORed with the new key K<sub>x </sub>(this encrypts the new key). The first two output parameters are signed with the old key to ensure that ChipP knows it decoded K<sub>x </sub>correctly.
5417This whole procedure should only be allowed a given number of times. The actual number can conveniently be stored in the local M<sub>0</sub>[0] (eg word 0 of M<sub>0</sub>) with ReadOnly permission. Of course another chip could perform an Authorised write to update the number (via a ChipS) should it be desired.
5418The GetProgramKey command is implemented by the following steps:
5419<tables id="TABLE-US-00386" num="00386"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>Loop through all of Flash, reading each word (will trigger checks)</entry></row><row><entry>Accept n</entry></row><row><entry>Restrict n to N</entry></row><row><entry>Accept R<sub>E</sub></entry></row><row><entry>If (M<sub>0</sub>[0] = 0)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Output 60 bytes of 0x00 # no more keys allowed to be generated</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>from this chipF</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Done</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>Advance R<sub>L</sub></entry></row><row><entry>SIG <img file="US7165824B2_D0227.tif" /> S<sub>Kn</sub>[R<sub>L</sub>|R<sub>E</sub>|C<sub>3</sub>] # calculation must take constant time</entry></row><row><entry>Tmp <img file="US7165824B2_D0228.tif" /> SIG ⊕ K<sub>X</sub></entry></row><row><entry>Output R<sub>L</sub></entry></row><row><entry>Output Tmp</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>Decrement M<sub>0</sub>[0]</entry><entry># reduce the number of allowable key</entry></row><row><entry>generations by 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>SIG <img file="US7165824B2_D0229.tif" /> S<sub>KX</sub>[R<sub>L</sub>|Tmp|C<sub>3</sub>]</entry><entry># calculation must take constant time</entry></row><row><entry>Output SIG</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 15.1.7 Random <ul id="ul0675" list-style="none"><li id="ul0675-0001" num="0000"><ul id="ul0676" list-style="none"><li id="ul0676-0001" num="5420">Input: None</li><li id="ul0676-0002" num="5421">Output: R<sub>L</sub>=[20 bytes]</li><li id="ul0676-0003" num="5422">Changes: None</li></ul></li></ul>
5423The Random command is used by a client to obtain an input for use in a subsequent authentication procedure. Since the Random command requires no input parameters, it is therefore simply 1 byte containing the RND opcode.
5424The output of the Random command from a trusted QA Chip can be fed straight into the non-trusted chip's Read command as part of the input parameters. There is no need for the client to store them at all, since they are not required again. However the Test command will only succeed if the data passed to the Read command was obtained first from the Random command.
5425If a caller only calls the Random function multiple times, the same output will be returned each time. R will only advance to the next random number in the sequence after a successful call to a function that returns or tests a signature (e.g. Test, see Section 15.1.13 on page 725 for more information).
5426The Random command is implemented by the following steps: <ul id="ul0677" list-style="none"><li id="ul0677-0001" num="0000"><ul id="ul0678" list-style="none"><li id="ul0678-0001" num="5427">Loop through all of Flash, reading each word (will trigger checks)</li><li id="ul0678-0002" num="5428">Output R<sub>L </sub><br /> 15.1.8 Read </li><li id="ul0678-0003" num="5429">Input: n, t, R<sub>E</sub>=[1 byte, 1 byte, 20 bytes]</li><li id="ul0678-0004" num="5430">Output: R<sub>L</sub>, M<sub>Lt</sub>, S<sub>Kn</sub>[R<sub>E</sub>|R<sub>L</sub>|C<sub>1</sub>|M<sub>Lt</sub>]=[20 bytes, 64 bytes, 20 bytes]</li><li id="ul0678-0005" num="5431">Changes: R<sub>L </sub></li></ul></li></ul>
5432The Read command is used to read the entire state data (M<sub>t</sub>) from an QA Chip. Only an QA Chip programmed with the correct value of K<sub>n </sub>can respond correctly to the Read request. The output bytestream from the Read command can be fed as the input bytestream to the Test command on a trusted QA Chip for verification, with M<sub>t </sub>stored for later use if Test returns success.
5433The input bytestream consists of the RD opcode followed by the key number to use for the signature, which M to read, and the bytes <b>0</b>–<b>19</b> of R<sub>E</sub>. 23 bytes are transferred in total. R<sub>E </sub>is obtained by calling the trusted QA Chip's Random command. The 20 bytes output by the trusted chip's Random command can therefore be fed directly into the non-trusted chip's Read command, with no need for these bits to be stored by System.
5434Calls to Read must wait for MinTicksRemaining to reach 0 to ensure that a minimum time will elapse between calls to Read.
5435The output values are calculated, MinTicksRemaining is updated, and the signature is returned. The contents of M<sub>Lt </sub>are transferred least significant byte to most significant byte. The signature S<sub>Kn</sub>[R<sub>E</sub>|R<sub>L</sub>|C<sub>1</sub>|M<sub>Lt</sub>] must be calculated in constant time.
5436The next random number is generated from R using a 160-bit maximal period LFSR (tap selections on bits <b>5</b>, <b>3</b>, <b>2</b>, and <b>0</b>). The initial 160-bit value for R is set up when the chip is programmed, and can be any random number except 0 (an LFSR filled with 0s will produce a never-ending stream of 0s). R is transformed by XORing bits <b>0</b>, <b>2</b>, <b>3</b>, and <b>5</b> together, and shifting all 160 bits right 1 bit using the XOR result as the input bit to b<sub>159</sub>. The process is shown in <figref idref="DRAWINGS">FIG. 347</figref> below.
5437Care should be taken when updating R since it lives in Flash. Program code must assume power could be removed at any time.
5438The Read command is implemented with the following steps:
5439<tables id="TABLE-US-00387" num="00387"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>Wait for MinTicksRemaining to become 0</entry></row><row><entry /><entry>Loop through all of Flash, reading each word (will trigger checks)</entry></row><row><entry /><entry>Accept n</entry></row><row><entry /><entry>Accept t</entry></row><row><entry /><entry>Restrict n to N</entry></row><row><entry /><entry>Restrict t to T</entry></row><row><entry /><entry>Accept R<sub>E</sub></entry></row><row><entry /><entry>Advance R<sub>L</sub></entry></row><row><entry /><entry>Output R<sub>L</sub></entry></row><row><entry /><entry>Output M<sub>Lt</sub></entry></row><row><entry /><entry>SIG <img file="US7165824B2_D0230.tif" /> S<sub>Kn</sub>[R<sub>E</sub>|R<sub>L</sub>|C<sub>1</sub>|M<sub>Lt</sub>] # calculation must take constant time</entry></row><row><entry /><entry>MinTicksRemaining <img file="US7165824B2_D0231.tif" /> MinTicks</entry></row><row><entry /><entry>Output Sig</entry></row><row><entry /><entry>Wait for MinTicksRemaining to become 0</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 15.1.9 Set Permissions <ul id="ul0679" list-style="none"><li id="ul0679-0001" num="0000"><ul id="ul0680" list-style="none"><li id="ul0680-0001" num="5440">Input: n, p, R<sub>E</sub>, P<sub>E</sub>, SIG<sub>E</sub>=[1 byte, 1 byte, 20 bytes, 4 bytes, 20 bytes]</li><li id="ul0680-0002" num="5441">Output: P<sub>p </sub></li><li id="ul0680-0003" num="5442">Changes: P<sub>p</sub>, R<sub>L </sub></li></ul></li></ul>
5443The SetPermissions command is used to securely update the contents of P<sub>p </sub>(containing QA Chip permissions). The WriteAuth command only attempts to replace P<sub>p </sub>if the new value is signed combined with our local R.
5444It is only possible to sign messages by knowing K<sub>n</sub>. This can be achieved by a call to the SignP command (because only a ChipS can know K<sub>n</sub>). It means that without a chip that can be used to produce the required signature, a write of any value to P<sub>p </sub>is not possible.
5445The process is very similar to Test, except that if the validation succeeds, the P<sub>E </sub>input parameter is additionally ORed with the current value for P<sub>p</sub>. Note that this is an OR, and not a replace. Since the SetParms command only sets bits in P<sub>p</sub>, the effect is to allow the permission bits corresponding to M[n] to progress from RW to either MSR, NMSR, or RO.
5446The SetPermissions command is implemented with the following steps:
5447<tables id="TABLE-US-00388" num="00388"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>Wait for MinTicksRemaining to become 0</entry></row><row><entry /><entry>Loop through all of Flash, reading each word (will trigger checks)</entry></row><row><entry /><entry>Accept n</entry></row><row><entry /><entry>Restrict n to N</entry></row><row><entry /><entry>Accept p</entry></row><row><entry /><entry>Restrict p to T+N</entry></row><row><entry /><entry>Accept R<sub>E</sub></entry></row><row><entry /><entry>Accept P<sub>E</sub></entry></row><row><entry /><entry>SIG<sub>L </sub><img file="US7165824B2_D0232.tif" /> S<sub>Kn </sub>[R<sub>L</sub>|R<sub>E</sub>|P<sub>E</sub>|C<sub>2</sub>] # calculation must take constant time</entry></row><row><entry /><entry>Accept SIG<sub>E</sub></entry></row><row><entry /><entry>If (SIG<sub>E </sub>= SIG<sub>L</sub>)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Update R<sub>L</sub></entry></row><row><entry /><entry>P<sub>P </sub><img file="US7165824B2_D0233.tif" /> P<sub>P </sub><img file="US7165824B2_D0234.tif" /> P<sub>E</sub></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>Output P<sub>P </sub># success or failure will be determined by receiver</entry></row><row><entry /><entry>MinTicksRemaining <img file="US7165824B2_D0235.tif" /> MinTicks</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 15.1.10 ReplaceKey <ul id="ul0681" list-style="none"><li id="ul0681-0001" num="0000"><ul id="ul0682" list-style="none"><li id="ul0682-0001" num="5448">Input: n, R<sub>E</sub>, V, SIG<sub>E</sub>=[1 byte, 20 bytes, 20 bytes, 20 bytes]</li><li id="ul0682-0002" num="5449">Output: Boolean (0x76=failure, 0x89=success)</li><li id="ul0682-0003" num="5450">Changes: K<sub>n</sub>, M<sub>L</sub>, R<sub>L </sub></li></ul></li></ul>
5451The ReplaceKey command is used to replace the specified key in the QA Chip flash memory. However K<sub>n </sub>can only be replaced if the previous value is known. A return byte of 0x89 is produced if the key was successfully updated, while 0x76 is returned for failure.
5452A ReplaceKey command consists of the WR<sub>A </sub>command opcode followed by 0x89, 0x76, and then the appropriate parameters. Note that the new key is not sent in the clear, it is sent encrypted with the signature of R<sub>L</sub>, R<sub>E </sub>and C<sub>3 </sub>(signed with the old key). The first two input parameters must be verified by generating a signature using the old key.
5453The ReplaceKey command is implemented with the following steps:
5454<tables id="TABLE-US-00389" num="00389"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>Loop through all of Flash, reading each word (will trigger checks)</entry></row><row><entry>Accept n</entry></row><row><entry>Restrict n to N</entry></row><row><entry>Accept R<sub>E </sub># session key from ChipF</entry></row><row><entry>Accept V # encrypted key</entry></row><row><entry>SIG<sub>L </sub><img file="US7165824B2_D0236.tif" /> S<sub>Kn</sub>[R<sub>E</sub>|V|C<sub>3</sub>] # calculation must take constant time</entry></row><row><entry>Accept SIG<sub>E</sub></entry></row><row><entry>If (SIG<sub>L </sub>= SIG<sub>E2</sub>) # comparison must take constant time</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>SIG<sub>L </sub><img file="US7165824B2_D0237.tif" /> S<sub>Kn</sub>[R<sub>L</sub>|R<sub>E</sub>|C<sub>3</sub>] # calculation must take constant time</entry></row><row><entry /><entry>Advance R<sub>L</sub></entry></row><row><entry /><entry>K<sub>E </sub><img file="US7165824B2_D0238.tif" /> SIG<sub>L </sub>⊕ V</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>K<sub>n </sub><img file="US7165824B2_D0239.tif" /> K<sub>E</sub></entry><entry># involves storing (K<sub>E </sub>⊕ R<sub>K</sub>) and (<img file="US7165824B2_D0240.tif" /> K<sub>E </sub>⊕</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>R<sub>K</sub>)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Output 0x89 # success</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Output 0x76 # failure</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 15.1.11 SignM <ul id="ul0683" list-style="none"><li id="ul0683-0001" num="0000"><ul id="ul0684" list-style="none"><li id="ul0684-0001" num="5455">Input: n, R<sub>X</sub>, R<sub>E</sub>, M<sub>E</sub>, SIG<sub>E</sub>, M<sub>desired</sub>=[1 byte, 20 bytes, 20 bytes, 64 bytes,32 bytes]</li><li id="ul0684-0002" num="5456">Output: R<sub>L</sub>, M<sub>new</sub>, S<sub>Kn</sub>[R<sub>E</sub>|R<sub>l</sub>|C<sub>1</sub>|M<sub>new</sub>]=[20 bytes, 64 bytes, 20 bytes]</li><li id="ul0684-0003" num="5457">Changes:R<sub>L </sub></li></ul></li></ul>
5458Note: The SignM command is only implemented in ChipS, and not in all QA Chips. The SignM command is used to produce a valid signed M for use in an authenticated write transaction. Only an QA Chip programmed with correct value of K<sub>n </sub>can respond correctly to the SignM request. The output bytestream from the SignM command can be fed as the input bytestream to the WriteA command on a different QA Chip.
5459The input bytestream consists of the SMR opcode followed by 1 byte containing the key number to use for generating the signature, 20 bytes of Rx (representing the number passed in as R to ChipU's READ command, i.e. typically 0), the output from the READ command (namely R<sub>E</sub>, M<sub>E</sub>, and SIG<sub>E</sub>), and finally the desired M to write to ChipU.
5460The SignM command only succeeds when SIG<sub>E</sub>=S<sub>K</sub>[R<sub>X</sub>|R<sub>E</sub>|C<sub>1</sub>|M<sub>E</sub>], indicating that the request was generated from a chip that knows K. This generation and comparison must take the same amount of time regardless of whether the input parameters are correct or not. If the times are not the same, an attacker can gain information about which bits of the supplied signature are incorrect. If the signatures match, then R<sub>L </sub>is updated to be the next random number in the sequence.
5461Since the SignM function generates signatures, the function must wait for the MinTicksRemaining register to reach 0 before processing takes place.
5462Once all the inputs have been verified, a new memory vector is produced by applying a specially stored P value (eg word 1 of M<sub>0</sub>) and M<sub>desired </sub>against M<sub>E</sub>. Effectively, it is performing a regular Write, but with separate P against someone else's M. The M<sub>new </sub>is signed with an updated R<sub>L </sub>(and the passed in R<sub>E</sub>), and all three values are output (the random number R<sub>L</sub>, M<sub>new</sub>, and the signature). The time taken to generate this signature must be the same regardless of the inputs.
5463Typically, the SignM command will be acting as a form of consumable command, so that a given ChipS can only generate a given number of signatures. The actual number can conveniently be stored in M<sub>0 </sub>(eg word 0 of M<sub>0</sub>) with ReadOnly permissions. Of course another chip could perform an Authorised write to update the number (using another ChipS) should it be desired.
5464The SignM command is implemented with the following steps:
5465<tables id="TABLE-US-00390" num="00390"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>Wait for MinTicksRemaining to become 0</entry></row><row><entry>Loop through all of Flash, reading each word (will trigger checks)</entry></row><row><entry>Accept n</entry></row><row><entry>Restrict n to N</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="140pt" align="left" /><tbody valign="top"><row><entry>Accept R<sub>X</sub></entry><entry># don't care what this number is</entry></row><row><entry>Accept R<sub>E</sub></entry></row><row><entry>Accept M<sub>E</sub></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>SIG<sub>L </sub><img file="US7165824B2_D0241.tif" /> S<sub>Kn</sub>[R<sub>X</sub>|R<sub>E</sub>|C<sub>1</sub>|M<sub>E</sub>] # calculation must take constant time</entry></row><row><entry>Accept SIG<sub>E</sub></entry></row><row><entry>Accept M<sub>desired</sub></entry></row><row><entry>If ((SIG<sub>E </sub>≠ SIG<sub>L</sub>) OR (M<sub>L</sub>[0] = 0)) # fail if bad signature or if</entry></row><row><entry>allowed sigs = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="112pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry>Output appropriate number of 0</entry><entry># report failure</entry></row><row><entry /><entry>Done</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>Update R<sub>L</sub></entry></row><row><entry># Create the new version of M in ram from W and Permissions</entry></row><row><entry># This is the same as the core process of Write function</entry></row><row><entry># except that we don't write the results back to M</entry></row><row><entry>DecEncountered <img file="US7165824B2_D0242.tif" /> 0</entry></row><row><entry>EqEncountered <img file="US7165824B2_D0243.tif" /> 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="126pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><tbody valign="top"><row><entry>Permissions = M<sub>L</sub>[1]</entry><entry># assuming M<sub>0</sub></entry></row><row><entry>contains appropriate permissions</entry></row><row><entry>For n <img file="US7165824B2_D0244.tif" /> msw to lsw #(word 15 to 0)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>AM <img file="US7165824B2_D0245.tif" /> Permissions[n]</entry></row><row><entry /><entry>LT <img file="US7165824B2_D0246.tif" /> (M<sub>desired</sub>[n] < M<sub>E</sub>[n]) # comparison is unsigned</entry></row><row><entry /><entry>EQ <img file="US7165824B2_D0247.tif" /> (M<sub>desired</sub>[n] = M<sub>E</sub>[n])</entry></row><row><entry /><entry>WE <img file="US7165824B2_D0248.tif" /> (AM = RW) <img file="US7165824B2_D0249.tif" /> ((AM = MSR) <img file="US7165824B2_D0250.tif" /> LT) <img file="US7165824B2_D0251.tif" /></entry></row><row><entry /><entry>((AM = NMSR) <img file="US7165824B2_D0252.tif" /></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>(DecEncountered <img file="US7165824B2_D0253.tif" /> LT))</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>DecEncountered <img file="US7165824B2_D0254.tif" /> ((AM = MSR) <img file="US7165824B2_D0255.tif" /> LT)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry><img file="US7165824B2_D0256.tif" /> ((AM = NMSR) <img file="US7165824B2_D0257.tif" /> DecEncountered)</entry></row><row><entry /><entry><img file="US7165824B2_D0258.tif" /> ((AM = NMSR) <img file="US7165824B2_D0259.tif" /> EqEncountered <img file="US7165824B2_D0260.tif" /> LT)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EqEncountered <img file="US7165824B2_D0261.tif" /> ((AM = MSR) <img file="US7165824B2_D0262.tif" /> EQ) <img file="US7165824B2_D0263.tif" /> ((AM =</entry></row><row><entry /><entry>NMSR) <img file="US7165824B2_D0264.tif" /></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EqEncountered <img file="US7165824B2_D0265.tif" /> EQ)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>If (<img file="US7165824B2_D0266.tif" /> WE) <img file="US7165824B2_D0267.tif" /> (M<sub>E</sub>[n] ≠ M<sub>desired</sub>[n])</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="112pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><tbody valign="top"><row><entry /><entry>Output appropriate number of 0</entry><entry># report failure</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndFor</entry></row><row><entry># At this point, M<sub>desired </sub>is correct</entry></row><row><entry>Output R<sub>L</sub></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="98pt" align="left" /><colspec colname="2" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>Output M<sub>desired</sub></entry><entry># M<sub>desired </sub>is now effectively M<sub>new</sub></entry></row><row><entry>Sig <img file="US7165824B2_D0268.tif" /> S<sub>Kn</sub>[R<sub>E</sub>|R<sub>L</sub>|C<sub>1</sub>|M<sub>desired</sub>]</entry><entry># calculation must take constant time</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>MinTicksRemaining <img file="US7165824B2_D0269.tif" /> MinTicks</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>Decrement M<sub>L</sub>[0]</entry><entry># reduce the number of allowable signatures</entry></row><row><entry>by</entry></row><row><entry>1</entry></row><row><entry>Output Sig</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 15.1.12 SignP <ul id="ul0685" list-style="none"><li id="ul0685-0001" num="0000"><ul id="ul0686" list-style="none"><li id="ul0686-0001" num="5466">Input: n,R<sub>E</sub>,P<sub>desired</sub>=[1 byte, 20 bytes, 4 bytes]</li><li id="ul0686-0002" num="5467">Output: R<sub>L</sub>, S<sub>Kn</sub>[R<sub>E</sub>|R<sub>L</sub>|P<sub>desired</sub>|C<sub>2</sub>]=[20 bytes, 20 bytes]</li><li id="ul0686-0003" num="5468">Changes: R<sub>L </sub></li></ul></li></ul>
5469Note: The SignP command is only implemented in ChipS, and not in all QA Chips.
5470The SignP command is used to produce a valid signed P for use in a SetPermissions transaction.
5471Only an QA Chip programmed with correct value of K<sub>n </sub>can respond correctly to the SignP request. The output bytestream from the SignP command can be fed as the input bytestream to the SetPermissions command on a different QA Chip.
5472The input bytestream consists of the SMP opcode followed by 1 byte containing the key number to use for generating the signature, 20 bytes of R<sub>E </sub>(representing the number obtained from ChipU's RND command, and finally the desired P to write to ChipU.
5473Since the SignP function generates signatures, the function must wait for the MinTicksRemaining register to reach 0 before processing takes place.
5474Once all the inputs have been verified, the P<sub>desired </sub>is signed with an updated R<sub>L </sub>(and the passed in R<sub>E</sub>), and both values are output (the random number R<sub>L </sub>and the signature). The time taken to generate this signature must be the same regardless of the inputs.
5475Typically, the SignP command will be acting as a form of consumable command, so that a given ChipS can only generate a given number of signatures. The actual number can conveniently be stored in M<sub>0 </sub>(eg word 0 of M<sub>0</sub>) with ReadOnly permissions. Of course another chip could perform an Authorised write to update the number (using another ChipS) should it be desired.
5476The SignM command is implemented with the following steps:
5477<tables id="TABLE-US-00391" num="00391"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>Wait for MinTicksRemaining to become 0</entry></row><row><entry>Loop through all of Flash, reading each word (will trigger checks)</entry></row><row><entry>Accept n</entry></row><row><entry>Restrict n to N</entry></row><row><entry>Accept R<sub>E</sub></entry></row><row><entry>Accept P<sub>desired</sub></entry></row><row><entry>If (M<sub>L</sub>[0] = 0) # fail if allowed sigs = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="112pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry>Output appropriate number of 0</entry><entry># report failure</entry></row><row><entry /><entry>Done</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>Update R<sub>L</sub></entry></row><row><entry>Output R<sub>L</sub></entry></row><row><entry>Sig <img file="US7165824B2_D0270.tif" /> S<sub>Kn</sub>[R<sub>E</sub>|R<sub>L</sub>|P<sub>desired</sub>|C<sub>2</sub>] # calculation must take constant time</entry></row><row><entry>MinTicksRemaining <img file="US7165824B2_D0271.tif" /> MinTicks</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>Decrement M<sub>L</sub>[0]</entry><entry># reduce the number of allowable signatures by</entry></row><row><entry>1</entry></row><row><entry>Output Sig</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 15.1.13 Test <ul id="ul0687" list-style="none"><li id="ul0687-0001" num="0000"><ul id="ul0688" list-style="none"><li id="ul0688-0001" num="5478">Input: n, R<sub>E</sub>, M<sub>E</sub>, SIG<sub>E</sub>=[1 byte, 20 bytes, 64 bytes, 20 bytes]</li><li id="ul0688-0002" num="5479">Output: Boolean (0x76=failure, 0x89=success)</li><li id="ul0688-0003" num="5480">Changes: R<sub>L </sub></li></ul></li></ul>
5481The Test command is used to authenticate a read of an M from a non-trusted QA Chip.
5482The Test command consists of the TST command opcode followed by input parameters: n, R<sub>E</sub>, M<sub>E</sub>, and SIG<sub>E</sub>. The byte order is least significant byte to most significant byte for each command component. All but the first input parameter bytes are obtained as the output bytes from a Read command to a non-trusted QA Chip. The entire data does not have to be stored by the client. Instead, the bytes can be passed directly to the trusted QA Chip's Test command, and only M should be kept from the Read.
5483Calls to Test must wait for the MinTicksRemaining register to reach 0.
5484S<sub>Kn</sub>[R<sub>L</sub>|R<sub>E</sub>|C<sub>1</sub>|M<sub>E</sub>] is then calculated, and compared against the input signature SIG<sub>E</sub>. If they are different, R<sub>L </sub>is not changed, and 0x76 is returned to indicate failure. If they are the same, then R<sub>L </sub>is updated to be the next random number in the sequence and 0x89 is returned to indicate success. Updating R<sub>L </sub>only after success forces the caller to use a new random number (via the Random command) each time a successful authentication is performed.
5485The calculation of S<sub>Kn</sub>[R<sub>L</sub>|R<sub>E</sub>|C<sub>1</sub>|M<sub>E</sub>] and the comparison against SIG<sub>E </sub>must take identical time so that the time to evaluate the comparison in the TST function is always the same. Thus no attacker can compare execution times or number of bits processed before an output is given.
5486The Test command is implemented with the following steps:
5487<tables id="TABLE-US-00392" num="00392"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>Wait for MinTicksRemaining to become 0</entry></row><row><entry>Loop through all of Flash, reading each word (will trigger checks)</entry></row><row><entry>Accept n</entry></row><row><entry>Restrict n to N</entry></row><row><entry>Accept R<sub>E</sub></entry></row><row><entry>Accept M<sub>E</sub></entry></row><row><entry>SIG<sub>L </sub><img file="US7165824B2_D0272.tif" /> S<sub>Kn</sub>[R<sub>L</sub>|R<sub>E</sub>|C<sub>1</sub>|M<sub>E</sub>] # calculation must take constant time</entry></row><row><entry>Accept SIG<sub>E</sub></entry></row><row><entry>If (SIG<sub>E </sub>= SIG<sub>L</sub>)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Update R<sub>L</sub></entry></row><row><entry /><entry>Output 0x89 # success</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="105pt" align="left" /><colspec colname="2" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry>Output 0x76</entry><entry># report failure</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>MinTicksRemaining <img file="US7165824B2_D0273.tif" /> MinTicks</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 15.1.14 Write <ul id="ul0689" list-style="none"><li id="ul0689-0001" num="0000"><ul id="ul0690" list-style="none"><li id="ul0690-0001" num="5488">Input: t, M<sub>new</sub>, SIG<sub>E</sub>=[1 byte, 64 bytes, 20 bytes]</li><li id="ul0690-0002" num="5489">Output: Boolean (0x76=failure, 0x89=success)</li><li id="ul0690-0003" num="5490">Changes: M<sub>t </sub></li></ul></li></ul>
5491The Write command is used to update M<sub>t </sub>according to the permissions in P<sub>t</sub>. The WR command by itself is not secure, since a clone QA Chip may simply return success every time. Therefore a Write command should be followed by an authenticated read of M<sub>t </sub>(e.g. via a Read command) to ensure that the change was actually made.
5492The Write command is called by passing the WR command opcode followed by which M to be updated, the new data to be written to M, and a digital signature of M. The data is sent least significant byte to most significant byte.
5493The ability to write to a specific 32-bit word within M<sub>t </sub>is governed by the corresponding Permissions bits as stored in P<sub>t</sub>. P<sub>t </sub>can be set using the SetPermissions command.
5494The fact that M<sub>t </sub>is Flash memory must be taken into account when writing the new value to M. It is possible for an attacker to remove power at any time. In addition, only the changes to M should be stored for maximum utilization. In addition, the longevity of M will need to be taken into account. This may result in the location of M being updated.
5495The signature is not keyed, since it must be generated by the consumable user.
5496The Write command is implemented with the following steps:
5497<tables id="TABLE-US-00393" num="00393"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>Loop through all of Flash, reading each word (will trigger checks)</entry></row><row><entry /><entry>Accept t</entry></row><row><entry /><entry>Restrict t to T</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>Accept M<sub>E</sub></entry><entry># new M</entry></row><row><entry /><entry>Accept SIG<sub>E</sub></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>SIG<sub>L </sub>= Generate SHA1[M<sub>E</sub>]</entry></row><row><entry /><entry>If (SIG<sub>L </sub>= SIG<sub>E</sub>)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>output 0x76 # failure due to invalid signature</entry></row><row><entry /><entry>exit</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>DecEncountered <img file="US7165824B2_D0274.tif" /> 0</entry></row><row><entry /><entry>EqEncountered <img file="US7165824B2_D0275.tif" /> 0</entry></row><row><entry /><entry>For i <img file="US7165824B2_D0276.tif" /> msw to lsw #(word 15 to 0)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>P <img file="US7165824B2_D0277.tif" /> P<sub>t</sub>[i]</entry></row><row><entry /><entry>LT <img file="US7165824B2_D0278.tif" /> (M<sub>E</sub>[i] < M<sub>t</sub>[i]) # comparison is unsigned</entry></row><row><entry /><entry>EQ <img file="US7165824B2_D0279.tif" /> (M<sub>E</sub>[i] = M<sub>t</sub>[i])</entry></row><row><entry /><entry>WE <img file="US7165824B2_D0280.tif" /> (P = RW) <img file="US7165824B2_D0281.tif" /> ((P = MSR) <img file="US7165824B2_D0282.tif" /> LT) <img file="US7165824B2_D0283.tif" /> ((P = NMSR) <img file="US7165824B2_D0284.tif" /></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>(DecEncountered <img file="US7165824B2_D0285.tif" /> LT))</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>DecEncountered <img file="US7165824B2_D0286.tif" /> ((P = MSR) <img file="US7165824B2_D0287.tif" /> LT)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry><img file="US7165824B2_D0288.tif" /> ((P = NMSR) <img file="US7165824B2_D0289.tif" /> DecEncountered)</entry></row><row><entry /><entry><img file="US7165824B2_D0290.tif" /> ((P = NMSR) <img file="US7165824B2_D0291.tif" /> EqEncountered <img file="US7165824B2_D0292.tif" /> LT)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EqEncountered <img file="US7165824B2_D0293.tif" /> ((P = MSR) <img file="US7165824B2_D0294.tif" /> EQ) <img file="US7165824B2_D0295.tif" /> ((P = NMSR) <img file="US7165824B2_D0296.tif" /></entry></row><row><entry /><entry>EqEncountered</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry><img file="US7165824B2_D0297.tif" /> EQ)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>If (<img file="US7165824B2_D0298.tif" /> WE)<img file="US7165824B2_D0299.tif" /> (M<sub>E</sub>[i] ≠ M<sub>t</sub>[i])</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>output 0x76 # failure due to wanting a change but not</entry></row><row><entry /><entry>allowed</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>it</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndFor</entry></row><row><entry /><entry># At this point, M<sub>E </sub>(desired) is correct to be written to the</entry></row><row><entry /><entry>flash</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>M<sub>t </sub><img file="US7165824B2_D0300.tif" /> M<sub>E</sub></entry><entry># update flash</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="119pt" align="left" /><tbody valign="top"><row><entry /><entry>output 0x89</entry><entry># success</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 15.1.15 WriteAuth <ul id="ul0691" list-style="none"><li id="ul0691-0001" num="0000"><ul id="ul0692" list-style="none"><li id="ul0692-0001" num="5498">Input: n, R<sub>E</sub>, M<sub>E</sub>, SIG<sub>E</sub>=[1 byte, 20 bytes, 64 bytes, 20 bytes]</li><li id="ul0692-0002" num="5499">Output: Boolean (0x76=failure, 0x89=success)</li><li id="ul0692-0003" num="5500">Changes:M<sub>0</sub>, R<sub>L </sub></li></ul></li></ul>
5501The WriteAuth command is used to securely replace the entire contents of M<sub>0 </sub>(containing QA Chip application specific data) according to the P<sub>T+n</sub>. The WriteAuth command only attempts to replace M<sub>0 </sub>if the new value is signed combined with our local R.
5502It is only possible to sign messages by knowing K<sub>n</sub>. This can be achieved by a call to the SignM command (because only a ChipS can know K<sub>n</sub>). It means that without a chip that can be used to produce the required signature, a write of any value to M<sub>0 </sub>is not possible.
5503The process is very similar to Write, except that if the validation succeeds, the M<sub>E </sub>input parameter is processed against M<sub>0 </sub>using permissions P<sub>T+n</sub>.
5504The WriteAuth command is implemented with the following steps:
5505<tables id="TABLE-US-00394" num="00394"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>Wait for MinTicksRemaining to become 0</entry></row><row><entry>Loop through all of Flash, reading each word (will trigger checks)</entry></row><row><entry>Accept n</entry></row><row><entry>Restrict n to N</entry></row><row><entry>Accept R<sub>E</sub></entry></row><row><entry>Accept M<sub>E</sub></entry></row><row><entry>SIG<sub>L </sub><img file="US7165824B2_D0301.tif" /> S<sub>Kn</sub>[R<sub>L</sub>|R<sub>E</sub>|C<sub>1</sub>|M<sub>E</sub>] # calculation must take constant time</entry></row><row><entry>Accept SIG<sub>E</sub></entry></row><row><entry>If (SIG<sub>E </sub>= SIG<sub>L</sub>)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Update R<sub>L</sub></entry></row><row><entry /><entry>DecEncountered <img file="US7165824B2_D0302.tif" /> 0</entry></row><row><entry /><entry>EqEncountered <img file="US7165824B2_D0303.tif" /> 0</entry></row><row><entry /><entry>For i <img file="US7165824B2_D0304.tif" /> msw to lsw #(word 15 to 0)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>P <img file="US7165824B2_D0305.tif" /> P<sub>T+n</sub>[i]</entry></row><row><entry /><entry>LT <img file="US7165824B2_D0306.tif" /> (M<sub>E</sub>[i] < M<sub>0</sub>[i]) # comparison is unsigned</entry></row><row><entry /><entry>EQ <img file="US7165824B2_D0307.tif" /> (M<sub>E</sub>[i] = M<sub>0</sub>[i])</entry></row><row><entry /><entry>WE <img file="US7165824B2_D0308.tif" /> (P = RW)<img file="US7165824B2_D0309.tif" /> ((P = MSR)<img file="US7165824B2_D0310.tif" /> LT) <img file="US7165824B2_D0311.tif" /> ((P = NMSR) <img file="US7165824B2_D0312.tif" /></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>(DecEncountered <img file="US7165824B2_D0313.tif" /> LT))</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>DecEncountered <img file="US7165824B2_D0314.tif" /> ((P = MSR) <img file="US7165824B2_D0315.tif" /> LT)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry><img file="US7165824B2_D0316.tif" /> ((P = NMSR) <img file="US7165824B2_D0317.tif" /> DecEncountered)</entry></row><row><entry /><entry><img file="US7165824B2_D0318.tif" /> ((P = NMSR) <img file="US7165824B2_D0319.tif" /> EqEncountered <img file="US7165824B2_D0320.tif" /> LT)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EqEncountered <img file="US7165824B2_D0321.tif" /> ((P = MSR) <img file="US7165824B2_D0322.tif" /> EQ) <img file="US7165824B2_D0323.tif" /> ((P = NMSR) <img file="US7165824B2_D0324.tif" /></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EqEncountered <img file="US7165824B2_D0325.tif" /> EQ)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>If ((<img file="US7165824B2_D0326.tif" /> WE) <img file="US7165824B2_D0327.tif" /> (M<sub>E</sub>[i] ≠ M<sub>0</sub>[i]))</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>output 0x76 # failure due to wanting a change but not</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>allowed it</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndFor</entry></row><row><entry /><entry># At this point, M<sub>E </sub>(desired) is correct to be written to the</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>flash</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>M<sub>0 </sub><img file="US7165824B2_D0328.tif" /> M<sub>E</sub></entry><entry># update flash</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="98pt" align="left" /><colspec colname="2" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry>output 0x89</entry><entry># success</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>MinTicksRemaining <img file="US7165824B2_D0329.tif" /> MinTicks</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 16 Manufacture
5506This chapter makes some general comments about the manufacture and implementation of authentication chips. While the comments presented here are general, see [84] for a detailed description of an implementation of an authentication chip.
5507The authentication chip algorithms do not constitute a strong encryption device. The net effect is that they can be safely manufactured in any country (including the USA) and exported to anywhere in the world.
5508The circuitry of the authentication chip must be resistant to physical attack. A summary of manufacturing implementation guidelines is presented, followed by specification of the chip's physical defenses (ordered by attack).
5509Note that manufacturing comments are in addition to any legal protection undertaken, such as patents, copyright, and license agreements (for example, penalties if caught reverse engineering the authentication chip).
000016.1 Guidelines for Manufacturing
5510The following are general guidelines for implementation of an authentication chip in terms of manufacture (see [84] for a detailed description of an authentication chip). No special security is required during the manufacturing process. <ul id="ul0693" list-style="none"><li id="ul0693-0001" num="0000"><ul id="ul0694" list-style="none"><li id="ul0694-0001" num="5511">Standard process</li><li id="ul0694-0002" num="5512">Minimum size (if possible)</li><li id="ul0694-0003" num="5513">Clock Filter</li><li id="ul0694-0004" num="5514">Noise Generator</li><li id="ul0694-0005" num="5515">Tamper Prevention and Detection circuitry</li><li id="ul0694-0006" num="5516">Protected memory with tamper detection</li><li id="ul0694-0007" num="5517">Boot circuitry for loading program code</li><li id="ul0694-0008" num="5518">Special implementation of FETs for key data paths</li><li id="ul0694-0009" num="5519">Data connections in polysilicon layers where possible</li><li id="ul0694-0010" num="5520">OverUnderPower Detection Unit</li><li id="ul0694-0011" num="5521">No test circuitry</li><li id="ul0694-0012" num="5522">Transparent epoxy packaging</li></ul></li></ul>
5523Finally, as a general note to manufacturers of Systems, the data line to the System authentication chip and the data line to the Consumable authentication chip must not be the same line. See Section 16.2.3 on page 736.
000016.1.1 Standard Process
5524The authentication chip should be implemented with a standard manufacturing process (such as Flash). This is necessary to: <ul id="ul0695" list-style="none"><li id="ul0695-0001" num="0000"><ul id="ul0696" list-style="none"><li id="ul0696-0001" num="5525">allow a great range of manufacturing location options</li><li id="ul0696-0002" num="5526">take advantage of well-defined and well-behaved technology</li><li id="ul0696-0003" num="5527">reduce cost</li></ul></li></ul>
5528Note that the standard process still allows physical protection mechanisms.
000016.1.2 Minimum Size
5529The authentication chip must have a low manufacturing cost in order to be included as the authentication mechanism for low cost consumables. It is therefore desirable to keep the chip size as low as reasonably possible.
5530Each authentication chip requires 962 bits of non-volatile memory. In addition, the storage required for optimized HMAC-SHA1 is 1024 bits. The remainder of the chip (state machine, processor, CPU or whatever is chosen to implement Protocol C1) must be kept to a minimum in order that the number of transistors is minimized and thus the cost per chip is minimized. The circuit areas that process the secret key information or could reveal information about the key should also be minimized (see Section 16.1.8 on page 734 for special data paths).
000016.1.3 Clock Filter
5531The authentication chip circuitry is designed to operate within a specific clock speed range. Since the user directly supplies the clock signal, it is possible for an attacker to attempt to introduce race-conditions in the circuitry at specific times during processing. An example of this is where a high clock speed (higher than the circuitry is designed for) may prevent an XOR from working properly, and of the two inputs, the first may always be returned. These styles of transient fault attacks can be very efficient at recovering secret key information, and have been documented in [5] and [1]. The lesson to be learned from this is that the input clock signal cannot be trusted.
5532Since the input clock signal cannot be trusted, it must be limited to operate up to a maximum frequency. This can be achieved a number of ways.
5533One way to filter the clock signal is to use an edge detect unit passing the edge on to a delay, which in turn enables the input clock signal to pass through.
5534<figref idref="DRAWINGS">FIG. 348</figref> shows clock signal flow within the Clock Filter.
5535The delay should be set so that the maximum clock speed is a particular frequency (e.g. about 4 MHz). Note that this delay is not programmable—it is fixed.
5536The filtered clock signal would be further divided internally as required.
000016.1.4 Noise Generator
5537Each authentication chip should contain a noise generator that generates continuous circuit noise. The noise will interfere with other electromagnetic emissions from the chip's regular activities and add noise to the I<sub>dd </sub>signal. Placement of the noise generator is not an issue on an authentication chip due to the length of the emission wavelengths.
5538The noise generator is used to generate electronic noise, multiple state changes each clock cycle, and as a source of pseudo-random bits for the Tamper Prevention and Detection circuitry (see Section 16.1.5 on page 731).
5539A simple implementation of a noise generator is a 64-bit maximal period LFSR seeded with a non-zero number. The clock used for the noise generator should be running at the maximum clock rate for the chip in order to generate as much noise as possible.
000016.1.5 Tamper Prevention and Detection Circuitry
5540A set of circuits is required to test for and prevent physical attacks on the authentication chip. However what is actually detected as an attack may not be an intentional physical attack. It is therefore important to distinguish between these two types of attacks in an authentication chip: <ul id="ul0697" list-style="none"><li id="ul0697-0001" num="0000"><ul id="ul0698" list-style="none"><li id="ul0698-0001" num="5541">where you can be certain that a physical attack has occurred.</li><li id="ul0698-0002" num="5542">where you cannot be certain that a physical attack has occurred.</li></ul></li></ul>
5543The two types of detection differ in what is performed as a result of the detection. In the first case, where the circuitry can be certain that a true physical attack has occurred, erasure of Flash memory key information is a sensible action. In the second case, where the circuitry cannot be sure if an attack has occurred, there is still certainly something wrong. Action must be taken, but the action should not be the erasure of secret key information. A suitable action to take in the second case is a chip RESET. If what was detected was an attack that has permanently damaged the chip, the same conditions will occur next time and the chip will RESET again. If, on the other hand, what was detected was part of the normal operating environment of the chip, a RESET will not harm the key.
5544A good example of an event that circuitry cannot have knowledge about, is a power glitch. The glitch may be an intentional attack, attempting to reveal information about the key. It may, however, be the result of a faulty connection, or simply the start of a power-down sequence. It is therefore best to only RESET the chip, and not erase the key. If the chip was powering down, nothing is lost. If the System is faulty, repeated RESETs will cause the consumer to get the System repaired. In both cases the consumable is still intact.
5545A good example of an event that circuitry can have knowledge about, is the cutting of a data line within the chip. If this attack is somehow detected, it could only be a result of a faulty chip (manufacturing defect) or an attack. In either case, the erasure of the secret information is a sensible step to take.
5546Consequently each authentication chip should have 2 Tamper Detection Lines—one for definite attacks, and one for possible attacks. Connected to these Tamper Detection Lines would be a number of Tamper Detection test units, each testing for different forms of tampering. In addition, we want to ensure that the Tamper Detection Lines and Circuits themselves cannot also be tampered with.
5547At one end of the Tamper Detection Line is a source of pseudo-random bits (clocking at high speed compared to the general operating circuitry). The Noise Generator circuit described above is an adequate source. The generated bits pass through two different paths—one carries the original data, and the other carries the inverse of the data. The wires carrying these bits are in the layer above the general chip circuitry (for example, the memory, the key manipulation circuitry etc.). The wires must also cover the random bit generator. The bits are recombined at a number of places via an XOR gate. If the bits are different (they should be), a 1 is output, and used by the particular unit (for example, each output bit from a memory read should be ANDed with this bit value). The lines finally come together at the Flash memory Erase circuit, where a complete erasure is triggered by a 0 from the XOR. Attached to the line is a number of triggers, each detecting a physical attack on the chip. Each trigger has an oversize nMOS transistor attached to GND. The Tamper Detection Line physically goes through this nMOS transistor. If the test fails, the trigger causes the Tamper Detect Line to become 0. The XOR test will therefore fail on either this clock cycle or the next one (on average), thus RESETing or erasing the chip.
5548<figref idref="DRAWINGS">FIG. 349</figref> illustrates the basic principle of a Tamper Detection Line in terms of tests and the XOR connected to either the Erase or RESET circuitry.
5549The Tamper Detection Line must go through the drain of an output transistor for each test, as illustrated by <figref idref="DRAWINGS">FIG. 350</figref>:
5550It is not possible to break the Tamper Detect Line since this would stop the flow of 1 s and 0s from the random source. The XOR tests would therefore fail. As the Tamper Detect Line physically passes through each test, it is not possible to eliminate any particular test without breaking the Tamper Detect Line.
5551It is important that the XORs take values from a variety of places along the Tamper Detect Lines in order to reduce the chances of an attack. <figref idref="DRAWINGS">FIG. 351</figref> illustrates the taking of multiple XORs from the Tamper Detect Line to be used in the different parts of the chip. Each of these XORs can be considered to be generating a ChipOK bit that can be used within each unit or sub-unit.
5552A sample usage would be to have an OK bit in each unit that is ANDed with a given ChipOK bit each cycle. The OK bit is loaded with 1 on a RESET. If OK is 0, that unit will fail until the next RESET. If the Tamper Detect Line is functioning correctly, the chip will either RESET or erase all key information. If the RESET or erase circuitry has been destroyed, then this unit will not function, thus thwarting an attacker.
5553The destination of the RESET and Erase line and associated circuitry is very context sensitive. It needs to be protected in much the same way as the individual tamper tests. There is no point generating a RESET pulse if the attacker can simply cut the wire leading to the RESET circuitry. The actual implementation will depend very much on what is to be cleared at RESET, and how those items are cleared.
5554Finally, <figref idref="DRAWINGS">FIG. 352</figref> shows how the Tamper Lines cover the noise generator circuitry of the chip. The generator and NOT gate are on one level, while the Tamper Detect Lines run on a level above the generator.
000016.1.6 Protected Memory with Tamper Detection
5555It is not enough to simply store secret information or program code in Flash memory. The Flash memory and RAM must be protected from an attacker who would attempt to modify (or set) a particular bit of program code or key information. The mechanism used must conform to being used in the Tamper Detection Circuitry (described above).
5556The first part of the solution is to ensure that the Tamper Detection Line passes directly above each Flash or RAM bit. This ensures that an attacker cannot probe the contents of Flash or RAM. A breach of the covering wire is a break in the Tamper Detection Line. The breach causes the Erase signal to be set, thus deleting any contents of the memory. The high frequency noise on the Tamper Detection Line also obscures passive observation.
5557The second part of the solution for Flash is to use multi-level data storage, but only to use a subset of those multiple levels for valid bit representations. Normally, when multi-level Flash storage is used, a single floating gate holds more than one bit. For example, a 4-voltage-state transistor can represent two bits. Assuming a minimum and maximum voltage representing 00 and 11 respectively, the two middle voltages represent 01 and 10. In the authentication chip, we can use the two middle voltages to represent a single bit, and consider the two extremes to be invalid states. If an attacker attempts to force the state of a bit one way or the other by closing or cutting the gate's circuit, an invalid voltage (and hence invalid state) results.
5558The second part of the solution for RAM is to use a parity bit. The data part of the register can be checked against the parity bit (which will not match after an attack).
5559The bits coming from Flash and RAM can therefore be validated by a number of test units (one per bit) connected to the common Tamper Detection Line. The Tamper Detection circuitry would be the first circuitry the data passes through (thus stopping an attacker from cutting the data lines).
5560While the multi-level Flash protection is enough for non-secret information, such as program code, R, and MinTicks, it is not sufficient for protecting K<sub>1 </sub>and K<sub>2</sub>. If an attacker adds electrons to a gate (see Section 5.7.2.15 on page 656) representing a single bit of K<sub>1</sub>, and the chip boots up yet doesn't activate the Tamper Detection Line, the key bit must have been a 0. If it does activate the Tamper Detection Line, it must have been a 1. For this reason, all other non-volatile memory can activate the Tamper Detection Line, but K<sub>1 </sub>and K<sub>2 </sub>must not. Consequently Checksum is used to check for tampering of K<sub>1 </sub>and K<sub>2</sub>. A signature of the expanded form of K<sub>1 </sub>and K<sub>2 </sub>(i.e. 320 bits instead of 160 bits for each of K<sub>1 </sub>and K<sub>2</sub>) is produced, and the result compared against the Checksum. Any non-match causes a clear of all key information.
000016.1.7 Boot Circuitry for Loading Program Code
5561Program code should be kept in multi-level Flash instead of ROM, since ROM is subject to being altered in a non-testable way. A boot mechanism is therefore required to load the program code into Flash memory (Flash memory is in an indeterminate state after manufacture).
5562The boot circuitry must not be in ROM—a small state-machine would suffice. Otherwise the boot code could be modified in an undetectable way.
5563The boot circuitry must erase all Flash memory, check to ensure the erasure worked, and then load the program code. Flash memory must be erased before loading the program code. Otherwise an attacker could put the chip into the boot state, and then load program code that simply extracted the existing keys. The state machine must also check to ensure that all Flash memory has been cleared (to ensure that an attacker has not cut the Erase line) before loading the new program code.
5564The loading of program code must be undertaken by the secure Programming Station before secret information (such as keys) can be loaded. This step must be undertaken as the first part of the programming process.
000016.1.8 Special Implementation of FETs for Key Data Paths
5565The normal situation for FET implementation for the case of a CMOS Inverter (which involves a pMOS transistor combined with an nMOS transistor) as shown in <figref idref="DRAWINGS">FIG. 353</figref>:
5566During the transition, there is a small period of time where both the nMOS transistor and the pMOS transistor have an intermediate resistance. The resultant power-ground short circuit causes a temporary increase in the current, and in fact accounts for the majority of current consumed by a CMOS device. A small amount of infrared light is emitted during the short circuit, and can be viewed through the silicon substrate (silicon is transparent to infrared light). A small amount of light is also emitted during the charging and discharging of the transistor gate capacitance and transmission line capacitance.
5567For circuitry that manipulates secret key information, such information must be kept hidden. An alternative non-flashing CMOS implementation should therefore be used for all data paths that manipulate the key or a partially calculated value that is based on the key.
5568The use of two non-overlapping clocks φ1 and φ2 can provide a non-flashing mechanism. φ1 is connected to a second gate of all nMOS transistors, and φ2 is connected to a second gate of all pMOS transistors. The transition can only take place in combination with the clock. Since φ1 and φ2 are non-overlapping, the pMOS and nMOS transistors will not have a simultaneous intermediate resistance. The setup is shown in <figref idref="DRAWINGS">FIG. 354</figref>:
5569Finally, regular CMOS inverters can be positioned near critical non-Flashing CMOS components. These inverters should take their input signal from the Tamper Detection Line above. Since the Tamper Detection Line operates multiple times faster than the regular operating circuitry, the net effect will be a high rate of light-bursts next to each non-Flashing CMOS component. Since a bright light overwhelms observation of a nearby faint light, an observer will not be able to detect what switching operations are occurring in the chip proper. These regular CMOS inverters will also effectively increase the amount of circuit noise, reducing the SNR and obscuring useful EMI.
5570There are a number of side effects due to the use of non-Flashing CMOS: <ul id="ul0699" list-style="none"><li id="ul0699-0001" num="0000"><ul id="ul0700" list-style="none"><li id="ul0700-0001" num="5571">The effective speed of the chip is reduced by twice the rise time of the clock per clock cycle. This is not a problem for an authentication chip.</li><li id="ul0700-0002" num="5572">The amount of current drawn by the non-Flashing CMOS is reduced (since the short circuits do not occur). However, this is offset by the use of regular CMOS inverters.</li><li id="ul0700-0003" num="5573">Routing of the clocks increases chip area, especially since multiple versions of φ1 and φ2 are required to cater for different levels of propagation. The estimation of chip area is double that of a regular implementation.</li><li id="ul0700-0004" num="5574">Design of the non-Flashing areas of the authentication chip are slightly more complex than to do the same with a with a regular CMOS design. In particular, standard cell components cannot be used, making these areas full custom. This is not a problem for something as small as an authentication chip, particularly when the entire chip does not have to be protected in this manner. <br /> 16.1.9 Connections in Polysilicon Layers where Possible </li></ul></li></ul>
5575Wherever possible, the connections along which the key or secret data flows, should be made in the polysilicon layers. Where necessary, they can be in metal 1, but must never be in the top metal layer (containing the Tamper Detection Lines).
000016.1.10 OverUnderPower Detection Unit
5576Each authentication chip requires an OverUnderPower Detection Unit to prevent Power Supply Attacks. An OverUnderPower Detection Unit detects power glitches and tests the power level against a Voltage Reference to ensure it is within a certain tolerance. The Unit contains a single Voltage Reference and two comparators. The OverUnderPower Detection Unit would be connected into the RESET Tamper Detection Line, thus causing a RESET when triggered.
5577A side effect of the OverUnderPower Detection Unit is that as the voltage drops during a power-down, a RESET is triggered, thus erasing any work registers.
000016.1.11 No Test Circuitry
5578Test hardware on an authentication chip could very easily introduce vulnerabilities. As a result, the authentication chip should not contain any BIST or scan paths.
5579The authentication chip must therefore be testable with external test vectors. This should be possible since the authentication chip is not complex.
000016.1.12 Transparent Epoxy Packaging
5580The authentication chip needs to be packaged in transparent epoxy so it can be photo-imaged by the programming station to prevent Trojan horse attacks. The transparent packaging does not compromise the security of the authentication chip since an attacker can fairly easily remove a chip from its packaging. For more information see Section 16.2.20 on page 743 and [86].
000016.2 Resistance to Physical Attacks
5581While this chapter only describes manufacture in general terms (since this document does not cover a specific implementation of a Protocol C1 authentication chip), we can still make some observations about such a chip's resistance to physical attack. A description of the general form of each physical attack can be found in Section 5.7.2 on page 652.
000016.2.1 Reading ROM
5582This attack depends on the key being stored in an addressable ROM. Since each authentication chip stores its authentication keys in internal Flash memory and not in an addressable ROM, this attack is irrelevant.
000016.2.2 Reverse Engineering the Chip
5583Reverse engineering a chip is only useful when the security of authentication lies in the algorithm alone. However our authentication chips rely on a secret key, and not in the secrecy of the algorithm. Our authentication algorithm is, by contrast, public, and in any case, an attacker of a high volume consumable is assumed to have been able to obtain detailed plans of the internals of the chip.
5584In light of these factors, reverse engineering the chip itself, as opposed to the stored data, poses no threat.
000016.2.3 Usurping the Authentication Process
5585There are several forms this attack can take, each with varying degrees of success. In all cases, it is assumed that a clone manufacturer will have access to both the System and the consumable designs.
5586An attacker may attempt to build a chip that tricks the System into returning a valid code instead of generating an authentication code. This attack is not possible for two reasons. The first reason is that System authentication chips and Consumable authentication chips, although physically identical, are programmed differently. In particular, the RD opcode and the RND opcode are the same, as are the WR and TST opcodes. A System authentication Chip cannot perform a RD command since every call is interpreted as a call to RND instead. The second reason this attack would fail is that separate serial data lines are provided from the System to the System and Consumable authentication chips. Consequently neither chip can see what is being transmitted to or received from the other.
5587If the attacker builds a clone chip that ignores WR commands (which decrement the consumable remaining), Protocol C1 ensures that the subsequent RD will detect that the WR did not occur. The System will therefore not go ahead with the use of the consumable, thus thwarting the attacker. The same is true if an attacker simulates loss of contact before authentication—since the authentication does not take place, the use of the consumable doesn't occur.
5588An attacker is therefore limited to modifying each System in order for clone consumables to be accepted (see Section 16.2.4 on page 737 for details of resistance this attack).
000016.2.4 Modification of System
5589The simplest method of modification is to replace the System's authentication chip with one that simply reports success for each call to TST. This can be thwarted by System calling TST several times for each authentication, with the first few times providing false values, and expecting a fail from TST. The final call to TST would be expected to succeed. The number of false calls to TST could be determined by some part of the returned result from RD or from the system clock. Unfortunately an attacker could simply rewire System so that the new System clone authentication chip can monitor the returned result from the consumable chip or clock. The clone System authentication chip would only return success when that monitored value is presented to its TST function. Clone consumables could then return any value as the hash result for RD, as the clone System chip would declare that value valid. There is therefore no point for the System to call the System authentication chip multiple times, since a rewiring attack will only work for the System that has been rewired, and not for all Systems.
5590A similar form of attack on a System is a replacement of the System ROM. The ROM program code can be altered so that the Authentication never occurs. There is nothing that can be done about this, since the System remains in the hands of a consumer. Of course this would void any warranty, but the consumer may consider the alteration worthwhile if the clone consumable were extremely cheap and more readily available than the original item.
5591The System/consumable manufacturer must therefore determine how likely an attack of this nature is. Such a study must include given the pricing structure of Systems and Consumables, frequency of System service, advantage to the consumer of having a physical modification performed, and where consumers would go to get the modification performed.
5592The likelihood of physical alteration increases with the perceived artificiality of the consumable marketing scheme. It is one thing for a consumable to be protected against clone manufacturers. It is quite another for a consumable's market to be protected by a form of exclusive licensing arrangement that creates what is viewed by consumers as artificial markets. In the former case, owners are not so likely to go to the trouble of modifying their system to allow a clone manufacturer's goods. In the latter case, consumers are far more likely to modify their System. A case in point is DVD. Each DVD is marked with a region code, and will only play in a DVD player from that region. Thus a DVD from the USA will not play in an Australian player, and a DVD from Japan, Europe or Australia will not play in a USA DVD player. Given that certain DVD titles are not available in all regions, or because of quality differences, pricing differences or timing of releases, many consumers have had their DVD players modified to accept DVDs from any region. The modification is usually simple (it often involves soldering a single wire), voids the owner's warranty, and often costs the owner some money. But the interesting thing to note is that the change is not made so the consumer can use clone consumables—the consumer will still only buy real consumables, but from different regions. The modification is performed to remove what is viewed as an artificial barrier, placed on the consumer by the movie companies. In the same way, a System/Consumable scheme that is viewed as unfair will result in people making modifications to their Systems.
5593The limit case of modifying a system is for a clone manufacturer to provide a completely clone System which takes clone consumables. This may be simple competition or violation of patents. Either way, it is beyond the scope of the authentication chip and depends on the technology or service being cloned.
000016.2.5 Direct Viewing of Chip Operation by Conventional Probing
5594In order to view the chip operation, the chip must be operating. However, the Tamper Prevention and Detection circuitry covers those sections of the chip that process or hold the key. It is not possible to view those sections through the Tamper Prevention lines.
5595An attacker cannot simply slice the chip past the Tamper Prevention layer, for this will break the Tamper Detection Lines and cause an erasure of all keys at power-up. Simply destroying the erasure circuitry is not sufficient, since the multiple ChipOK bits (now all 0) feeding into multiple units within the authentication chip will cause the chip's regular operating circuitry to stop functioning.
5596To set up the chip for an attack, then, requires the attacker to delete the Tamper Detection lines, stop the Erasure of Flash memory, and somehow rewire the components that relied on the ChipOK lines. Even if all this could be done, the act of slicing the chip to this level will most likely destroy the charge patterns in the non-volatile memory that holds the keys, making the process fruitless.
000016.2.6 Direct Viewing of the Non-volatile Memory
5597If the authentication chip were sliced so that the floating gates of the Flash memory were exposed, without discharging them, then the keys could probably be viewed directly using an STM or SKM. However, slicing the chip to this level without discharging the gates is probably impossible. Using wet etching, plasma etching, ion milling, or chemical mechanical polishing will almost certainly discharge the small charges present on the floating gates. This is true of regular Flash memory, but even more so of multi-level Flash memory.
000016.2.7 Viewing the Light Bursts Caused by State Changes
5598All sections of circuitry that manipulate secret key information are implemented in the non-Flashing CMOS described above. This prevents the emission of the majority of light bursts. Regular CMOS inverters placed in close proximity to the non-Flashing CMOS will hide any faint emissions caused by capacitor charge and discharge. The inverters are connected to the Tamper Detection circuitry, so they change state many times (at the high clock rate) for each non-Flashing CMOS state change.
000016.2.8 Viewing the Keys Using an SEPM
5599An SEPM attack can be simply thwarted by adding a metal layer to cover the circuitry. However an attacker could etch a hole in the layer, so this is not an appropriate defense.
5600The Tamper Detection circuitry described above will shield the signal as well as cause circuit noise. The noise will actually be a greater signal than the one that the attacker is looking for. If the attacker attempts to etch a hole in the noise circuitry covering the protected areas, the chip will not function, and the SEPM will not be able to read any data.
5601An SEPM attack is therefore fruitless.
000016.2.9 Monitoring EMI
5602The Noise Generator described above will cause circuit noise. The noise will interfere with other electromagnetic emissions from the chip's regular activities and thus obscure any meaningful reading of internal data transfers.
000016.2.10 Viewing I<sub>dd </sub>Fluctuations
5603The solution against this kind of attack is to decrease the SNR in the I<sub>dd </sub>signal. This is accomplished by increasing the amount of circuit noise and decreasing the amount of signal.
5604The Noise Generator circuit (which also acts as a defense against EMI attacks) will also cause enough state changes each cycle to obscure any meaningful information in the I<sub>dd </sub>signal.
5605In addition, the special Non-Flashing CMOS implementation of the key-carrying data paths of the chip prevents current from flowing when state changes occur. This has the benefit of reducing the amount of signal.
000016.2.11 Differential Fault Analysis
5606Differential fault bit errors are introduced in a non-targeted fashion by ionization, microwave radiation, and environmental stress. The most likely effect of an attack of this nature is a change in Flash memory (causing an invalid state) or RAM (bad parity). Invalid states and bad parity are detected by the Tamper Detection Circuitry, and cause an erasure of the key.
5607Since the Tamper Detection Lines cover the key manipulation circuitry, any error introduced in the key manipulation circuitry will be mirrored by an error in a Tamper Detection Line. If the Tamper Detection Line is affected, the chip will either continually RESET or simply erase the key upon a power-up, rendering the attack fruitless.
5608Rather than relying on a non-targeted attack and hoping that “just the right part of the chip is affected in just the right way”, an attacker is better off trying to introduce a targeted fault (such as overwrite attacks, gate destruction etc.). For information on these targeted fault attacks, see the relevant sections below.
000016.2.12 Clock Glitch Attacks
5609The Clock Filter (described above) eliminates the possibility of clock glitch attacks.
000016.2.13 Power Supply Attacks
5610The OverUnderPower Detection Unit (described above) eliminates the possibility of power supply attacks.
000016.2.14 Overwriting ROM
5611Authentication chips store program code, keys and secret information in Flash memory, and not in ROM. This attack is therefore not possible.
000016.2.15 Modifying EEPROM/Flash
5612Authentication chips store program code, keys and secret information in multi-level Flash memory. However the Flash memory is covered by two Tamper Prevention and Detection Lines. If either of these lines is broken (in the process of destroying a gate via a laser-cutter) the attack will be detected on power-up, and the chip will either RESET (continually) or erase the keys from Flash memory. This process is described in Section 16.1.6 on page 733.
5613Even if an attacker is able to somehow access the bits of Flash and destroy or short out the gate holding a particular bit, this will force the bit to have no charge or a full charge. These are both invalid states for the authentication chip's usage of the multi-level Flash memory (only the two middle states are valid). When that data value is transferred from Flash, detection circuitry will cause the Erasure Tamper Detection Line to be triggered—thereby erasing the remainder of Flash memory and RESETing the chip. This is true for program code, and non-secret information. As key data is read from multi-level flash memory, it is not imediately checked for validity (otherwise information about the key is given away). Instead, a specific key validation mechanism is used to protect the secret key information.
5614An attacker could theoretically etch off the upper levels of the chip, and deposit enough electrons to
5615Writes to M<sub>1</sub>[n] only succeed when all of M<sub>1</sub>[0 . . . n−1] have already written to (i.e. previous fields are defined) i.e. result, the authentication chip must perform a validation of the keys before replying to the Random, Test or Random commands. The SHA-1 algorithm must be run on the keys, and the results compared against an internal checksum value. This gives an attacker a 1 in 2<sup>160 </sup>chance of tricking the chip, which is the same chance as guessing either of the keys.
5616A Modify EEPROM/Flash attack is therefore fruitless.
000016.2.16 Gate Destruction Attacks
5617Gate Destruction Attacks rely on the ability of an attacker to modify a single gate to cause the chip to reveal information during operation. However any circuitry that manipulates secret information is covered by one of the two Tamper Prevention and Detection lines. If either of these lines is broken (in the process of destroying a gate) the attack will be detected on power-up, and the chip will either RESET (continually) or erase the keys from Flash memory.
5618To launch this kind of attack, an attacker must first reverse-engineer the chip to determine which gate(s) should be targeted. Once the location of the target gates has been determined, the attacker must break the covering Tamper Detection line, stop the Erasure of Flash memory, and somehow rewire the components that rely on the ChipOK lines. Rewiring the circuitry cannot be done without slicing the chip, and even if it could be done, the act of slicing the chip to this level will most likely destroy the charge patterns in the non-volatile memory that holds the keys, making the process fruitless.
000016.2.17 Overwrite Attack
5619An overwrite attack relies on being able to set individual bits of the key without knowing the previous value. It relies on probing the chip, as in the conventional probing attack and destroying gates as in the gate destruction attack. Both of these attacks (as explained in their respective sections), will not succeed due to the use of the Tamper Prevention and Detection Circuitry and ChipOK lines.
5620However, even if the attacker is able to somehow access the bits of Flash and destroy or short out the gate holding a particular bit, this will force the bit to have no charge or a full charge. These are both invalid states for the authentication chip's usage of the multi-level Flash memory (only the two middle states are valid). When that data value is transferred from Flash detection circuitry will cause the Erasure Tamper Detection Line to be triggered—thereby erasing the remainder of Flash memory and RESETing the chip. In the same way, a parity check on tampered values read from RAM will cause the Erasure Tamper Detection Line to be triggered.
5621An overwrite attack is therefore fruitless.
000016.2.18 Memory Remanence Attack
5622Any working registers or RAM within the authentication chip may be holding part of the authentication keys when power is removed. The working registers and RAM would continue to hold the information for some time after the removal of power. If the chip were sliced so that the gates of the registers/RAM were exposed, without discharging them, then the data could probably be viewed directly using an STM.
5623The first defense can be found above, in the description of defense against power glitch attacks. When power is removed, all registers and RAM are cleared, just as the RESET condition causes a clearing of memory.
5624The chances then, are less for this attack to succeed than for a reading of the Flash memory. RAM charges (by nature) are more easily lost than Flash memory. The slicing of the chip to reveal the RAM will certainly cause the charges to be lost (if they haven't been lost simply due to the memory not being refreshed and the time taken to perform the slicing).
5625This attack is therefore fruitless.
000016.2.19 Chip Theft Attack
5626There are distinct phases in the lifetime of an authentication chip. Chips can be stolen when at any of these stages: <ul id="ul0701" list-style="none"><li id="ul0701-0001" num="0000"><ul id="ul0702" list-style="none"><li id="ul0702-0001" num="5627">After manufacture, but before programming of key</li><li id="ul0702-0002" num="5628">After programming of key, but before programming of state data</li><li id="ul0702-0003" num="5629">After programming of state data, but before insertion into the consumable or system</li><li id="ul0702-0004" num="5630">After insertion into the system or consumable</li></ul></li></ul>
5631A theft in between the chip manufacturer and programming station would only provide the clone manufacturer with blank chips. This merely compromises the sale of authentication chips, not anything authenticated by the authentication chips. Since the programming station is the only mechanism with consumable and system product keys, a clone manufacturer would not be able to program the chips with the correct key. Clone manufacturers would be able to program the blank chips for their own Systems and Consumables, but it would be difficult to place these items on the market without detection.
5632The second form of theft can only happen in a situation where an authentication chip passes through two or more distinct programming phases. This is possible, but unlikely. In any case, the worst situation is where no state data has been programmed, so all of M is read/write. If this were the case, an attacker could attempt to launch an adaptive chosen text attack on the chip. The HMAC-SHA1 algorithm is resistant to such attacks. For more information see Section 14.7 on page 699.
5633The third form of theft would have to take place in between the programming station and the installation factory. The authentication chips would already be programmed for use in a particular system or for use in a particular consumable. The only use these chips have to a thief is to place them into a clone System or clone Consumable. Clone systems are irrelevant—a cloned System would not even require an authentication chip. For clone Consumables, such a theft would limit the number of cloned products to the number of chips stolen. A single theft should not create a supply constant enough to provide clone manufacturers with a cost-effective business.
5634The final form of theft is where the System or Consumable itself is stolen. When the theft occurs at the manufacturer, physical security protocols must be enhanced. If the theft occurs anywhere else, it is a matter of concern only for the owner of the item and the police or insurance company. The security mechanisms that the authentication chip uses assume that the consumables and systems are in the hands of the public. Consequently, having them stolen makes no difference to the security of the keys.
000016.2.20 Trojan Horse Attack
5635A Trojan horse attack involves an attacker inserting a fake authentication chip into the programming station and retrieving the same chip after it has been programmed with the secret key information.
5636The difficulty of these two tasks depends on both logical and physical security, but is an expensive attack—the attacker has to manufacture a false authentication chip, and it will only be useful where the effort is worth the gain. For example, obtaining the secret key for a specific car's authentication chip is most likely not worth an attacker's efforts, while the key for a printer's ink cartridge may be very valuable.
5637The problem arises if the programming station is unable to tell a Trojan horse authentication chip from a real one—which is the problem of authenticating the authentication chip.
5638One solution to the authentication problem is for the manufacturer to have a programming station attached to the end of the production line. Chips passing the manufacture QA tests are programmed with the manufacturer's secret key information. The chip can therefore be verified by the C1 authentication protocol, and give information such as the expected batch number, serial number etc. The information can be verified and recorded, and the valid chip can then be reprogrammed with the System or Consumable key and state data. An attacker would have to substitute an authentication chip with a Trojan horse programmed with the manufacturer's secret key information and copied batch number data from the removed authentication chip. This is only possible if the manufacturer's secret key is compromised (the key is changed regularly and not known by a human) or if the physical security at the manufacturing plant is compromised at the end of the manufacturing chain.
5639Even if the solution described were to be undertaken, the possibility of a Trojan horse attack does not go away—it merely is removed to the manufacturer's physical location. A better solution requires no physical security at the manufacturing location.
5640The preferred solution then, is to use transparent epoxy on the chip's packaging and to image the chip before programming it. Once the chip has been mounted for programming it is in a known fixed orientation. It can therefore be high resolution photo-imaged and X-rayed from multiple directions, and the images compared against “signature”images. Any chip not matching the image signature is treated as a Trojan horse and rejected.
00001 Refill of Ink in Printers—Printer Based Refill Device
00001.1 Functional Purpose
5641The functional purpose of the printer based refill device is as follows: <ul id="ul0703" list-style="none"><li id="ul0703-0001" num="0000"><ul id="ul0704" list-style="none"><li id="ul0704-0001" num="5642">To refill ink into printers by physically connecting the refill device to the printer.</li><li id="ul0704-0002" num="5643">To ensure that the correct ink is used for the correct operation of the printer (i.e. will not damage the printhead).</li><li id="ul0704-0003" num="5644">To ensure accurate measure of ink is transferred from the refilling device to the printer during refills.</li><li id="ul0704-0004" num="5645">The refill device is controlled by the printer. Apart from the QA Chip<sup>1 </sup>the refill device has no other processing power. <sup>1</sup>General Note: Througout this document, if secure refilling is required then a physical QA Chip or any other virtual device performing the QA Chip protocol can be used. Refer to [1]. <br /> 1.2 Basic Components of the Refill Device </li></ul></li></ul>
5646<figref idref="DRAWINGS">FIG. 355</figref> shows the components of the printer based refill device.
5647The printer based refill device will consist of following components: <ul id="ul0705" list-style="none"><li id="ul0705-0001" num="0000"><ul id="ul0706" list-style="none"><li id="ul0706-0001" num="5648">An ink reservoir—which stores the ink. Each refill device will allow ink reservoirs of various capacities. When the ink reservoir empties out, it is replaced by another reservoir containing more ink of the same type or different type or refilled (for example through a refill station as described in Section 2 and Section 3).</li><li id="ul0706-0002" num="5649">An ink output device—which dispenses ink to the printer being refilled when physically connected to the printer.</li><li id="ul0706-0003" num="5650">A QA Chip and associated circuitry—which stores the amount of ink in the reservoir along with the attributes of the ink in a digital format.</li><li id="ul0706-0004" num="5651">The electrical connections to the QA Chip.</li><li id="ul0706-0005" num="5652">NB—No additional microprocessors are required to be present in the refill device. Hence the refill device uses the processing power of the printer to oversee the refilling process.</li><li id="ul0706-0006" num="5653">An ink transfer mechanism (optional) which controls the flow ink from the refill device to the printer and is controlled by the printer. Therefore the control connections for the ink transfer mechanism will be connected to the printer.</li><li id="ul0706-0007" num="5654">Alternatively, the ink transfer mechanism could be in the printer. Refer to Section 1.3. <br /> 1.3 Printer Description and Functions </li></ul></li></ul>
5655Printers which will be refilled by these refilling devices must have the following components: <ul id="ul0707" list-style="none"><li id="ul0707-0001" num="0000"><ul id="ul0708" list-style="none"><li id="ul0708-0001" num="5656">Microprocessor assembly which will control the refill procedure as described Section 1.4. The microprocessor assembly will access the QA Chip and ink transfer mechanism of the refill device.</li><li id="ul0708-0002" num="5657">A QA Chip storing the ink amount remaining in the printer.</li><li id="ul0708-0003" num="5658">An optional ink transfer mechanism to control the flow of ink from the refill device to the printer. This ink transfer mechanism must be present in the printer if the refill device doesn't have one of its own. <br /> 1.4 Operational Procedure </li></ul></li></ul>
5659The operational procedure can be divided into two parts: <ul id="ul0709" list-style="none"><li id="ul0709-0001" num="0000"><ul id="ul0710" list-style="none"><li id="ul0710-0001" num="5660">Refilling printers using the refill device.</li><li id="ul0710-0002" num="5661">Refilling of the ink reservoir in the refill device. See Section 2 and Section 3. <br /> 1.4.1 Refilling of Printers </li></ul></li></ul>
5662<figref idref="DRAWINGS">FIG. 356</figref> shows a printer being refilled by a printer based refill device. The ink transfer mechanism is located in the printer in this case. The ink transfer mechanism could be also located in the refill device as described in Section 1.2.
5663The following is a description for refilling of printers using the printer based refill device: <ul id="ul0711" list-style="none"><li id="ul0711-0001" num="0000"><ul id="ul0712" list-style="none"><li id="ul0712-0001" num="5664">Ink output device from the refilling device is connected to the printer.</li><li id="ul0712-0002" num="5665">The QA Chip electrical connection is connected to the printer.</li><li id="ul0712-0003" num="5666">The refill option is selected on the user interface of the printer. The microprocessor assembly in the printer will then do the following:</li></ul></li><li id="ul0711-0002" num="5667">a. Read ink attributes (for example ink type, ink characteristics, ink colour, ink manufacturer etc) stored in the QA Chip of the ink reservoir unit. Refer to [1].</li><li id="ul0711-0003" num="5668">b. Compare the ink attributes as required by the printer for correct operation. This may require reading of data from the QA Chip in the printer.</li><li id="ul0711-0004" num="5669">c. Only if Step b is successful, then do the following: <ul id="ul0713" list-style="none"><li id="ul0713-0001" num="5670">i. Determine the amount of ink to be transferred by any or all of the following means, ensuring that the reservoir has enough ink for the transfer: <ul id="ul0714" list-style="none"><li id="ul0714-0001" num="5671">Fixed amount (e.g. based on a pre-programmed value or printer model).</li><li id="ul0714-0002" num="5672">User-selectable amount.</li></ul></li><li id="ul0713-0002" num="5673">ii. Decrement the amount of ink transferred from the QA Chip in the refill station and increment the QA Chip in the printer (which stores the amount of ink in the printer) with corresponding ink amount.</li><li id="ul0713-0003" num="5674">iii. Command the ink transfer mechanism to release the ink to the printer through the output device. <br /> 2 Home Use Refill Station <br /> 2.1 Functional Purpose </li></ul></li></ul>
5675The functional purpose of the commercial refill station is as follows: <ul id="ul0715" list-style="none"><li id="ul0715-0001" num="0000"><ul id="ul0716" list-style="none"><li id="ul0716-0001" num="5676">To refill ink into ink cartridges at home or in a small office.</li><li id="ul0716-0002" num="5677">Single ink cartridge is filled at a time.</li><li id="ul0716-0003" num="5678">To ensure that the correct ink present in the refill station is transferred to the correct ink cartridge.</li><li id="ul0716-0004" num="5679">To ensure accurate measure of ink is transferred from the refilling station to the ink cartridge during refills.</li><li id="ul0716-0005" num="5680">The refilling station provides the processing power required to perform refills of ink cartridges. <br /> 2.2 Basic Components </li></ul></li></ul>
5681<figref idref="DRAWINGS">FIG. 357</figref> shows the components of a home refill station.
5682A home refill station will consist of one of the following ink refill units: <ul id="ul0717" list-style="none"><li id="ul0717-0001" num="0000"><ul id="ul0718" list-style="none"><li id="ul0718-0001" num="5683">A single reservoir ink refill unit suitable for black ink (or any other single colour).</li><li id="ul0718-0002" num="5684">A multi reservoir ink refill unit suitable for coloured ink for example CMY (Cyan, Magenta, Yellow). <br /> 2.2.1 Ink Reservoir Unit </li></ul></li></ul>
5685<figref idref="DRAWINGS">FIG. 358</figref> shows the components of a three-ink reservoir unit.
5686The ink reservoir unit will consist of the following: <ul id="ul0719" list-style="none"><li id="ul0719-0001" num="0000"><ul id="ul0720" list-style="none"><li id="ul0720-0001" num="5687">Multiple ink reservoirs or a single ink reservoir which stores ink. Each refill station will allow ink reservoirs of various capacities. When the ink reservoir empties out, it is replaced by another reservoir containing more ink of the same or different type or refilled (for example through a refill station as described in Section 3).</li><li id="ul0720-0002" num="5688">A QA Chip and associated circuitry in each of the ink reservoirs—which stores the amount of ink in the reservoir along with the attributes of the ink.</li><li id="ul0720-0003" num="5689">The electrical connections to each of the QA Chips. <br /> 2.2.2 Ink Transfer Unit </li></ul></li></ul>
5690The ink reservoir unit will consist of the following: <ul id="ul0721" list-style="none"><li id="ul0721-0001" num="0000"><ul id="ul0722" list-style="none"><li id="ul0722-0001" num="5691">Ink output device from each ink reservoir.</li><li id="ul0722-0002" num="5692">The output ink transfer mechanism controls the flow ink from the ink refill unit to the ink cartridge and is controlled by the microprocessor assembly.</li><li id="ul0722-0003" num="5693">Final ink output devices to the cartridge interface assembly <br /> 2.2.3 Cartridge Interface Unit </li></ul></li></ul>
5694This unit will provide the physical interface to the ink cartridges. Each ink cartridge interface unit will hold a single or multiple cartridges of particular physical dimension.
5695The cartridge interface unit can removed from the ink refill unit and replaced with another interface unit to cater for other physically different cartridges.
00002.2.4 Microprocessor Assembly
5696The controls connections for the ink transfer mechanism and the electrical connections of the QA Chip are connected to the microprocessor assembly. The microprocessor assembly oversees and controls the refill process.
5697The microprocessor assembly will communicate with a user interface to accept commands and provide responses for various refill operations.
00002.3 Ink Cartridge Description
5698Ink cartridges which will be refilled in a home refill station must have a QA Chip storing the following components: <ul id="ul0723" list-style="none"><li id="ul0723-0001" num="0000"><ul id="ul0724" list-style="none"><li id="ul0724-0001" num="5699">Ink amount remaining.</li><li id="ul0724-0002" num="5700">Ink attributes (for example—ink type, ink characteristics, ink colour, ink manufacturer). <br /> 2.4 Operational Procedure </li></ul></li></ul>
5701The operational procedure can be divided into two parts: <ul id="ul0725" list-style="none"><li id="ul0725-0001" num="0000"><ul id="ul0726" list-style="none"><li id="ul0726-0001" num="5702">Refilling of ink cartridges using the home refill station.</li><li id="ul0726-0002" num="5703">Refilling the ink reservoirs used in the refill station is discussed in Section 3. <br /> 2.5 Refilling of Ink Cartridges Using the Home Refill Station </li></ul></li></ul>
5704<figref idref="DRAWINGS">FIG. 359</figref> shows the refill of ink cartridges in a home refill station.
5705The following is a description for refilling of ink cartridges in the home refill station: <ul id="ul0727" list-style="none"><li id="ul0727-0001" num="0000"><ul id="ul0728" list-style="none"><li id="ul0728-0001" num="5706">Load the ink cartridge into the cartridge interface unit of the ink refill unit. This will connect the QA Chip of the ink cartridge to the microprocessor assembly. It will also connect the ink output device of the ink refill unit to the ink cartridge.</li><li id="ul0728-0002" num="5707">The model number of the ink cartridge is read from the QA Chip by the microprocessor assembly controlling the ink refill units.</li><li id="ul0728-0003" num="5708">The microprocessor assembly will determine whether the ink refill unit is suitable for the ink cartridge model.</li><li id="ul0728-0004" num="5709">The refill option is selected on the microprocessor assembly through the user interface. The microprocessor assembly will then do the following:</li></ul></li><li id="ul0727-0002" num="5710">a. Read ink attributes (for example ink type, ink characteristics, ink colour, ink manufacturer etc) stored in the QA Chip of the ink cartridge. Refer to [1].</li><li id="ul0727-0003" num="5711">b. Compare the read ink attributes to the ink attribute list in the refill station. This may also require reading of the ink attributes stored in the QA Chip of the ink reservoirs in the refill unit.</li><li id="ul0727-0004" num="5712">c. Only if Step b is successful, then do the following: <ul id="ul0729" list-style="none"><li id="ul0729-0001" num="5713">i. Determine the amount of ink to be transferred by any or all of the following means, ensuring that the reservoir has enough ink for the transfer: <ul id="ul0730" list-style="none"><li id="ul0730-0001" num="5714">Fixed amount (e.g. based on a pre-programmed value cartridge model or reservoir type).</li><li id="ul0730-0002" num="5715">User-selectable amount.</li></ul></li><li id="ul0729-0002" num="5716">ii. Check the ink reservoir in the ink refill unit has adequate amount of ink to refill the ink cartridge</li><li id="ul0729-0003" num="5717">iii. Decrement the amount of ink transferred from the QA Chip in the ink refill unit and increment the QA Chip in the ink cartridge with corresponding ink amount.</li><li id="ul0729-0004" num="5718">iv. If incrementing of the QA Chip with ink amount is successful then a command is sent to the ink transfer mechanism to release the ink to the ink cartridge through the output device. <br /> 3 Commercial Refill Station <br /> 3.1 Functional Purpose </li></ul></li></ul>
5719The functional purpose of the commercial refill station is as follows: <ul id="ul0731" list-style="none"><li id="ul0731-0001" num="0000"><ul id="ul0732" list-style="none"><li id="ul0732-0001" num="5720">To refill ink into ink cartridges that are taken to the refill station for refilling.</li><li id="ul0732-0002" num="5721">Multiple ink cartridges of different models can be refilled.</li><li id="ul0732-0003" num="5722">To ensure that the correct ink present in the refill station is transferred to the ink cartridge.</li><li id="ul0732-0004" num="5723">To ensure accurate measure of ink is transferred from the refilling station to the ink cartridge during refills.</li><li id="ul0732-0005" num="5724">The refilling station provides all processing power required to perform refills of ink cartridges. <br /> 3.2 Basic Components of the Refill Station </li></ul></li></ul>
5725<figref idref="DRAWINGS">FIG. 360</figref> shows the components of a commercial refill station.
5726A commercial refill station will consist of multiple ink refill units controlled by a single microprocessor assembly. Each ink refill unit can refill a single ink cartridge at a time.
5727Each ink refill unit will consist of the following sub units: <ul id="ul0733" list-style="none"><li id="ul0733-0001" num="0000"><ul id="ul0734" list-style="none"><li id="ul0734-0001" num="5728">Ink reservoir unit</li><li id="ul0734-0002" num="5729">Switch unit</li><li id="ul0734-0003" num="5730">Ink transfer unit</li><li id="ul0734-0004" num="5731">Multiple cartridge interface unit <br /> 3.2.1 <br /> Ink Reservoir Unit </li></ul></li></ul>
5732<figref idref="DRAWINGS">FIG. 361</figref> shows the components of a ink reservoir unit.
5733The ink reservoir unit will consist of the following: <ul id="ul0735" list-style="none"><li id="ul0735-0001" num="0000"><ul id="ul0736" list-style="none"><li id="ul0736-0001" num="5734">Multiple ink reservoirs—which stores ink. Each refill device will allow ink reservoirs of various capacities. When the ink reservoir empties out, it is replaced by another reservoir containing more ink of the same or different type or refilled. Refer to Section 3.5.</li><li id="ul0736-0002" num="5735">A QA Chip and associated circuitry in each of the ink reservoirs—which stores the amount of ink in the reservoir along with the attributes of the ink in digital format.</li><li id="ul0736-0003" num="5736">The electrical connections of each of the QA Chips are connected to the microprocessor assembly. <br /> 3.2.2 Switch Unit </li></ul></li></ul>
5737This unit will switch the inks selected from different ink reservoirs to the ink transfer unit to be dispensed into ink cartridges.
5738The switch unit will prevent mixing of any residual ink left in dispensing devices after each ink cartridge is refilled.
000027.1.4.14 GetFieldDataWords(FieldNum,FieldData<img file="US7165824B2_D0330.tif" />, M0,M1)
5739The ink reservoir unit will consist of the following: <ul id="ul0737" list-style="none"><li id="ul0737-0001" num="0000"><ul id="ul0738" list-style="none"><li id="ul0738-0001" num="5740">Ink output device from each ink reservoir.</li><li id="ul0738-0002" num="5741">An output ink transfer mechanism which controls the flow ink from the ink refill unit to the ink cartridge and is controlled by the microprocessor assembly.</li><li id="ul0738-0003" num="5742">Final ink output devices to the multiple cartridge interface assembly <br /> 3.2.4 Multiple Cartridge Interface Unit </li></ul></li></ul>
5743This unit will provide the physical interface to the ink cartridges. Each ink cartridge interface will hold cartridges of different physical dimensions.
5744Each cartridge interface unit can provide an interface for about 20 physically different cartridges.
5745The cartridge interface unit can removed from the ink refill unit and replaced with another interface unit to cater for other physically different cartridges.
00003.2.5 Microprocessor Assembly with a User Interface
5746The controls connections for the ink transfer mechanism and the electrical connections of the QA Chip are connected to the microprocessor assembly. The microprocessor assembly will oversee and control the refill process.
5747The microprocessor assembly will communicate with a user interface to accept commands and provide responses for various refill operations.
00003.3 Ink Cartridge Description
5748Ink cartridges which will be refilled in a commercial refill station must have a QA Chip storing the following components: <ul id="ul0739" list-style="none"><li id="ul0739-0001" num="0000"><ul id="ul0740" list-style="none"><li id="ul0740-0001" num="5749">Ink amount remaining.</li><li id="ul0740-0002" num="5750">Ink attributes (for example—ink type, ink characteristics, ink colour, ink manufacturer). <br /> 3.4 Operational Procedure </li></ul></li></ul>
5751The operational procedure can be divided into two parts: <ul id="ul0741" list-style="none"><li id="ul0741-0001" num="0000"><ul id="ul0742" list-style="none"><li id="ul0742-0001" num="5752">Refilling of ink cartridges using the commercial refill station.</li><li id="ul0742-0002" num="5753">Refilling the ink reservoirs used in the refill station is covered in Section 3.5. <br /> 3.4.1 Refilling Ink Cartridges Using the Commercial Refill Station </li></ul></li></ul>
5754<figref idref="DRAWINGS">FIG. 362</figref> shows the refill of ink cartridges in a commercial refill station.
5755The following is a description for refilling of ink cartridges in the commercial refill station: <ul id="ul0743" list-style="none"><li id="ul0743-0001" num="0000"><ul id="ul0744" list-style="none"><li id="ul0744-0001" num="5756">Load the ink cartridge into the multiple cartridge interface unit of the ink refill unit. This will connect the QA Chip of the ink cartridge to the microprocessor assembly. It will also connect the ink output device of the ink refill unit to the ink cartridge.</li><li id="ul0744-0002" num="5757">The model number of the ink cartridge automatically is read from the QA Chip by the microprocessor assembly controlling the ink refill units.</li><li id="ul0744-0003" num="5758">The microprocessor assembly will determine whether the ink refill unit is suitable for the ink cartridge model.</li><li id="ul0744-0004" num="5759">The refill option is selected on the microprocessor assembly through the user interface. The microprocessor assembly will then do the following:</li></ul></li><li id="ul0743-0002" num="5760">a. Read ink attributes (for example ink type, ink characteristics, ink colour, ink manufacturer etc) stored in the QA Chip of the ink cartridge. Refer to [1].</li><li id="ul0743-0003" num="5761">b. Compare the read ink attributes to the ink attribute list in the refill station. This may also require reading of the ink attributes stored in the QA Chip of the ink reservoirs in the refill unit.</li><li id="ul0743-0004" num="5762">c. Only if Step b is successful, then do the following: <ul id="ul0745" list-style="none"><li id="ul0745-0001" num="5763">i. Determine the amount of ink to be transferred by any or all of the following means, ensuring that the reservoir has enough ink for the transfer: <ul id="ul0746" list-style="none"><li id="ul0746-0001" num="5764">Fixed amount (e.g. based on a pre-programmed value, cartridge model or reservoir type).</li><li id="ul0746-0002" num="5765">User-selectable amount.</li></ul></li><li id="ul0745-0002" num="5766">ii. The microprocessor assembly will calculate the cost of ink amount and interrogate the user for a payment method—credit card or cash. If credit card option is selected it will request a credit card number to be selected and interface to a payment system to complete the transaction before proceeding further.</li><li id="ul0745-0003" num="5767">iii. Decrement the amount of ink transferred from the QA Chip in the ink refill unit and increment the QA Chip in the ink cartridge with corresponding ink amount.</li><li id="ul0745-0004" num="5768">iv. If incrementing of the QA Chip with ink amount is successful then a command is sent to the ink transfer mechanism to release the ink to the ink cartridge through the output device. <br /> 3.5 Refilling the Ink Reservoirs </li></ul></li></ul>
5769The ink reservoirs of any ink refill device can be refilled recursively by the procedure described in Section 3.4.1, the only exception being the ink cartridge replaced by the ink reservoir.
00003.6 Commercial Refill Station for a Production Environment
5770This refill station resembles a commercial refill station but fills multiple ink cartridges of the same type at the same time. This will serve as a filling station for new cartridges in a production environment.
0000Logical Interface Specification for Preferred Form of QA Chip
00001 Introduction
5771This document defines the QA Chip Logical Interface, which provides authenticated manipulation of specific printer and consumable parameters. The interface is described in terms of data structures and the functions that manipulate them, together with examples of use. While the descriptions and examples are targetted towards the printer application, they are equally applicable in other domains.
00002 Scope
5772The document describes the QA Chip Logical Interface as follows: <ul id="ul0747" list-style="none"><li id="ul0747-0001" num="0000"><ul id="ul0748" list-style="none"><li id="ul0748-0001" num="5773">data structures and their uses (Section 5 to Section 9).</li><li id="ul0748-0002" num="5774">functions, including inputs, outputs, signature formats, and a logical implementation sequence (Section 10 to Section 30).</li><li id="ul0748-0003" num="5775">typical functional sequences of printers and consumables, using the functions and data structures of the interface (Section 31 to Section 32).</li></ul></li></ul>
5776The QA Chip Logical Interface is a logical interface, and is therefore implementation independent.
5777Although this document does not cover implementation details on particular platforms, expected implementations include: <ul id="ul0749" list-style="none"><li id="ul0749-0001" num="0000"><ul id="ul0750" list-style="none"><li id="ul0750-0001" num="5778">Software only</li><li id="ul0750-0002" num="5779">Off-the-shelf cryptographic hardware.</li><li id="ul0750-0003" num="5780">ASICs, such as SBR4320 [2] and SOPEC [3] for physical insertion into printers and ink cartridges</li><li id="ul0750-0004" num="5781">Smart cards. <br /> 3 Nomenclature <br /> 3.1 Symbols </li></ul></li></ul>
5782The following symbolic nomenclature is used throughout this document:
5783<tables id="TABLE-US-00395" num="00395"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 246</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Summary of symbolic nomenclature</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>Symbol</entry><entry>Description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>F[X]</entry><entry>Function F, taking a single parameter X</entry></row><row><entry>F[X, Y]</entry><entry>Function F, taking two parameters, X and Y</entry></row><row><entry>X | Y</entry><entry>X concatenated with Y</entry></row><row><entry>X <img file="US7165824B2_D0331.tif" /> Y</entry><entry>Bitwise X AND Y</entry></row><row><entry>X <img file="US7165824B2_D0332.tif" /> Y</entry><entry>Bitwise X OR Y (inclusive-OR)</entry></row><row><entry>X ⊕ Y</entry><entry>Bitwise X XOR Y (exclusive-OR)</entry></row><row><entry><img file="US7165824B2_D0333.tif" /> X</entry><entry>Bitwise NOT X (complement)</entry></row><row><entry>X <img file="US7165824B2_D0334.tif" /> Y</entry><entry>X is assigned the value Y</entry></row><row><entry>X <img file="US7165824B2_D0335.tif" /> {Y, Z}</entry><entry>The domain of assignment inputs to X is Y and Z</entry></row><row><entry>X = Y</entry><entry>X is equal to Y</entry></row><row><entry>X ≠ Y</entry><entry>X is not equal to Y</entry></row><row><entry><img file="US7165824B2_D0336.tif" /> X</entry><entry>Decrement X by 1 (floor 0)</entry></row><row><entry><img file="US7165824B2_D0337.tif" /> X</entry><entry>Increment X by 1 (modulo register length)</entry></row><row><entry>Erase X</entry><entry>Erase Flash memory register X</entry></row><row><entry>SetBits[X, Y]</entry><entry>Set the bits of the Flash memory register X based</entry></row><row><entry /><entry>on Y</entry></row><row><entry>Z <img file="US7165824B2_D0338.tif" /> ShiftRight[X, Y]</entry><entry>Shift register X right one bit position, taking input</entry></row><row><entry /><entry>bit from Y and placing the output bit in Z</entry></row><row><entry>a.b</entry><entry>Data field or member function ‘b’ in object a.</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 3.2 Pseudocode <br /> 3.2.1 Asynchronous
5784The following pseudocode: <ul id="ul0751" list-style="none"><li id="ul0751-0001" num="0000"><ul id="ul0752" list-style="none"><li id="ul0752-0001" num="5785">var=expression <ul id="ul0753" list-style="none"><li id="ul0753-0001" num="5786">means the var signal or output is equal to the evaluation of the expression. <br /> 3.2.2 Synchronous </li></ul></li></ul></li></ul>
5787The following pseudocode: <ul id="ul0754" list-style="none"><li id="ul0754-0001" num="0000"><ul id="ul0755" list-style="none"><li id="ul0755-0001" num="5788">var←expression <br /> means the var register is assigned the result of evaluating the expression during this cycle. <br /> 3.2.3 Expression </li></ul></li></ul>
5789Expressions are defined using the nomenclature in Table 246 above. Therefore: <br /><i>var</i>=(<i>a=b</i>)<br /> is interpreted as the var signal is 1 if a is equal to b, and 0 otherwise. <br /> 4 Terms <br /> 4.1 QA Device and System
5790An instance of a QA Chip Logical Interface (on any platform) is a QA Device.
5791QA Devices cannot talk directly to each other. A System is a logical entity which has one or more QA Devices connected logically (or physically) to it, and calls the functions on the QA Devices. The system is considered secure and the program running on the system is considered to be trusted.
00004.2 Types of QA Devices
00004.2.1 Trusted QA Device
5792The Trusted QA Device forms an integral part of the system itself and resides within the trusted environment of the system. It enables the system to extend trust to external QA Device s. The Trusted QA Device is only trusted because the system itself is trusted.
00004.2.2 External Untrusted QA Device
5793The External untrusted QA Device is a QA Device that resides external to the trusted environment of the system and is therefore untrusted. The purpose of the QA Chip Logical Interface is to allow the external untrusted QA Devices to become effectively trusted. This is accomplished when a Trusted QA Device shares a secret key with the external untrusted QA Device, or with a Translation QA Device (see below).
5794In a printing application external untrusted QA Devices would typically be instances of SBR4320 implementations located in a consumable or the printer.
00004.2.3 Translation QA Device
5795A Translation QA Device is used to translate signatures between QA Devices and extend effective trust when secret keys are not directly shared between QA Devices.
5796The Translation QA Device must share a secret key with the Trusted QA Device that allows the Translation QA Device to effectively become trusted by the Trusted QA Device and hence trusted by the system. The Translation QA Device shares a different secret key with another external untrusted QA Device (which may in fact be a Translation QA Device etc). Although the Trusted QA Device doesn't share (know) the key of the external untrusted QA Device, signatures generated by that untrusted device can be translated by the Translation QA Device into signatures based on the key that the Trusted QA Device does know, and thus extend trust to the otherwise untrusted external QA Device.
5797In a SoPEC-based printing application, the Printer QA Device acts as a Translation QA Device since it shares a secret key with the SoPEC, and a different secret key with the ink carridges.
00004.2.4 Consumable QA Device
5798A Consumable QA Device is an external untrusted QA Device located in a consumable. It typically contains details about the consumable, including how much of the consumable remains.
5799In a printing application the consumable QA Device is typically found in an ink cartridge and is referred to as an Ink QA Device, or simply Ink QA since ink is the most common consumable for printing applications. However, other consumables in printing applications include media and impression counts, so consumable QA Device is more generic.
00004.2.5 Printer QA Device
5800A Printer QA Device is an external untrusted device located in the printer. It contains details about the operating parameters for the printer, and is often referred to as a Printer QA.
00004.2.6 Value Upgrader QA Device
5801A Value Upgrader QA Device contains the necessary functions to allow a system to write an initial value (e.g. an ink amount) into another QA Device, typically a consumable QA Device. It also allows a system to refill/replenish a value in a consumable QA Device after use.
5802Whenever a value upgrader QA Device increases the amount of value in another QA Device, the value in the value upgrader QA Device is correspondingly decreased. This means the value upgrader QA Device cannot create value—it can only pass on whatever value it itself has been issued with. Thus a value upgrader QA Device can itself be replenished or topped up by another value upgrader QA Device.
5803An example of a value upgrader is an Ink Refill QA Device, which is used to fill/refill ink amount in an Ink QA Device.
00004.2.7 Parameter Upgrader QA Device
5804A Parameter Upgrader QA Device contains the necessary functions to allow a system to write an initial parameter value (e.g. a print speed) into another QA Device, typically a printer QA Device. It also allows a system to change that parameter value at some later date.
5805A parameter upgrader QA Device is able to perform a fixed number of upgrades, and this number is effectively a consumable value. Thus the number of available upgrades decreases by 1 with each upgrade, and can be replenished by a value upgrader QA Device.
00004.2.8 Key Programmer QA Device
5806Secret batch keys are inserted into QA Devices during instantiation (e.g. manufacture). These keys must be replaced by the final secret keys when the purpose of the QA Device is known. The Key Programmer QA Device implements all necessary functions for replacing keys in other QA Devices.
00004.3 Signature
5807Digital signatures are used throughout the authentication protocols of the QA Chip Logical Interface. A signature is produced by passing data plus a secret key through a keyed hash function. The signature proves that the data was signed by someone who knew the secret key.
5808The signature function used throughout the QA Chip Logical Interface is HMAC-SHA1 [1].
00004.3.4 Authenticated Read
5809This is a read of data from a non-trusted QA Device that also includes a check of the signature (see Section 4.3.3). When the System determines that the signature is correct for the returned data (e.g. by asking a trusted QA Device to test the signature) then the System is able to trust that the data has not been tampered en route from the read, and was actually stored on the non-trusted QA Device.
00004.3.5 Authenticated Write
5810An authenticated write is a write to the data storage area in a QA Device where the write request includes both the new data and a signature. The signature is based on a key that has write access permissions to the region of data in the QA Device, and proves to the receiving QA Device that the writer has the authority to perform the write. For example, a Value Upgrader Refilling Device is able to authorize a system to perform an authenticated write to upgrade a Consumable QA Device (e.g. to increase the amount of ink in an Ink QA Device).
5811The QA Device that receives the write request checks that the signature matches the data (so that it hasn't been tampered with en route) and also that the signature is based on the correct authorization key.
5812An authenticated write can be followed by an authenticated read to ensure (from the system's point of view) that the write was successful.
00004.3.6 Non-authenticated Write
5813A non-authenticated write is a write to the data storage area in a QA Device where the write request includes only the new data (and no signature). This kind of write is used when the system wants to update areas of the QA Device that have no access-protection.
5814The QA Device verifies that the destination of the write request has access permissions that permit anyone to write to it. If access is permitted, the QA Device simply performs the write as requested. A non-authenticated write can be followed by an authenticated read to ensure (from the system's point of view) that the write was successful.
00004.3.7 Authorized Modification of Data
5815Authorized modification of data refers to modification of data via authenticated writes (see Section 4.3.5).
DATA STRUCTURES
0000Summary
5816<tables id="TABLE-US-00396" num="00396"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="350pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 2</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>List of data structures</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="56pt" align="left" /><colspec colname="3" colwidth="42pt" align="left" /><colspec colname="4" colwidth="42pt" align="center" /><colspec colname="5" colwidth="161pt" align="left" /><tbody valign="top"><row><entry>Group</entry><entry /><entry>Represented</entry><entry /><entry /></row><row><entry>description</entry><entry>Name</entry><entry>by</entry><entry>Size</entry><entry>Description</entry></row><row><entry namest="1" nameend="5" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="56pt" align="left" /><colspec colname="3" colwidth="42pt" align="left" /><colspec colname="4" colwidth="21pt" align="right" /><colspec colname="5" colwidth="21pt" align="left" /><colspec colname="6" colwidth="161pt" align="left" /><tbody valign="top"><row><entry>QA Device</entry><entry>Chip Identifier</entry><entry>ChipId</entry><entry>48</entry><entry>bits</entry><entry>Unique identifier for this QA Device.</entry></row><row><entry>instance</entry></row><row><entry>identifier</entry></row><row><entry>Key and key</entry><entry>Number of Keys</entry><entry>NumKeys</entry><entry>8</entry><entry /><entry>Number of key slots available in this QA Device.</entry></row><row><entry>related data</entry></row><row><entry /><entry>Key</entry><entry>K</entry><entry>160</entry><entry>bits</entry><entry>K is the secret key used for calculating signatures.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="56pt" align="left" /><colspec colname="3" colwidth="42pt" align="left" /><colspec colname="4" colwidth="42pt" align="center" /><colspec colname="5" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry /><entry>per key</entry><entry>K<sup>n </sup>is the key stored in the nth key slot.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="56pt" align="left" /><colspec colname="3" colwidth="42pt" align="left" /><colspec colname="4" colwidth="21pt" align="right" /><colspec colname="5" colwidth="21pt" align="left" /><colspec colname="6" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>Key Identifier</entry><entry>KeyId</entry><entry>31</entry><entry>bits</entry><entry>Unique identifier for each key</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="56pt" align="left" /><colspec colname="3" colwidth="42pt" align="left" /><colspec colname="4" colwidth="42pt" align="center" /><colspec colname="5" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry /><entry>per key</entry><entry>KeyId<sup>n </sup>is the key identifier for the key stored</entry></row><row><entry /><entry /><entry /><entry /><entry>in slot n.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="56pt" align="left" /><colspec colname="3" colwidth="42pt" align="left" /><colspec colname="4" colwidth="21pt" align="right" /><colspec colname="5" colwidth="21pt" align="left" /><colspec colname="6" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>KeyLock</entry><entry>KeyLock</entry><entry>1</entry><entry>bit</entry><entry>Flag indicates whether the key is locked in the</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="56pt" align="left" /><colspec colname="3" colwidth="42pt" align="left" /><colspec colname="4" colwidth="42pt" align="center" /><colspec colname="5" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry /><entry>per key</entry><entry>corresponding slot or not.</entry></row><row><entry /><entry /><entry /><entry /><entry>KeyLock<sup>n </sup>is the key lock flag for slot n.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="56pt" align="left" /><colspec colname="3" colwidth="42pt" align="left" /><colspec colname="4" colwidth="21pt" align="right" /><colspec colname="5" colwidth="21pt" align="left" /><colspec colname="6" colwidth="161pt" align="left" /><tbody valign="top"><row><entry>Operating and</entry><entry>Number of</entry><entry>NumVectors</entry><entry>4</entry><entry /><entry>Number of 512 bit memory vectors in this QA Device.</entry></row><row><entry>state data</entry><entry>Memory Vectors</entry></row><row><entry /><entry>Memory Vector</entry><entry>M</entry><entry>512</entry><entry>bits</entry><entry>M is a 512 bit memory vector.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="56pt" align="left" /><colspec colname="3" colwidth="42pt" align="left" /><colspec colname="4" colwidth="42pt" align="center" /><colspec colname="5" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry /><entry>per M<sup>1</sup></entry><entry>The 512-bit vector is divided into 16 × 32 bit words.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="56pt" align="left" /><colspec colname="3" colwidth="42pt" align="left" /><colspec colname="4" colwidth="21pt" align="right" /><colspec colname="5" colwidth="21pt" align="left" /><colspec colname="6" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry>M<sup>0</sup></entry><entry /><entry /><entry>M<sup>0 </sup>stores application specific data that is</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry>protected by access permissions for key-based and</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry>non-key based writes.</entry></row><row><entry /><entry /><entry>M<sup>1</sup></entry><entry /><entry /><entry>M<sup>1 </sup>stores the attributes for M<sup>0</sup>, and is</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry>write-once-only.</entry></row><row><entry /><entry /><entry>M<sup>2+</sup></entry><entry /><entry /><entry>M<sup>2+</sup> stores application specific data that is</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry>protected only by non key-based access permissions.</entry></row><row><entry /><entry>Permissions</entry><entry>P<sup>n</sup></entry><entry>16</entry><entry>bits</entry><entry>Access permissions for each word ofM<sup>1+</sup>. n = number</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="56pt" align="left" /><colspec colname="3" colwidth="42pt" align="left" /><colspec colname="4" colwidth="42pt" align="center" /><colspec colname="5" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry /><entry>per P</entry><entry>of M<sup>1+</sup> vectors</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="56pt" align="left" /><colspec colname="3" colwidth="42pt" align="left" /><colspec colname="4" colwidth="21pt" align="right" /><colspec colname="5" colwidth="21pt" align="left" /><colspec colname="6" colwidth="161pt" align="left" /><tbody valign="top"><row><entry>Session data</entry><entry>Random Number</entry><entry>R</entry><entry>160</entry><entry>bits</entry><entry>Current random number used to ensure time varying</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry>messages. Changes after each successful authentication</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry>or signature generation.</entry></row><row><entry namest="1" nameend="6" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 6 Instance/Device Identifier
5817Each QA Device requires an identifier that allows unique identification of that QA Device by external systems, ensures that messages are received by the correct QA Device, and ensures that the same device can be used across multiple transactions.
5818Strictly speaking, the identifier only needs to be unique within the context of a key, since QA Devices only accept messages that are appropriately signed. However it is more convenient to have the instance identifier completely unique, as is the case with this design.
5819The identifier functionality is provided by ChipId.
00006.1 ChipId
5820ChipId is the unique 64-bit QA Device identifier. The ChipId is set when the QA Device is instantiated, and cannot be changed during the lifetime of the QA Device.
5821A 64-bit ChipId gives a maximum of 1844674 trillion unique QA Devices.
00007 Key and Key Related Data
00007.1 NumKeys, K, keyID, and KeyLock
5822Each QA Device contains a number of secret keys that are used for signature generation and verification. These keys serve two basic functions: <ul id="ul0756" list-style="none"><li id="ul0756-0001" num="0000"><ul id="ul0757" list-style="none"><li id="ul0757-0001" num="5823">For reading, where they are used to verify that the read data came from the particular QA Device and was not altered en route.</li><li id="ul0757-0002" num="5824">For writing, where they are used to ensure only authorised modification of data.</li></ul></li></ul>
5825Both of these functions are achieved by signature generation; a key is used to generate a signature for subsequent transmission from the device, and to generate a signature to compare against a received signature.
5826The number of secret keys in a QA Device is given by NumKeys. For this version of the QA Chip Logical Interface, NumKeys has a maximum value of 8.
5827Each key is referred to as K, and the subscripted form K<sub>n </sub>refers to the nth key where n has the range 0 to NumKeys-1 (i.e. 0 to 7). For convenience we also refer to the nth key as being the key in the nth keyslot.
5828The length of each key is 160-bits. 160-bits was chosen because the output signature length from the signature generation function (HMAC-SHA1) is 160 bits, and a key longer than 160-bits does not add to the security of the function.
5829The security of the digital signatures relies upon keys being kept secret. To safeguard the security of each key, keys should be generated in a way that is not deterministic. Ideally each key should be programmed with a physically generated random number, gathered from a physically random phenomenon. Each key is initially programmed during QA Device instantiation.
5830Since all keys must be kept secret and must never leave the QA Device, each key has a corresponding 31-bit KeyId which can be read to determine the identity or label of the key without revealing the value of the key itself. Since the relationship between keys and KeyIds is 1:1, a system can read all the KeyIds from a QA Device and know which keys are stored in each of the keyslots.
5831Finally, each keyslot has a corresponding 1-bit KeyLock status indicating whether the key in that slot/position is allowed to be replaced (securely replaced, and only if the old key is known). Once a key has been locked into a slot, it cannot be unlocked i.e. it is the final key for that slot. A key can only be used to perform authenticated writes of data when it has been locked into its keyslot (i.e. its KeyLock status=1). Refer to Section 8.1.1.5 for further details.
5832Thus each of the NumKeys keyslots contains a 160-bit key, a 31-bit KeyID, and a 1-bit KeyLock.
00007.2 Common and Variant Signature Generation
5833To create a digital signature, we pass the data to be signed together with a secret key through a key dependent one-way hash function. The key dependent one-way hash function used throughout the QA Chip Logical Interface is HMAC-SHA1[1].
5834Signatures are only of use if they can be validated i.e. QA Device A produces a signature for data and QA Device B can check if the signature was valid for that particular data. This implies that A and B must share some secret information so that they can generate equivalent signatures.
5835Common key signature generation is when QA Device A and QA Device B share the exact same key i.e. key K<sub>A</sub>=key K<sub>B</sub>. Thus the signature for a message produced by A using K<sub>A </sub>can be equivalently produced by B using K<sub>B</sub>. In other words SIG<sub>KA</sub>(message)=SIG<sub>KB</sub>(message) because key K<sub>A</sub>=key K<sub>B</sub>.
5836Variant key signature generation is when QA Device B holds a base key, and QA Device A holds a variant of that key such that K<sub>A</sub>=owf(K<sub>B</sub>,U<sub>A</sub>) where owf is a one-way function based upon the base key (K<sub>B</sub>) and a unique number in A (U<sub>A</sub>). Thus A can produce SIG<sub>KA</sub>(message), but for B to produce an equivalent signature it must produce K<sub>A </sub>by reading U<sub>A </sub>from A and using its base key K<sub>B</sub>. K<sub>A </sub>is referred to as a variant key and K<sub>B </sub>is referred to as the base/common key. Therefore, B can produce equivalent signatures from many QA Devices, each of which has its own unique variant of K<sub>B</sub>. Since ChipId is unique to a given QA Device, we use that as U<sub>A</sub>. A one-way function is required to create K<sub>A </sub>from K<sub>B </sub>or it would be possible to derive K<sub>B </sub>if K<sub>A </sub>were exposed.
5837Common key signature generation is used when A and B are equally available<sup>1 </sup>to an attacker. For example, Printer QA Devices and Ink QA Devices are equally available to attackers (both are commonly available to an attacker), so shared keys between these two devices should be common keys. <sup>1</sup>The term “equally available” is relative. It typically means that the ease of availability of both are the effectively the same, regardless of price (e.g. both A and B are commercially available and effectively equally easy to come by).
5838Variant key signature generation is used when B is not readily available to an attacker, and A is readily available to an attacker. If an attacker is able to determine K<sub>A</sub>, they will not know K<sub>A </sub>for any other QA Device of class A, and they will not be able to determine K<sub>B</sub>.
5839The QA Device producing or testing a signature needs to know if it must use the common or variant means of signature generation. Likewise, when a key is stored in a QA Device, the status of the key (whether it is a base or variant key) must be stored along with it for future reference. Both of these requirements are met using the KeyId as follows:
5840The 31-bit KeyId is broken into two parts: <ul id="ul0758" list-style="none"><li id="ul0758-0001" num="0000"><ul id="ul0759" list-style="none"><li id="ul0759-0001" num="5841">A 30-bit unique identifier for the key. Bits <b>30</b>–<b>1</b> represents the Id.</li><li id="ul0759-0002" num="5842">A 1-bit Variant Flag, which represents whether the key is a base key or a variant key. Bit <b>0</b>. represents the Variant Flag.</li></ul></li></ul>
5843Table 247 describes the relationship of the Variant Flag with the key.
5844<tables id="TABLE-US-00397" num="00397"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 247</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Variant Flag representation</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry>value</entry><entry>Key represented</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>0</entry><entry>Base key</entry></row><row><entry /><entry>1</entry><entry>Variant key</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 7.2.1 Equivalent Signature Generation Between QA Devices
5845Equivalent signature generation between 4 QA Devices A, B, C and D is shown in <figref idref="DRAWINGS">FIG. 363</figref>. Each device has a single key. KeyId.Id of all four keys are the same i.e KeyId<sub>A</sub>.Id=KeyId<sub>B</sub>.Id=KeyId<sub>C</sub>.Id=KeyId<sub>D</sub>.Id.
5846If KeyId<sub>A</sub>. VariantFlag=0 and KeyId<sub>B</sub>. VariantFlag=0, then a signature produced by A, can be equivalently produced by B because K<sub>A</sub>=K<sub>B</sub>.
5847If KeyId<sub>B</sub>. VariantFlag=0 and KeyId<sub>C</sub>. VariantFlag=1, then a signature produced by C, is equivalently produced by B because K<sub>C</sub>=f (K<sub>B</sub>, ChipId<sub>C</sub>).
5848If KeyId<sub>C</sub>. VariantFlag=1 and KeyId<sub>D</sub>. VariantFlag=1, then a signature produced by C, cannot be equivalently produced by D because there is no common base key between the two devices.
5849If KeyId<sub>D</sub>. VariantFlag=1 and KeyId<sub>A</sub>. VariantFlag=0, then a signature produced by D, can be equivalently produced by A because K<sub>D</sub>=f (K<sub>A</sub>, ChipId<sub>D</sub>).
00008 Operating and State Data
5850The primary purpose of a QA Device is to securely hold application-specific data. For example if the QA Device is an Ink QA Device it may store ink characteristics and the amount of ink-remaining. If the QA Device is a Printer QA Device it may store the maximum speed and width of printing.
5851For secure manipulation of data: <ul id="ul0760" list-style="none"><li id="ul0760-0001" num="0000"><ul id="ul0761" list-style="none"><li id="ul0761-0001" num="5852">Data must be clearly identified (includes typing of data).</li><li id="ul0761-0002" num="5853">Data must have clearly defined access criteria and permissions.</li></ul></li></ul>
5854The QA Chip Logical Interface contains structures to permit these activities.
5855The QA Device contains a number of kinds of data with differing access requirements: <ul id="ul0762" list-style="none"><li id="ul0762-0001" num="0000"><ul id="ul0763" list-style="none"><li id="ul0763-0001" num="5856">Data that can be decremented by anyone, but only increased in an authorised fashion e.g. the amount of ink-remaining in an ink cartridge.</li><li id="ul0763-0002" num="5857">Data that can only be decremented in an authorised fashion e.g. the number of times a Parameter Upgrader QA Device has upgraded another QA Device.</li><li id="ul0763-0003" num="5858">Data that is normally read-only, but can be written to (changed) in an authorised fashion e.g. the operating parameters of a printer.</li><li id="ul0763-0004" num="5859">Data that is always read-only and doesn't ever need to be changed e.g. ink attributes or the serial number of an ink cartridge or printer.</li><li id="ul0763-0005" num="5860">Data that is written by QACo/Silverbrook, and must not be changed by the OEM or end user e.g. a licence number containing the OEM's identification that must match the software in the printer.</li><li id="ul0763-0006" num="5861">Data that is written by the OEM and must not be changed by the end-user e.g. the machine number that filled the ink cartridge with ink (for problem tracking). <br /> 8.1 M </li></ul></li></ul>
5862M is the general term for all of the memory (or data) in a QA Device. M is further subscripted to refer to those different parts of M that have different access requirements as follows: <ul id="ul0764" list-style="none"><li id="ul0764-0001" num="0000"><ul id="ul0765" list-style="none"><li id="ul0765-0001" num="5863">M<sub>0 </sub>contains all of the data that is protected by access permissions for key-based (authenticated) and non-key-based (non-authenticated) writes.</li><li id="ul0765-0002" num="5864">M<sub>1 </sub>contains the type information and access permissions for the M<sub>0 </sub>data, and has write-once permissions (each sub-part of M<sub>1 </sub>can only be written to once) to avoid the possibility of changing the type or access permissions of something after it has been defined.</li><li id="ul0765-0003" num="5865">M<sub>2</sub>, M<sub>3 </sub>etc., referred to as M<sub>2+</sub>, contains all the data that can be updated by anyone until the permissions for those sub-parts of M<sub>2+</sub> have changed from read/write to read-only.</li></ul></li></ul>
5866While all QA Devices must have at least M<sub>0 </sub>and M<sub>1</sub>, the exact number of memory vectors (M<sub>n</sub>s) available in a particular QA Device is given by NumVectors. In this version of the QA Chip Logical Interface there are exactly 4 memory vectors, so NumVectors=4.
5867Each M<sub>n </sub>is 512 bits in length, and is further broken into 16×32 bit words. The ith word of M<sub>n </sub>is referred to as M<sub>n</sub>[i]. M<sub>n</sub>[0] is the least significant word of M<sub>n</sub>, and M<sub>n</sub>[15] is the most significant word of M<sub>n</sub>.
00008.1.1 M<sub>0 </sub>and M<sub>1 </sub>
5868In the general case of data storage, it is up to the external accessor to interpret the bits in any way it wants. Data structures can be arbitrarily arranged as long as the various pieces of software and hardware that interpret those bits do so consistently. However if those bits have value, as in the case of a consumable, it is vital that the value cannot be increased without appropriate authorisation, or one type of value cannot be added to another incompatible kind e.g. dollars should never be added to yen.
5869Therefore M<sub>0 </sub>is divided into a number of fields, where each field has a size, a position, a type and a set of permissions. M<sub>0 </sub>contains all of the data that requires authenticated write access (one data element per field), and M<sub>1 </sub>contains the field information i.e. the size, type and access permissions for the data stored in M<sub>0</sub>.
5870Each 32-bit word of M<sub>1 </sub>defines a field. Therefore there is a maximum of 16 defined fields. M<sub>1</sub>[0] defines field 0, M<sub>1</sub>[1] defines field 1 and so on. Each field is defined in terms of: <ul id="ul0766" list-style="none"><li id="ul0766-0001" num="0000"><ul id="ul0767" list-style="none"><li id="ul0767-0001" num="5871">size and position, to permit external accessors determine where a data item is</li><li id="ul0767-0002" num="5872">type, to permit external accessors determine what the data represents</li><li id="ul0767-0003" num="5873">permissions, to ensure approriate access to the field by external accessors.</li></ul></li></ul>
5874The 32-bit value M<sub>1</sub>[n] defines the conceptual field attributes for field n as follows: With regards to consistency of interpretation, the type, size and position information stored in the various words of M<sub>1 </sub>allows a system to determine the contents of the corresponding fields (in M<sub>0</sub>) held in the QA Device. For example, a 3-color ink cartridge may have an Ink QA Device that holds the amount of cyan ink in field 0, the amount of magenta ink in field 1, and the amount of yellow ink in field 2, while another single-color Ink QA Device may hold the amount of yellow ink in field 0, where the size of the fields in the two Ink QA Devices are different.
5875A field must be defined (in M<sub>1</sub>) before it can be written to (in M<sub>0</sub>). At QA Device instantiation, the whole of M<sub>0 </sub>is 0 and no fields are defined (all of M<sub>1 </sub>is 0). The first field (field 0) can only be created by writing an appropriate value to M<sub>1</sub>[0]. Once field 0 has been defined, the words of M<sub>0 </sub>corresponding to field 0 can be written to (via the appropriate permissions within the field definition M<sub>1</sub>[0]).
5876Once a field has been defined (i.e. M<sub>1</sub>[n] has been written to), the size, type and permissions for that field cannot be changed i.e. M<sub>1 </sub>is write-once. Otherwise, for example, a field could be defined to be lira and given an initial value, then the type changed to dollars.
5877The size of a field is measured in terms of the number of consecutive 32-bit words it occupies. Since there are only 16×32-bit words in M<sub>0</sub>, there can only be 16 fields when all 16 fields are defined to be 1 word sized each. Likewise, the maximum size of a field is 512 bits when only a single field is defined, and it is possible to define two fields of 256-bits each.
5878Once field 0 has been created, field 1 can be created, and so on. When enough fields have been created to allocate all of M<sub>0</sub>, the remaining words in M<sub>1 </sub>are available for write-once general data storage purposes.
5879It must be emphasised that when a field is created the permissions for that field are final and cannot be changed. This also means that any keys referred to by the field permissions must be already locked into their keyslots. Otherwise someone could set up a field's permissions that the key in a particular keyslot has write access to that field without any guarantee that the desired key will be ever stored in that slot (thus allowing potential mis-use of the field's value).
00008.1.1.1 Field Size and Position
5880A field's size and position are defined by means of 4 bits (referred to as EndPos) that point to the least significant word of the field, with an implied position of the field's most significant word. The implied position of field 0's most significant word is M<sub>0</sub>[15]. The positions and sizes of all fields can therefore be calculated by starting from field 0 and working upwards until all the words of M<sub>0 </sub>have been accounted for.
5881The default value of M<sub>1</sub>[0] is 0, which means field0.endPos=0. Since field0.startPos=15, field 0 is the only field and is 16 words long.
00008.1.1.1.1 Example
5882Suppose for example, we want to allocate 4 fields as follows: <ul id="ul0768" list-style="none"><li id="ul0768-0001" num="0000"><ul id="ul0769" list-style="none"><li id="ul0769-0001" num="5883">field 0: 128 bits (4×32-bit words)</li><li id="ul0769-0002" num="5884">field 1: 32 bits (1×32-bit word)</li><li id="ul0769-0003" num="5885">field 2: 160 bits (5×32-bit words)</li><li id="ul0769-0004" num="5886">field 3: 192 bits (6×32-bit words)</li></ul></li></ul>
5887Field 0's position and size is defined by M<sub>1</sub>[0], and has an assumed start position of 15, which means the most significant word of field 0 must be in M<sub>0</sub>[15]. Field 0 therefore occupies M<sub>0</sub>[12] through to M<sub>0</sub>[15], and has an endPos value of 12.
5888Field 1's position and size is defined by M<sub>1</sub>[1], and has an assumed start position of 11 (i.e. M<sub>1</sub>[0].endPos-1). Since it has a length of 1 word, field 1 therefore occupies only M<sub>0</sub>[11] and its end position is the same as its start position i.e. its endPos value is 11.
5889Likewise field 2's position and size is defined by M<sub>1</sub>[2], and has an assumed start position of 10 (i.e. M<sub>1</sub>[1].endPos-1). Since it has a length of 5 words, field 2 therefore occupies M<sub>0</sub>[6] through to M<sub>0</sub>[10] and and has an endPos value of 6.
5890Finally, field 3's position and size is defined by M<sub>1</sub>[3], and has an assumed start position of 5 (i.e. M<sub>1</sub>[2].endPos-1). Since it has a length of 6 words, field 3 therefore occupies M<sub>0</sub>[5] through to M<sub>0</sub>[0] and and has an endPos value of 0.
5891Since all 16 words of M<sub>0 </sub>are now accounted for in the 4 fields, the remaining words of M<sub>1 </sub>(i.e. M<sub>1</sub>[4] though to M<sub>1</sub>[15]) are ignored, and can be used for any write-once (and thence read-only) data.
5892<figref idref="DRAWINGS">FIG. 365</figref> shows the same example in diagramatic format.
00008.1.1.1.2 Determining the Number of Fields
5893The following pseudocode illustrates a means of determining the number of fields:
5894<tables id="TABLE-US-00398" num="00398"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>fieldNum FindNumFields(M1)</entry></row><row><entry /><entry>startPos <img file="US7165824B2_D0339.tif" /> 15</entry></row><row><entry /><entry>fieldNum <img file="US7165824B2_D0340.tif" /> 0</entry></row><row><entry /><entry>While (fieldNum < 16)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>endPos <img file="US7165824B2_D0341.tif" /> M1[fieldNum].endPos</entry></row><row><entry /><entry>If (endPos > startPos)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry># error in this field... so must be an attack</entry></row><row><entry /><entry>attackDetected( ) # most likely clears all keys and data</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>fieldNum++</entry></row><row><entry /><entry>If (endPos = 0)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>return fieldNum # is already incremented</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>startPos <img file="US7165824B2_D0342.tif" /> endPos − 1 # endpos must be > 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndWhile</entry></row><row><entry /><entry># error if get here since 16 fields are consumed in 16 words at</entry></row><row><entry /><entry>most</entry></row><row><entry /><entry>attackDetected( ) # most likely clears all keys and data</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 8.1.1.1.3 Determining the Sizes of All Fields
5895The following pseudocode illustrates a means of determing the sizes of all valid fields:
5896<tables id="TABLE-US-00399" num="00399"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>FindFieldSizes(M1, fieldSize[ ])</entry></row><row><entry>numFields <img file="US7165824B2_D0343.tif" /> FindNumFields (M1) # assumes that FindNumFields does</entry></row><row><entry>all checking</entry></row><row><entry>ntartPos <img file="US7165824B2_D0344.tif" /> 15</entry></row><row><entry>fieldNum <img file="US7165824B2_D0345.tif" /> 0</entry></row><row><entry>While (fieldNum < numFields)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndPos <img file="US7165824B2_D0346.tif" /> M1[fieldNum].endPos</entry></row><row><entry /><entry>fieldSize[fieldNum] = startPos − endPos + 1</entry></row><row><entry /><entry>startPos <img file="US7165824B2_D0347.tif" /> endPos − 1 # endpos must be > 0</entry></row><row><entry /><entry>fieldNum++</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndWhile</entry></row><row><entry>While (fieldNum < 16)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>fieldSize[fieldNum] <img file="US7165824B2_D0348.tif" /> 0</entry></row><row><entry /><entry>fieldNum++</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndWhile</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 8.1.1.2 Field Type
5897The system must be able to identify the type of data stored in a field so that it can perform operations using the correct data. For example, a printer system must be able identify which of a consumable's fields are ink fields (and which field is which ink) so that the ink usage can be correctly applied during printing.
5898A field's type is defined by 15 bits. Table 332 in Appendix A lists the field types that are specifically required by the QA Chip Logical Interface and therefore apply across all applications.
5899The default value of M<sub>1</sub>[0] is 0, which means field0.type=0 (i.e. non-initialised).
5900Strictly speaking, the type need only be interpreted by all who can securely read and write to that field i.e. within the context of one or more keys. However it is convenient if possible to keep all types unique for simplistic identification of data across all applications.
5901In the general case, an external system communicating with a QA Device can identify the data stored in M0 in the following way: <ul id="ul0770" list-style="none"><li id="ul0770-0001" num="0000"><ul id="ul0771" list-style="none"><li id="ul0771-0001" num="5902">Read the KeyId of the key that has permission to write to the field. This will a give broad identification of the data type, which may be sufficient for certain applications.</li><li id="ul0771-0002" num="5903">Read the type attribute for the field to narrow down the identity within the broader context of the KeyId.</li></ul></li></ul>
5904For example, the printer system can read the KeyId to deduce that the data stored in a field can be written to via the HP_Network_InkRefill key, which means that any data is of the general ink category known to HP Network printers. By further reading the type attribute for the field the system can determine that the ink is Black ink.
00008.1.1.3 Field Permissions
5905All fields can be ready by everyone. However writes to fields are governed by 13-bits of permissions that are present in each field's attribute definition. The permissions describe who can do what to a specific field.
5906Writes to fields can either be authenticated (i.e. the data to be written is signed by a key and this signature must be checked by the receiving device before write access is given) or non-authenticated (i.e. the data is not signed by a key). Therefore we define a single bit (AuthRW) that specifies whether authenticated writes are permitted, and a single bit (NonAuthRW) specifying whether non-authenticated writes are permitted. Since it is pointless to permit both authenticated and non-authenticated writes to write any value (the authentciated writes are pointless), we further define the case when both bits are set to be interpreted as authenticated writes are permitted, but non-authenticated writes only succeed when the new value is less than the previous value i.e. the permission is decrement-only. The interpretation of these two bits is shown in Table 249.
5907<tables id="TABLE-US-00400" num="00400"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 249</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Interpretation of AuthRW and NonAuthRW</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="42pt" align="center" /><colspec colname="2" colwidth="35pt" align="center" /><colspec colname="3" colwidth="140pt" align="left" /><tbody valign="top"><row><entry>NonAuthRW</entry><entry>AuthRW</entry><entry>Interpretation</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>0</entry><entry>0</entry><entry>Read-only access (no-one can write to this</entry></row><row><entry /><entry /><entry>field).</entry></row><row><entry /><entry /><entry>This is the initial state for each field.</entry></row><row><entry /><entry /><entry>At instantiation all of M<sub>1 </sub>is 0 which means</entry></row><row><entry /><entry /><entry>AuthRW and NonAuthRW are 0 for each</entry></row><row><entry /><entry /><entry>field, and hence none of M<sub>0 </sub>can be written to</entry></row><row><entry /><entry /><entry>until a field is defined.</entry></row><row><entry>0</entry><entry>1</entry><entry>Authenticated write access is permitted</entry></row><row><entry /><entry /><entry>Non-authenticated write acecss is not</entry></row><row><entry /><entry /><entry>permitted</entry></row><row><entry>1</entry><entry>0</entry><entry>Authenticated write access is not permitted</entry></row><row><entry /><entry /><entry>Non-authenticated write access is permitted</entry></row><row><entry /><entry /><entry>(i.e. anyone can write to this field)</entry></row><row><entry>1</entry><entry>1</entry><entry>Authenticated write access is permitted</entry></row><row><entry /><entry /><entry>Non-authenticated write access is</entry></row><row><entry /><entry /><entry>decrement-only.</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
5908If authenticated write access is permitted, there are 11 additional bits (bringing the total number of permission bits to 13) to more fully describe the kind of write access for each key. We only permit a single key to have the ability to write any value to the field, and the remaining keys are defined as being either not permitted to write, or as having decrement-only write access. A 3-bit KeyNum represents the slot number of the key that has the ability to write any value to the field (as long as the key is locked into its key slot), and an 8-bit KeyPerms defines the write permissions for the (maximum of) 8 keys as follows: <ul id="ul0772" list-style="none"><li id="ul0772-0001" num="0000"><ul id="ul0773" list-style="none"><li id="ul0773-0001" num="5909">KeyPerms[n]=0: The key in slot n (i.e. K<sub>n</sub>) has no write access to this field (except when n=KeyNum). Setting KeyPerms to 0 prohibits a key from transferring value (when an amount is deducted from field in one QA Device and transferred to another field in a different QA Device)</li><li id="ul0773-0002" num="5910">KeyPerms[n]=1: The key in slot n (i.e. K<sub>n</sub>) is permitted to perform decrement-only writes to this field (as long as K<sub>n </sub>is locked in its key slot). Setting KeyPerms to 1 allows a key to transfer value (when an amount is deducted from field in one QA Device and transferred to another field in a different QA Device).</li></ul></li></ul>
5911The 13-bits of permissions (within bits <b>4</b>–<b>16</b> of M<sub>1</sub>[n]) are allocated as follows:
00008.1.1.3.1 Example 1
0000<ul id="ul0774" list-style="none"><li id="ul0774-0001" num="0000"><ul id="ul0775" list-style="none"><li id="ul0775-0001" num="5912"><figref idref="DRAWINGS">FIG. 367</figref> shows an example of permission bits for a field.</li><li id="ul0775-0002" num="5913">In this example we can see: <ul id="ul0776" list-style="none"><li id="ul0776-0001" num="5914">NonAuthRW=0 and AuthRW=1, which means that only authenticated writes are allowed i.e. writes to the field without an appropriate signature are not permitted.</li><li id="ul0776-0002" num="5915">KeyNum=3, so the only key permitted to write any value to the field is key 3 (i.e. K<sub>3</sub>).</li><li id="ul0776-0003" num="5916">KeyPerms[3]=0, which means that although key 3 is permitted to write to this field, key 3 can't be used to transfer value from this field to other QA Devices.</li><li id="ul0776-0004" num="5917">KeyPerms[0,4,5,6,7]=0, which means that these respective keys cannot write to this field.</li><li id="ul0776-0005" num="5918">KeyPerms[1,2]=1, which means that keys 1 and 2 have decrement-only access to this field i.e. they are permitted to write a new value to the field only when the new value is less than the current value. <br /> 8.1.1.3.2 Example 2 </li></ul></li><li id="ul0775-0003" num="5919"><figref idref="DRAWINGS">FIG. 368</figref> shows a second example of permission bits for a field.</li><li id="ul0775-0004" num="5920">In this example we can see: <ul id="ul0777" list-style="none"><li id="ul0777-0001" num="5921">NonAuthRW and AuthRW=1, which means that authenticated writes are allowed and writes to the field without a signature are only permitted when the new value is less than the current value (i.e. non-authenticated writes have decrement-only permission).</li><li id="ul0777-0002" num="5922">KeyNum=3, so the only key permitted to write any value to the field is key 3 (i.e. K<sub>3</sub>).</li><li id="ul0777-0003" num="5923">KeyPerms[3]=1, which means that key 3 is permitted to write to this field, and can be used to transfer value from this field to other QA Devices.</li><li id="ul0777-0004" num="5924">KeyPerms[0,4,5,6,7]=0, which means that these respective keys cannot write to this field.</li><li id="ul0777-0005" num="5925">KeyPerms[1,2]=1, which means that keys 1 and 2 have decrement-only access to this field i.e. they are permitted to write a new value to the field only when the new value is less than the current value. <br /> 8.1.1.4 Summary of Field Attributes </li></ul></li><li id="ul0775-0005" num="5926"><figref idref="DRAWINGS">FIG. 369</figref> shows the breakdown of bits within the 32-bit field attribute value M<sub>1</sub>[n].</li><li id="ul0775-0006" num="5927">Table 250 summarises each attribute.</li></ul></li></ul>
5928<tables id="TABLE-US-00401" num="00401"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 250</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Attributes for a field</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="28pt" align="center" /><colspec colname="4" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry>Sub-</entry><entry /><entry /></row><row><entry /><entry>attribute</entry><entry>Size</entry></row><row><entry>Attribute</entry><entry>name</entry><entry>in bits</entry><entry>Interpretation</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="28pt" align="char" char="." /><colspec colname="4" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>Type</entry><entry>Type</entry><entry>15</entry><entry>Gives additional identification</entry></row><row><entry /><entry /><entry /><entry>of the data stored in the field</entry></row><row><entry /><entry /><entry /><entry>within the context of the</entry></row><row><entry /><entry /><entry /><entry>accessors of that field.</entry></row><row><entry>Permissions</entry><entry>KeyNum</entry><entry>3</entry><entry>The slot number of the key that</entry></row><row><entry /><entry /><entry /><entry>has authenticated write access</entry></row><row><entry /><entry /><entry /><entry>to the field.</entry></row><row><entry /><entry>NonAuthRW</entry><entry>1</entry><entry>0 = non-authenticated writes</entry></row><row><entry /><entry /><entry /><entry>are not permitted to this field.</entry></row><row><entry /><entry /><entry /><entry>1 = non-authenticated writes</entry></row><row><entry /><entry /><entry /><entry>are permitted to this field</entry></row><row><entry /><entry /><entry /><entry>(see Table 249).</entry></row><row><entry /><entry>AuthRW</entry><entry>1</entry><entry>0 = authenticated writes are</entry></row><row><entry /><entry /><entry /><entry>not permitted to this field.</entry></row><row><entry /><entry /><entry /><entry>1 = authenticated writes are</entry></row><row><entry /><entry /><entry /><entry>permitted to this field.</entry></row><row><entry /><entry>KeyPerms</entry><entry>8</entry><entry>Bitmap representing the write</entry></row><row><entry /><entry /><entry /><entry>permissions for each of the keys</entry></row><row><entry /><entry /><entry /><entry>when AuthRW = 1.</entry></row><row><entry /><entry /><entry /><entry>For each bit:</entry></row><row><entry /><entry /><entry /><entry>0 = no write access for this</entry></row><row><entry /><entry /><entry /><entry>key (except for key KeyNum)</entry></row><row><entry /><entry /><entry /><entry>1 = decrement-only access</entry></row><row><entry /><entry /><entry /><entry>is permitted for this key.</entry></row><row><entry>Size and</entry><entry>EndPos</entry><entry>4</entry><entry>The word number in M<sub>0 </sub>that holds</entry></row><row><entry>Position</entry><entry /><entry /><entry>the lsw of the field. The msw is</entry></row><row><entry /><entry /><entry /><entry>held in M1[fieldNum − 1],</entry></row><row><entry /><entry /><entry /><entry>where msw of field 0 is 15.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 8.1.1.5 Permissions of M<sub>1 </sub>
5929M<sub>1 </sub>holds the field attributes for data stored in M<sub>0</sub>, and each word of M<sub>1 </sub>can be written to once only. It is important that a system can determine which words are available for writing. While this can be determined by reading M<sub>1 </sub>and determining which of the words is non-zero, a 16-bit permissions value P<sub>1 </sub>is available, with each bit indicating whether or not a given word in M<sub>1 </sub>has been written to. Bit n of P<sub>1 </sub>represents the permissions for M<sub>1</sub>[n] as follows:
5930<tables id="TABLE-US-00402" num="00402"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 251</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Interpretation of P<sub>1</sub>[n] i.e. bit n of M<sub>1</sub>'s permission</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="77pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>Description</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>0</entry><entry>writes to M<sub>1</sub>[n] are not permitted</entry></row><row><entry /><entry /><entry>i.e. this word is now read-only</entry></row><row><entry /><entry>1</entry><entry>writes to M<sub>1</sub>[n] are permitted</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
5931Since M<sub>1 </sub>is write-once, whenever a word is written to in M<sub>1</sub>, the corresponding bit of P<sub>1 </sub>is also cleared, i.e. writing to M<sub>1</sub>[n] clears P<sub>1</sub>[n].
5932Writes to M<sub>1</sub>[n] only succeed when all of M<sub>1</sub>[0 . . . n−1] have already written to (i.e. previous fields are defined) i.e. <ul id="ul0778" list-style="none"><li id="ul0778-0001" num="0000"><ul id="ul0779" list-style="none"><li id="ul0779-0001" num="5933">M<sub>1</sub>[0 . . . n−1] must have already been written to (i.e. P<sub>1</sub>[0 . . . n−1] are 0)</li><li id="ul0779-0002" num="5934">P<sub>1</sub>[n]=1 (i.e. it has not yet been written to)</li></ul></li></ul>
5935In addition, if M<sub>1</sub>[n−1].endPos≠0, the new M<sub>1</sub>[n] word will define the attributes of field n, so must be further checked as follows: <ul id="ul0780" list-style="none"><li id="ul0780-0001" num="0000"><ul id="ul0781" list-style="none"><li id="ul0781-0001" num="5936">The new M<sub>1</sub>[n].endPos must be valid (i.e. must be less than M<sub>1</sub>[n−1].endPos)</li><li id="ul0781-0002" num="5937">If the new M<sub>1</sub>[n].authRW is set, K<sub>keyNum </sub>must be locked, and all keys referred to by the new M<sub>1</sub>[n].keyPerms must also be locked.</li></ul></li></ul>
5938However if M<sub>1</sub>[n−1].endPos=0, then all of M<sub>0 </sub>has been defined in terms of fields. Since enough fields have been created to allocate all of M<sub>0</sub>, any remaining words in M<sub>1 </sub>are available for write-once general data storage purposes, and are not checked any further.
00008.1.2 M2+
5939M<sub>2</sub>, M<sub>3 </sub>etc., referred to as M<sub>2</sub>+, contains all the data that can be updated by anyone (i.e. no authenticated write is required) until the permissions for those sub-parts of M<sub>2+</sub> have changed from read/write to read-only.
5940The same permissions representation as used for M<sub>1 </sub>is also used for M<sub>2+</sub>. Consequently P<sub>n </sub>is a 16-bit value that contains the permissions for M<sub>n </sub>(where n>0). The permissions for word w of M<sub>n </sub>is given by a single bit P<sub>n</sub>[w]. However, unlike writes to M<sub>1</sub>, writes to M<sub>2+</sub> do not automatically clear bits in P. Only when the bits in P<sub>2+</sub> are explictly cleared (by anyone) do those corresponding words become read-only and final.
00009 Session Data
5941Data that is valid only for the duration of a particular communication session is referred to as session data. Session data ensures that every signature contains different data (sometimes referred to as a nonce) and this prevents replay attacks.
9.1 R
5942R is a 160-bit random number seed that is set up (when the QA Device is instantiated) and from that point on it is internally managed and updated by the QA Device. R is used to ensure that each signed item contains time varying information (not chosen by an attacker), and each QA Device's R is unrelated from one QA Device to the next.
5943This R is used in the generation and testing of signatures.
5944An attacker must not be able to deduce the values of R in present and future devices. Therefore, R should be programmed with a cryptographically strong random number, gathered from a physically random phenomenon (must not be deterministic).
00009.2 Advancing R
5945The session component of the message must only last for a single session (challenge and response).
5946The rules for updating R are as follows: <ul id="ul0782" list-style="none"><li id="ul0782-0001" num="0000"><ul id="ul0783" list-style="none"><li id="ul0783-0001" num="5947">Reads of R do not advance R.</li><li id="ul0783-0002" num="5948">Everytime a signature is produced with R, R is advanced to a new random number.</li><li id="ul0783-0003" num="5949">Everytime a signature including R is tested and is found to be correct, R is advanced to a new random number. <br /> 9.3 R<sub>L </sub>and R<sub>E </sub></li></ul></li></ul>
5950Each signature contains 2 pieces of session data i.e. 2 Rs: <ul id="ul0784" list-style="none"><li id="ul0784-0001" num="0000"><ul id="ul0785" list-style="none"><li id="ul0785-0001" num="5951">One R comes from the QA Device issuing the challenge i.e. the challenger. This is so the challenger can ensure that the challenged QA Device isn't simply replaying an old signature i.e. the challenger is protecting itself against the challenged.</li><li id="ul0785-0002" num="5952">One R comes from the device responding to the challenge i.e. the challenged. This is so the challenged never signs anything that is given to it without inserting some time varying change i.e. protects the challenged from the challenger in case the challenger is actually an attacker performing a chosen text attack</li></ul></li></ul>
5953Since there are two Rs, we need to distinguish between them. We do so by defining each R as external (R<sub>E</sub>) or local (R<sub>L</sub>) depending on its use in a given function. For example, the challenger sends out its local R, referred to as R<sub>L</sub>. The device being challenged receives the challenger's R as an external R, i.e R<sub>E</sub>. It then generates a signature using its R<sub>L </sub>and the challenger's R<sub>E</sub>. The resultant signature and R<sub>L </sub>are sent to the challenger as the response. The challenger receives the signature and R<sub>E </sub>(signature and R<sub>L </sub>produced by the device being challenged), produces its own signature using R<sub>L </sub>(sent to the device being challenged earlier) and R<sub>E </sub>received, and compares that signature to the signature received as response.
0000Signature Functions
000010 Objects
000010.1 KeyRef
000010.1.1 Object Description
5954Instead of passing keys directly into a function, a KeyRef (i.e. key reference) object is passed instead. A KeyRef object encapsulates the process by which a key is formed for common and variant forms of signature generation (based on the setting of the variables within the object). A KeyRef defines which key to use, whether it is a common or variant form of that key, and, if it is a variant form, the ChipId to use to create the variant. For more information about common and variant forms of keys, see Section 7.2.
5955Users pass KeyRef objects in as input parameters to public functions of the QA Chip Logical Interface, and these KeyRefs are subsequently passed to the signature function (called within the interface function). Note, however, that the method functions for KeyRef objects are not available outside the QA Chip Logical Interface.
000010.1.2 Object Variables
5956Table 252 describes each of the variables within a KeyRef object.
5957<tables id="TABLE-US-00403" num="00403"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 252</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Description of object variables for KeyRef object</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>Parameter</entry><entry>Description</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>keyNum</entry><entry>Slot number of the key to use as the basis for</entry></row><row><entry /><entry /><entry>key formation</entry></row><row><entry /><entry>useChipId</entry><entry>0 = the key to be formed is a common key</entry></row><row><entry /><entry /><entry>(i.e. is the same as K<sub>keyNum</sub>)</entry></row><row><entry /><entry /><entry>1 = the key to be formed is a variant key</entry></row><row><entry /><entry /><entry>based on K<sub>keyNum</sub></entry></row><row><entry /><entry>ChipId</entry><entry>When useChipId = 1, this is the ChipId</entry></row><row><entry /><entry /><entry>to be used to form the variant key (this will</entry></row><row><entry /><entry /><entry>be the ChipId of the QA Device which stores</entry></row><row><entry /><entry /><entry>the variant of K<sub>keyNum</sub>)</entry></row><row><entry /><entry /><entry>When useChipId = 0, chipId is not used</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 10.1.3 Object Methods <br /> 10.1.3.1 getKey <ul id="ul0786" list-style="none"><li id="ul0786-0001" num="0000"><ul id="ul0787" list-style="none"><li id="ul0787-0001" num="5958">public key getKey(void) <br /> 10.1.3.1.1 Method Description </li></ul></li></ul>
5959This method is a public method (public in object oriented terms, not public to users of the QA Chip Logical Interface) and is called by the GenerateSignature function to return the key for use in signature generation.
5960If useChipId is true, the formKeyVariant method is called to form the key using chipid and then return the variant key. If useChipId is false, the key stored in slot keyNum is returned.
000010.1.3.1.2 Method Sequence
5961The getKey method is illustrated by the following pseudocode:
5962<tables id="TABLE-US-00404" num="00404"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="63pt" align="left" /><colspec colname="1" colwidth="154pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>If (useChipId = 0)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="77pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>key <img file="US7165824B2_D0349.tif" /> K<sub>keyNum</sub></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="63pt" align="left" /><colspec colname="1" colwidth="154pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="77pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>key <img file="US7165824B2_D0350.tif" /> formKeyVariant( )</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="63pt" align="left" /><colspec colname="1" colwidth="154pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>Return key</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 10.1.3.2 formKeyVariant <ul id="ul0788" list-style="none"><li id="ul0788-0001" num="0000"><ul id="ul0789" list-style="none"><li id="ul0789-0001" num="5963">private key formKeyVariant (voID) <br /> 10.1.3.2.1 Method Description </li></ul></li></ul>
5964This method produces the variant form of a key, based on the K<sub>keyNum </sub>and chipId. As described in Section 7.2, the variant form of key K<sub>keyNum </sub>is generated by owf (K<sub>keyNum</sub>, chipID) where owf is a one-way function.
5965In addition, the time taken by owf must not depend on the value of the key i.e. the timing should be effectively constant. This prevents timing attacks on the key.
5966At present, owf is SHA1, although this still needs to be verified. Thus the variant key is defined to be SHA1(K<sub>keyNum</sub>|chipId).
000010.1.3.2.2 Method Sequence
5967The formKeyVariant method is illustrated by the following pseudocode:
5968<tables id="TABLE-US-00405" num="00405"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>key <img file="US7165824B2_D0351.tif" /> SHA1( K<sub>keyNum</sub>| chipId) # Calculation must take constant time</entry></row><row><entry>Return key</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 11 Functions
5969Digital signatures form the basis of all authentication protocols within the QA Chip Logical Interface. The signature functions are not directly available to users of the QA Chip Logical Interface, since a golden rule of digital signatures is never to sign anything exactly as it has been given to you.
5970Instead, these signature functions are internally available to the functions that comprise the public interface, and are used by those functions for the formation of keys and the generation of signatures.
000011.1 GenerateSignature
0000<ul id="ul0790" list-style="none"><li id="ul0790-0001" num="0000"><ul id="ul0791" list-style="none"><li id="ul0791-0001" num="5971">Input: KeyRef, Data, Random1, Random2</li><li id="ul0791-0002" num="5972">Output: SIG</li><li id="ul0791-0003" num="5973">Changes: None</li><li id="ul0791-0004" num="5974">Availability: All devices <br /> 11.1.1 Function Description </li></ul></li></ul>
5975This function uses KeyRef to obtain the actual key required for signature generation, appends Random1 and Random2 to Data, and performs HMAC_SHA1[key, Data] to output a signature. HMAC_SHA1 is described in [1]. In addition, this operation must take constant time irrespective of the value of the key (see Section 10.1.3.2 for more details).
000011.1.2 Input Parameter Description
5976Table 253 describes each of the input parameters:
5977<tables id="TABLE-US-00406" num="00406"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 253</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Description of input parameters for GenerateSignature</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="175pt" align="left" /><tbody valign="top"><row><entry>Parameter</entry><entry>Description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>KeyRef</entry><entry>This is an instance of the KeyRef object for use by</entry></row><row><entry /><entry>the GenerateSignature function. For common key</entry></row><row><entry /><entry>signature generation: KeyRef.keyNum = Slot number</entry></row><row><entry /><entry>of the key to be used to produce the signature.</entry></row><row><entry /><entry>KeyRef.useChipId = 0</entry></row><row><entry /><entry>For variant key signature generation:</entry></row><row><entry /><entry>KeyRef.keyNum = Slot number of the key to be</entry></row><row><entry /><entry>used for generating the variant key, where the</entry></row><row><entry /><entry>var iant key is to be used to produce the signature</entry></row><row><entry /><entry>KeyRef.useChipId = 1 KeyRef.chipId = ChipId</entry></row><row><entry /><entry>of the QA Device which stores the variant of</entry></row><row><entry /><entry>K<sub>KeyRef.keyNum</sub>, and uses the variant key for</entry></row><row><entry /><entry>signature generation.</entry></row><row><entry>Data</entry><entry>Preformatted data to be signed.</entry></row><row><entry /><entry>Random1 and Random2 are appended to Data before the</entry></row><row><entry /><entry>signature is generated to ensure that the signature</entry></row><row><entry /><entry>is session based (applicable only to a single session).</entry></row><row><entry>Random1</entry><entry>This is the session component from the QA Device that</entry></row><row><entry /><entry>is responding to the challenge.</entry></row><row><entry>Random2</entry><entry>This is the session component from the QA Device that</entry></row><row><entry /><entry>issued the challenge.</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 11.1.3 Output Parameter Description
5978Table 254 describes each of the output parameters.
5979<tables id="TABLE-US-00407" num="00407"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 254</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Description of output parameters for GenerateSignature</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="175pt" align="left" /><tbody valign="top"><row><entry>Parameter</entry><entry>Description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>SIG</entry><entry>SIG = SIG<sub>key</sub>(Data | Random1 | Random2) where key =</entry></row><row><entry /><entry>KeyRef.getKey( )</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 11.1.4 Function Sequence <ul id="ul0792" list-style="none"><li id="ul0792-0001" num="0000"><ul id="ul0793" list-style="none"><li id="ul0793-0001" num="5980">The GenerateSignature function is illustrated by the following pseudocode:</li></ul></li></ul>
5981<tables id="TABLE-US-00408" num="00408"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>key <img file="US7165824B2_D0352.tif" /> KeyRef.getKey( )</entry></row><row><entry>dataToBeSigned <img file="US7165824B2_D0353.tif" /> Data|Random1|Random2</entry></row><row><entry>SIG <img file="US7165824B2_D0354.tif" /> HMAC_SHA1(key, dataToBeSigned) # Calculation must take</entry></row><row><entry>constant time</entry></row><row><entry>Output SIG</entry></row><row><entry>Return</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> Basic Functions <br /> 12 Definitions
5982This section defines return codes and constants referred to by functions and pseudocode.
000012.1 ResultFlag
5983The ResultFlag is a byte that indicates the return status from a function. Callers can use the value of ResultFlag to determine whether a call to a function succeeded or failed, and if the call failed, the specific error condition.
5984Table 255 describes the ResultFlag values and the mnemonics used in the pseudocode.
5985<tables id="TABLE-US-00409" num="00409"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 255</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>ResultFlag value description</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>Mnemonic</entry><entry>Description</entry><entry>Possible causes</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>Pass</entry><entry>Function</entry><entry>Function successfully</entry></row><row><entry /><entry>completed</entry><entry>completed requested task.</entry></row><row><entry /><entry>sucessfully</entry></row><row><entry>Fail</entry><entry>General</entry><entry>An error occurred during</entry></row><row><entry /><entry>Failure</entry><entry>function processing.</entry></row><row><entry>BadSig</entry><entry>Signature</entry><entry>Input signature didn't match</entry></row><row><entry /><entry>mismatch</entry><entry>the generated signature.</entry></row><row><entry>InvalidKey</entry><entry>KeyRef</entry><entry>Input KeyRef.keyNum > 3.</entry></row><row><entry /><entry>incorrect</entry></row><row><entry>InvalidVector</entry><entry>VectNum</entry><entry>Input M<sub>VectNum </sub>> 3.</entry></row><row><entry /><entry>incorrect</entry></row><row><entry>InvalidPermission</entry><entry>Permission</entry><entry>Trying to perform a Write or</entry></row><row><entry /><entry>not adqeuate</entry><entry>WriteAuth with incorrect</entry></row><row><entry /><entry>to per form</entry><entry>permissions.</entry></row><row><entry /><entry>operation.</entry></row><row><entry>KeyAlreadyLocked</entry><entry>Key already</entry><entry>Key cannot be changed because</entry></row><row><entry /><entry>locked.</entry><entry>it has already been locked.</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.2 Constants
5986Table 256 describes the constants referred to by functions and pseudocode.
5987<tables id="TABLE-US-00410" num="00410"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 256</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Constants</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="119pt" align="left" /><tbody valign="top"><row><entry /><entry>Definition</entry><entry>Value</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>MaxKey</entry><entry>NumKeys − 1 (typically 7)</entry></row><row><entry /><entry>MaxM</entry><entry>NumVectors − 1 (typically 3)</entry></row><row><entry /><entry>MaxWordInM</entry><entry>16 − 1 = 15</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 13 GetInfo
5988<tables id="TABLE-US-00411" num="00411"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="203pt" align="left" /><thead><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>Input:</entry><entry>None</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="189pt" align="left" /><tbody valign="top"><row><entry>Output:</entry><entry>ResultFlag, SoftwareReleaseIdMajor, SoftwareReleaseIdMinor,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>NumVec tors, NumKeys,ChipId</entry></row><row><entry /><entry>DepthOfRollBackCache (for an upgrade device only)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="203pt" align="left" /><tbody valign="top"><row><entry>Changes :</entry><entry>None</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="189pt" align="left" /><tbody valign="top"><row><entry>Availability:</entry><entry>All devices</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 13.1 Function Description
5989Users of QA Devices must call the GetInfo function on each QA Device before calling any other functions on that device.
5990The GetInfo function tells the caller what kind of QA Device this is, what functions are available and what properties this QA Device has. The caller can use this information to correctly call functions with appropriately formatted parameters.
5991The first value returned, SoftwareReleaseIdMajor, effectively identifies what kind of QA Device this is, and therefore what functions are available to callers. SoftwareReleaseIdMinor tells the caller which version of the specific type of QA Device this is. The mapping between the SoftwareReleaseIdMajor and type of device and their different functions is described in Table 258 Every QA Device also returns NumVectors, NumKeys and ChipId which are required to set input parameter values for commands to the device.
5992Additional information may be returned depending on the type of QA Device. The VarDataLen and VarData fields of the output hold this additional information.
000013.2 Output parameters
5993Table 257 describes each of the output parameters.
5994<tables id="TABLE-US-00412" num="00412"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 257</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Description of output parameters for GetInfo function</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="49pt" align="center" /><colspec colname="3" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry>#</entry><entry /></row><row><entry>Parameter</entry><entry>bytes</entry><entry>Description</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>ResultFlag</entry><entry /><entry>Indicates whether the</entry></row><row><entry /><entry /><entry>function completed</entry></row><row><entry /><entry /><entry>successfully or not.</entry></row><row><entry /><entry /><entry>If it did not complete</entry></row><row><entry /><entry /><entry>successfully, the</entry></row><row><entry /><entry /><entry>reason for the failure</entry></row><row><entry /><entry /><entry>is returned here.</entry></row><row><entry /><entry /><entry>See Section 12.1.</entry></row><row><entry>SoftwareReleaseIdMajor</entry><entry>1</entry><entry>This defines the</entry></row><row><entry /><entry /><entry>function set that is</entry></row><row><entry /><entry /><entry>available on this QA</entry></row><row><entry /><entry /><entry>Device.</entry></row><row><entry>SoftwareReleaseIdMinor</entry><entry>1</entry><entry>This defines minor</entry></row><row><entry /><entry /><entry>software releases</entry></row><row><entry /><entry /><entry>within a major</entry></row><row><entry /><entry /><entry>release, and are</entry></row><row><entry /><entry /><entry>incremental changes to</entry></row><row><entry /><entry /><entry>the software mainly to</entry></row><row><entry /><entry /><entry>deal with bug fixes.</entry></row><row><entry>NumVectors</entry><entry>1</entry><entry>Total number of memory</entry></row><row><entry /><entry /><entry>vectors in this QA</entry></row><row><entry /><entry /><entry>Device.</entry></row><row><entry>NumKeys</entry><entry>1</entry><entry>Total number of keys</entry></row><row><entry /><entry /><entry>in this QA Device.</entry></row><row><entry>ChipId</entry><entry>6</entry><entry>This QA Device's</entry></row><row><entry /><entry /><entry>ChipId</entry></row><row><entry>VarDataLen</entry><entry>1</entry><entry>Length of bytes to</entry></row><row><entry /><entry /><entry>follow.</entry></row><row><entry>VarData</entry><entry>(VarDataLen</entry><entry>This is additional</entry></row><row><entry /><entry>bytes)</entry><entry>application specific</entry></row><row><entry /><entry /><entry>data, and will be of</entry></row><row><entry /><entry /><entry>length VarDataLen</entry></row><row><entry /><entry /><entry>(i.e. may be 0).</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
5995Table 258 shows the mapping between the SoftwareReleaseIdMajor, the type of QA Device and the available device functions.
5996<tables id="TABLE-US-00413" num="00413"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 258</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Mapping between SoftwareReleaseIdMajor</entry></row><row><entry>and available device functions</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="63pt" align="center" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="77pt" align="left" /><tbody valign="top"><row><entry>Software</entry><entry /><entry /></row><row><entry>ReleaseId</entry></row><row><entry>Major</entry><entry>Device description</entry><entry>Functions available</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>1</entry><entry>Ink or Printer QA</entry><entry>GetInfo</entry></row><row><entry /><entry>Device</entry><entry>Random</entry></row><row><entry /><entry /><entry>Read</entry></row><row><entry /><entry /><entry>Test</entry></row><row><entry /><entry /><entry>Translate</entry></row><row><entry /><entry /><entry>WriteM1+</entry></row><row><entry /><entry /><entry>WriteFields</entry></row><row><entry /><entry /><entry>WriteFieldsAuth</entry></row><row><entry /><entry /><entry>SetPerm</entry></row><row><entry /><entry /><entry>ReplaceKey</entry></row><row><entry>2</entry><entry>Value Upgrader QA</entry><entry>All functions in</entry></row><row><entry /><entry>Device (e.g. Ink</entry><entry>the Ink or Printer</entry></row><row><entry /><entry>Refill QA Device)</entry><entry>Device, plus:</entry></row><row><entry /><entry /><entry>StartXfer</entry></row><row><entry /><entry /><entry>XferAmount</entry></row><row><entry /><entry /><entry>StartRollBack</entry></row><row><entry /><entry /><entry>RollBackAmount</entry></row><row><entry>3</entry><entry>Parameter Upgrader</entry><entry>All functions in</entry></row><row><entry /><entry>QA Device</entry><entry>the Ink or Printer</entry></row><row><entry /><entry /><entry>device, plus:</entry></row><row><entry /><entry /><entry>StartXfer</entry></row><row><entry /><entry /><entry>XferField</entry></row><row><entry /><entry /><entry>StartRollBack</entry></row><row><entry /><entry /><entry>RollBackField</entry></row><row><entry>4</entry><entry>Key Replacement</entry><entry>All functions in</entry></row><row><entry /><entry>device</entry><entry>the Ink or Printer</entry></row><row><entry /><entry /><entry>Device, plus:</entry></row><row><entry /><entry /><entry>GetProgramKey</entry></row><row><entry /><entry /><entry>ReplaceKey - is</entry></row><row><entry /><entry /><entry>different from the</entry></row><row><entry /><entry /><entry>Ink or Printer</entry></row><row><entry /><entry /><entry>device</entry></row><row><entry>5</entry><entry>Trusted device</entry><entry>All functions in</entry></row><row><entry /><entry /><entry>the Ink or Printer</entry></row><row><entry /><entry /><entry>Device, plus:</entry></row><row><entry /><entry /><entry>SignM</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
5997Table 259 shows the VarData components for Value Upgrader and Parameter Upgrader QA Devices.
5998<tables id="TABLE-US-00414" num="00414"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 259</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>VarData for Value and Parameter Upgrader QA Devices</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="35pt" align="center" /><colspec colname="3" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>VarData</entry><entry>Length in</entry><entry /></row><row><entry>Components</entry><entry>bytes</entry><entry>Description</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>DepthOfRollBackCache</entry><entry>1</entry><entry>The number of datasets that can be</entry></row><row><entry /><entry /><entry>accommodated in the Xfer Entry</entry></row><row><entry /><entry /><entry>cache of the device.</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 13.3 Function Sequence <ul id="ul0794" list-style="none"><li id="ul0794-0001" num="0000"><ul id="ul0795" list-style="none"><li id="ul0795-0001" num="5999">The GetInfo command is illustrated by the following pseudocode:</li></ul></li></ul>
6000<tables id="TABLE-US-00415" num="00415"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>Output SoftwareReleaseIdMajor</entry></row><row><entry /><entry>Output SoftwareReleaseIdMinor</entry></row><row><entry /><entry>Output NumVectors</entry></row><row><entry /><entry>Output NumKeys</entry></row><row><entry /><entry>Output ChipId</entry></row><row><entry /><entry>VarDataLen <img file="US7165824B2_D0355.tif" /> 1 # In case of an upgrade device</entry></row><row><entry /><entry>Output DepthOfRollBackCache</entry></row><row><entry /><entry>Return</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 14 Random <ul id="ul0796" list-style="none"><li id="ul0796-0001" num="0000"><ul id="ul0797" list-style="none"><li id="ul0797-0001" num="6001">Input: None</li><li id="ul0797-0002" num="6002">Output: R<sub>L </sub></li><li id="ul0797-0003" num="6003">Changes: None</li><li id="ul0797-0004" num="6004">Availability: All devices</li></ul></li></ul>
6005The Random command is used by the caller to obtain a session component (challenge) for use in subsequent signature generation.
6006If a caller calls the Random function multiple times, the same output will be returned each time. R<sub>L </sub>(i.e. this QA Device's R) will only advance to the next random number in the sequence after a successful test of a signature or after producing a new signature. The same R<sub>L </sub>can never be used to produce two signatures from the same QA Device.
6007The Random command is illustrated by the following pseudocode: <ul id="ul0798" list-style="none"><li id="ul0798-0001" num="0000"><ul id="ul0799" list-style="none"><li id="ul0799-0001" num="6008">Output: R<sub>L </sub></li><li id="ul0799-0002" num="6009">Return <br /> 15 Read </li><li id="ul0799-0003" num="6010">Input: KeyRef, SigOnly, MSelect, KeyIdSelect, WordSelect, R<sub>E </sub></li><li id="ul0799-0004" num="6011">Output: ResultFlag, SelectedWordsOfSelectedMs, SelectedKeyIds, R<sub>L</sub>, SIG<sub>out </sub></li><li id="ul0799-0005" num="6012">Changes: R<sub>L </sub></li><li id="ul0799-0006" num="6013">Availability: All devices <br /> 15.1 Function Description </li></ul></li></ul>
6014The Read command is used to read data and keyIds from a QA Device. The caller can specify which words from M and which KeyIds are read.
6015The Read command can return both data and signature, or just the signature of the requested data. Since the return of data is based on the caller's input request, it prevents unnecessary information from being sent back to the caller. Callers typically request only the signature in order to confirm that locally cached values match the values on the QA Device.
6016The data read from an untrusted QA Device (A) using a Read command is validated by a trusted QA Device (B) using the Test command. The R<sub>L </sub>and SIG<sub>out </sub>produced as output from the Read command are input (along with correctly formatted data) to the Test command on a trusted QA Device for validation of the signature and hence the data. SIG<sub>out </sub>can also optionally be passed through the Translate command on a number of QA Devices between Read and Test if the QA Devices A and B do not share keys.
000015.2 Input Parameters
6017Table 260 describes each of the input parameters:
6018<tables id="TABLE-US-00416" num="00416"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 260</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Description of input parameters for Read</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="175pt" align="left" /><tbody valign="top"><row><entry>Parameter</entry><entry>Description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>KeyRef</entry><entry>For common key signature generation: KeyRef.keyNum =</entry></row><row><entry /><entry>Slot number of the key to be used for producing the</entry></row><row><entry /><entry>output signature. KeyRef.useChipId = 0</entry></row><row><entry /><entry>No variant key signature generation required</entry></row><row><entry>SigOnly</entry><entry>Flag indicating return of signature and data.</entry></row><row><entry /><entry>0- indicates both the signature and data are to be</entry></row><row><entry /><entry>returned. 1- indicates only the signature is to be</entry></row><row><entry /><entry>returned.</entry></row><row><entry>Mselect</entry><entry>Selection of memory vectors to be read - each bit</entry></row><row><entry /><entry>corresponding to a given memory vector (a maximum</entry></row><row><entry /><entry>of NumVector bits) 0- indicates the memory vector</entry></row><row><entry /><entry>must not be read. 1- indicates memory vector must</entry></row><row><entry /><entry>be read.</entry></row><row><entry>KeyIdSelect</entry><entry>Selection of KeyIds to be read - each bit</entry></row><row><entry /><entry>corresponds to a given KeyId (a maximum of NumKey</entry></row><row><entry /><entry>bits). 0- indicates KeyId must not be read.</entry></row><row><entry /><entry>1- indicates KeyId must be read.</entry></row><row><entry>WordSelect</entry><entry>Selection of words read from a desired M as</entry></row><row><entry /><entry>requested in MSelect. Each WordSelect is 16 bits</entry></row><row><entry /><entry>corresponding to each bit in MSelect. Each bit in</entry></row><row><entry /><entry>the WordSelect indicates whether or not to read</entry></row><row><entry /><entry>the corresponding word for the particular M.</entry></row><row><entry /><entry>0- indicates word must not be read. 1- indicates</entry></row><row><entry /><entry>word must be read.</entry></row><row><entry>R<sub>E</sub></entry><entry>External random value required for output signature</entry></row><row><entry /><entry>generation (i.e the challenge). R<sub>E </sub>is obtained by</entry></row><row><entry /><entry>calling the Random function on the device which</entry></row><row><entry /><entry>will receive the SIG<sub>out </sub>from the Read function.</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 15.3 Output Parameters
6019<tables id="TABLE-US-00417" num="00417"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="126pt" align="left" /><thead><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>Parameter</entry><entry>Description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>ResultFlag</entry><entry>Indicates whether the function completed</entry></row><row><entry /><entry>successfully or not. If it did not</entry></row><row><entry /><entry>complete successfully, the reason for</entry></row><row><entry /><entry>the failure is returned here.</entry></row><row><entry /><entry>See Section 12.1.</entry></row><row><entry>SelectedWordsOfSelectedMs</entry><entry>Selected words from selected memory</entry></row><row><entry /><entry>vectors as requested by MSelect and</entry></row><row><entry /><entry>WordSelect.</entry></row><row><entry>SelectedKeyIds</entry><entry>Selected KeyIds as requested by</entry></row><row><entry /><entry>KeyIdSelect.</entry></row><row><entry>R<sub>L</sub></entry><entry>Local random value added to the output</entry></row><row><entry /><entry>signature (i.e SIG<sub>out</sub>). Refer to</entry></row><row><entry /><entry>FIG. 370.</entry></row><row><entry>SIG<sub>out</sub></entry><entry>SIG<sub>out </sub>= SIG<sub>KeyRef</sub>(data | R<sub>L </sub>| R<sub>E</sub>)</entry></row><row><entry /><entry>as shown in FIG. 8.</entry></row><row><entry /><entry>Refer to Section 10.1.3.1 for details</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 15.3.1 SIG<sub>out </sub><ul id="ul0800" list-style="none"><li id="ul0800-0001" num="0000"><ul id="ul0801" list-style="none"><li id="ul0801-0001" num="6020"><figref idref="DRAWINGS">FIG. 370</figref> shows the formatting of data for output signature generation.</li><li id="ul0801-0002" num="6021">Table 262 gives the parameters included in SIG<sub>out</sub></li></ul></li></ul>
6022<tables id="TABLE-US-00418" num="00418"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="98pt" align="left" /><colspec colname="2" colwidth="35pt" align="center" /><colspec colname="3" colwidth="63pt" align="left" /><colspec colname="4" colwidth="21pt" align="center" /><thead><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry /><entry /><entry /><entry>Value</entry></row><row><entry /><entry /><entry /><entry>set</entry></row><row><entry /><entry>Length</entry><entry>Value set</entry><entry>from</entry></row><row><entry>Parameter</entry><entry>in bits</entry><entry>internally</entry><entry>Input</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="98pt" align="left" /><colspec colname="2" colwidth="35pt" align="char" char="." /><colspec colname="3" colwidth="63pt" align="left" /><colspec colname="4" colwidth="21pt" align="center" /><tbody valign="top"><row><entry>RWSense</entry><entry>3</entry><entry>read constant =</entry><entry /></row><row><entry /><entry /><entry>000</entry></row><row><entry /><entry /><entry>Refer to Section</entry></row><row><entry /><entry /><entry>15.3.1.1</entry></row><row><entry>MSelect</entry><entry>4</entry><entry /><entry>●</entry></row><row><entry>KeyIdSelect</entry><entry>8</entry><entry /><entry>●</entry></row><row><entry>ChipId</entry><entry>48</entry><entry>This QA Device's</entry></row><row><entry /><entry /><entry>ChipId</entry></row><row><entry>WordSelect</entry><entry>16</entry><entry /><entry>●</entry></row><row><entry /><entry>per M</entry></row><row><entry>SelectedWordsOfSelectedMs</entry><entry>32</entry><entry>The appropriate</entry><entry>●</entry></row><row><entry /><entry>per word</entry><entry>words from the</entry></row><row><entry /><entry /><entry>various Ms as</entry></row><row><entry /><entry /><entry>selected by the</entry></row><row><entry /><entry /><entry>caller</entry></row><row><entry>R<sub>L</sub></entry><entry>160</entry><entry>This QA Device's</entry></row><row><entry /><entry /><entry>current R</entry></row><row><entry>R<sub>E</sub></entry><entry>160</entry><entry /><entry>●</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 15.3.1.1 RWSense
6023An RWSense value is present in the signed data to distinguish whether a signature was produced from a Read or produced for a WriteAuth.
6024The RWSense is set to a read constant (000) for producing a signature from a read function. The RWSense is set to a write constant (001) for producing a signature for a write function.
6025The RWSense prevents signatures produced by Read to be subsequently sent into a WriteAuth function. Only signatures produced with RWSense set to write (001), are accepted by a write function.
000015.4 Function sequence
6026The Read command is illustrated by the following pseudocode:
6027<tables id="TABLE-US-00419" num="00419"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>Accept input parameters- KeyRef, SigOnly, MSelect, KeyIdSelect</entry></row><row><entry># Accept input parameter WordSelect based on MSelect</entry></row><row><entry>For i <img file="US7165824B2_D0356.tif" /> 0 to MaxM</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>If(MSelect[i] = 1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Accept next WordSelect</entry></row><row><entry /><entry>WordSelectTemp[i] <img file="US7165824B2_D0357.tif" /> WordSelect</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndFor</entry></row><row><entry>Accept R<sub>E</sub></entry></row><row><entry>Check range of KeyRef.keyNum</entry></row><row><entry>If invalid</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0358.tif" /> InvalidKey</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>#Build SelectedWordsOfSelectedMs</entry></row><row><entry>k <img file="US7165824B2_D0359.tif" /> 0 # k stores the word count for SelectedWordsOfSelectedMs</entry></row><row><entry>SelectedWordsOfSelectedMs[k] <img file="US7165824B2_D0360.tif" /> 0</entry></row><row><entry>For i<img file="US7165824B2_D0361.tif" /> 0 to 3</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>If(MSelect[i] = 1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>For j <img file="US7165824B2_D0362.tif" /> 0 to MaxWordInM</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>If(WordSelectTemp[i][j] = 1)</entry></row><row><entry /><entry> SelectedWordsOfSelectedMs[k] <img file="US7165824B2_D0363.tif" /> (M<sub>i</sub>[j])</entry></row><row><entry /><entry> k++</entry></row><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndFor</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndFor</entry></row><row><entry>#Build SelectedKeyIds</entry></row><row><entry>l <img file="US7165824B2_D0364.tif" /> 0 # l stores the word count for SelectedKeyIds</entry></row><row><entry>SelectedKeyIds[l] <img file="US7165824B2_D0365.tif" /> 0</entry></row><row><entry>For i <img file="US7165824B2_D0366.tif" /> 0 to MaxKey</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>If(KeyIdSelect[i] = 1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>SelectedKeyIds[l] <img file="US7165824B2_D0367.tif" /> KeyId[i]</entry></row><row><entry /><entry>l++</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndFor</entry></row><row><entry>#Generate message for passing into the GenerateSignature function</entry></row><row><entry>data <img file="US7165824B2_D0368.tif" /> (RWSense|MSelect|KeyIdSelect|ChipId|WordSelect</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>|SelectedWordsOfSelectedMs|SelectedKeyIds) # Refer to</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Figure 370.</entry></row><row><entry>#Generate Signature function</entry></row><row><entry>SIG<sub>L </sub><img file="US7165824B2_D0369.tif" /> GenerateSignature(KeyRef,data,R<sub>L</sub>,R<sub>E</sub>) # See Section 11.1</entry></row><row><entry>Update R<sub>L </sub>to R<sub>L2</sub></entry></row><row><entry>ResultFlag <img file="US7165824B2_D0370.tif" /> Pass</entry></row><row><entry>Output ResultFlag</entry></row><row><entry>If(SigOnly = 0)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Output SelectedWordsOfSelectedMs, SelectedKeyIds</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>Output R<sub>L</sub>, SIG<sub>L</sub></entry></row><row><entry>Return</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 16 Test <ul id="ul0802" list-style="none"><li id="ul0802-0001" num="0000"><ul id="ul0803" list-style="none"><li id="ul0803-0001" num="6028">Input: KeyRef, DataLength, Data, R<sub>E</sub>, SIG<sub>E </sub></li><li id="ul0803-0002" num="6029">Output: ResultFlag</li><li id="ul0803-0003" num="6030">Changes: R<sub>L </sub></li><li id="ul0803-0004" num="6031">Availability: All devices except ink device <br /> 16.1 Function Description </li></ul></li></ul>
6032The Test command is used to validate data that has been read from an untrusted QA Device according to a digital signature SIG<sub>E</sub>. The data will typically be memory vector and KeyId data. SIG<sub>E </sub>(and its related R<sub>E</sub>) is the most recent signature—this will be the signature produced by Read if Translate was not used, or will be the output from the most recent Translate if Translate was used. The Test function produces a local signature (SIG<sub>L</sub>=SIG<sub>key</sub>(Data|R<sub>E</sub>|R<sub>L</sub>) and compares it to the input signature (SIG<sub>E</sub>). If the two signatures match the function returns ‘Pass’, and the caller knows that the data read can be trusted.
6033The key used to produce SIG<sub>L </sub>depends on whether SIG<sub>E </sub>was produced by a QA Device sharing a common key or a variant key. The KeyRef object passed into the interface must be set appropriately to reflect this.
6034The Test function accepts preformatted data (as DataLength number of words), and appends the external R<sub>E </sub>and local R<sub>L </sub>to the preformatted data to generate the signature as shown in <figref idref="DRAWINGS">FIG. 371</figref>.
000016.2 Input Parameters
6035Table 263 describes each of the input parameters.
6036<tables id="TABLE-US-00420" num="00420"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 263</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Description of input parameters for Test</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="168pt" align="left" /><tbody valign="top"><row><entry>Parameter</entry><entry>Description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>KeyRef</entry><entry>For testing common key signature: KeyRef.keyNum =</entry></row><row><entry /><entry>Slot number of the key to be used for testing the</entry></row><row><entry /><entry>signature. SIG<sub>E </sub>produced using K<sub>KeyRef.keyNum </sub>by the</entry></row><row><entry /><entry>external device. KeyRef.useChipId = 0</entry></row><row><entry /><entry>For testing variant key signature: KeyRef.keyNum =</entry></row><row><entry /><entry>Slot number of the key to be used for generating</entry></row><row><entry /><entry>the variant key. SIG<sub>E </sub>produced using a variant of</entry></row><row><entry /><entry>K<sub>KeyRef.keyNum </sub>by the external device.</entry></row><row><entry /><entry>KeyRef.useChipId = 1 KeyRef.chipId = ChipId of</entry></row><row><entry /><entry>the device which generated SIG<sub>E </sub>using a variant of</entry></row><row><entry /><entry>K<sub>KeyRef.keyNum</sub>.</entry></row><row><entry>DataLength</entry><entry>Length of preformatted data in words. Must be non</entry></row><row><entry /><entry>zero.</entry></row><row><entry>Data</entry><entry>Preformatted data to be used for producing the</entry></row><row><entry /><entry>signature.</entry></row><row><entry>R<sub>E</sub></entry><entry>External random value required for verifying the</entry></row><row><entry /><entry>input signature. This will be the R from the input</entry></row><row><entry /><entry>signature generator (i.e the device generating SIG<sub>E</sub>).</entry></row><row><entry>SIG<sub>E</sub></entry><entry>External signature required for authenticating input</entry></row><row><entry /><entry>data as shown in FIG. 371.</entry></row><row><entry /><entry>The external signature is generated either by a</entry></row><row><entry /><entry>Read function or a Translate function. A correct</entry></row><row><entry /><entry>SIG<sub>E </sub>= SIG<sub>KeyRef</sub>(Data | R<sub>E </sub>| R<sub>L</sub>).</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 16.2.1 Input Signature Verification Data Format
6037<figref idref="DRAWINGS">FIG. 371</figref> shows the formatting of data for input signature verification.
6038The data in <figref idref="DRAWINGS">FIG. 371</figref> (i.e. not R<sub>E </sub>or R<sub>L</sub>) is typically output from a Read function (formatted as per <figref idref="DRAWINGS">FIG. 370</figref>). The data may also be generated in the same format by the system from its cache as will be the case when it performs a Read using SigOnly=1.
000016.3 Output Parameters
6039Table 264 describes each of the output parameters.
6040<tables id="TABLE-US-00421" num="00421"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 264</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Description of output parameters for Test</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="168pt" align="left" /><tbody valign="top"><row><entry>Parameter</entry><entry>Description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>ResultFlag</entry><entry>Indicates whether the function completed successfully</entry></row><row><entry /><entry>or not. If it did not complete successfully, the</entry></row><row><entry /><entry>reason for the failure is returned here.</entry></row><row><entry /><entry>See Section 12.1.</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 16.4 Function Sequence
6041The Test command is illustrated by the following pseudocode: <ul id="ul0804" list-style="none"><li id="ul0804-0001" num="0000"><ul id="ul0805" list-style="none"><li id="ul0805-0001" num="6042">Accept input parameters—KeyRef, DataLength</li></ul></li></ul>
6043<tables id="TABLE-US-00422" num="00422"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry># Accept input parameter- Data based on DataLength</entry></row><row><entry>For i <img file="US7165824B2_D0371.tif" /> 0 to (DataLength − 1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Accept next word of Data</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndFor</entry></row><row><entry>Accept input parameters - R<sub>E</sub>, SIG<sub>E</sub></entry></row><row><entry>Check range of KeyRef.keyNum</entry></row><row><entry>If invalid</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0372.tif" /> InvalidKey</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>#Generate signature</entry></row><row><entry>SIG<sub>L </sub><img file="US7165824B2_D0373.tif" /> GenerateSignature(KeyRef,Data,R<sub>E</sub>,R<sub>L</sub>) # Refer to Figure 371.</entry></row><row><entry>#Check signature</entry></row><row><entry>If(SIG<sub>L </sub>= SIG<sub>E</sub>)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Update R<sub>L </sub>to R<sub>L2</sub></entry></row><row><entry /><entry>ResultFlag <img file="US7165824B2_D0374.tif" /> Pass</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0375.tif" /> BadSig</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>Output ResultFlag</entry></row><row><entry>Return</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 17 Translate <ul id="ul0806" list-style="none"><li id="ul0806-0001" num="6044">Input: InputKeyRef, DataLength, Data, R<sub>E</sub>, SIG<sub>E</sub>, OutputKeyRef, R<sub>E2 </sub></li><li id="ul0806-0002" num="6045">Output: ResultFlag, R<sub>L2</sub>, SIG<sub>out </sub></li><li id="ul0806-0003" num="6046">Changes: R<sub>L </sub></li><li id="ul0806-0004" num="6047">Availability: Printer device, and possibly on other devices <br /> 17.1 Function Description </li></ul>
6048It is possible for a system to call the Read function on QA Device A to obtain data and signature, and then call the Test function on QA Device B to validate the data and signature. In the same way it is possible for a system to call the SignM function on a trusted QA Device B and then call the WriteAuth function on QA Device B to actually store data on B. Both of these actions are only possible when QA Devices A and B share secret key information.
6049If however, A and B do not share secret keys, we can create a validation chain (and hence extension of trust) by means of translation of signatures. A given QA Device can only translate signatures if it knows the key of the previous stage in the chain as well as the key of the next stage in the chain. The Translate function provides this functionality.
6050The Translate function translates a signature from one based on one key to one based another key. The Translate function first performs a test of the input signature using the InputKeyRef, and if the test succeeds produces an output signature using the OutputKeyRef. The Translate function can therefore in some ways be considered to be a combination of the Test and Read function, except that the data is input into the QA Device instead of being read from it.
6051The InputKeyRef object passed into Translate must be set appropriately to reflect whether SIG<sub>E </sub>was produced by a QA Device sharing a common key or a variant key.
000027.1.4.14 GetFieldDataWords(FieldNum,FieldData<img file="US7165824B2_D0376.tif" />, M0,M1) a common key or a variant key with the QA Device receiving the signature. The OutputKeyRef object passed into Translate must be set appropriately to reflect this.
6052Since the Translate function does not interpret or generate the data in any way, only preformatted data can be passed in. The Translate function does however append the external R<sub>E </sub>and local R<sub>L </sub>to the preformatted data for verifying the input signature, then advances R<sub>L </sub>to R<sub>L2</sub>, and appends R<sub>L2 </sub>and R<sub>E2 </sub>to the preformatted data to produce the output signature. This is done to protect the keys and prevent replay attacks.
6053The Translate functions translates: <ul id="ul0807" list-style="none"><li id="ul0807-0001" num="0000"><ul id="ul0808" list-style="none"><li id="ul0808-0001" num="6054">signatures for subsequent use in Test, typically originating from Read</li><li id="ul0808-0002" num="6055">signatures for subsequent use in WriteAuth, typically originating from SignM</li></ul></li></ul>
6056In both cases, preformatted data is passed into the Translate function by the system. For translation of data destined for Test, the data should be preformatted as per <figref idref="DRAWINGS">FIG. 370</figref> (all words except the Rs). For translation of signatures for use in WriteAuth, the data should be preformatted as per <figref idref="DRAWINGS">FIG. 373</figref> (all words except the Rs).
000017.2 Input Parameters
6057Table 265 describes each of the input parameters.
6058<tables id="TABLE-US-00423" num="00423"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 265</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Description or input parameters for Translate</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="161pt" align="left" /><tbody valign="top"><row><entry>Parameter</entry><entry>Description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>InputKeyRef</entry><entry>For translating common key input signature:</entry></row><row><entry /><entry>InputKeyRef.keyNum = Slot number of the key to</entry></row><row><entry /><entry>be used for testing the signature. SIG<sub>E </sub>produced using</entry></row><row><entry /><entry>K<sub>InputKeyRef.keyNum </sub>by the external device.</entry></row><row><entry /><entry>InputKeyRef.useChipId = 0</entry></row><row><entry /><entry>For translating variant key input signatures:</entry></row><row><entry /><entry>InputKeyRef.keyNum = Slot number of the key to</entry></row><row><entry /><entry>be used for generating the variant key. SIG<sub>E </sub>produced</entry></row><row><entry /><entry>using a variant of K<sub>InputKeyRef.keyNum </sub>by the external</entry></row><row><entry /><entry>device. InputKeyRef.useChipId = 1</entry></row><row><entry /><entry>InputKeyRef.chipId = ChipId of the device which</entry></row><row><entry /><entry>generated SIG<sub>E </sub>using a variant of K<sub>InputKeyRef.keyNum</sub>.</entry></row><row><entry>DataLength:</entry><entry>Length of data in words.</entry></row><row><entry>Data</entry><entry>Data used for testing the input signature and for</entry></row><row><entry /><entry>producing the output signature.</entry></row><row><entry>R<sub>E</sub></entry><entry>External random value required for verifying input</entry></row><row><entry /><entry>signature. This will be the R from the input signature</entry></row><row><entry /><entry>generator (i.e device generating SIG<sub>E</sub>).</entry></row><row><entry>SIG<sub>E</sub></entry><entry>External signature required for authenticating input</entry></row><row><entry /><entry>data. The external signature is either generated by a</entry></row><row><entry /><entry>Read function, a Xfer/Rollback function or a Translate</entry></row><row><entry /><entry>function. A correct SIG<sub>E </sub>= SIG<sub>KeyRef</sub>(Data | R<sub>E </sub>| R<sub>L</sub>).</entry></row><row><entry>OutputKeyRef</entry><entry>For generating common key output signature:</entry></row><row><entry /><entry>OutputKeyRef.keyNum = Slot number of the key</entry></row><row><entry /><entry>for producing the output signature. SIGout produced</entry></row><row><entry /><entry>using K<sub>OutputKeyRef.keyNum </sub>because the device</entry></row><row><entry /><entry>receiving SIGout shares K<sub>OutputKeyRef.keyNum </sub>with</entry></row><row><entry /><entry>the translating device. OutputKeyRef.useChipId = 0</entry></row><row><entry /><entry>For generating variant key output signature:</entry></row><row><entry /><entry>OutputKeyRef.keyNum = Slot number of the key</entry></row><row><entry /><entry>to be used for generating the variant key. SIGout</entry></row><row><entry /><entry>produced using a variant of K<sub>OutputKeyRef.keyNum</sub></entry></row><row><entry /><entry>because the device receiving SIGout shares a</entry></row><row><entry /><entry>variant of K<sub>OutputKeyRef.keyNum </sub>with the</entry></row><row><entry /><entry>translating device. OutputKeyRef.useChipId = 1</entry></row><row><entry /><entry>OutputKeyRef.chipId = ChipId of the device</entry></row><row><entry /><entry>which receives SIG<sub>out </sub>produced by a variant of</entry></row><row><entry /><entry>K<sub>OutputKeyRef.keyNum</sub>.</entry></row><row><entry>R<sub>E2</sub></entry><entry>External random value required for output signature</entry></row><row><entry /><entry>generation. This will be the R from the destination of</entry></row><row><entry /><entry>SIG<sub>out</sub>. R<sub>E2 </sub>is obtained by calling the Random function</entry></row><row><entry /><entry>on the device which will receive the SIG<sub>out </sub>from the</entry></row><row><entry /><entry>Translate function.</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 17.2.1 Input Signature Verification Data Format
6059This is the same format as used in the Test function. Refer to Section 16.2.1.
000017.3 Output parameters
6060Table 266 describes each of the output parameters.
6061<tables id="TABLE-US-00424" num="00424"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 266</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Description of output parameters for Translate</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="175pt" align="left" /><tbody valign="top"><row><entry>Parameter</entry><entry>Description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>ResultFlag</entry><entry>Indicates whether the function completed successfully</entry></row><row><entry /><entry>or not. If it did not complete successfully, the</entry></row><row><entry /><entry>reason for the failure is returned here. See Section 12.1.</entry></row><row><entry>R<sub>L2</sub></entry><entry>Local random value used in output signature</entry></row><row><entry /><entry>(i.e SIG<sub>Out</sub>).</entry></row><row><entry>SIG<sub>Out</sub></entry><entry>Output signature produced using OutputKeyRef.keyNum</entry></row><row><entry /><entry>using the data format described in FIG. 372.</entry></row><row><entry /><entry>SIGout = SIG<sub>OutKeyRef</sub>(Data | R<sub>L2</sub>| R<sub>E2</sub>).</entry></row><row><entry /><entry>Refer to Section 10.1.3.1 for details.</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 17.3.1 SIG<sub>out </sub>
6062<figref idref="DRAWINGS">FIG. 372</figref> shows the data format for output signature generation from the Translate function.
000017.4 Function Sequence
6063The Translate command is illustrated by the following pseudocode:
6064<tables id="TABLE-US-00425" num="00425"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>Accept input parameters-InputKeyRef, DataLength</entry></row><row><entry /><entry># Accept input parameter- Data based on DataLength</entry></row><row><entry /><entry>For i <img file="US7165824B2_D0377.tif" /> 0 to (DataLength − 1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Accept next Data</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndFor</entry></row><row><entry /><entry>Accept input parameters - R<sub>E</sub>, SIG<sub>E</sub>, OutputKeyRef, R<sub>E2</sub></entry></row><row><entry /><entry>Check range of InputKeyRef.keyNum and OutputKeyRef.keyNum</entry></row><row><entry /><entry>If invalid</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0378.tif" /> Invalidkey</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>#Generate Signature</entry></row><row><entry /><entry>SIG<sub>L </sub><img file="US7165824B2_D0379.tif" /> GenerateSignature(InputKeyRef,Data,R<sub>E</sub>,R<sub>L</sub>) # Refer to</entry></row><row><entry /><entry>Figure 371.</entry></row><row><entry /><entry>#Validate input signature</entry></row><row><entry /><entry>If(SIG<sub>L </sub>= SIG<sub>E</sub>)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Update R<sub>L </sub>to R<sub>L2</sub></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0380.tif" /> BadSig</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>#Generate output signature</entry></row><row><entry /><entry>SIG<sub>Out </sub><img file="US7165824B2_D0381.tif" /> GenerateSignature(OutputKeyRef,Data,R<sub>E</sub>,R<sub>L</sub>) # Refer to</entry></row><row><entry /><entry>Figure 372.</entry></row><row><entry /><entry>Update R<sub>L2 </sub>to R<sub>L3</sub></entry></row><row><entry /><entry>ResultFlag <img file="US7165824B2_D0382.tif" /> Pass</entry></row><row><entry /><entry>Output ResultFlag, R<sub>L2</sub>, SIG<sub>Out</sub></entry></row><row><entry /><entry>Return</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 18 WriteM1+ <ul id="ul0809" list-style="none"><li id="ul0809-0001" num="0000"><ul id="ul0810" list-style="none"><li id="ul0810-0001" num="6065">Input: VectNum, WordSelect, MVal</li><li id="ul0810-0002" num="6066">Output: ResultFlag</li><li id="ul0810-0003" num="6067">Changes: M<sub>VectNum </sub></li><li id="ul0810-0004" num="6068">Availability: All devices <br /> 18.1 Function description </li></ul></li></ul>
6069The WriteM1+ function is used to update selected words of M1+, subject to the permissions corresponding to those words stored in P<sub>VectNum</sub>.
6070Note: Unlike WriteAuth, a signature is not required as an input to this function.
000018.2 Input Parameters
6071Table 267 describes each of the input parameters.
6072<tables id="TABLE-US-00426" num="00426"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 267</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Description of input parameters for WriteM1+</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="154pt" align="left" /><tbody valign="top"><row><entry /><entry>Parameter</entry><entry>Description</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>VectNum</entry><entry>Number of the memory vector to be written.</entry></row><row><entry /><entry /><entry>Must be in range 1 to (NumVectors − 1)</entry></row><row><entry /><entry>WordSelect</entry><entry>Selection of words to be written.</entry></row><row><entry /><entry /><entry>0- indicates corresponding word is not written.</entry></row><row><entry /><entry /><entry>1- indicates corresponding word is to be</entry></row><row><entry /><entry /><entry>written as per input.</entry></row><row><entry /><entry /><entry>If WordSelect[N bit] is set, then write</entry></row><row><entry /><entry /><entry>to M<sub>VectNum </sub>word N.</entry></row><row><entry /><entry>MVal</entry><entry>Multiple of words corresponding to the number</entry></row><row><entry /><entry /><entry>of words selected for write.</entry></row><row><entry /><entry /><entry>Starts with LSW of M<sub>VectNum</sub>.</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
6073Note: Since this function has no accompanying signatures, additional input parameter error checking is required.
000018.3 Output Parameters
6074Table 268 describes each of the output parameters.
6075<tables id="TABLE-US-00427" num="00427"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 268</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Description of output parameters for WriteM1+</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="168pt" align="left" /><tbody valign="top"><row><entry>Parameter</entry><entry>Description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>ResultFlag</entry><entry>Indicates whether the function completed successfully</entry></row><row><entry /><entry>or not. If it did not complete successfully, the</entry></row><row><entry /><entry>reason for the failure is returned here.</entry></row><row><entry /><entry>See Section 12.1.</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 18.4 Function Sequence
6076The WriteM1+ command is illustrated by the following pseudocode:
6077<tables id="TABLE-US-00428" num="00428"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>Accept input parameters VectNum, WordSelect</entry></row><row><entry>#Accept MVal as per WordSelect</entry></row><row><entry>MValTemp[16] <img file="US7165824B2_D0383.tif" /> 0 # Temporary buffer to hold MVal after being read</entry></row><row><entry>For i <img file="US7165824B2_D0384.tif" /> 0 to MaxWordInM # word 0 to word 15</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>If(WordSelect[i] = 1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Accept next MVal</entry></row><row><entry /><entry>MValTemp[i] <img file="US7165824B2_D0385.tif" /> MVal # Store MVal in temporary buffer</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndFor</entry></row><row><entry>Check range of VectNum</entry></row><row><entry>If invalid</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0386.tif" /> InvalidVector</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>#Checking non authenticated write permission for M1+</entry></row><row><entry>PermOK <img file="US7165824B2_D0387.tif" /> CheckM1+Perm(VectNum,WordSelect)</entry></row><row><entry>#Writing M with MVal</entry></row><row><entry>If(PermOK =1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>WriteM(VectNum,MValTemp[ ])</entry></row><row><entry /><entry>ResultFlag <img file="US7165824B2_D0388.tif" /> Pass</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0389.tif" /> InvalidPermission</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>Output ResultFlag</entry></row><row><entry>Return</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 18.4.1 PermOK CheckM1+Perm (VectNum, WordSelect)
6078This function checks WordSelect against permission P<sub>VectNum </sub>for the selected word
6079<tables id="TABLE-US-00429" num="00429"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>For i <img file="US7165824B2_D0390.tif" /> 0 to MaxWordInM # word 0 to word 15</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>If(WordSelect[i] = 1) <img file="US7165824B2_D0391.tif" /> (P<sub>VectNum</sub>[i] = 0) # Trying to write a</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ReadOnly word</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>Return PermOK<img file="US7165824B2_D0392.tif" /> 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndFor</entry></row><row><entry /><entry>Return PermOK<img file="US7165824B2_D0393.tif" /> 1</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 18.4.2 WriteM(VectNum, MvalTemp<img file="US7165824B2_D0394.tif" />) <ul id="ul0811" list-style="none"><li id="ul0811-0001" num="0000"><ul id="ul0812" list-style="none"><li id="ul0812-0001" num="6080">This function copies MvalTemp to M<sub>VectNum</sub>.</li></ul></li></ul>
6081<tables id="TABLE-US-00430" num="00430"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>For i <img file="US7165824B2_D0395.tif" /> 0 to MaxWordInM # Copying word from temp buff to M</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>If(VectNum = 1) # If M1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>P<sub>VectNum</sub>[i]<img file="US7165824B2_D0396.tif" /> 0 # Set permission to ReadOnly before writing</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="119pt" align="left" /><colspec colname="2" colwidth="70pt" align="left" /><tbody valign="top"><row><entry /><entry>M<sub>VectNum</sub>[i] <img file="US7165824B2_D0397.tif" /> MValTemp[i]</entry><entry># copy word</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>buffer to M word</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndFor</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 19 WriteFields <ul id="ul0813" list-style="none"><li id="ul0813-0001" num="0000"><ul id="ul0814" list-style="none"><li id="ul0814-0001" num="6082">Input: FieldSelect, FieldVal</li><li id="ul0814-0002" num="6083">Output: ResultFlag</li><li id="ul0814-0003" num="6084">Changes: M<sub>VectNum </sub></li><li id="ul0814-0004" num="6085">Availability: All devices <br /> 19.1 Function Description </li></ul></li></ul>
6086The WriteFields function is used to write new data to selected fields (stored in M0). The write is carried out subject to the non-authenticated write access permissions of the fields as stored in the appropriate words of M1 (see Section 8.1.1.3).
6087The WriteFields function is used whenever authorization for a write (i.e. a valid signature) is not required. The WriteFieldsAuth function is used to perform authenticated writes to fields. For example, decrementing the amount of ink in an ink cartridge field is permitted by anyone via the WriteFields, but incrementing it during a refill operation is only permitted using WriteFieldsAuth. Therefore WriteFields does not require a signature as one of its inputs.
000019.2 Input Parameters
6088Table 269 describes each of the input parameters.
6089<tables id="TABLE-US-00431" num="00431"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 269</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Description of input parameters for WriteFields</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="154pt" align="left" /><tbody valign="top"><row><entry /><entry>Parameter</entry><entry>Description</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>FieldSelect</entry><entry>Selection of fields to be written.</entry></row><row><entry /><entry /><entry>0- indicates corresponding field is not written.</entry></row><row><entry /><entry /><entry>1- indicates corresponding field is to be</entry></row><row><entry /><entry /><entry>written as per input.</entry></row><row><entry /><entry /><entry>If FieldSelect [N bit] is set, then write</entry></row><row><entry /><entry /><entry>to Field N of M0.</entry></row><row><entry /><entry>FieldVal</entry><entry>Multiple of words corresponding to the words for</entry></row><row><entry /><entry /><entry>all selected fields.</entry></row><row><entry /><entry /><entry>Since Field0 starts at M0[15], FieldVal words</entry></row><row><entry /><entry /><entry>starts with MSW of lower field.</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 19.3 Output Parameters
6090Table 270 describes each of the output parameters.
6091<tables id="TABLE-US-00432" num="00432"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 270</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Description of output parameters for WriteFields</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="168pt" align="left" /><tbody valign="top"><row><entry>Parameter</entry><entry>Description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>ResultFlag</entry><entry>Indicates whether the function completed successfully</entry></row><row><entry /><entry>or not. If it did not complete successfully, the</entry></row><row><entry /><entry>reason for the failure is returned here.</entry></row><row><entry /><entry>See Section 12.1.</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 19.4 Function Sequence
6092The WriteFields command is illustrated by the following pseudocode:
6093<tables id="TABLE-US-00433" num="00433"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>Accept input parameters FieldSelect</entry></row><row><entry>#Accept FieldVal as per FieldSelect into a temporary buffer</entry></row><row><entry>MValTemp</entry></row><row><entry>#Find the size of each FieldNum to accept FieldData</entry></row><row><entry>FieldSize[16] <img file="US7165824B2_D0398.tif" /> 0 # Array to hold FieldSize assuming there are 16</entry></row><row><entry>fields</entry></row><row><entry>NumFields<img file="US7165824B2_D0399.tif" /> FindNumberOfFieldsInM0(M1,FieldSize)</entry></row><row><entry>MValTemp[16] <img file="US7165824B2_D0400.tif" /> 0 # Temporary buffer to hold FieldVal after being</entry></row><row><entry>read</entry></row><row><entry>For i <img file="US7165824B2_D0401.tif" /> 0 to NumFields</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>If FieldSelect[i] = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>If i = 0 # Check if field number is 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>PreviousFieldEndPos <img file="US7165824B2_D0402.tif" /> MaxWordInM</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>PreviousFieldEndPos <img file="US7165824B2_D0403.tif" /> M1[i−1].EndPos # position of</entry></row><row><entry /><entry> the last</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>word for the</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="126pt" align="left" /><colspec colname="1" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry># previous</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>field</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>For j <img file="US7165824B2_D0404.tif" /> (PreviousFieldEndPos −1) to M1[FieldNum].EndPos ( )</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>MValTemp[j] = Next FieldVal word #Store FieldVal in</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>MValTemp.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndFor</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndFor</entry></row><row><entry>#Check non-authenticated write permissions for all fields in</entry></row><row><entry>FieldSelect</entry></row><row><entry>PermOK <img file="US7165824B2_D0405.tif" /> CheckM0NonAuthPerm(FieldSelect,MValTemp,M0,M1)</entry></row><row><entry>#Writing M0 with MValTemp if permissions allow writing</entry></row><row><entry>If(PermOK =1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>WriteM(0,MValTemp)</entry></row><row><entry /><entry>ResultFlag <img file="US7165824B2_D0406.tif" /> Pass</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0407.tif" /> InvalidPermission</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>Output ResultFlag</entry></row><row><entry>Return</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 19.4.1 NumFields FindNumOfFieldsInM0(M1,FieldSize<img file="US7165824B2_D0408.tif" />)
6094This function returns the number of fields in M0 and an array FieldSize which stores the size of each field.
6095<tables id="TABLE-US-00434" num="00434"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>CurrPos <img file="US7165824B2_D0409.tif" /> 0</entry></row><row><entry>NumFields <img file="US7165824B2_D0410.tif" /> 0</entry></row><row><entry>FieldSize[16] <img file="US7165824B2_D0411.tif" /> 0 # Array storing field sizes</entry></row><row><entry>For FieldNum <img file="US7165824B2_D0412.tif" /> 0 to MaxWordInM</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>If(CurrPos = 0) # check if last field has reached</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Return FieldNum #FieldNum indicates number of fields in M0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>FieldSize[FieldNum] <img file="US7165824B2_D0413.tif" /> CurrPos − M1[FieldNum].EndPos</entry></row><row><entry /><entry>If(FieldSize[FieldNum] < 0)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Error # Integrity problem with field attributes</entry></row><row><entry /><entry>Return FieldNum # Lower M0 fields are still valid but higher</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>M0 fields are</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="84pt" align="left" /><colspec colname="1" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry># ignored</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>CurrPos<img file="US7165824B2_D0414.tif" /> M1[FieldNum].EndPos</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndFor</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 19.4.2 Word BitMapForField GetWordMapForField(FieldNum,M1)
6096This function returns the word bitmap corresponding to a field i.e the field consists of which consecutive words.
6097<tables id="TABLE-US-00435" num="00435"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>WordBitMapForField<img file="US7165824B2_D0415.tif" /> 0</entry></row><row><entry>WordMapTemp <img file="US7165824B2_D0416.tif" /> 0</entry></row><row><entry>PreviousFieldEndPos <img file="US7165824B2_D0417.tif" /> M1[FieldNum −1].EndPos # position of the</entry></row><row><entry>last word for the</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="154pt" align="left" /><colspec colname="1" colwidth="63pt" align="left" /><tbody valign="top"><row><entry /><entry># previous</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>field</entry></row><row><entry>For j <img file="US7165824B2_D0418.tif" /> (PreviousFieldEndPos +1) to M1[FieldNum].EndPos( )</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry># Set bit corresponding to the word position</entry></row><row><entry /><entry>WordMapTemp <img file="US7165824B2_D0419.tif" /> SHIFTLEFT (1,j)</entry></row><row><entry /><entry>WordBitMapForField <img file="US7165824B2_D0420.tif" /> WordMapTemp <img file="US7165824B2_D0421.tif" /> WordBitMapForField</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndFor</entry></row><row><entry>Return WordBitMapForField</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><ul id="ul0815" list-style="none"><li id="ul0815-0001" num="0000"><ul id="ul0816" list-style="none"><li id="ul0816-0001" num="6098">Return WordBitMapForField <br /> 19.4.3 PermOK CheckM0NonAuthPerm(FieldSelect,MValTemp<img file="US7165824B2_D0422.tif" />,M0,M1) </li></ul></li></ul>
6099This functions checks non-authenticated write permissions for all fields in FieldSelect.
6100<tables id="TABLE-US-00436" num="00436"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>PermOK CheckM0NonAuthPerm( )</entry></row><row><entry>FieldSize[16] <img file="US7165824B2_D0423.tif" /> 0</entry></row><row><entry>NumFields <img file="US7165824B2_D0424.tif" /> FindNumOfFieldsInM0(FieldSize)</entry></row><row><entry># Loop through all fields in FieldSelect and check their</entry></row><row><entry># non-authenticated permission</entry></row><row><entry>For i <img file="US7165824B2_D0425.tif" /> 0 to NumFields</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>If FieldSelect[i] = 1 # check selected</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>WordBitMapForField<img file="US7165824B2_D0426.tif" /> GetWordMapForField(i,M1) #get word</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>bitmap for field</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>PermOK</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry><img file="US7165824B2_D0427.tif" /> CheckFieldNonAuthPerm(i,WordBitMapForField,MValTemp,M0,)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry># Check permission for field i in</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>FieldSelect</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>If(PermOK = 0) #Writing is not allowed, return if</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>permissions for field</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry># doesn't allow writing</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>Return PermOK</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndFor</entry></row><row><entry>Return PermOK</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 19.4.4 PermOK <ul id="ul0817" list-style="none"><li id="ul0817-0001" num="0000"><ul id="ul0818" list-style="none"><li id="ul0818-0001" num="6101">CheckFieldNonAuthPerm(FieldNum,WordBitMapForField, MValTemp<img file="US7165824B2_D0428.tif" />, M0)</li></ul></li></ul>
6102This function checks non authenticated write permissions for the field.
6103<tables id="TABLE-US-00437" num="00437"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>DecrementOnly <img file="US7165824B2_D0429.tif" /> 0</entry></row><row><entry>AuthRW <img file="US7165824B2_D0430.tif" /> M1[FieldNum].AuthRW</entry></row><row><entry>NonAuthRW <img file="US7165824B2_D0431.tif" /> M1[FieldNum].AuthRW</entry></row><row><entry>If(NonAuthRW = 0) # No NonAuth write allowed</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Return PermOK<img file="US7165824B2_D0432.tif" /> 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>If((AuthRW = 0) <img file="US7165824B2_D0433.tif" /> (NonAuthRW = 1)) # NonAuthRW allowed</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Return PermOK<img file="US7165824B2_D0434.tif" /> 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>ElseIf(AuthRW = 1) <img file="US7165824B2_D0435.tif" /> (NonAuthRW = 1) # NonAuth DecrementOnly</entry></row><row><entry>allowed</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>PermOK</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry><img file="US7165824B2_D0436.tif" /> CheckInputDataForDecrementOnly(M0,MValTemp,</entry></row><row><entry>WordBitMapForField)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Return PermOK</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 19.4.5 PermOK CheckInputDataForDecrementOnly(M0,MValTemp<img file="US7165824B2_D0437.tif" />,WordBitMapForField)
6104This function checks the data to be written to the field is less than the current value.
6105<tables id="TABLE-US-00438" num="00438"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>DecEncountered <img file="US7165824B2_D0438.tif" /> 0</entry></row><row><entry /><entry>LessThanFlag <img file="US7165824B2_D0439.tif" /> 0</entry></row><row><entry /><entry>EqualToFlag <img file="US7165824B2_D0440.tif" /> 0</entry></row><row><entry /><entry>For i = MaxWordInM to 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>If(WordBitMapForField[i] = 1) # starting word of the field -</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>starting at MSW</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry># comparing the word of temp buffer with M0 current value</entry></row><row><entry /><entry>LessThanFlag <img file="US7165824B2_D0441.tif" /> M0[i] < MValTemp[i]</entry></row><row><entry /><entry>EqualToFlag<img file="US7165824B2_D0442.tif" /> M0[i] = MValTemp[i]</entry></row><row><entry /><entry># current value is less or previous value has been</entry></row><row><entry /><entry>decremented</entry></row><row><entry /><entry>If(LessThanFlag =1) <img file="US7165824B2_D0443.tif" /> (DecEncountered = 1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>DecEncountered <img file="US7165824B2_D0444.tif" /> 1</entry></row><row><entry /><entry>PermOK<img file="US7165824B2_D0445.tif" /> 1</entry></row><row><entry /><entry>Return PermOK</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>ElseIf(EqualToFlag≠1) # Only if the value is greater than</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>current and decrement not encountered in previous words</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>PermOK<img file="US7165824B2_D0446.tif" /> 0</entry></row><row><entry /><entry>Return PermOK</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndFor</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 19.4.6 WriteM(VectNum, MValTemp<img file="US7165824B2_D0447.tif" />) <ul id="ul0819" list-style="none"><li id="ul0819-0001" num="0000"><ul id="ul0820" list-style="none"><li id="ul0820-0001" num="6106">Refer to Section 18.4.2 for details. <br /> 20 WriteFieldsAuth </li><li id="ul0820-0002" num="6107">Input: KeyRef, FieldSelect, FieldVal, R<sub>E</sub>, SIG<sub>E </sub></li><li id="ul0820-0003" num="6108">Output: ResultFlag</li><li id="ul0820-0004" num="6109">Changes: <sub>M0 </sub>and R<sub>L </sub></li><li id="ul0820-0005" num="6110">Availability: All devices <br /> 20.1 Function Description </li></ul></li></ul>
6111The WriteFieldsAuth command is used to securely update a number of fields (in <sub>M0</sub>). The write is carried out subject to the authenticated write access permissions of the fields as stored in the appropriate words of M1 (see Section 8.1.1.3). WriteFieldsAuth will either update all of the requested fields or none of them; the write only succeeds when all of the requested fields can be written to.
6112The WriteFieldsAuth function requires the data to be accompanied by an appropriate signature based on a key that has appropriate write permissions to the field, and the signature must also include the local R (i.e. nonce/challenge) as previously read from this QA Device via the Random function.
6113The appropriate signature can only be produced by knowing K<sub>KeyRef</sub>. This can be achieved by a call to an appropriate command on a QA Device that holds a key matching K<sub>KeyRef</sub>. Appropriate commands include SignM, XferAmount, XferField, StartXfer, and StartRollBack.
000020.2 Input Parameters
6114Table 271 describes each of the input parameters for WriteAuth.
6115<tables id="TABLE-US-00439" num="00439"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="154pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>Parameter</entry><entry>Description</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>KeyRef</entry><entry>For common key signature generation:</entry></row><row><entry /><entry /><entry>KeyRef.keyNum = Slot number of the key to</entry></row><row><entry /><entry /><entry>be used for testing the input signature.</entry></row><row><entry /><entry /><entry>KeyRef.useChipId = 0</entry></row><row><entry /><entry /><entry>No variant key signature generation required</entry></row><row><entry /><entry>FieldSelect</entry><entry>Selection of fields to be written.</entry></row><row><entry /><entry /><entry>0- indicates corresponding field is not written.</entry></row><row><entry /><entry /><entry>1- indicates corresponding field is to be written</entry></row><row><entry /><entry /><entry>as per input. If FieldSelect [N bit] is set,</entry></row><row><entry /><entry /><entry>then write to Field N of M0.</entry></row><row><entry /><entry>FieldVal</entry><entry>Multiple of words corresponding to the total</entry></row><row><entry /><entry /><entry>number of words for all selected fields. Since</entry></row><row><entry /><entry /><entry>Field0 starts at M0[15], FieldVal words</entry></row><row><entry /><entry /><entry>starts with MSW of lower field.</entry></row><row><entry /><entry>RE</entry><entry>External random value used to verify input</entry></row><row><entry /><entry /><entry>signature. This will be the R from the input</entry></row><row><entry /><entry /><entry>signature generator (i.e device generating SIG<sub>E</sub>).</entry></row><row><entry /><entry>SIGE</entry><entry>External signature required for authenticating</entry></row><row><entry /><entry /><entry>input data. The external signature is either</entry></row><row><entry /><entry /><entry>generated by a Translate or one of the Xfer</entry></row><row><entry /><entry /><entry>functions. A correct SIG<sub>E </sub>=</entry></row><row><entry /><entry /><entry>SIG<sub>KeyRef</sub>(data | R<sub>E </sub>| R<sub>L</sub>).</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 20.2.1 Input Signature Verification Data Format
6116<figref idref="DRAWINGS">FIG. 373</figref> shows the input signature verification data format for the WriteAuth function. <ul id="ul0821" list-style="none"><li id="ul0821-0001" num="0000"><ul id="ul0822" list-style="none"><li id="ul0822-0001" num="6117">Table 272 gives the parameters included in SIG<sub>E </sub>for Write Auth</li></ul></li></ul>
6118<tables id="TABLE-US-00440" num="00440"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="42pt" align="center" /><colspec colname="3" colwidth="91pt" align="left" /><colspec colname="4" colwidth="42pt" align="center" /><thead><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry /><entry /><entry /><entry>Value set</entry></row><row><entry /><entry>Length</entry><entry /><entry>from</entry></row><row><entry>Parameter</entry><entry>in bits</entry><entry>Value set internally</entry><entry>Input</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="42pt" align="char" char="." /><colspec colname="3" colwidth="91pt" align="left" /><colspec colname="4" colwidth="42pt" align="center" /><tbody valign="top"><row><entry>RWSense</entry><entry>3</entry><entry>write constant = 001</entry><entry /></row><row><entry /><entry /><entry>Refer to Section 15.3.1.1</entry></row><row><entry>FieldNum</entry><entry>4</entry><entry /><entry>●</entry></row><row><entry>ChipID</entry><entry>48</entry><entry>This QA Device's ChipId</entry></row><row><entry>FieldData</entry><entry>32</entry><entry /><entry>●</entry></row><row><entry /><entry>per word</entry></row><row><entry>R<sub>E</sub></entry><entry>160</entry><entry /><entry>●</entry></row><row><entry>R<sub>L</sub></entry><entry>160</entry><entry>random value from device</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 20.3 Output Parameters
6119Table 273 describes each of the output parameters.
6120<tables id="TABLE-US-00441" num="00441"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 273</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Description of output parameters for WriteAuth</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="168pt" align="left" /><tbody valign="top"><row><entry>Parameter</entry><entry>Description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>ResultFlag</entry><entry>Indicates whether the function completed successfully</entry></row><row><entry /><entry>or not. If it did not complete successfully, the</entry></row><row><entry /><entry>reason for the failure is returned here.</entry></row><row><entry /><entry>See Section 12.1.</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 20.4 Function Sequence
6121The WriteAuth command is illustrated by the following pseudocode:
6122<tables id="TABLE-US-00442" num="00442"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>Accept input parameters-KeyRef, FieldSelect,</entry></row><row><entry>#Accept FieldVal as per FieldSelect into a temporary buffer</entry></row><row><entry>MValTemp</entry></row><row><entry>#Find the size of each FieldNum to accept FieldData</entry></row><row><entry>FieldSize[16] <img file="US7165824B2_D0448.tif" /> 0 # Array to hold FieldSize assuming there are 16</entry></row><row><entry>fields</entry></row><row><entry>NumFields<img file="US7165824B2_D0449.tif" /> FindNumberOfFieldsInM0(M1,FieldSize)</entry></row><row><entry>MValTemp[16] <img file="US7165824B2_D0450.tif" /> 0 # Temporary buffer to hold FieldVal after being</entry></row><row><entry>read</entry></row><row><entry>For i <img file="US7165824B2_D0451.tif" /> 0 to NumFields</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>If i = 0 # Check if field number is 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>PreviousFieldEndPos <img file="US7165824B2_D0452.tif" /> MaxWordInM</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>PreviousFieldEndPos <img file="US7165824B2_D0453.tif" /> M1[i−1].EndPos # position of the</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>last word for the previous field</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>For j <img file="US7165824B2_D0454.tif" /> (PreviousFieldEndPos −1) to M1[FieldNum].EndPos( )</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>MValTemp[j] = Next FieldVal word #Store FieldVal in</entry></row><row><entry /><entry>MValTemp.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndFor</entry></row><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndFor</entry></row><row><entry>Accept R<sub>E</sub>, SIG<sub>E</sub></entry></row><row><entry>Check range of KeyRef.keyNum</entry></row><row><entry>If invalid range</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0455.tif" /> InvalidKey</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>#Generate message for passing to GenerateSignature function</entry></row><row><entry>data <img file="US7165824B2_D0456.tif" /> (RWSense|FieldSelect|ChipId|FieldVal</entry></row><row><entry>#Generate Signature</entry></row><row><entry>SIG<sub>L </sub><img file="US7165824B2_D0457.tif" /> GenerateSignature(KeyRef,data,R<sub>E</sub>,R<sub>L</sub>) # Refer to Figure 373.</entry></row><row><entry>#Check signature</entry></row><row><entry>If(SIG<sub>L </sub>= SIG<sub>E</sub>)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Update R<sub>L </sub>to R<sub>L2</sub></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0458.tif" /> BadSig</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>#Check authenticated write permission for all fields in</entry></row><row><entry>FieldSelect using KeyRef</entry></row><row><entry>PermOK<img file="US7165824B2_D0459.tif" /> CheckM0AuthPerm(FieldSelect,MValTemp,M0,M1,KeyRef)</entry></row><row><entry>If(PermOK = 1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>WriteM(0,MValTemp[ ])# Copy temp buffer to M0</entry></row><row><entry /><entry>ResultFlag <img file="US7165824B2_D0460.tif" /> Pass</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0461.tif" /> InvalidPermission</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>Output ResultFlag</entry></row><row><entry>Return</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 20.4.1 PermOK CheckM0AuthPerm(FieldSelect,MValTemp<img file="US7165824B2_D0462.tif" />,M0, M1, KeyRef)
6123This functions checks non-authenticated write permissions for all fields in FieldSelect using KeyRef.
6124<tables id="TABLE-US-00443" num="00443"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>PermOK CheckM0NonAuthPerm( )</entry></row><row><entry>FieldSize[16] <img file="US7165824B2_D0463.tif" /> 0</entry></row><row><entry>NumFields <img file="US7165824B2_D0464.tif" /> FindNumOfFieldsInM0(FieldSize)</entry></row><row><entry># Loop through fields</entry></row><row><entry>For i <img file="US7165824B2_D0465.tif" /> 0 to NumFields</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>If FieldSelect[i] = 1 # check selected</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>WordBitMapForField<img file="US7165824B2_D0466.tif" /> GetWordMapForField(i,M1) #get word</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>bitmap for field</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>PermOK <img file="US7165824B2_D0467.tif" /> CheckAuthFieldPerm(i,WordBitMapForField,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>MValTemp,M0, KeyRef)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry># Check permission for field i in</entry></row><row><entry /><entry>FieldSelect</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="119pt" align="left" /><tbody valign="top"><row><entry /><entry>If(PermOK = 0)</entry><entry>#Writing is not allowed, return if</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>#permissions for field doesn't allow writing</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>Return PermOK</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndFor</entry></row><row><entry>Return PermOK</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 20.4.2 PermOK CheckAuthFieldPerm(FieldNum, WordMapForField,MValTemp<img file="US7165824B2_D0468.tif" />, M0,KeyRef) <ul id="ul0823" list-style="none"><li id="ul0823-0001" num="0000"><ul id="ul0824" list-style="none"><li id="ul0824-0001" num="6125">This function checks authenticated permissions for an M<sub>0 </sub>field using KeyRef (whether KeyRef has write permissions to the field).</li></ul></li></ul>
6126<tables id="TABLE-US-00444" num="00444"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>AuthRW <img file="US7165824B2_D0469.tif" /> M1[FieldNum].AuthRW</entry></row><row><entry>KeyNumAtt <img file="US7165824B2_D0470.tif" /> M1[FieldNum].KeyNum</entry></row><row><entry>If (AuthRW = 0) # Check whether any key has write permissions</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Return PermOK<img file="US7165824B2_D0471.tif" /> 0 # No authenticated write permissions</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry># Check KeyRef has ReadWrite Permission to the field and it is</entry></row><row><entry>locked</entry></row><row><entry>If(KeyLock<sub>KeyNum </sub>= locked) <img file="US7165824B2_D0472.tif" /> (KeyNumAtt = KeyRef.keyNum)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Return PermOK<img file="US7165824B2_D0473.tif" /> 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Else # KeyNum is not a ReadWrite Key</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>KeyPerms <img file="US7165824B2_D0474.tif" /> M1[FieldNum].DOForKeys # Isolate KeyPerms for</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>FieldNum</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry># Check Decrement Only Permission for Key</entry></row><row><entry /><entry>If(KeyPerms[KeyRef.keyNum] = 1) # Key is allowed to Decrement</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>field</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>PermOK</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry><img file="US7165824B2_D0475.tif" /> CheckInputDataForDecrementOnly(M0,MValTemp,WordMapForField)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="126pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry><entry># Key is a ReadOnly key</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>PermOK<img file="US7165824B2_D0476.tif" /> 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>Return PermOK</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 20.4.3 WordBitMapField GetWordMapForField(FieldNum,M1) <ul id="ul0825" list-style="none"><li id="ul0825-0001" num="0000"><ul id="ul0826" list-style="none"><li id="ul0826-0001" num="6127">Refer to Section 19.4.2 for details. <br /> 20.4.4 PermOK CheckInputDataForDecrementOnly(M0,MValTemp<img file="US7165824B2_D0477.tif" />,WordMapForField) </li><li id="ul0826-0002" num="6128">Refer to Section 19.4.5 for details. <br /> 20.4.5 WriteM(VectNum, MValTemp<img file="US7165824B2_D0478.tif" />) </li><li id="ul0826-0003" num="6129">Refer to Section 18.4.2 for details. <br /> 21 SetPerm </li><li id="ul0826-0004" num="6130">Input: VectNum, PermVal</li><li id="ul0826-0005" num="6131">Output: ResultFlag, NewPerm</li><li id="ul0826-0006" num="6132">Changes: P<sub>n </sub></li><li id="ul0826-0007" num="6133">Availability: All devices <br /> 21.1 Function Description </li></ul></li></ul>
6134The SetPerm command is used to update the contents of P<sub>VectNum </sub>(which stores the permission for M<sub>VectNum</sub>).
6135The new value for P<sub>VectNum </sub>is a combination of the old and new permissions in such a way that the more restrictive permission for each part of P<sub>VectNum </sub>is kept.
6136M0's permissions are set by M1 therefore they can't be changed.
6137M1's permissions cannot be changed by SetPerm. M1 is a write-once memory vector and its permissions are set by writing to it.
6138See Section 8.1.1.3 and Section 8.1.1.5 for more information about permissions.
000021.2 Input Parameters
6139<tables id="TABLE-US-00445" num="00445"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="161pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>Parameter</entry><entry>Description</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>VectNum</entry><entry>Number of the memory vector whose permission is</entry></row><row><entry /><entry /><entry>being changed.</entry></row><row><entry /><entry>PermVal</entry><entry>Bitmap of permission for the corresponding Memory</entry></row><row><entry /><entry /><entry>Vector.</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
6140Note: Since this function has no accompanying signatures, additional input parameter error checking is required.
000021.3 Output Parameters
6141<tables id="TABLE-US-00446" num="00446"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="175pt" align="left" /><thead><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>Parameter</entry><entry>Description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>ResultFlag</entry><entry>Indicates whether the function completed successfully</entry></row><row><entry /><entry>or not. If it did not complete successfully, the</entry></row><row><entry /><entry>reason for the failure is returned here. See Section</entry></row><row><entry /><entry>12.1.</entry></row><row><entry>Perm</entry><entry>If VectNum = 0, then no Perm is returned.</entry></row><row><entry /><entry>If VectNum = 1, then old Perm is returned.</entry></row><row><entry /><entry>If VectNum > 1, then new Perm is returned after P<sub>VectNum</sub></entry></row><row><entry /><entry>has been changed based on PermVal.</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 21.4 Function Sequence
6142The SetPerm command is illustrated by the following pseudocode: <ul id="ul0827" list-style="none"><li id="ul0827-0001" num="0000"><ul id="ul0828" list-style="none"><li id="ul0828-0001" num="6143">Accept input parameters—VectNum, PermVal</li></ul></li></ul>
6144<tables id="TABLE-US-00447" num="00447"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>Check range of VectNum</entry></row><row><entry>If invalid</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0479.tif" /> InvalidVector</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>If(VectNum = 0) # No permssions for M0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0480.tif" /> Pass</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>ElseIf(VectNum = 1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0481.tif" /> Pass</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Output P<sub>1</sub></entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>ElseIf(VectNum >1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry># Check that only ‘RW’ parts are being changed</entry></row><row><entry /><entry># RW(1) → RO(0), RO(0) →RO(0), RW(1) →RW(1) - valid change</entry></row><row><entry /><entry># RO(0) →RW(1) - Invalid change</entry></row><row><entry /><entry># checking for change from ReadOnly to ReadWrite</entry></row><row><entry /><entry>temp<img file="US7165824B2_D0482.tif" /> ~P<sub>VectNum </sub><img file="US7165824B2_D0483.tif" /> PermVal</entry></row><row><entry /><entry>If(temp = 1 ) # If invalid change is 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0484.tif" /> InvalidPermission</entry></row><row><entry /><entry>Output ResultFlag</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>P<sub>VectNum </sub><img file="US7165824B2_D0485.tif" /> PermVal</entry></row><row><entry /><entry>ResultFlag <img file="US7165824B2_D0486.tif" /> Pass</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Output P<sub>VectNum</sub></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 22 ReplaceKey <ul id="ul0829" list-style="none"><li id="ul0829-0001" num="0000"><ul id="ul0830" list-style="none"><li id="ul0830-0001" num="6145">Input: KeyRef, KeyID, KeyLock, EncryptedKey, R<sub>E</sub>, SIG<sub>E </sub></li><li id="ul0830-0002" num="6146">Output: ResultFlag</li><li id="ul0830-0003" num="6147">Changes: K<sub>KeyRef.keyNum </sub>and R<sub>L </sub></li><li id="ul0830-0004" num="6148">Availability: All devices <br /> 22.1 Function Description </li></ul></li></ul>
6149The ReplaceKey command is used to replace the contents of a non-locked keyslot, which means replacing the key, its associated keyID, and the lock status bit for the keyslot. A key can only be replaced if the slot has not been locked i.e. the KeyLock for the slot is 0. The procedure for replacing a key also requires knowledge of the value of the current key in the keyslot i.e. you can only replace a key if you know the current key.
6150Whenever the ReplaceKey function is called, the caller has the ability to make this new key the final key for the slot. This is accomplished by passing in a new value for the KeyLock flag. A new KeyLock flag of 0 keeps the slot unlocked, and permits further replacements. A new KeyLock flag of 1 means the slot is now locked, with the new key as the final key for the slot i.e. no further key replacement is permitted for that slot.
000022.2 Input Parameters
6151<tables id="TABLE-US-00448" num="00448"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="161pt" align="left" /><thead><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>Parameter</entry><entry>Description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>KeyRef</entry><entry>For common key signature generation:</entry></row><row><entry /><entry>KeyRef.keyNum = Slot number of the key to be</entry></row><row><entry /><entry>used for testing the input signature, and will be</entry></row><row><entry /><entry>replaced by the new key.</entry></row><row><entry /><entry>KeyRef.useChipId = 0</entry></row><row><entry /><entry>No variant key signature generation required</entry></row><row><entry>KeyId</entry><entry>KeyId of the new key. The LSB represents whether</entry></row><row><entry /><entry>the new key is a variant or a common key.</entry></row><row><entry>KeyLock</entry><entry>Flag indicating whether the new key should be the</entry></row><row><entry /><entry>final key for the slot or not. (1 = final key,</entry></row><row><entry /><entry>0 = not final key)</entry></row><row><entry>EncryptedKey</entry><entry>SIG<sub>Kold</sub>(R<sub>E</sub>|R<sub>L</sub>) ⊕ K<sub>new </sub>where K<sub>old </sub>=</entry></row><row><entry /><entry>KeyRef.getkey( ). Refer to Section 10.1.3.1</entry></row><row><entry>RE</entry><entry>External random value required for verifying input</entry></row><row><entry /><entry>signature. This will be the R from the input</entry></row><row><entry /><entry>signature generator (device generating SIG<sub>E</sub>). In</entry></row><row><entry /><entry>this case the input signature is a generated by</entry></row><row><entry /><entry>calling the GetProgramKey function on a Key</entry></row><row><entry /><entry>Programming device.</entry></row><row><entry>SIGE</entry><entry>External signature required for authenticating</entry></row><row><entry /><entry>input data and determining the new key from the</entry></row><row><entry /><entry>EncryptedKey.</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 22.2.1 Input Signature Generation Data Format
6152<figref idref="DRAWINGS">FIG. 374</figref> shows the input signature generation data format for the ReplaceKey function.
6153Table 277 gives the parameters included in SIG<sub>E </sub>for ReplaceKey.
6154<tables id="TABLE-US-00449" num="00449"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="56pt" align="center" /><colspec colname="3" colwidth="35pt" align="left" /><colspec colname="4" colwidth="63pt" align="center" /><thead><row><entry /><entry namest="offset" nameend="4" align="center" rowsep="1" /></row><row><entry /><entry /><entry>Length</entry><entry>Value set</entry><entry>Value set</entry></row><row><entry /><entry>Parameter</entry><entry>in bits</entry><entry>internally</entry><entry>from Input</entry></row><row><entry /><entry namest="offset" nameend="4" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="56pt" align="char" char="." /><colspec colname="3" colwidth="35pt" align="left" /><colspec colname="4" colwidth="63pt" align="center" /><tbody valign="top"><row><entry /><entry>ChipId</entry><entry>48</entry><entry>This QA</entry><entry /></row><row><entry /><entry /><entry /><entry>Device's</entry></row><row><entry /><entry /><entry /><entry>ChipId</entry></row><row><entry /><entry>KeyId</entry><entry>32</entry><entry /><entry>●</entry></row><row><entry /><entry>R<sub>E</sub></entry><entry>160</entry><entry /><entry>●</entry></row><row><entry /><entry>EncryptedKey</entry><entry>160</entry><entry /><entry>●</entry></row><row><entry /><entry namest="offset" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 22.3 Output Parameters
6155Table 278 describes each of the output parameters for ReplaceKey.
6156<tables id="TABLE-US-00450" num="00450"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="168pt" align="left" /><thead><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>Parameter</entry><entry>Description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>ResultFlag</entry><entry>Indicates whether the function completed successfully</entry></row><row><entry /><entry>or not. If it did not complete successfully, the reason</entry></row><row><entry /><entry>for the failure is returned here.</entry></row><row><entry /><entry>See Section 12.1.</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 22.4 Function Sequence <ul id="ul0831" list-style="none"><li id="ul0831-0001" num="0000"><ul id="ul0832" list-style="none"><li id="ul0832-0001" num="6157">The ReplaceKey command is illustrated by the following pseudocode:</li></ul></li></ul>
6158<tables id="TABLE-US-00451" num="00451"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>Accept input parameters - KeyRef, KeyId, KeyLock, EncryptedKey,R<sub>E</sub>,</entry></row><row><entry>SIG<sub>E</sub></entry></row><row><entry>Check KeyRef.keyNum range</entry></row><row><entry>If invalid</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0487.tif" /> InvalidKey</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>#Generate message for passing to GenerateSignature function</entry></row><row><entry>data <img file="US7165824B2_D0488.tif" /> (ChipId|KeyId|KeyLock|R<sub>E</sub>|EncryptedKey)</entry></row><row><entry>#Generate Signature</entry></row><row><entry>SIG<sub>L </sub><img file="US7165824B2_D0489.tif" /> GenerateSignature(KeyRef,data,Null,Null) # Refer to Figure</entry></row><row><entry>374.</entry></row><row><entry># Check if the key slot is unlocked</entry></row><row><entry>If (KeyLock # unlock)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0490.tif" /> KeyAlreadyLocked</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>#Test SIG<sub>E</sub></entry></row><row><entry>If (SIG<sub>L </sub># SIG<sub>E</sub>)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0491.tif" /> BadSig</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>SIG<sub>L </sub><img file="US7165824B2_D0492.tif" /> GenerateSignature (Key,null,R<sub>E</sub>,R<sub>L</sub>)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Advance R<sub>L</sub></entry></row><row><entry /><entry># Must be atomic - must not be possible to remove power and have</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>KeyId and KeyNum mismatched. Also preferable for KeyLock, although</entry></row><row><entry>not strictly required.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>K<sub>KeyNum </sub><img file="US7165824B2_D0493.tif" /> SIG<sub>L </sub>⊕ EncryptedKey</entry></row><row><entry /><entry>KeyId<sub>KeyNum </sub><img file="US7165824B2_D0494.tif" /> KeyId</entry></row><row><entry /><entry>KeyLock<sub>KeyNum </sub><img file="US7165824B2_D0495.tif" /> KeyLock</entry></row><row><entry /><entry>ResultFlag <img file="US7165824B2_D0496.tif" /> Pass</entry></row><row><entry /><entry>Output ResultFlag</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Return</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 23 SignM <ul id="ul0833" list-style="none"><li id="ul0833-0001" num="0000"><ul id="ul0834" list-style="none"><li id="ul0834-0001" num="6159">Input: KeyRef, FieldSelect, FieldValLength, FieldVal, ChipID, R<sub>E </sub></li><li id="ul0834-0002" num="6160">Output: ResultFlag, R<sub>L</sub>, SIG<sub>out </sub></li><li id="ul0834-0003" num="6161">Changes: R<sub>L </sub></li><li id="ul0834-0004" num="6162">Availability: Trusted device only <br /> 23.1 Function Description </li></ul></li></ul>
6163The SignM function is used to generate the appropriate digital signature required for the authenticated write function WriteFieldsAuth. The SignM function is used whenever the caller wants to write a new value to a field that requires key-based write access.
6164The caller typically passes the new field value as input to the SignM function, together with the nonce (R<sub>E</sub>) from the QA Device who will receive the generated signature. The SignM function then produces the appropriate signature SIG<sub>out</sub>. Note that SIG<sub>out </sub>may need to be translated via the Translate function on its way to the final WriteFieldsAuth QA Device.
6165The SignM function is typically used by the system to update preauthorisation fields (Section 31.4.3).
6166The key used to produce output signature SIG<sub>out </sub>depends on whether the trusted device shares a common key or a variant key with the QA Device directly receiving the signature. The KeyRef object passed into the interface must be set appropriately to reflect this.
000023.2 Input Parameters
6167<tables id="TABLE-US-00452" num="00452"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="154pt" align="left" /><thead><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>Parameter</entry><entry>Description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>KeyRef</entry><entry>For generating common key output signature:</entry></row><row><entry /><entry>Ref.keyNum = Slot number of the key for</entry></row><row><entry /><entry>producing the output signature. SIG<sub>out</sub></entry></row><row><entry /><entry>produced using K<sub>KeyRef.keyNum </sub>because the</entry></row><row><entry /><entry>device receiving SIG<sub>out </sub>shares K<sub>KeyRef.keyNum</sub></entry></row><row><entry /><entry>with the trusted device.</entry></row><row><entry /><entry>KeyRef.useChipId = 0</entry></row><row><entry /><entry>For generating variant key output signature:</entry></row><row><entry /><entry>KeyRef.keyNum = Slot number of the key</entry></row><row><entry /><entry>to be used for generating the variant key.</entry></row><row><entry /><entry>SIG<sub>out </sub>produced using a variant of K<sub>KeyRef.keyNum</sub></entry></row><row><entry /><entry>because the device receiving SIG<sub>out </sub>shares a</entry></row><row><entry /><entry>variant of K<sub>KeyRef.keyNum </sub>with the trusted</entry></row><row><entry /><entry>device.</entry></row><row><entry /><entry>KeyRef.useChipId = 1</entry></row><row><entry /><entry>KeyRef.chipId = ChipId of the device which</entry></row><row><entry /><entry>receives SIG<sub>out</sub>.</entry></row><row><entry>FieldNum</entry><entry>Field number of the field that will be</entry></row><row><entry /><entry>written to.</entry></row><row><entry>FieldDataLength</entry><entry>The length of the FieldData in words.</entry></row><row><entry>FieldData</entry><entry>The value that will be written to the</entry></row><row><entry /><entry>field selected by FieldNum.</entry></row><row><entry>R<sub>E</sub></entry><entry>External random value used in the output</entry></row><row><entry /><entry>signature generation.</entry></row><row><entry /><entry>R<sub>E </sub>is obtained by calling the Random</entry></row><row><entry /><entry>function on the device, which will receive</entry></row><row><entry /><entry>the SIG<sub>out </sub>from the SignM function, which</entry></row><row><entry /><entry>in this case is the WriteAuth function</entry></row><row><entry /><entry>or the Translate function.</entry></row><row><entry>ChipId</entry><entry>Chip identifier of the device whose</entry></row><row><entry /><entry>WriteAuth function will be called sub-</entry></row><row><entry /><entry>sequently to perform an authenticated</entry></row><row><entry /><entry>write to its FieldNum of M0.</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 23.3 Output Parameters <ul id="ul0835" list-style="none"><li id="ul0835-0001" num="0000"><ul id="ul0836" list-style="none"><li id="ul0836-0001" num="6168">Table 280 describes each of the output parameters.</li></ul></li></ul>
6169<tables id="TABLE-US-00453" num="00453"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 280</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Description of output parameters for SignM</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="175pt" align="left" /><tbody valign="top"><row><entry>Parameter</entry><entry>Description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>ResultFlag</entry><entry>Indicates whether the function completed successfully</entry></row><row><entry /><entry>or not. If it did not complete successfully, the</entry></row><row><entry /><entry>reason for the failure is returned here.</entry></row><row><entry /><entry>See Section 12.1.</entry></row><row><entry>R<sub>L</sub></entry><entry>Internal random value used in the output signature.</entry></row><row><entry>SIG<sub>out</sub></entry><entry>SIG<sub>out </sub>= SIG<sub>KeyRef</sub>(data | R<sub>L </sub>| R<sub>E</sub>) as shown in FIG. 373.</entry></row><row><entry /><entry>As per FIG. 373, R<sub>E </sub>is actually R<sub>L </sub>and R<sub>L </sub>is R<sub>E </sub>with</entry></row><row><entry /><entry>respect to device producing SIG<sub>out </sub>to be applied to</entry></row><row><entry /><entry>WriteAuth function.</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 23.3.1 SIG<sub>out </sub><ul id="ul0837" list-style="none"><li id="ul0837-0001" num="0000"><ul id="ul0838" list-style="none"><li id="ul0838-0001" num="6170">Refer to Section 20.2.1. <br /> 23.4 Function Sequence </li><li id="ul0838-0002" num="6171">The SignM command is illustrated by the following pseudocode:</li></ul></li></ul>
6172<tables id="TABLE-US-00454" num="00454"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>Accept input parameters - KeyRef, FieldNum, FieldDataLength</entry></row><row><entry /><entry># Accept FieldData words</entry></row><row><entry /><entry>For i = 0 to FieldValLength</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Accept next FieldData</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndFor</entry></row><row><entry /><entry>Accept ChipId, R<sub>E</sub></entry></row><row><entry /><entry>Check KeyRef.keyNum range</entry></row><row><entry /><entry>If invalid</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0497.tif" /> InvalidKey</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>#Generate message for passing into the GenerateSignature function</entry></row><row><entry /><entry>data <img file="US7165824B2_D0498.tif" /> (RWSense | FieldSelect | ChipId | FieldVal)</entry></row><row><entry /><entry>#Generate Signature</entry></row><row><entry /><entry>SIG<sub>out </sub><img file="US7165824B2_D0499.tif" /> GenerateSignature(KeyRef,data,R<sub>L</sub>,R<sub>E</sub>) # Refer to Section</entry></row><row><entry /><entry>20.2.1.</entry></row><row><entry /><entry>Advance R<sub>L</sub>to R<sub>L2</sub></entry></row><row><entry /><entry>ResultFlag <img file="US7165824B2_D0500.tif" /> Pass</entry></row><row><entry /><entry>Output parameters ResultFlag, R<sub>L,</sub>SIG<sub>out</sub></entry></row><row><entry /><entry>Return</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> Functions on a <br /> Key Programming QA Device <br /> 24 Concepts
6173The key programming device is used to replace keys in other devices.
6174The key programming device stores both the old key which will be replaced in the device being programmed, and the new key which will replace the old key in the device being programmed. The keys reside in normal key slots of the key programming device.
6175Any key stored in the key programming device can be used as an old key or a new key for the device being programmed, provided it is permitted by the key replacement map stored within the key programming device.
6176<figref idref="DRAWINGS">FIG. 375</figref> is representation of a key replacement map. The 1 s indicates that the new key is permitted to replace the old key. The 0s indicates that key replacement is not permitted for those positions. The positions in <figref idref="DRAWINGS">FIG. 13</figref> which are blank indicate a 0.
6177According to the key replacement map in <figref idref="DRAWINGS">FIG. 13</figref>, K<sub>5 </sub>can replace K<sub>1</sub>, K<sub>6 </sub>can replace K<sub>3</sub>, K<sub>4</sub>, K<sub>5</sub>,K<sub>7</sub>, K<sub>3 </sub>can replace K<sub>2</sub>, K<sub>0 </sub>can replace K<sub>2</sub>, and K<sub>2 </sub>can replace K<sub>6</sub>. No key can replace itself.
0000FIG. <b>375</b>._Key Replacement Map
6178The key replacement map must be readable from an external system and must be updateable by an authenticated write. Therefore, the key replacement map must be stored in an M0 field. This requires one of the keys residing in the key programming device to be have ReadWrite access to the key replacement map. This key is referred to as the key replacement map key and is used to update the key replacement map.
6179There will one key replacement map field in a key programming device.
6180No key replacement mappings are allowed to the key replacement map key because it should not be used in another device being programmed. To prevent the key replacement map key from being used in key replacement, in case the mapping has been accidentally changed, the key replacement map key is allocated a fixed key slot of 0 in all key programming devices. If a GetProgram function is invoked on the key programming device with the key replacement map key slot number 0 it immediately returns an error, even before the key replacement map is checked.
6181The keys K<sub>0 </sub>to K<sub>7 </sub>in the key programming device are initially set during the instantiation of the key programming device. Thereafter, any key can be replaced on the key programming device by another key programming device If a key in a key slot of the key programming device is being replaced, the key replacement map for the old key must be invalidated automatically. This is done by setting the row and column for the corresponding key slot to 0 For example, if K<sub>1 </sub>is replaced, then column 1 and row 1 are set to 0, as indicated in <figref idref="DRAWINGS">FIG. 376</figref>.
6182The new mapping information for K, is then entered by performing an authenticated write of the key replacement map field using the key replacement map key.
000024.1 Key Replacement Map Data Structure
6183As mentioned in Section 24, the key replacement map must be readable by external systems and must be updateable using an authenticated write by the key replacement map key. Therefore, the key replacement map is stored in an M0 field of the key programming device. The map is 8×8 bits in size and therefore can be stored in a two word field. The LSW of key replacement map stores the mappings for K<sub>0</sub>–K<sub>3</sub>. The MSW of key replacement map stores the mappings for K<sub>4</sub>–K<sub>7</sub>. Referring to <figref idref="DRAWINGS">FIG. 375</figref>, key replacement map LSW is 0x40092000 and MSW is 0x40224040. Referring to <figref idref="DRAWINGS">FIG. 376</figref>, after K<sub>1 </sub>is replaced in the key programming device, the value of the key replacement map LSW is 0x40090000 and MSW is 0x40224040.
6184The key replacement map field has an M1 word representing its attributes. The attribute setting for this field is specified in Table 281.
6185<tables id="TABLE-US-00455" num="00455"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 281</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Key replacement map attribute setting</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>Attribute</entry><entry /><entry /></row><row><entry>name</entry><entry>Value</entry><entry>Explanation</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>Type</entry><entry>TYPE_KEY_MAP</entry><entry>Indicates that the field value</entry></row><row><entry /><entry>Refer to</entry><entry>represents a key replacement map.</entry></row><row><entry /><entry>Appendix A.</entry><entry>Only one such field per key</entry></row><row><entry /><entry /><entry>programming QA Device.</entry></row><row><entry>KeyNum</entry><entry>0</entry><entry>Slot number of the key</entry></row><row><entry /><entry /><entry>replacement map key.</entry></row><row><entry>NonAuthRW</entry><entry>0</entry><entry>No non authenticated writes is</entry></row><row><entry /><entry /><entry>permitted.</entry></row><row><entry>AuthRW</entry><entry>1</entry><entry>Authenticated write is permitted.</entry></row><row><entry>KeyPerms</entry><entry>0</entry><entry>No Decrement Only permission for</entry></row><row><entry /><entry /><entry>any key.</entry></row><row><entry>EndPos</entry><entry>Value such that</entry></row><row><entry /><entry>field size is 2</entry></row><row><entry /><entry>words</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 24.2 Basic Scheme
6186The Key Replacement sequence is shown <figref idref="DRAWINGS">FIG. 377</figref>.
6187Following is a sequential description of the transfer and rollback process: <ul id="ul0839" list-style="none"><li id="ul0839-0001" num="6188">1. The System gets a Random number from the QA Device whose keys are going to be replaced.</li><li id="ul0839-0002" num="6189">2. The System makes a GetProgramKey Request to the Key Programming QA Device. The Key Programming QA Device must contain both keys for QA Device whose keys are being replaced—Old Keys which are the keys that exist currently (before key replacement), and the New Keys which are the keys which the QA Device will have after a successful processing of the ReaplceKey Request. The GetProgramKey Request is called with the Key number of the Old Key (in the Key Programming QA Device) and the Key Number of the New Key (in the Key Programming QA Device), and the Random number from (1). The Key Programming QA Device validates the GetProgramKey Request based on the KeyReplacement map, and then produces the necessary GetProgramKey Output. The GetProgramKey Output consists of the encrypted New Key (encryption done using the Old Key), along with a signature using the Old Key.</li><li id="ul0839-0003" num="6190">3. The System then applies GetProgramKey Output to the QA Device whose key is being replaced, by calling the ReplaceKey function on it, passing in the GetProgramKey Output. The ReplaceKey function will decrypt the encrypted New Key using the Old Key, and then replace its Old Key with the decrypted New Key. <br /> 25 Functions <br /> 25.1 GetProgamKey <ul id="ul0840" list-style="none"><li id="ul0840-0001" num="6191">Input: OldKeyRef, ChipID, R<sub>E</sub>, KeyLock, NewKeyRef</li><li id="ul0840-0002" num="6192">Output: ResultFlag, R<sub>L</sub>, EncryptedKey, KeyIdOfNewKey, SIGo<sub>out </sub></li><li id="ul0840-0003" num="6193">Changes: R<sub>L </sub></li><li id="ul0840-0004" num="6194">Availability: Key programming device <br /> 25.1.1 Function Description </li></ul></li></ul>
6195The GetProgramKey works in conjunction with the ReplaceKey command, and is used to replace the specified key and its KeyId. This function is available on a key programming device and produces the necessary inputs for the ReplaceKey function. The ReplaceKey command is then run on the device whose key is being replaced.
6196The key programming device must have both the old key and the new key programmed as its keys, and the key replacement map stored in one of its M0 field, before GetProgramKey can be called on the device.
6197Depending on the OldKeyRef object and the NewKeyRef object passed in, the GetProgramKey will produce a signature to replace a common key by a common key, a variant key by a common key, a common key by a variant key or a variant key by a variant key.
000025.1.2 Input Parameters
6198<tables id="TABLE-US-00456" num="00456"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="168pt" align="left" /><thead><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>Parameter</entry><entry>Description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>OldKeyRef</entry><entry>Old key is a common key: OldKeyRef.keyNum =</entry></row><row><entry /><entry>Slot number of the old key in the Key Prog-</entry></row><row><entry /><entry>ramming QA Device. The device whose key is</entry></row><row><entry /><entry>being replaced, shares a common key</entry></row><row><entry /><entry>K<sub>OldKeyRef.keyNum </sub>with the key programming</entry></row><row><entry /><entry>device. OldKeyRef.useChipId = 0</entry></row><row><entry /><entry>Old key is a variant key KeyRef.keyNum = Slot</entry></row><row><entry /><entry>number of the old key in the Key Programming QA</entry></row><row><entry /><entry>Device. that will be used to generate the variant</entry></row><row><entry /><entry>key. The device whose key is being replaced, shares</entry></row><row><entry /><entry>a variant of K<sub>OldKeyRef.keyNum </sub>with the key</entry></row><row><entry /><entry>programming device. OldKeyRef.useChipId = 1</entry></row><row><entry /><entry>OldKeyRef.chipId = ChipId of the device whose</entry></row><row><entry /><entry>variant of K<sub>OldKeyRef.keyNum </sub>key is being replaced.</entry></row><row><entry>ChipId</entry><entry>Chip identifier of the device whose key is being</entry></row><row><entry /><entry>replaced.</entry></row><row><entry>R<sub>E</sub></entry><entry>External random value which will be used in output</entry></row><row><entry /><entry>signature generation. R<sub>E </sub>is obtained by calling</entry></row><row><entry /><entry>the Random function on the device being programmed.</entry></row><row><entry /><entry>This will also receive the SIGout from the</entry></row><row><entry /><entry>GetProgramKey function. SIGout is passed in to</entry></row><row><entry /><entry>ReplaceKeyfunction.</entry></row><row><entry>KeyLock</entry><entry>Flag indicating whether the new key should be</entry></row><row><entry /><entry>unlocked/locked into its slot.</entry></row><row><entry>NewKeyRef</entry><entry>New key is a common key: NewKeyRef.keyNum =</entry></row><row><entry /><entry>Slot number of the new key in the Key Programming</entry></row><row><entry /><entry>QA Device. The device whose key is being replaced,</entry></row><row><entry /><entry>will receive a common key K <sub>NewKeyRef.keyNum </sub>from</entry></row><row><entry /><entry>the key programming device.</entry></row><row><entry /><entry>NewKeyRef.useChipId = 0</entry></row><row><entry /><entry>NewKey is a variant key: NewKeyRef.keyNum =</entry></row><row><entry /><entry>Slot number of the new key in the KeyProgramming</entry></row><row><entry /><entry>QA Device. that will be used to generate the new</entry></row><row><entry /><entry>variant key. The device whose key is being replaced,</entry></row><row><entry /><entry>will receive a new key which is a variant of</entry></row><row><entry /><entry>K<sub>NewKeyRef.keyNum </sub>from the key programming</entry></row><row><entry /><entry>device. NewKeyRef.useChipId = 1</entry></row><row><entry /><entry>NewKeyRef.chipId = ChipId of the device</entry></row><row><entry /><entry>receiving a new key, the new key is a variant</entry></row><row><entry /><entry>of the K<sub>NewKeyRef.keyNum</sub>.</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 25.1.3 Output Parameters
6199<tables id="TABLE-US-00457" num="00457"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="161pt" align="left" /><thead><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>Parameter</entry><entry>Description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>ResultFlag</entry><entry>Indicates whether the function completed successfully</entry></row><row><entry /><entry>or not. If it did not complete successfully, the</entry></row><row><entry /><entry>reason for the failure is returned here. See</entry></row><row><entry /><entry>Section 12.1 and Table 284</entry></row><row><entry>R<sub>L</sub></entry><entry>Internal random value used in the output signature.</entry></row><row><entry>EncryptedKey</entry><entry>SIG<sub>Kold</sub>(R<sub>L</sub>|R<sub>E</sub>) ⊕ K<sub>new</sub></entry></row><row><entry>KeyIdOfNewKey</entry><entry>KeyId of the new key. The LSB represents whether the</entry></row><row><entry /><entry>new key is a variant or a common key.</entry></row><row><entry>SIG<sub>out</sub></entry><entry>SIG<sub>out </sub>= SIG<sub>Kold</sub>(data | R<sub>L </sub>| R<sub>E</sub>)</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
6200<tables id="TABLE-US-00458" num="00458"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 284</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>ResultFlag definitions for GetProgramKey</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="105pt" align="left" /><colspec colname="2" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>Result Flag</entry><entry>Description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>InvalidKeyReplacementMap</entry><entry>Key replacement map field invalid</entry></row><row><entry /><entry>or doesn't exist.</entry></row><row><entry>KeyReplacementNotAllowed</entry><entry>Key replacement not allowed as</entry></row><row><entry /><entry>per key replacement map.</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 25.1.3.1 SIG<sub>out </sub><ul id="ul0841" list-style="none"><li id="ul0841-0001" num="0000"><ul id="ul0842" list-style="none"><li id="ul0842-0001" num="6201"><figref idref="DRAWINGS">FIG. 378</figref> shows the output signature generation data format for the GetProgramKey function. <br /> 25.1.4 Function Sequence </li><li id="ul0842-0002" num="6202">The GetProgramKey command is illustrated by the following pseudocode:</li></ul></li></ul>
6203<tables id="TABLE-US-00459" num="00459"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>Accept input parameters - OldKeyRef, ChipId, R<sub>E</sub>, KeyLock,</entry></row><row><entry>NewKeyRef</entry></row><row><entry>----------------------------------------------------------------</entry></row><row><entry># key replacement map key stored in K0, must not be used for key</entry></row><row><entry>replacement</entry></row><row><entry>If(OldKeyRef.keyNum = 0) <img file="US7165824B2_D0501.tif" /> (NewKeyRef.keyNum = 0)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0502.tif" /> Fail</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>----------------------------------------------------------------</entry></row><row><entry>CheckRange(OldKeyRef.keyNum)</entry></row><row><entry>If invalid</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0503.tif" /> InvalidKey</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>----------------------------------------------------------------</entry></row><row><entry>CheckRange (NewKeyRef.keyNum)</entry></row><row><entry>If invalid</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0504.tif" /> InvalidKey</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>----------------------------------------------------------------</entry></row><row><entry># Find M0 words that represent the key replacement map</entry></row><row><entry>WordSelectForKeyMapField <img file="US7165824B2_D0505.tif" /> GetWordSelectForKeyMapField(M1)</entry></row><row><entry>If(WordSelectForKeyMapField = 0)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0506.tif" /> InvalidKeyReplacementMap</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>----------------------------------------------------------------</entry></row><row><entry>#CheckMapPermits key replacement</entry></row><row><entry>ReplaceOK</entry></row><row><entry><img file="US7165824B2_D0507.tif" /> CheckMapPermits(WordSelectForKeyMapField,OldKeyNum,</entry></row><row><entry>NewKeyNum)</entry></row><row><entry>If(ReplaceOK = 0)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0508.tif" /> KeyReplacementNotAllowed</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>----------------------------------------------------------------</entry></row><row><entry>#All checks are OK, now generate Signature with OldKey</entry></row><row><entry>SIG<sub>L </sub><img file="US7165824B2_D0509.tif" /> GenerateSignature(OldKeyRef,null,R<sub>L</sub>,R<sub>E</sub>)</entry></row><row><entry>#Get new key</entry></row><row><entry>K<sub>NewKey</sub><img file="US7165824B2_D0510.tif" /> NewKeyRef.getKey( )</entry></row><row><entry>#Generate Encrypted Key</entry></row><row><entry>EncryptedKey <img file="US7165824B2_D0511.tif" /> SIG<sub>L </sub>⊕ K<sub>NewKey</sub></entry></row><row><entry>#Set base key or variant key - bit 0 of KeyId</entry></row><row><entry>If(NewKeyRef.useChipId = 1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>KeyId<img file="US7165824B2_D0512.tif" /> 0x0001 <img file="US7165824B2_D0513.tif" /> 0x0001</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>KeyId <img file="US7165824B2_D0514.tif" /> 0x0001 <img file="US7165824B2_D0515.tif" /> 0x0000</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>#Set the new key KeyId to the KeyId - bits 1–30 of KeyId</entry></row><row><entry>KeyIdOfNewKey<img file="US7165824B2_D0516.tif" /> SHIFTLEFT(KeyIdOfNewKey,1)</entry></row><row><entry>KeyId<img file="US7165824B2_D0517.tif" /> KeyId <img file="US7165824B2_D0518.tif" /> KeyIdOfNewKey</entry></row><row><entry>#Set the KeyLock as per input - bit 31 of KeyId</entry></row><row><entry>KeyLock<img file="US7165824B2_D0519.tif" /> SHIFTLEFT(KeyLock,31)</entry></row><row><entry>#KeyId<img file="US7165824B2_D0520.tif" /> KeyId <img file="US7165824B2_D0521.tif" /> KeyLock</entry></row><row><entry>#Generate message for passing in to the GenerateSignature</entry></row><row><entry>function</entry></row><row><entry>data <img file="US7165824B2_D0522.tif" /> ChipId | KeyId | R<sub>L </sub>| EncryptedKey</entry></row><row><entry>#Generate output signature</entry></row><row><entry>SIG<sub>out </sub><img file="US7165824B2_D0523.tif" /> GenerateSignature(OldKeyRef,data,null,null)</entry></row><row><entry># Refer to Figure 378</entry></row><row><entry>Advance R<sub>L</sub>to R<sub>L2</sub></entry></row><row><entry>ResultFlag <img file="US7165824B2_D0524.tif" /> Pass</entry></row><row><entry>Output ResultFlag, R<sub>L,</sub>SIG<sub>out</sub>,KeyId, EncryptedKey</entry></row><row><entry>Return</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 25.1.4.1 WordSelectForField GetWordSelectForKeyMapField(M1) <ul id="ul0843" list-style="none"><li id="ul0843-0001" num="0000"><ul id="ul0844" list-style="none"><li id="ul0844-0001" num="6204">This function gets the words corresponding to the key replacement map in M0.</li></ul></li></ul>
6205<tables id="TABLE-US-00460" num="00460"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>FieldSize[16] <img file="US7165824B2_D0525.tif" /> 0 # Array to hold FieldSize assuming there are 16</entry></row><row><entry /><entry>fields</entry></row><row><entry /><entry>NumFields <img file="US7165824B2_D0526.tif" /> FindNumberOfFieldsInM0(M1,FieldSize)</entry></row><row><entry /><entry>#Find the key replacement map field</entry></row><row><entry /><entry>For i <img file="US7165824B2_D0527.tif" /> 0 to NumFields</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>If(TYPE_KEY_MAP = M1[i].Type) # Field is key map field</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>MapFieldNum <img file="US7165824B2_D0528.tif" /> i</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Endif</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndFor</entry></row><row><entry /><entry>#Get the words corresponding to the key replacement map</entry></row><row><entry /><entry>WordMapForField<img file="US7165824B2_D0529.tif" /> GetWordMapForField(MapFieldNum,M1)</entry></row><row><entry /><entry>Return WordSelectForField</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 25.1.4.2 NumFields FindNumOfFieldsInM0(M1, FieldSize<img file="US7165824B2_D0530.tif" />) <ul id="ul0845" list-style="none"><li id="ul0845-0001" num="0000"><ul id="ul0846" list-style="none"><li id="ul0846-0001" num="6206">Refer to Figure 19.4.1 for details <br /> 25.1.4.3 WordMapForField GetWordMapForField(FieldNum,M1) </li><li id="ul0846-0002" num="6207">Refer to Section 19.4.2 for details. <br /> 25.1.4.4 ReplaceOK CheckMapPermits(WordSelectForKeyMapField, OldKeyNum, NewKeyNum,M0) </li><li id="ul0846-0003" num="6208">This function checks whether key replacement map permits key replacement.</li></ul></li></ul>
6209<tables id="TABLE-US-00461" num="00461"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>#Isolate KeyReplacementMap based on WordSelectForKeyMapField and</entry></row><row><entry>M0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>KeyReplacementMap [64 bit]</entry></row><row><entry /><entry>#Isolate permission bit corresponding for NewKeyNum in the map</entry></row><row><entry /><entry>for OldKeyNm</entry></row><row><entry /><entry>ReplaceOK <img file="US7165824B2_D0531.tif" /> KeyReplacementMap[(OldKeyNum ×8+NewKeyNum)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>bit]</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Return ReplaceOK</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 25.2 ReplaceKey <ul id="ul0847" list-style="none"><li id="ul0847-0001" num="0000"><ul id="ul0848" list-style="none"><li id="ul0848-0001" num="6210">Input: KeyRef, KeyID, KeyLock, EncryptedKey,R<sub>E</sub>, SIG<sub>E </sub></li><li id="ul0848-0002" num="6211">Output: ResultFlag</li><li id="ul0848-0003" num="6212">Changes: K<sub>KeyNum </sub>and R<sub>L </sub></li><li id="ul0848-0004" num="6213">Availability: Key programming device <br /> 25.2.1 Function Description </li></ul></li></ul>
6214This function is used for replacing a key in a key programming device and is similar to the generic ReplaceKey function(Refer to Section 24), with an additional step of setting the KeyRef.keyNum column and KeyRef.keyNum row key replacement map to 0.
000025.2.2 Input Parameters
0000<ul id="ul0849" list-style="none"><li id="ul0849-0001" num="0000"><ul id="ul0850" list-style="none"><li id="ul0850-0001" num="6215">Refer to Section 22. <br /> 25.2.3 Output Parameters </li><li id="ul0850-0002" num="6216">Refer to Section 22. <br /> 25.2.4 Function Sequence </li><li id="ul0850-0003" num="6217">The ReplaceKey command is illustrated by the following pseudocode:</li></ul></li></ul>
6218<tables id="TABLE-US-00462" num="00462"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>Accept input parameters - KeyRef, KeyId, EncryptedKey,R<sub>E</sub>, SIG<sub>E</sub></entry></row><row><entry /><entry>#Generate message for passing into GenerateSignature function</entry></row><row><entry /><entry>data <img file="US7165824B2_D0532.tif" /> (ChipId|KeyId|R<sub>E</sub>|EncryptedKey)# Refer to Figure 374.</entry></row><row><entry /><entry>----------------------------------------------------------------</entry></row><row><entry /><entry># Validate KeyRef, and then verify signature</entry></row><row><entry /><entry>ResultFlag = ValidateKeyRefAndSignature(KeyRef,data,R<sub>E</sub>,R<sub>L</sub>)</entry></row><row><entry /><entry>If (ResultFlag ≠ Pass)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>----------------------------------------------------------------</entry></row><row><entry /><entry># Check if the key slot is unlocked</entry></row><row><entry /><entry>Isolate KeyLock for KeyRef</entry></row><row><entry /><entry>If(KeyLock = lock)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0533.tif" /> KeyAlreadyLocked</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>SIG<sub>L </sub><img file="US7165824B2_D0534.tif" /> GenerateSignature(Key,Null,R<sub>E</sub>,R<sub>L</sub>)</entry></row><row><entry /><entry>Advance R<sub>L</sub></entry></row><row><entry /><entry># Find M0 words that represent the key replacement map</entry></row><row><entry /><entry>WordSelectForKeyMapField <img file="US7165824B2_D0535.tif" /> GetWordSelectForKeyMapField(M1)</entry></row><row><entry /><entry># Set the bits corresponding to the KeyRef.keyNum row and column</entry></row><row><entry /><entry>to 0</entry></row><row><entry /><entry># i.e invalidate the key replacement map for KeyRef.keyNum.</entry></row><row><entry /><entry>#Must be done before the key is replaced and must be atomic with</entry></row><row><entry /><entry>key replacement.</entry></row><row><entry /><entry>SetFlag</entry></row><row><entry /><entry><img file="US7165824B2_D0536.tif" /> SetKeyMapForKeyNum(WordSelectForKeyMapField,KeyRef.keyNum,M0)</entry></row><row><entry /><entry>If(SetFlag = 1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry># Must be atomic - must not be possible to remove power and have</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>KeyId and</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>KeyNum mismatched</entry></row><row><entry /><entry>K<sub>KeyNum </sub><img file="US7165824B2_D0537.tif" /> SIG<sub>L </sub>⊕ EncryptedKey</entry></row><row><entry /><entry>KeyId<sub>KeyNum </sub><img file="US7165824B2_D0538.tif" /> KeyId</entry></row><row><entry /><entry>KeyLock<sub>KeyNum </sub><img file="US7165824B2_D0539.tif" /> KeyLock</entry></row><row><entry /><entry>ResultFlag <img file="US7165824B2_D0540.tif" /> Pass</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0541.tif" /> Fail</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 25.2.4.1 WordSelectForField GetWordSelectForKeyMapField(M1) <ul id="ul0851" list-style="none"><li id="ul0851-0001" num="0000"><ul id="ul0852" list-style="none"><li id="ul0852-0001" num="6219">Refer to Figure 25.1.4.1 for details. <br /> 25.2.4.2 SetFlag SetKeyMapForKeyNum(WordSelectForKeyMapField,KeyNum, M0) </li><li id="ul0852-0002" num="6220">This function invalidates the key replacement map for KeyNum.</li></ul></li></ul>
6221<tables id="TABLE-US-00463" num="00463"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>#Isolate KeyReplacementMap based on WordSelectForKeyMapField and</entry></row><row><entry>M0</entry></row><row><entry>KeyReplacementMap[64 bit]</entry></row><row><entry># Set KeyNum row (all bits) to 0 in the KeyReplacementMap</entry></row><row><entry>For i = 0 to 7</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>KeyReplacementMap[(KeyNum ×8+i)bit] <img file="US7165824B2_D0542.tif" /> 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndFor</entry></row><row><entry># Set KeyNum column to 0 in the KeyReplacementMap</entry></row><row><entry>For i = 0 to 7</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>KeyReplacementMap[(i×8+KeyNum)bit] <img file="US7165824B2_D0543.tif" /> 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndFor</entry></row><row><entry>SetFlag <img file="US7165824B2_D0544.tif" /> 1</entry></row><row><entry>Return SetFlag</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> Functions <br /> Upgrade Device <br /> (Ink Re/Fill) <br /> 26 Concepts <br /> 26.1 Purpose
6222In a printing application, an ink cartridge contains an Ink QA Device storing the ink-remaining values for that ink cartridge. The ink-remaining values decrement as the ink cartridge is used to print.
6223When an ink cartridge is physically re/filled, the Ink QA Device needs to be logically re/filled as well. Therefore, the main purpose of an upgrade is to re/fill the ink-remaining values of an Ink QA Device in an authorised manner.
6224The authorisation for a re/fill is achieved by using a Value Upgrader QA Device which contains all the necessary functions to re/write to the Ink QA Device. In this case, the value upgrader is called an Ink Refill QA Device, which is used to fill/refill ink amount in an Ink QA Device.
6225When an Ink Refill QA Device increases (additive) the amount of ink-remaining in an Ink QA Device, the amount of ink-remaining in the Ink Refill QA Device is correspondingly decreased. This means that the Ink Refill QA Device can only pass on whatever ink-remaining value it itself has been issued with. Thus an Ink Refill QA Device can itself be replenished or topped up by another Ink Refill QA Device.
6226The Ink Refill QA Device can also be referred to as the Upgrading QA Device, and the Ink QA Device can also be referred to as the QA Device being upgraded.
6227The refill of ink can also be referred to as a transfer of ink, or transfer of amount/valu, or an upgrade.
6228Typically, the logical transfer of ink is done only after a physical transfer of ink is successful.
000026.2 Requirements
6229The transfer process has two basic requirements: <ul id="ul0853" list-style="none"><li id="ul0853-0001" num="0000"><ul id="ul0854" list-style="none"><li id="ul0854-0001" num="6230">The transfer can only be performed if the transfer request is valid. The validity of the transfer request must be completely checked by the Ink Refill QA Device, before it produces the required output for the transfer. It must not be possible to apply the transfer output to the Ink QA Device, if the Ink Refill QA Device has been already been rolled back for that particular transfer.</li><li id="ul0854-0002" num="6231">A process of rollback is available if the transfer was not received by the Ink QA Device. A rollback is performed only if the rollback request is valid. The validity of the rollback request must be completely checked by the Ink Refill QA Device, before it adjusts its value to a previous value before the transfer request was issued. It must not be possible to rollback an Ink Refill QA Device for a transfer which has already been applied to the Ink QA Device i.e the Ink Refill QA Device must only be rolled back for transfers that have actually failed. <br /> 26.3 Basic Scheme </li></ul></li></ul>
6232The transfer and rollback process is shown in <figref idref="DRAWINGS">FIG. 379</figref>.
6233Following is a sequential description of the transfer and rollback process: <ul id="ul0855" list-style="none"><li id="ul0855-0001" num="6234">1. The System Reads the memory vectors M0 and M1 of the Ink QA Device. The output from the read which includes the M0 and M1 words of the Ink QA Device, and a signature, is passed as an input to the Transfer Request. It is essential that M0 and M1 are read together. This ensures that the field information for M0 fields are correct, and have not been modified, or substituted from another device. Entire M0 and M1 must be read to verify the correctness of the subsequent Transfer Request by the Ink Refill QA Device.</li><li id="ul0855-0002" num="6235">2. The System makes a Transfer Request to the Ink Refill QA Device with the amount that must be transferred, the field in the Ink Refill QA Device the amount must be transferred from, and the field in Ink QA Device the amount must be transferred to. The Transfer Request also includes the output from Read of the Ink QA Device. The Ink Refill QA Device validates the Transfer Request based on the Read output, checks that it has enough value for a successful transfer, and then produces the necessary Transfer Output. The Transfer Output typically consists of new field data for the field being refilled or upgraded, additional field data required to ensure the correctness of the transfer/rollback, along with a signature.</li><li id="ul0855-0003" num="6236">3. The System then applies the Transfer Output to the Ink QA Device, by calling an authenticated Write function on it, passing in the Transfer Output. The Write is either successful or not. If the Write is not successful, then the System will repeat calling the Write function using the same transfer output, which may be successful or not. If unsuccesful the System will initiate a rollback of the transfer. The rollback must be performed on the Ink Refill QA Device, so that it can adjust its value to a previous value before the current Transfer Request was initiated. It is not necessary to perform a rollback immediately after a failed Transfer. The Ink QA Device can still be used to print, if there is any ink remaining in it.</li><li id="ul0855-0004" num="6237">4. The System starts a rollback by Reading the memory vectors M0 and M1 of the Ink QA Device.</li><li id="ul0855-0005" num="6238">5. The System makes a StartRollBack Request to the Ink Refill QA Device with same input parameters as the Transfer Request, and the output from Read in (4). The Ink Refill QA Device validates the StartRollBack Request based on the Read output, and then produces the necessary Pre-rollback output. The Pre-rollback output consists only of additional field data along with a signature.</li><li id="ul0855-0006" num="6239">6. The System then applies the Pre-rollback Output to the Ink QA Device, by calling an authenticated Write function on it, passing in the Pre-rollback output. The Write is either successful or not. If the Write is not successful, then either (6), or (5) and (6) must be repeated.</li><li id="ul0855-0007" num="6240">7. The System then Reads the memory vectors M0 and M1 of the Ink QA Device.</li><li id="ul0855-0008" num="6241">8. The System makes a RollBack Request to the Ink Refill QA Device with same input parameters as the Transfer Request, and the output from Read (7). The Ink Refill QA Device validates the RollBack Request based on the Read output, and then rolls back its field corresponding to the transfer. <br /> 26.3.1 Transfer </li></ul>
6242As we mentioned, the Ink QA Device stores ink-remaining values in its M0 fields, and its corresponding M<sub>1 </sub>words contains field information for its ink-remaining fields. The field information consists of the size of the field, the type of data stored in field and the access permission to the field. See Section 8.1.1 for details.
6243The Ink Refill QA Device also stores its ink-remaining values in its M0 fields, and its coressponding M<sub>1 </sub>words contains field information for its ink-remaining fields.
000026.3.1.1 Authorisation
6244The basic authorisation for a transfer comes from a key, which has authenticated ReadWrite permission (stored in field information as KeyNum) to the ink-remaining field (to which ink will be transferrred) in the Ink QA Device. We will refer to this key as the refill key. The refill key must also have authenticated decrement-only permission for the ink-remaining field (from which ink will be transferred) in the Ink Refill QA Device.
6245After validating the input transfer request, the Ink Refill QA Device will decrement the amount to be transferred from its ink-remaining field, and produce a transfer amount (previous ink-remaining amount in the Ink QA Device+transfer amount), additional field data, and a signature using the refill key. Note that the Ink Refill QA Device can decrement its ink-remaining field only if the refill key has the permission to decrement it.
6246The signature produced by the Ink Refill QA Device is subsequently applied to the Ink QA Device. The Ink QA Device will accept the transfer amount only if the signature is valid. Note that the signature will only be valid if it was produced using the refill key which has write permission to the ink-remaining field being written.
000026.3.1.2 Data Type Matching
6247The Ink Refill QA Device validates the transfer request by matching the Type of the data in ink-remaining information field of Ink QA Device to the Type of data in ink-remaining information field of the Ink Refill QA Device. This ensures that equivalent data Types are transferred i.e Network_OEM1_infrared ink is not transferred to Network_OEM1_cyan ink.
000026.3.1.3 Addition Validation
6248Additional validation of the transfer request must also be performed before a transfer output is generated by the Ink Refill QA Device. These are as follows: <ul id="ul0856" list-style="none"><li id="ul0856-0001" num="0000"><ul id="ul0857" list-style="none"><li id="ul0857-0001" num="6249">For the Ink Refill QA Device:</li></ul></li><li id="ul0856-0002" num="6250">1. Whether the field being upgraded is actually present.</li><li id="ul0856-0003" num="6251">2. Whether the field being upgraded can hold the upgraded amount. <ul id="ul0858" list-style="none"><li id="ul0858-0001" num="6252">For the Ink QA Device:</li></ul></li><li id="ul0856-0004" num="6253">1. Whether the field from which the amount is transferred is actually present.</li><li id="ul0856-0005" num="6254">2. Whether the field has sufficient amount required for the transfer. <br /> 26.3.1.4 Rollback Facilitation </li></ul>
6255To facilitate a rollback, the Ink Refill QA Device will store a list of transfer requests processed by it. This list is referred to as the Xfer Entry cache. Each record in the list consists of the transfer parameters corresponding to the transfer request.
000026.3.2 Rollback
6256A rollback request is validated by looking through the Xfer Entry of the Ink Refill QA Device and finding the request that should be rolled back. After the right transfer request is found the Ink Refill QA Device checks that the output from the transfer request was not applied to the Ink QA Device by comparing the current Read of the Ink QA Device to the values in the Xfer Entry cache, and finally rolls back its ink-remaining field (from which the ink was transferred) to a previous value before the transfer request was issued.
6257The Ink Refill QA Device must be absolutely sure that the Ink QA Device didn't receive the transfer. This factor determines the additional fields that must be written along with transfer amount, and also the parameters of the transfer request that must be stored in the Xfer Entry cache to facilitate a rollback, to prove that the Printer QA Device didn't actually receive the transfer.
000026.3.2.1 Sequence Fields
6258The rollback process must ensure that the transfer output (which was previously produced) for which the rollback is being performed, cannot be applied after the rollback has been performed. How do we achieve this? There are two separate decrement-only sequence fields (SEQ<sub>—</sub>1 and SEQ<sub>—</sub>2) in the Ink QA Device which can only be decremented by the Ink Refill QA Device using the refill key. The nature of data to be written to the sequence fields is such that either the transfer output or the pre-rollback output can be applied to the Ink QA Device, but not both i.e they must be mutually exclusive.Refer to Table 285 for details.
6259<tables id="TABLE-US-00464" num="00464"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="280pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 285</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Sequence field data for Transfer and Pre-rollback</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="140pt" align="center" /><colspec colname="2" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry>Sequence Field data</entry><entry /></row><row><entry /><entry>written to Ink QA Device</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="70pt" align="left" /><colspec colname="3" colwidth="70pt" align="left" /><colspec colname="4" colwidth="98pt" align="left" /><tbody valign="top"><row><entry>Function</entry><entry>SEQ_1</entry><entry>SEQ_2</entry><entry>Explanation</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>Initialised</entry><entry>0xFFFFFFFF</entry><entry>0xFFFFFFFF</entry><entry>Written using the sequence key</entry></row><row><entry /><entry /><entry /><entry>which is different from the refill</entry></row><row><entry /><entry /><entry /><entry>key</entry></row><row><entry>Write using</entry><entry>(Previous Value − 2)</entry><entry>(Previous Value − 1)</entry><entry>Written using the refill key using</entry></row><row><entry>Transfer</entry><entry>If Previous Value =</entry><entry>If Previous Value =</entry><entry>the refill key which has</entry></row><row><entry>Output</entry><entry>intialised value</entry><entry>intialised value</entry><entry>decrement-only</entry></row><row><entry /><entry>then 0xFFFFFFFD</entry><entry>then 0xFFFFFFFE</entry><entry>permission on the fields.</entry></row><row><entry /><entry /><entry /><entry>Value cannot be written if pre-</entry></row><row><entry /><entry /><entry /><entry>rollback</entry></row><row><entry /><entry /><entry /><entry>output is already written.</entry></row><row><entry>Write usiing</entry><entry>(Previous Value − 1)</entry><entry>(Previous Value − 2)</entry><entry>Written using the refill key using</entry></row><row><entry>Pre-rollback</entry><entry>If Previous Value =</entry><entry>If Previous Value =</entry><entry>the refill key which has</entry></row><row><entry /><entry>intialised value</entry><entry>initialised value</entry><entry>decrement-only</entry></row><row><entry /><entry>then 0xFFFFFFFE</entry><entry>then 0xFFFFFFFD</entry><entry>permission on the fields.</entry></row><row><entry /><entry /><entry /><entry>Value can be written only if</entry></row><row><entry /><entry /><entry /><entry>Transfer</entry></row><row><entry /><entry /><entry /><entry>Output has not been written.</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
6260The two sequence fields are initialised to 1xFFFFFFFF using sequence key. The sequence key is different to the refill key, and has authenticated ReadWrite permission to both the sequence fields. The transfer output consists of the new data for the field being upgraded, field data of the two sequence fields, and a signature using the refill key. The field data for SEQ<sub>—</sub>1 is decremented by 2 from the original value that was passed in with the transfer request. The field data for SEQ<sub>—</sub>2 is decremented by 1 from the original value that was passed in with the transfer request.
6261The pre-rollback output consists only of the field data of the two sequence fields, and a signature using the refill key. The field data for SEQ<sub>—</sub>1 is decremented by 1 from the original value that was passed in with the transfer request. The field data for SEQ<sub>—</sub>2 is decremented by 2 from the original value that was passed in with the transfer request.
6262Since the two sequence fields are decrement-only fields, the writing of the transfer output to QA Device being upgraded will prevent the writing of the pre-rollback output to QA Device being upgraded. If the writing of the transfer output fails, then pre-rollback can be written. However, the transfer output cannot be written after the pre-rollback has been written.
6263Before a rollback is performed, the Ink Refill QA Device must confirm that the sequence fields was successfully written to the pre-rollback values in the Ink QA Device. Because the sequence fields are Decrement-Only fields, the Ink QA Device will allow pre-rollback output to be written only if the upgrade output has not been written. It also means that the transfer output cannot be written after the pre-rollback values have been written.
000026.3.2.1.1 Field Information of the Sequence Data Field
6264For a device to be upgradeable the device must have two sequence fields SEQ<sub>—</sub>1 and SEQ<sub>—</sub>2 which are written with sequence data during the transfer sequence. Thus all upgrading QA devices, ink QA Devices and printer QA Devices must have two sequence fields. The upgrading QA Devices must also have these fields because they can be upgraded as well.
6265The sequence field information is defined in Table 286.
6266<tables id="TABLE-US-00465" num="00465"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 286</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Sequence field information</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="98pt" align="left" /><tbody valign="top"><row><entry>Attribute</entry><entry /><entry /></row><row><entry>Name</entry><entry>Value</entry><entry>Explanation</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>Type</entry><entry>TYPE_SEQ_1 or</entry><entry>See Appendix A for exact</entry></row><row><entry /><entry>TYPE_SEQ_2.</entry><entry>value.</entry></row><row><entry>KeyNum</entry><entry>Slot number of</entry><entry>Only the sequence key has</entry></row><row><entry /><entry>the sequence</entry><entry>authenticated ReadWrite</entry></row><row><entry /><entry>key.</entry><entry>access to this field.</entry></row><row><entry>Non Auth</entry><entry>0</entry><entry>Non authenticated ReadWrite</entry></row><row><entry>RW Perm</entry><entry /><entry>is not allowed to the field.</entry></row><row><entry>Auth RW</entry><entry>1</entry><entry>Authenticated (key based)</entry></row><row><entry>Perm</entry><entry /><entry>ReadWrite access is allowed</entry></row><row><entry /><entry /><entry>to the field.</entry></row><row><entry>KeyPerm</entry><entry>KeyPerms[KeyNum] = 0</entry><entry>KeyNum is the slot number</entry></row><row><entry /><entry /><entry>of the sequence key, which</entry></row><row><entry /><entry /><entry>has ReadWrite permission</entry></row><row><entry /><entry /><entry>to the field.</entry></row><row><entry /><entry>KeyPerms</entry><entry>Refill key can decrement</entry></row><row><entry /><entry>[Slot number of</entry><entry>the sequence field.</entry></row><row><entry /><entry>the refill</entry></row><row><entry /><entry>key] = 1</entry></row><row><entry /><entry>KeyPerms[others =</entry><entry>All other keys have</entry></row><row><entry /><entry>0 . . . 7(except</entry><entry>ReadOnly access.</entry></row><row><entry /><entry>refill key)] = 0</entry></row><row><entry>End Pos</entry><entry /><entry>Set as required. Size is</entry></row><row><entry /><entry /><entry>typically 1 word.</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 26.3.3 Upgrade States
6267There are three states in an transfer sequence, the first state is initiated for every transfer, while the next two states are initiated only when the transfer fails. The states are—Xfer, StartRollback, and Rollback.
000026.3.3.1 Upgrade Flow
6268<figref idref="DRAWINGS">FIG. 380</figref> shows a typical upgrade flow.
000026.3.3.2 Xfer
6269This state indicates the start of the transfer process, and is the only state required if the transfer is successful. During this state, the Ink Refill QA Device adds a new record to its Xfer Entry cache, decrements its amount, produces new amount, new sequence data (as described in Section 26.3.2.1) and a signature based on the refill key.
6270The Ink QA Device will subsequently write the new amount and new sequence data, after verifying the signature. If the new amount can be successfully written to the Ink QA Device, then this will finish a successful transfer.
6271If the writing of the new amount is unsuccessful (result returned is BAD SIG), the System will re-transmit the transfer output to the Ink QA Device, by calling the authenticated Write function on it again, using the same transfer output.
6272If retrying to write the same transfer output fails repeatedly, the System will start the rollback process on Ink Refill QA Device, by calling the Read function on the Ink QA Device, and subsequently calling the StartRollBack function on the Ink Refill QA Device. After a successful rollback is performed, the System will invoke the transfer sequence again.
000026.3.3.3 StartRollBack
6273This state indicates the start of the rollback process. During this state, the Ink Refill QA Device produces the next sequence data and a signature based on the refill key. This is also called a pre-rollback, as described in Section 26.3.2.
6274The pre-rollback output can only be written to the Ink QA Device, if the previous transfer output has not been written. The writing of the pre-rollback sequence data also ensures, that if the previous transfer output was captured and not applied, then it cannot be applied to the Ink QA Device in the future.
6275If the writing of the pre-rollback output is unsuccessful (result returned is BAD SIG), the System will re-transmit the pre-rollback output to the Ink QA Device, by calling the authenticated Write function on it again, using the same pre-rollback output.
6276If retrying to write the same pre-rollback output fails repeatedly, the System will call the StartRollback on the Ink Refill QA Device again, and subsequently calling the authenticated Write function on the Ink QA Device using this output.
000026.3.3.4 Rollback
6277This state indicates a successful deletion (completion) of a transfer sequence. During this state, the Ink Refill QA Device verifies the sequence data produced from StartRollBack has been correctly written to Ink Refill QA Device, then rolls its ink-remaining field to a previous value before the transfer request was issued.
000026.3.4 Xfer Entry Cache
6278The Xfer Entry data structure must allow for the following: <ul id="ul0859" list-style="none"><li id="ul0859-0001" num="0000"><ul id="ul0860" list-style="none"><li id="ul0860-0001" num="6279">Stores the transfer state and sequence data for a given transfer sequence.</li><li id="ul0860-0002" num="6280">Store all data corresponding to a given transfer, to facilitate a rollback to the previous value before the transfer output was generated.</li></ul></li></ul>
6281The Xfer Entry cache depth will depend on the QA Chip Logical Interface implementation. For some implementations a single Xfer Entry value will be saved. If the Ink Refill QA Device has no powersafe storage of Xfer Entry cache, a power down will cause the erasure of the Xfer Entry cache and the Ink Refill QA Device will not be able to rollback to a pre-power-down value.
6282A dataset in the Xfer Entry cache will consist of the following: <ul id="ul0861" list-style="none"><li id="ul0861-0001" num="0000"><ul id="ul0862" list-style="none"><li id="ul0862-0001" num="6283">Information about the QA Device being upgraded:</li></ul></li><li id="ul0861-0002" num="6284">a. ChipId of the device.</li><li id="ul0861-0003" num="6285">b. FieldNum of the M0 field (i.e what was being upgraded). <ul id="ul0863" list-style="none"><li id="ul0863-0001" num="6286">Information about the upgrading QA Device:</li></ul></li><li id="ul0861-0004" num="6287">a. FieldNum of the M0 field used to transfer the amount from. <ul id="ul0864" list-style="none"><li id="ul0864-0001" num="6288">XferVal—the transfer amount.</li><li id="ul0864-0002" num="6289">Xfer State—indicating at which state the transfer sequence is. This will consist of:</li></ul></li><li id="ul0861-0005" num="6290">a. State definition which could be one of the following: —Xfer, StartRollBack and complete/deleted.</li><li id="ul0861-0006" num="6291">b. The value of sequence data fields SEQ<sub>—</sub>1 and SEQ<sub>—</sub>2. <br /> 26.3.4.1 Adding New Dataset </li></ul>
6292A new dataset is added to Xfer Entry cache by the Xfer function.
6293There are three methods which can be used to add new dataset to the Xfer Entry cache. The methods have been listed below in the order of their priority: <ul id="ul0865" list-style="none"><li id="ul0865-0001" num="6294">1. Replacing existing dataset in Xfer Entry cache with new dataset based on ChipId and FieldNum of the Ink QA Device in the new dataset. A matching ChipId and FieldNum could be found because a previous transfer output corresponding to the dataset stored in the Xfer Entry cache has been correctly received and processed by the Ink Refill QA Device, and a new transfer request for the same Ink QA Device, same field, has come through to the Ink Refill QA Device.</li><li id="ul0865-0002" num="6295">2. Replace existing dataset cache with new dataset based on the Xfer State. If the Xfer State for a dataset indicates deleted (complete), then such a dataset will not be used for any further functions, and can be overwritten by a new dataset.</li><li id="ul0865-0003" num="6296">3. Add new dataset to the end of the cache. This will automatically delete the oldest dataset from the cache regardless of the Xfer State. <br /> 26.4 Different Types of Transfer </li></ul>
6297There can be three types of transfer: <ul id="ul0866" list-style="none"><li id="ul0866-0001" num="0000"><ul id="ul0867" list-style="none"><li id="ul0867-0001" num="6298">Peer to Peer Transfer—This transfer could be one of the 2 types described below:</li></ul></li><li id="ul0866-0002" num="6299">a. From an Ink Refill QA Device to a Ink QA Device. This is performed when the Ink QA Device is refilled by the Ink Refill QA Device.</li><li id="ul0866-0003" num="6300">b. From one Ink Refill QA Device to another Ink Refill QA Device, where both QA Devices belong to the same OEM. This is typically performed when OEM divides ink from one Ink Refill QA Device to another Ink Refill QA Device, where both devices belong to the same OEM <ul id="ul0868" list-style="none"><li id="ul0868-0001" num="6301">Heirachical Transfer—This is a transfer from one Ink Refill QA Device to another Ink Refill QA Device, where the QA Devices belong to different organisation, say ComCo and OEM. This is typically performed when ComCo divides ink from its refill device to several refill devices belonging to several OEMs.</li></ul></li></ul>
6302<figref idref="DRAWINGS">FIG. 381</figref> is a representation of various authorised ink refill paths in the printing system.
000026.4.1 Hierarchical Transfer
6303Referring to <figref idref="DRAWINGS">FIG. 381</figref>, this transfer is typically performed when ink is transferred from ComCo's Ink Refill QA Device to OEM's Ink Refill QA Device, or from QACo's Ink Refill QA Device to ComCo's Ink Refill QA Device.
000026.4.1.1 Keys and Access Permission
6304We will explain this using a transfer from ComCo to OEM.
6305There is an ink-remaining field associated with the ComCo's Ink Refill QA Device. This ink-remaining field has two keys associated with: <ul id="ul0869" list-style="none"><li id="ul0869-0001" num="0000"><ul id="ul0870" list-style="none"><li id="ul0870-0001" num="6306">The first key transfers ink to the device from another refill device (which is higher in the heirachy), fills/refills (upgrades) the device itself. This key has authenticated ReadWrite permission to the field.</li><li id="ul0870-0002" num="6307">The second key transfers ink from it to other devices (which are lower in the heirachy), fills/refills (upgrades) other devices from it. This key has authenticated decrement-only permission to the field.</li></ul></li></ul>
6308There is an ink-remaining field associated with the OEM's Ink refill device. This ink-remaining field has a single key associated with: <ul id="ul0871" list-style="none"><li id="ul0871-0001" num="0000"><ul id="ul0872" list-style="none"><li id="ul0872-0001" num="6309">This key transfers ink to the device from another refill device (which is higher or at the same level in the hierarchy), fills/refills (upgrades) the device itself, and additionally transfers ink from it to other devices (which are lower in the heirachy), fills/refills (upgrades) other devices from it. Therefore, this key has both authenticated ReadWrite and decrement-only permission to the field. For a successful transfer ink from ComCo's refill device to an OEM's refill device, the ComCo's refill device and the OEM's refill device must share a common key or a variant key. This key is fill/refill key with respect to the OEM's refill device and it is the transfer key with respect to the ComCo's refill device.</li></ul></li></ul>
6310For a ComCo to successfully fill/refill its refill device from another refill device (which is higher in the heirachy possibly belonging to the QACo), the ComCo's refill device and the QACo's refill device must share a common key or a variant key. This key is fill/refill key with respect to the ComCo's refill device and it is the transfer key with respect to the QACo's refill device.
000026.4.1.1.1 Ink—Remaining Field Information
6311Table 287 shows the field information for an <sub>M0 </sub>field storing logical ink-remaining amounts in the refill device and which has the ability to transfer down the heirachy.
6312<tables id="TABLE-US-00466" num="00466"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="35pt" align="left" /><colspec colname="2" colwidth="126pt" align="left" /><colspec colname="3" colwidth="98pt" align="left" /><thead><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>Attribute</entry><entry /><entry /></row><row><entry>Name</entry><entry>Value</entry><entry>Explanation</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>Type</entry><entry>For e.g -</entry><entry>Type describing the logical</entry></row><row><entry /><entry>TYPE_HIGHQUALITY_BLACK_INK<sup>a</sup></entry><entry>ink stored in the ink-remaining</entry></row><row><entry /><entry /><entry>field in the refill device.</entry></row><row><entry>KeyNum</entry><entry>Slot number of the refill</entry><entry>Only the refill key has</entry></row><row><entry /><entry>key.</entry><entry>authenticated ReadWrite</entry></row><row><entry /><entry /><entry>access to this field.</entry></row><row><entry>Non Auth</entry><entry>0</entry><entry>Non authenticated ReadWrite</entry></row><row><entry>RW Perm<sup>b</sup></entry><entry /><entry>is not allowed to the field.</entry></row><row><entry>Auth RW</entry><entry>1</entry><entry>Authenticated (key based)</entry></row><row><entry>Perm<sup>c</sup></entry><entry /><entry>ReadWrite access is allowed</entry></row><row><entry /><entry /><entry>to the field.</entry></row><row><entry>KeyPerm</entry><entry>KeyPerms[KeyNum] = 0</entry><entry>KeyNum is the slot number</entry></row><row><entry /><entry /><entry>of the refill key, which</entry></row><row><entry /><entry /><entry>has ReadWrite permission</entry></row><row><entry /><entry /><entry>to the field.</entry></row><row><entry /><entry>KeyPerms[Slot Num of</entry><entry>Transfer key can decrement</entry></row><row><entry /><entry>transfer key] = 1</entry><entry>the field.</entry></row><row><entry /><entry>KeyPerms[others =</entry><entry>All other keys have</entry></row><row><entry /><entry>0 . . . 7(except</entry><entry>ReadOnly access.</entry></row><row><entry /><entry>transfer key)] = 0</entry></row><row><entry>End Pos</entry><entry>Set as required.</entry><entry>Depends on the amount of</entry></row><row><entry /><entry /><entry>logical ink the device can</entry></row><row><entry /><entry /><entry>store and storage resolution -</entry></row><row><entry /><entry /><entry>i.e in picolitres or in</entry></row><row><entry /><entry /><entry>microlitres.</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry namest="1" nameend="3" align="left" id="FOO-00051"><sup>a</sup>This is a sample type only and is not included in the Type Map in Appendix A.</entry></row><row><entry namest="1" nameend="3" align="left" id="FOO-00052"><sup>b</sup>Non authenticated Read Write permission.</entry></row><row><entry namest="1" nameend="3" align="left" id="FOO-00053"><sup>c</sup>Authenticated Read Write permission.</entry></row></tbody></tgroup></table></tables><br /> 26.4.2 Peer to Peer Transfer
6313Referring to <figref idref="DRAWINGS">FIG. 381</figref>, this transfer is typically performed when ink is transferred from OEM's Ink Refill Device to another Ink Refill Device belonging to the same OEM, or OEM's Ink Refill Device to Ink Device belonging to the same OEM.
000026.4.2.1 Keys and Access Permission
6314There is an ink-remaining field associated with the refill device which transfers ink amounts to other refill devices (peer devices), or to other ink devices. This ink-remaining field has a single key associated with: <ul id="ul0873" list-style="none"><li id="ul0873-0001" num="0000"><ul id="ul0874" list-style="none"><li id="ul0874-0001" num="6315">This key transfers ink to the device from another refill device (which is higher or at the same level in the heirachy), fills/refills (upgrades) the device itself, and additionally transfers ink from it to other devices (which are lower in the heirachy), fills/refills (upgrades) other devices from it.</li></ul></li></ul>
6316This key is referred to as the fill/refill key and is used for both fill/refill and transfer. Hence, this key has both ReadWrite and Decrement-Only permission to the ink-remaining field in the refill device.
000026.4.2.1.1 Ink-remaining Field Information
6317Table 288 shows the field information for an <sub>M0 </sub>field storing logical ink-remaining amounts in the refill device with the ability to transfer between peers.
6318<tables id="TABLE-US-00467" num="00467"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="35pt" align="left" /><colspec colname="2" colwidth="126pt" align="left" /><colspec colname="3" colwidth="98pt" align="left" /><thead><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>Attribute</entry><entry /><entry /></row><row><entry>Name</entry><entry>Value</entry><entry>Explanation</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>Type</entry><entry>For e.g -</entry><entry>Type describing the logical</entry></row><row><entry /><entry>TYPE_HIGHQUALITY_BLACK_INK<sup>a</sup></entry><entry>ink stored in the ink-remaining</entry></row><row><entry /><entry /><entry>field in the refill device.</entry></row><row><entry>KeyNum</entry><entry>Slot number of the refill</entry><entry>Only the refill key has</entry></row><row><entry /><entry>key.</entry><entry>authenticated ReadWrite</entry></row><row><entry /><entry /><entry>access to this field.</entry></row><row><entry>Non Auth</entry><entry>0</entry><entry>Non authenticated ReadWrite</entry></row><row><entry>RW Perm<sup>b</sup></entry><entry /><entry>is not allowed to the field.</entry></row><row><entry>Auth RW</entry><entry>1</entry><entry>Authenticated (key based)</entry></row><row><entry>Perm<sup>c</sup></entry><entry /><entry>ReadWrite access is allowed</entry></row><row><entry /><entry /><entry>to the field.</entry></row><row><entry>KeyPerm</entry><entry>KeyPerms[KeyNum] = 1</entry><entry>KeyNum is the slot number of</entry></row><row><entry /><entry /><entry>the refill key, which has</entry></row><row><entry /><entry /><entry>ReadWrite and Decrement</entry></row><row><entry /><entry /><entry>permission to the field.</entry></row><row><entry /><entry>KeyPerms[others =</entry><entry>All other keys have</entry></row><row><entry /><entry>0 . . . 7(except</entry><entry>ReadOnly access.</entry></row><row><entry /><entry>KeyNum)] = 0</entry></row><row><entry>End Pos</entry><entry>Set as required.</entry><entry>Depends on the amount of</entry></row><row><entry /><entry /><entry>logical ink the device can</entry></row><row><entry /><entry /><entry>store and storage resolution -</entry></row><row><entry /><entry /><entry>i.e in picolitres or in</entry></row><row><entry /><entry /><entry>microlitres.</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry namest="1" nameend="3" align="left" id="FOO-00054"><sup>a</sup>This is a sample type only and is not included in the Type Map in Appendix A.</entry></row><row><entry namest="1" nameend="3" align="left" id="FOO-00055"><sup>b</sup>Non authenticated Read Write permission.</entry></row><row><entry namest="1" nameend="3" align="left" id="FOO-00056"><sup>c</sup>Authenticated Read Write permission.</entry></row></tbody></tgroup></table></tables><br /> 27 Functions <br /> 27.1 XferAmount <ul id="ul0875" list-style="none"><li id="ul0875-0001" num="0000"><ul id="ul0876" list-style="none"><li id="ul0876-0001" num="6319">Input: KeyRef, <sub>M0</sub>OfExternal, <sub>M1</sub>OfExternal, ChipID, FieldNumL, FieldNumE, XferValLength, XferVal, InputParameterCheck (optional), R<sub>E</sub>, SIG<sub>E</sub>, R<sub>E2 </sub></li><li id="ul0876-0002" num="6320">Output: ResultFlag, FieldSelect, FieldVal, R<sub>L2</sub>, SIG<sub>out </sub></li><li id="ul0876-0003" num="6321">Changes: <sub>M0 </sub>and R<sub>L </sub></li><li id="ul0876-0004" num="6322">Availability Ink refill QA Device <br /> 27.1.1 Function Description </li></ul></li></ul>
6323The XferAmount function produces data and signature for updating a given <sub>M0 </sub>field. This data and signature when applied to the appropriate device through the WriteFieldsAuth function, will update the <sub>M0 </sub>field of the device.
6324The system calls the XferAmount function on the upgrade device with a certain XferVal, this XferVal is validated by the XferAmount function for various rules as described in Section 27.1.4, the function then produces the data and signature for the passing into the WriteFieldsAuth function for the device being upgraded.
6325The transfer amount output consists of the new data for the field being upgraded, field data of the two sequence fields, and a signature using the refill key. When a transfer output is produced, the sequence field data in SEQ<sub>—</sub>1 is decremented by 2 from the previous value (as passed in with the input), and the sequence field data in SEQ 2 is decremented by 1 from the previous value (as passed in with the input).
6326Additional InputParameterCheck value must be provided for the parameters not included in the SIG<sub>E</sub>, if the transmission between the System and Ink Refill QA Device is error prone, and these errors are not corrected by the transimission protocol itself. InputParameterCheck is SHA-1[FieldNumL|FieldNumE|XferValLength|XferVal], and is required to ensure the integrity of these parameters, when these inputs are received by the Ink Refill QA Device. This will prevent an incorrect transfer amount being deducted.
6327The XferAmount function must first calculate the SHA-1[FieldNumL|FieldNumE|XferValLength|XferVal], compare the calculated value to the value received (InputParameterCheck) and only if the values match act upon the inputs.
000027.1.2 Input Parameters
6328Table 289 describes each of the output parameters for XferAmount function.
6329<tables id="TABLE-US-00468" num="00468"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="161pt" align="left" /><thead><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>Parameter</entry><entry>Description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>KeyRef</entry><entry>For comsmon key input and output signature:</entry></row><row><entry /><entry>KeyRef.keyNum = Slot number of the key to be</entry></row><row><entry /><entry>used for testing input signature and producing</entry></row><row><entry /><entry>the output signature. SIG<sub>E </sub>produced using</entry></row><row><entry /><entry>K<sub>KeyRef.keyNum </sub>by the QA Device being upgraded.</entry></row><row><entry /><entry>SIGout produced using K<sub>KeyRef.keyNum </sub>for delivery</entry></row><row><entry /><entry>to the QA Device being upgraded.</entry></row><row><entry /><entry>KeyRef.useChipId = 0</entry></row><row><entry /><entry>For variant key input and output signatures:</entry></row><row><entry /><entry>KeyRef.keyNum = Slot number of the key to be</entry></row><row><entry /><entry>used for generating the variant key. SIG<sub>E </sub>produced</entry></row><row><entry /><entry>using a variant of K<sub>KeyRef.keyNum </sub>by the QA Device</entry></row><row><entry /><entry>being upgraded. SIGout produced using a variant</entry></row><row><entry /><entry>of K<sub>KeyRef.keyNum </sub>for delivery to the QA Device</entry></row><row><entry /><entry>being upgraded.</entry></row><row><entry /><entry>KeyRef.useChipId = 1 KeyRef.chipId = ChipId of</entry></row><row><entry /><entry>the device which generated SIG<sub>E </sub>and will receive</entry></row><row><entry /><entry>SIGout.</entry></row><row><entry><sub>M0</sub>OfExternal</entry><entry>All 16 words of <sub>M0 </sub>of the QA Device being upgraded.</entry></row><row><entry><sub>M1</sub>OfExternal</entry><entry>All 16 words of <sub>M1 </sub>of the QA Device being upgraded.</entry></row><row><entry>ChipId</entry><entry>ChipId of the QA Device being upgraded.</entry></row><row><entry>FieldNumL</entry><entry><sub>M0 </sub>field number of the local (refill) device from</entry></row><row><entry /><entry>which the value will be transferred.</entry></row><row><entry>FieldNumE</entry><entry><sub>M0 </sub>field number of the QA Device being upgraded to</entry></row><row><entry /><entry>which the value will be transferred.</entry></row><row><entry>XferValLength</entry><entry>XferVal length in words. Non zero length required.</entry></row><row><entry>XferVal</entry><entry>The logical amount that will be transferred</entry></row><row><entry /><entry>from the local device to the external device.</entry></row><row><entry>R<sub>E</sub></entry><entry>External random value used to verify input</entry></row><row><entry /><entry>signature. This will be the R from the input</entry></row><row><entry /><entry>signature generator (i.e device generating SIG<sub>E</sub>).</entry></row><row><entry /><entry>The input signal generator in this case, is the</entry></row><row><entry /><entry>device being upgraded or a translation device.</entry></row><row><entry>R<sub>E2</sub></entry><entry>External random value used to produce output</entry></row><row><entry /><entry>signature. This will be R obtained by calling</entry></row><row><entry /><entry>the Random function on the device which will</entry></row><row><entry /><entry>receive the SIG<sub>out </sub>from the XferAmount function.</entry></row><row><entry /><entry>The device receiving the SIG<sub>out</sub>, in this case,</entry></row><row><entry /><entry>is the device being upgraded or a translation</entry></row><row><entry /><entry>device.</entry></row><row><entry>SIG<sub>E</sub></entry><entry>External signature required for authenticating</entry></row><row><entry /><entry>input data. The input data in this case, is the</entry></row><row><entry /><entry>output from the Read function performed on the</entry></row><row><entry /><entry>device being upgraded.</entry></row><row><entry /><entry>A correct SIG<sub>E </sub>= SIG<sub>KeyRef</sub>(Data | R<sub>E </sub>| R<sub>L</sub>).</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 27.1.2.1 Input Signature Verification Data Format
6330The input signature passed in to the XferAmount function is the output signature from the Read function of the Ink QA Device.
6331<figref idref="DRAWINGS">FIG. 382</figref> shows the input signature verification data format for the XferAmount function.
6332Table 277 gives the parameters included in SIG<sub>E </sub>for XferAmount function.
6333<tables id="TABLE-US-00469" num="00469"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="42pt" align="center" /><colspec colname="3" colwidth="56pt" align="left" /><colspec colname="4" colwidth="63pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="4" align="center" rowsep="1" /></row><row><entry /><entry /><entry>Length</entry><entry>Value set</entry><entry>Value set</entry></row><row><entry /><entry>Parameter</entry><entry>in bits</entry><entry>internally</entry><entry>from Input</entry></row><row><entry /><entry namest="offset" nameend="4" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="42pt" align="char" char="." /><colspec colname="3" colwidth="56pt" align="left" /><colspec colname="4" colwidth="63pt" align="left" /><tbody valign="top"><row><entry /><entry>RWSense</entry><entry>3</entry><entry>000</entry><entry /></row><row><entry /><entry /><entry /><entry>Refer to</entry></row><row><entry /><entry /><entry /><entry>Section</entry></row><row><entry /><entry /><entry /><entry>15.3.1.1</entry></row><row><entry /><entry>MSelect</entry><entry>4</entry><entry>0011</entry></row><row><entry /><entry>KeyIdSelect</entry><entry>8</entry><entry>00000000</entry></row><row><entry /><entry>ChipId</entry><entry>48</entry><entry /><entry>ChipId of the</entry></row><row><entry /><entry /><entry /><entry /><entry>QA Device being</entry></row><row><entry /><entry /><entry /><entry /><entry>upgraded</entry></row><row><entry /><entry>WordSelect</entry><entry>16</entry><entry>All bits</entry></row><row><entry /><entry>for M<sub>0</sub></entry><entry /><entry>set to 1</entry></row><row><entry /><entry>WordSelect</entry><entry>16</entry><entry>All bits</entry></row><row><entry /><entry>for M<sub>1</sub></entry><entry /><entry>set to 1</entry></row><row><entry /><entry>M0</entry><entry>512</entry><entry /><entry>●</entry></row><row><entry /><entry>M1</entry><entry>512</entry><entry /><entry>●</entry></row><row><entry /><entry>R<sub>E</sub></entry><entry>160</entry><entry /><entry>●</entry></row><row><entry /><entry>R<sub>L</sub></entry><entry>160</entry><entry>Based on the</entry><entry>●</entry></row><row><entry /><entry /><entry /><entry>internal R</entry></row><row><entry /><entry namest="offset" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
6334The XferAmount function is not passed all the parameters required to generate SIG<sub>E</sub>. For producing SIG<sub>L </sub>which is used to test SIG<sub>E</sub>, the function uses the expected values of some the parameters.
000027.1.3 Output Parameters
0000<ul id="ul0877" list-style="none"><li id="ul0877-0001" num="0000"><ul id="ul0878" list-style="none"><li id="ul0878-0001" num="6335">Table 291 describes each of the output parameters for XferAmount.</li></ul></li></ul>
6336<tables id="TABLE-US-00470" num="00470"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="161pt" align="left" /><thead><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>Parameter</entry><entry>Description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>ResultFlag</entry><entry>Indicates whether the function completed</entry></row><row><entry /><entry>successfully or not. If it did not complete</entry></row><row><entry /><entry>successfully, the reason for the failure is</entry></row><row><entry /><entry>returned here. See Table 47.</entry></row><row><entry>FieldSelect</entry><entry>Selection of fields to be written</entry></row><row><entry /><entry>In this case the bit corresponding to SEQ_1 ,</entry></row><row><entry /><entry>SEQ_2 and to FieldNumE are set to 1.</entry></row><row><entry /><entry>All other bits are set to 0.</entry></row><row><entry>FieldVal</entry><entry>Updated data words for Sequence data field</entry></row><row><entry /><entry>and FieldNumE for QA Device being upgraded.</entry></row><row><entry /><entry>Starts with LSW of lower field.</entry></row><row><entry /><entry>This must be passed as input to the WriteFieldsAuth</entry></row><row><entry /><entry>function of the QA Device being upgraded.</entry></row><row><entry>R<sub>L2</sub></entry><entry>Internal random value required to generate</entry></row><row><entry /><entry>output signature. This must be passed as input</entry></row><row><entry /><entry>to the WriteFieldsAuth function or Translate</entry></row><row><entry /><entry>function of the QA Device being upgraded.</entry></row><row><entry>SIG<sub>out</sub></entry><entry>Output signature which must be passed as an input</entry></row><row><entry /><entry>to the WriteFieldsAuth function of the QA Device</entry></row><row><entry /><entry>being upgraded.</entry></row><row><entry /><entry>SIG<sub>out </sub>= SIG<sub>KeyRef</sub>(data | R<sub>L2 </sub>| R<sub>E2</sub>) as</entry></row><row><entry /><entry>per FIG. 373.</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><ul id="ul0879" list-style="none"><li id="ul0879-0001" num="0000"><ul id="ul0880" list-style="none"><li id="ul0880-0001" num="6337">Table 292. Result Flag definitions for XferAmount</li></ul></li></ul>
6338<tables id="TABLE-US-00471" num="00471"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 292</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Result Flag definitions for XferAmount</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="98pt" align="left" /><colspec colname="2" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>ResultFlag Definition</entry><entry>Description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>FieldNumEInvalid</entry><entry>FieldNum to which the amount is</entry></row><row><entry /><entry>being transferred, or which is</entry></row><row><entry /><entry>being upgraded in the QA Device</entry></row><row><entry /><entry>being upgraded is invalid.</entry></row><row><entry>SeqFieldInvalid</entry><entry>The sequence field for the QA</entry></row><row><entry /><entry>Device being upgraded is invalid.</entry></row><row><entry>FieldNumEWritePermInvalid</entry><entry>FieldNum to which the amount is</entry></row><row><entry /><entry>being transferred, or which is</entry></row><row><entry /><entry>being upgraded in the QA Device</entry></row><row><entry /><entry>being upgraded has no authenti-</entry></row><row><entry /><entry>cated write permission.</entry></row><row><entry>FieldNumLInvalid</entry><entry>FieldNum from which the amount</entry></row><row><entry /><entry>is being transferred, or from</entry></row><row><entry /><entry>which the value is being copied</entry></row><row><entry /><entry>in the Upgrading QA Device is</entry></row><row><entry /><entry>invalid.</entry></row><row><entry>FieldNumLWritePermInvalid</entry><entry>FieldNum from which the amount</entry></row><row><entry /><entry>is being transferred in the</entry></row><row><entry /><entry>Upgrading QA Device has no au-</entry></row><row><entry /><entry>thenticated permission, or no</entry></row><row><entry /><entry>authenticated permission with</entry></row><row><entry /><entry>the KeyRef.</entry></row><row><entry>TypeMismatch</entry><entry>Type of the data from which the</entry></row><row><entry /><entry>amount is being transferred in</entry></row><row><entry /><entry>the Upgrading QA Device, doesn't</entry></row><row><entry /><entry>match the Type of data to which</entry></row><row><entry /><entry>the amount in being transferred</entry></row><row><entry /><entry>in the Device being upgraded.</entry></row><row><entry>UpgradeFieldEInvalid</entry><entry>Only applicable for transferring</entry></row><row><entry /><entry>count-remaining values. The upgrade</entry></row><row><entry /><entry>field associated with the count-</entry></row><row><entry /><entry>remaining field in the QA Device</entry></row><row><entry /><entry>being upgraded is invalid.</entry></row><row><entry>UpgradeFieldLInvalid</entry><entry>Only applicable for transferring</entry></row><row><entry /><entry>count-remaining values. The upgrade</entry></row><row><entry /><entry>field associated with the count-</entry></row><row><entry /><entry>remaining field in the Upgrading</entry></row><row><entry /><entry>QA Device is invalid.</entry></row><row><entry>UpgradeFieldMismatch</entry><entry>Only applicable for transferring</entry></row><row><entry /><entry>count-remaining values. Type of</entry></row><row><entry /><entry>the data in the upgrade field in</entry></row><row><entry /><entry>the Upgrading QA Device, doesn't</entry></row><row><entry /><entry>match the Type of data in the</entry></row><row><entry /><entry>upgrade field in the Device being</entry></row><row><entry /><entry>upgraded.</entry></row><row><entry>FieldNumESizeInsufficient</entry><entry>FieldNum to which the amount is</entry></row><row><entry /><entry>being transferred, or which is</entry></row><row><entry /><entry>being upgraded in the QA Device is</entry></row><row><entry /><entry>not big enough to store the trans-</entry></row><row><entry /><entry>ferred data.</entry></row><row><entry>FieldNumLAmountInsufficient</entry><entry>FieldNum in the Upgrading QA Device</entry></row><row><entry /><entry>from which the amount is being</entry></row><row><entry /><entry>transferred doesn't have the amount</entry></row><row><entry /><entry>required for the transfer.</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 27.1.3.1 SIG<sub>out </sub><ul id="ul0881" list-style="none"><li id="ul0881-0001" num="0000"><ul id="ul0882" list-style="none"><li id="ul0882-0001" num="6339">Refer to Section 20.2.1 for details. <br /> 27.1.4 Function Sequence </li><li id="ul0882-0002" num="6340">The XferAmount command is illustrated by the following pseudocode:</li></ul></li></ul>
6341<tables id="TABLE-US-00472" num="00472"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>Accept input parameters-KeyRef, M0OfExternal, M1OfExternal,</entry></row><row><entry /><entry>ChipId, FieldNumL, FieldNumE, XferValLength</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry># Accept XferVal words</entry></row><row><entry /><entry>For i <img file="US7165824B2_D0545.tif" /> 0 to XferValLength</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>Accept next XferVal</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>EndFor</entry></row><row><entry /><entry>Accept R<sub>E</sub>, SIG<sub>E</sub>, R<sub>E2</sub></entry></row><row><entry /><entry>#Generate message for passing into ValidateKeyRefAndSignature</entry></row><row><entry /><entry>function</entry></row><row><entry /><entry>data <img file="US7165824B2_D0546.tif" /> (RWSense|MSelect|KeyIdSelect|ChipId|WordSelect|M0|M1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry># Refer to Figure 382.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>----------------------------------------------------------------</entry></row><row><entry /><entry># Validate KeyRef, and then verify signature</entry></row><row><entry /><entry>ResultFlag = ValidateKeyRefAndSignature(KeyRef,data,R<sub>E</sub>,R<sub>L</sub>)</entry></row><row><entry /><entry>If (ResultFlag ≠ Pass)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>----------------------------------------------------------------</entry></row><row><entry /><entry>#Validate FieldNumE</entry></row><row><entry /><entry># FieldNumE is present in the device being upgraded</entry></row><row><entry /><entry>PresentFlagFieldNumE <img file="US7165824B2_D0547.tif" /> GetFieldPresent(M1OfExternal,FieldNumE)</entry></row><row><entry /><entry># Check FieldNumE present flag</entry></row><row><entry /><entry>If(PresentFlagFieldNumE ≠ 1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0548.tif" /> FieldNumEInvalid</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>------------------------------------------------------------------</entry></row><row><entry /><entry>---------------</entry></row><row><entry /><entry># Check Seq Fields Exist and get their Field Num</entry></row><row><entry /><entry># Get Seqdata field SEQ_1 num for the device being upgraded</entry></row><row><entry /><entry>XferSEQ_1FieldNum<img file="US7165824B2_D0549.tif" /> GetFieldNum(M1OfExternal, SEQ_1)</entry></row><row><entry /><entry># Check if the Seqdata field SEQ_1 is valid</entry></row><row><entry /><entry>If(XferSEQ_1FieldNum invalid)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0550.tif" /> SeqFieldInvalid</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry># Get Seqdata field SEQ_2 num for the device being upgraded</entry></row><row><entry /><entry>XferSEQ_2FieldNum<img file="US7165824B2_D0551.tif" /> GetFieldNum(M1OfExternal, SEQ_2)</entry></row><row><entry /><entry># Check if the Seqdata field SEQ_2 is valid</entry></row><row><entry /><entry>If(XferSEQ_2FieldNum invalid)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0552.tif" /> SeqFieldInvalid</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>----------------------------------------------------------------</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>#Check write permission for FieldNumE</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>PermOKFieldNumE <img file="US7165824B2_D0553.tif" /> CheckFieldNumEPerm(M1OfExternal,FieldNumE)</entry></row><row><entry /><entry>If(PermOKFieldNumE ≠ 1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0554.tif" /> FieldNumEWritePermInvalid</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>----------------------------------------------------------------</entry></row><row><entry /><entry>#Check that both SeqData fields have Decrement-Only permission</entry></row><row><entry /><entry>with the same key</entry></row><row><entry /><entry>#that has write permission on FieldNumE</entry></row><row><entry /><entry>PermOKXferSeqData <img file="US7165824B2_D0555.tif" /> CheckSeqDataFieldPerms(M1OfExternal,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="84pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>XferSEQ_1FieldNum,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>XferSEQ_2FieldNum,FieldNumE)</entry></row><row><entry /><entry>If(PermOKXferSeqData ≠ 1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0556.tif" /> SeqWritePermInvalid</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>----------------------------------------------------------------</entry></row><row><entry /><entry># Get SegData SEQ_1 data from device being upgraded</entry></row><row><entry /><entry>GetFieldDataWords(XferSEQ_1FieldNum,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>XferSEQ_1DataFromDevice,M0OfExternal, M1OfExternal)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry># Get SeqData SEQ_2 data from device being upgraded</entry></row><row><entry /><entry>GetFieldDataWords(XferSEQ_2FieldNum,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="84pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>XferSEQ_2DataFromDevice,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>M0OfExternal,M1OfExternal)</entry></row><row><entry /><entry>----------------------------------------------------------------</entry></row><row><entry /><entry># FieldNumL is a present in the refill device</entry></row><row><entry /><entry>PresentFlagFieldNumL <img file="US7165824B2_D0557.tif" /> GetFieldPresent(M1,FieldNumL)</entry></row><row><entry /><entry>If(PresentFlagFieldNumL ≠ 1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0558.tif" /> FieldNumLInvalid</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>#Check permission for FieldNumL</entry></row><row><entry /><entry>PermOKFieldNumL <img file="US7165824B2_D0559.tif" /> CheckFieldNumLPerm(M1,FieldNumL,KeyRef)</entry></row><row><entry /><entry>If(PermOKFieldNumL ≠ 1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0560.tif" /> FieldNumLWritePermInvalid</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>----------------------------------------------------------------</entry></row><row><entry /><entry>#Find the type attribute for FieldNumE</entry></row><row><entry /><entry>TypeFieldNumE <img file="US7165824B2_D0561.tif" /> FindFieldNumType(M1OfExternal,FieldNumE)</entry></row><row><entry /><entry>#Find the type attribute for FieldNumL</entry></row><row><entry /><entry>TypeFieldNumL <img file="US7165824B2_D0562.tif" /> FindFieldNumType(M1,FieldNumL)</entry></row><row><entry /><entry># Check type attribute for both fields match</entry></row><row><entry /><entry>If(TypeFieldNumE ≠TypeFieldNumL)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0563.tif" /> TypeMismatch</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>----------------------------------------------------------------</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>-----------------------------------------------------------------------</entry></row><row><entry /><entry>Do this if the Refill Device is transferring Count-remaining for Printer</entry></row><row><entry /><entry>upgrades</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry># If the Type is count remaining, check that upgrade values</entry></row><row><entry /><entry>associated with</entry></row><row><entry /><entry># the count remaining are valid. Refer to Section 28. for further</entry></row><row><entry /><entry>details on</entry></row><row><entry /><entry># count remaining and upgrade value.</entry></row><row><entry /><entry>If(TypeFieldNumL = TYPE_COUNT_REMAINING)<img file="US7165824B2_D0564.tif" /> (TypeFieldNumE</entry></row><row><entry /><entry>=TYPE_COUNT_REMAINING)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>#Upgrade value field is lower adjoining field</entry></row><row><entry /><entry>UpgradeValueFieldNumE = FieldNumE −1</entry></row><row><entry /><entry>If(UpgradeValueFieldNumE < 0) # upgrade field doesn't exist for</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>QA Device being upgraded</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0565.tif" /> UpgradeFieldEInvalid</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>UpgradeValueFieldNumL = FieldNumL − 1</entry></row><row><entry /><entry>If(UpgradeValueFieldNumL < 0) # upgrade field doesn't exist for</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>local device</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0566.tif" /> UpgradeFieldLInvalid</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>UpgradeValueCheckOK <img file="US7165824B2_D0567.tif" /></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>UpgradeValCheck(UpgradeValueFieldNumL,M0,M1,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>UpgradeValueFieldNumL,M0OfExternal,M1OfExternal,KeyRef)</entry></row><row><entry /><entry>If(UpgradeValueCheckOK = 0)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0568.tif" /> UpgradeFieldMismatch</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry># Do this if Field Type is Count Remaining........end</entry></row><row><entry /><entry>----------------------------------------------------------------</entry></row><row><entry /><entry>#Check whether the device being upgraded can hold the transfer</entry></row><row><entry /><entry>amount</entry></row><row><entry /><entry>#(XferVal + AmountLeft</entry></row><row><entry /><entry>OverFlow <img file="US7165824B2_D0569.tif" /> CanHold(FieldNumE,M0OfExternal,XferVal)</entry></row><row><entry /><entry>If OverFlow error</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0570.tif" /> FieldNumESizeInsufficient</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>----------------------------------------------------------------</entry></row><row><entry /><entry>#Check the refill device has the desired amount (XferVal < =</entry></row><row><entry /><entry>AmountLeft)</entry></row><row><entry /><entry>UnderFlow <img file="US7165824B2_D0571.tif" /> HasAmount(FieldNumL,M0,XferVal)</entry></row><row><entry /><entry>If UnderFlow error</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0572.tif" /> FieldNumLAmountInsufficient</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>----------------------------------------------------------------</entry></row><row><entry /><entry># All checks complete .....</entry></row><row><entry /><entry># Generate Seqdata for SEQ_1 and SEQ_2 fields</entry></row><row><entry /><entry>XferSEQ_1DataToDevice = XferSEQ_1DataFromDevice − 2</entry></row><row><entry /><entry>XferSEQ_2DataToDevice = XferSEQ_2DataFromDevice − 1</entry></row><row><entry /><entry># Add DataSet to Xfer Entry Cache</entry></row><row><entry /><entry>AddDataSetToXferEntryCache(ChipId,FieldNumE, FieldNumL,</entry></row><row><entry /><entry>XferLength, XferVal, XferSEQ_1DataFromDevice,</entry></row><row><entry /><entry>XferSEQ_2DataFromDevice)</entry></row><row><entry /><entry># Get current FieldDataE field data words to write to Xfer Entry</entry></row><row><entry /><entry>cache</entry></row><row><entry /><entry>GetFieldDataWords(FieldNumE,FieldDataE,M0OfExternal,M1OfExternal)</entry></row><row><entry /><entry>#Deduct XferVal from FieldNumL and Write new value</entry></row><row><entry /><entry>DeductAndWriteValToFieldNumL(XferVal,FieldNumL,M0)</entry></row><row><entry /><entry>#Generate new field data words for FieldNumE. The current</entry></row><row><entry /><entry>FieldDataE is added to</entry></row><row><entry /><entry># XferVal to generate new FieldDataE</entry></row><row><entry /><entry>GenerateNewFieldData(FieldNumE,XferVal,FieldDataE)</entry></row><row><entry /><entry># Generate FieldSelect and FieldVal for SeqData field SEQ_1,SEQ_2</entry></row><row><entry /><entry>and</entry></row><row><entry /><entry># FieldDataE...</entry></row><row><entry /><entry>CurrentFieldSelect<img file="US7165824B2_D0573.tif" /> 0</entry></row><row><entry /><entry>FieldVal <img file="US7165824B2_D0574.tif" /> 0</entry></row><row><entry /><entry>GenerateFieldSelectAndFieldVal(FieldNumE, FieldDataE,</entry></row><row><entry /><entry>XferSEQ_1FieldNum, XferSEQ_1DataToDevice,XferSEQ_2FieldNum,</entry></row><row><entry /><entry>XferSEQ_2DataToDevice,</entry></row><row><entry /><entry>FieldSelect,FieldVal)</entry></row><row><entry /><entry>#Generate message for passing into GenerateSignature function</entry></row><row><entry /><entry>data <img file="US7165824B2_D0575.tif" /> (RWSense|FieldSelect|ChipId|FieldVal)# Refer to Figure 373.</entry></row><row><entry /><entry>#Create output signature for FieldNumE</entry></row><row><entry /><entry>SIG<sub>out</sub><img file="US7165824B2_D0576.tif" /> GenerateSignature(KeyRef,data,R<sub>L2</sub>,R<sub>E2</sub>)</entry></row><row><entry /><entry>Update R<sub>L2 </sub>to R<sub>L3</sub></entry></row><row><entry /><entry>ResultFlag <img file="US7165824B2_D0577.tif" /> Pass</entry></row><row><entry /><entry>Output ResultFlag, FieldData, R<sub>L2 ,</sub>SIG<sub>out</sub></entry></row><row><entry /><entry>Return</entry></row><row><entry /><entry>EndIf</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 27.1.4.1 ResultFlag ValidateKeyRefAndSignature(KeyRef,data,R<sub>E</sub>,R<sub>L</sub>)
6342This function checks KeyRef is valid, and if KeyRef is valid, then input signature is verified using KeyRef.
6343<tables id="TABLE-US-00473" num="00473"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>CheckRange(KeyRef.keyNum)</entry></row><row><entry /><entry>If invalid</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0578.tif" /> InValidKey</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>#Generate message for passing into GenerateSignature function</entry></row><row><entry /><entry>data <img file="US7165824B2_D0579.tif" /> (RWSense|MSelect|KeyIdSelect|ChipId|WordSelect|M0|M1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry># Refer to Figure 382.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>#Generate Signature</entry></row><row><entry /><entry>SIG<sub>L </sub><img file="US7165824B2_D0580.tif" /> GenerateSignature(KeyRef,data,R<sub>E</sub>,R<sub>L</sub>)</entry></row><row><entry /><entry># Check input signature SIG<sub>E</sub></entry></row><row><entry /><entry>If(SIG<sub>L </sub>= SIG<sub>E</sub>)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Update R<sub>L </sub>to R<sub>L2</sub></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0581.tif" /> Bad Signature</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 27.1.4.2 GenerateFieldSelectAndFieldVal (FieldNumE, FieldDataE, XferSEQ<sub>—</sub>1FieldNum, XferSEQ<sub>—</sub>1DataToDevice, XferSEQ<sub>—</sub>2FieldNum, XferSEQ<sub>—</sub>2DataToDevice, FieldSelect, FieldVal)
6344This functions generates the FieldSelect and FieldVal for output from FieldNumE and its final data, and data to be written to Seq fields SEQ<sub>—</sub>1 and SEQ<sub>—</sub>2.
000027.1.4.3 PresentFlag GetFieldPresent(M1,FieldNum)
6345This function checks whether FieldNum is a valid.
6346<tables id="TABLE-US-00474" num="00474"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>FieldSize[16] <img file="US7165824B2_D0582.tif" /> 0 # Array to hold FieldSize assuming there are 16</entry></row><row><entry>fields</entry></row><row><entry>NumFields<img file="US7165824B2_D0583.tif" /> FindNumberOfFieldsInM0(M1,FieldSize) #Refer to Section</entry></row><row><entry>19.4.1</entry></row><row><entry>If(FieldNum< NumFields)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>PresentFlag<img file="US7165824B2_D0584.tif" /> 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>PresentFlag<img file="US7165824B2_D0585.tif" /> 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>Return PresentFlag</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 27.1.4.4 NumFields FindNumOfFieldsInM0(M1,FieldSize<img file="US7165824B2_D0586.tif" />)
6347Refer to Figure 19.4.1 for details.
000027.1.4.5 FieldNum GetFieldNum(M1, Type)
6348This function returns the field number based on the Type.
6349<tables id="TABLE-US-00475" num="00475"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>FieldSize[16] <img file="US7165824B2_D0587.tif" /> 0 # Array to hold FieldSize assuming there are 16</entry></row><row><entry>fields</entry></row><row><entry>NumFields<img file="US7165824B2_D0588.tif" /> FindNumberOfFieldsInM0(M1,FieldSize) #Refer to Section</entry></row><row><entry>19.4.1</entry></row><row><entry>For i = 0 to NumFields</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>If(M1[i].Type = Type)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Return i # This is field Num for matching field</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndFor</entry></row><row><entry>i = 255 # If XferSession field was not found then return an</entry></row><row><entry>invalid value</entry></row><row><entry>Return i</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 27.1.4.6 PermOK CheckFieldNumEPerm(M1,FieldNumE)
6350This function checks authenticated write permission for FieldNum which holds the upgraded value.
6351<tables id="TABLE-US-00476" num="00476"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>AuthRW <img file="US7165824B2_D0589.tif" /> M1[FieldNum].AuthRW</entry></row><row><entry /><entry>NonAuthRW <img file="US7165824B2_D0590.tif" /> M1[FieldNum].NonAuthRW</entry></row><row><entry /><entry>If(AuthRW = 1) <img file="US7165824B2_D0591.tif" /> (NonAuthRW = 0)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>PermOK <img file="US7165824B2_D0592.tif" /> 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>PermOK <img file="US7165824B2_D0593.tif" /> 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>Return PermOK</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 27.1.4.7 PermOK CheckSeqDataFieldPerms(M1, XferSEQ<sub>—</sub>1FieldNum, XferSEQ<sub>—</sub>2FieldNum, FieldNumE)
6352This function checks that both SeqData fields have Decrement-Only permission with the same key that has write permission on FieldNumE.
6353<tables id="TABLE-US-00477" num="00477"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>KeyNumForFieldNumE <img file="US7165824B2_D0594.tif" /> M1[FieldNumE].KeyNum # Isolate KeyNum for the</entry></row><row><entry>field that will</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="119pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry># be upgraded</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry># Isolate KeyNum for both SeqData fields and check that they can</entry></row><row><entry>be written using the same key</entry></row><row><entry>KeyNumForSEQ_1 <img file="US7165824B2_D0595.tif" /> M1[XferSEQ_1FieldNum].KeyNum</entry></row><row><entry>KeyNumForSEQ_2 <img file="US7165824B2_D0596.tif" /> M1[XferSEQ_2FieldNum].KeyNum</entry></row><row><entry>If(KeyNumForSEQ_1 ≠KeyNumForSEQ_2)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>PermOK <img file="US7165824B2_D0597.tif" /> 0</entry></row><row><entry /><entry>Return PermOK</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry># Check that the write key for FieldNumE and SeqData field is not</entry></row><row><entry>the same</entry></row><row><entry>If (KeyNumForSEQ_1 = KeyNumForFieldNumE)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>PermOK <img file="US7165824B2_D0598.tif" /> 0</entry></row><row><entry /><entry>Return PermOK</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>#Isolate Decrement-Only permissions with the write key of</entry></row><row><entry>FieldNumE</entry></row><row><entry>KeyPermsSEQ_1 <img file="US7165824B2_D0599.tif" /> M1[XferSEQ_1FieldNum].KeyPerms[KeyNumForFieldNumE]</entry></row><row><entry>KeyPermsSEQ_2 <img file="US7165824B2_D0600.tif" /> M1[XferSEQ_2FieldNum].KeyPerms[KeyNumForFieldNumE]</entry></row><row><entry># Check that both sequence fields have Decrement-Only permission</entry></row><row><entry>for this key</entry></row><row><entry>If(KeyPermsSEQ_1 =0) <img file="US7165824B2_D0601.tif" /> (KeyPermsSEQ_2 = 0)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>PermOK <img file="US7165824B2_D0602.tif" /> 0</entry></row><row><entry /><entry>Return PermOK</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>PermOK <img file="US7165824B2_D0603.tif" /> 1</entry></row><row><entry>Return PermOK</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 27.1.4.8 AddDataSetToXferEntryCache (ChipID, FieldNumE, FieldNumL, XferVal, SEQ<sub>—</sub>1Data, SEQ<sub>—</sub>2Data)
6354This function adds a new dataset to the Xfer Entry cache. Dataset is a single record in the Xfer Entrycache. Refer to Section 27 for details.
6355<tables id="TABLE-US-00478" num="00478"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="196pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry># Search for matching ChipId FieldNumE is Cache</entry></row><row><entry /><entry>DataSet <img file="US7165824B2_D0604.tif" /> SearchDataSetInCache (ChipId, FieldNumE)</entry></row><row><entry /><entry># If found</entry></row><row><entry /><entry>If(DataSet is valid)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>DeleteDataSetInCache(DataSet) # This creates a</entry></row><row><entry /><entry>vacant dataset</entry></row><row><entry /><entry>AddRecordToCache(ChipId, FieldNumE,FieldDataL,</entry></row><row><entry /><entry>XferVal,SEQ_1Data,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="196pt" align="left" /><tbody valign="top"><row><entry /><entry>SEQ_2Data)</entry></row><row><entry /><entry>EndIf</entry></row><row><entry /><entry># Searches the cache for XferState complete/deleted</entry></row><row><entry /><entry>Found<img file="US7165824B2_D0605.tif" /> SearchRecordsInCache(complete/deleted)</entry></row><row><entry /><entry>If(Found =1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>AddRecordToCache(ChipId, FieldNumE,FieldDataL,</entry></row><row><entry /><entry>XferVal,SEQ_1Data,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="196pt" align="left" /><tbody valign="top"><row><entry /><entry>SEQ_2Data)</entry></row><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry># This will overwrite the oldest DataSet in cache</entry></row><row><entry /><entry>AddRecordToCache(ChipId, FieldNumE,FieldDataL,</entry></row><row><entry /><entry>XferVal,SEQ_1Data,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="196pt" align="left" /><tbody valign="top"><row><entry /><entry>SEQ_2Data)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="196pt" align="left" /><tbody valign="top"><row><entry /><entry>Endif</entry></row><row><entry /><entry>Set XferState in record to Xfer</entry></row><row><entry /><entry>Return</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 27.1.4.9 FieldType FindFieldNumType(M1,FieldNum) <ul id="ul0883" list-style="none"><li id="ul0883-0001" num="0000"><ul id="ul0884" list-style="none"><li id="ul0884-0001" num="6356">This function gets the Type attribute for a given field.</li></ul></li><li id="ul0883-0002" num="6357">FieldType←M1[FieldNum].Type</li><li id="ul0883-0003" num="6358">Return FieldType <br /> 27.1.4.10 PermOK CheckFieldNumLPerm(M1, FieldNumL, KeyRef) </li></ul>
6359This function checks authenticated write permissions using KeyRef for FieldNumL in the refill device.
6360<tables id="TABLE-US-00479" num="00479"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>AuthRW <img file="US7165824B2_D0606.tif" /><sub>M1</sub>[FieldNumL].AuthRW</entry></row><row><entry>KeyNumAtt <img file="US7165824B2_D0607.tif" /><sub>M1</sub>[FieldNumL].KeyNum</entry></row><row><entry>DOForKeys <img file="US7165824B2_D0608.tif" /><sub>M1</sub>[FieldNumL].DOForKeys[KeyNum]</entry></row><row><entry># Authenticated write allowed</entry></row><row><entry># ReadWrite key for field is the same as Input KeyRef.keyNum</entry></row><row><entry># Key has both ReadWrite and DecrementOnly Permission</entry></row><row><entry>If(AuthRW = 1) <img file="US7165824B2_D0609.tif" /> (KeyRef.keyNum = KeyNumAtt) <img file="US7165824B2_D0610.tif" /> (DOForKeys = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>PermOK<img file="US7165824B2_D0611.tif" /> 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>PermOK<img file="US7165824B2_D0612.tif" /> 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>Return PermOK</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 27.1.4.11 CheckOK UpgradeValCheck(FieldNum1, M0OfFieldNum1, M1OfFieldNum1, FieldNum2, M0OfFieldNum2, M1OfFieldNum2,KeyRef)
6361This function checks the upgrade value corresponding to the count remaining. The upgrade value corresponding to the count remaining field is stored in the lower adjoining field. To upgrade the count remaining field, the upgrade value in refill device and the device being upgraded must match.
6362<tables id="TABLE-US-00480" num="00480"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>#Check authenticated write permissions is allowed to the field</entry></row><row><entry>#Check that only one key has ReadWrite access,</entry></row><row><entry>#and all other keys are ReadOnly access</entry></row><row><entry>PermCheckOKFieldNum1</entry></row><row><entry><img file="US7165824B2_D0613.tif" /> CheckUpgradeKeyForField(FieldNum1,M1OfFieldNum1,KeyRef)</entry></row><row><entry>If(PermCheckOKFieldNum1 ≠ 1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>CheckOK <img file="US7165824B2_D0614.tif" /> 0</entry></row><row><entry /><entry>Return CheckOK</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>PermCheckOKFieldNum2</entry></row><row><entry><img file="US7165824B2_D0615.tif" /> CheckUpgradeKeyForField(FieldNum2,M1OfFieldNum2,KeyRef)</entry></row><row><entry>If(PermCheckOKFieldNum2 ≠ 1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>CheckOK <img file="US7165824B2_D0616.tif" /> 0</entry></row><row><entry /><entry>Return CheckOK</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry># Get the upgrade value associated with field</entry></row><row><entry>GetFieldDataWords(FieldNum1,UpgradeValueFieldNum1,</entry></row><row><entry>M0OfFieldNum1,</entry></row><row><entry>M1ofFieldNum1)</entry></row><row><entry># Get the upgrade value associated with field</entry></row><row><entry>GetFieldDataWords(FieldNum2,UpgradeValueFieldNum2,</entry></row><row><entry>M0OfFieldNum2,</entry></row><row><entry>M1OfFieldNum2)</entry></row><row><entry>If(UpgradeValueFieldNuml ≠ UpgradeValueFieldNum2)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>CheckOK <img file="US7165824B2_D0617.tif" /> 0</entry></row><row><entry /><entry>Return CheckOK</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry># Get the type attribute for the field</entry></row><row><entry>UpgradeTypeFieldNum1<img file="US7165824B2_D0618.tif" /> GetUpgradeType(FieldNum1,M1OfFieldNum1)</entry></row><row><entry>UpgradeTypeFieldNum2<img file="US7165824B2_D0619.tif" /> GetUpgradeType(FieldNum2,M1OfFieldNum2)</entry></row><row><entry>If(UpgradeTypeFieldNum1 ≠ UpgradeTypeFieldNum2)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>CheckOK <img file="US7165824B2_D0620.tif" /> 0</entry></row><row><entry /><entry>Return CheckOK</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>CheckOK <img file="US7165824B2_D0621.tif" /> 1</entry></row><row><entry>Return CheckOK</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 27.1.4.12 CheckOK CheckUpgradeKeyForField(FieldNum,M1,KeyRef)
6363This function checks that authenticated write permissions is allowed to the field. It also checks that only one key has ReadWrite access and all other keys have ReadOnly access. KeyRef which updates count remaining must not have write access to the upgarde value field.
6364<tables id="TABLE-US-00481" num="00481"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>KeyNum <img file="US7165824B2_D0622.tif" /> M1[FieldNum].KeyNum</entry></row><row><entry>AuthRW <img file="US7165824B2_D0623.tif" /> M1[FieldNum].AuthRW</entry></row><row><entry>NonAuthRW <img file="US7165824B2_D0624.tif" /> M1[FieldNum].NonAuthRW</entry></row><row><entry>DOForKeys<img file="US7165824B2_D0625.tif" /> M1[FieldNum].DOForKeys</entry></row><row><entry>#Check that KeyRef doesn't have write permissions to the field</entry></row><row><entry>If(KeyRef.keyNum = KeyNum)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>CheckOK <img file="US7165824B2_D0626.tif" /> 0</entry></row><row><entry /><entry>Return CheckOK</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>#AuthRW access allowed or NonAuthRW not allowed</entry></row><row><entry>If(AuthRW = 0) <img file="US7165824B2_D0627.tif" /> (NonAuthRW =1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>CheckOK <img file="US7165824B2_D0628.tif" /> 0</entry></row><row><entry /><entry>Return CheckOK</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>For i <img file="US7165824B2_D0629.tif" /> 0 to 7</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry># Keys other than KeyNum are allowed ReadOnly access,</entry></row><row><entry /><entry># DecrementOnly access not allowed for other keys (not KeyNum)</entry></row><row><entry /><entry>If (i ≠KeyNum) <img file="US7165824B2_D0630.tif" /> (DOForKeys[i] = 1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>CheckOK <img file="US7165824B2_D0631.tif" /> ;0</entry></row><row><entry /><entry>Return CheckOK</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>#ReadWrite access allowed for KeyNum,</entry></row><row><entry /><entry>#ReadWrite and DecrementOnly access not allowed for KeyNum.</entry></row><row><entry /><entry>If (i = KeyNum) <img file="US7165824B2_D0632.tif" /> (DOForKeys[i] = 1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>CheckOK <img file="US7165824B2_D0633.tif" /> 0</entry></row><row><entry /><entry>Return CheckOK</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndFor</entry></row><row><entry>CheckOK <img file="US7165824B2_D0634.tif" /> 1</entry></row><row><entry>Return CheckOK</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 27.1.4.13 UpgradeTypeGetUpgradeType(FieldNum, M1) <ul id="ul0885" list-style="none"><li id="ul0885-0001" num="0000"><ul id="ul0886" list-style="none"><li id="ul0886-0001" num="6365">This function gets the type attribute for the upgrade field.</li></ul></li></ul>
6366<tables id="TABLE-US-00482" num="00482"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>UpgradeType GetUpgradeType (FieldNum)</entry></row><row><entry /><entry>UpgradeType←M1 [FieldNum] .Type</entry></row><row><entry /><entry>Return UpgradeType</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 27.1.4.14 GetFieldDataWords(FieldNum,FieldData<img file="US7165824B2_D0635.tif" />, M0,M1)
6367This function gets the words corresponding to a given field.
6368<tables id="TABLE-US-00483" num="00483"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>CurrPos ← MaxWordInM</entry></row><row><entry>If FieldNum = 0</entry></row><row><entry> CurrPos ← MaxWordInM</entry></row><row><entry>Else</entry></row><row><entry> CurrPos ← (M1[FieldNum −1] .EndPos) −1 # Next lower word after</entry></row><row><entry>last word of the</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="175pt" align="left" /><colspec colname="1" colwidth="42pt" align="left" /><tbody valign="top"><row><entry /><entry># previous</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>field</entry></row><row><entry>EndIf</entry></row><row><entry>EndPos ← (M1[FieldNum] .EndPos)</entry></row><row><entry>For i ←EndPos to CurrPos j ←0</entry></row><row><entry> FieldData[j] ←M0 [i] #Copy M0 word to FieldData array</entry></row><row><entry>EndFor</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 27.2 StartRollBack <ul id="ul0887" list-style="none"><li id="ul0887-0001" num="0000"><ul id="ul0888" list-style="none"><li id="ul0888-0001" num="6369">Input: KeyRef, <sub>M0</sub>OfExternal, <sub>M1</sub>OfExternal, ChipID, FieldNumL, FieldNumE, InputParameterCheck (optional), R<sub>E</sub>, SIG<sub>E</sub>, R<sub>E2 </sub></li><li id="ul0888-0002" num="6370">Output: ResultFlag, FieldSelect, FieldVal, R<sub>L2 </sub>SIG<sub>out </sub></li><li id="ul0888-0003" num="6371">Changes: <sub>M0 </sub>and R<sub>L </sub></li><li id="ul0888-0004" num="6372">Availability Ink refill QA Device and Parameter Upgrader QA Device <br /> 27.2.1 Function Description </li></ul></li></ul>
6373StartRollBack function is used to start a rollback sequence if the QA Device being upgraded didn't receive the transfer message correctly and hence didn't receive the transfer.
6374The system calls the function on the upgrading QA Device, passing in FieldNumE and ChipId of the QA Device being upgraded, and FieldNumL of the upgrading QA Device. The upgrading QA Device checks that the QA Device being upgraded didn't actually receive the message correctly, by comparing the values read from the device with the values stored in the Xfer Entry cache. The values compared is the value of the sequence fields. After all checks are fulfilled, the upgrading QA Device produces the new data for the sequence fields and a signature. This is subsequently applied to the QA Device being upgraded (using the WriteFieldAuth function), which updates the sequence fields SEQ<sub>—</sub>1 and SEQ<sub>—</sub>2 to the pre-rollback values. However, the new data for the sequence fields and signature can only be applied if the previous data for the sequence fields produced by Xfer function has not been written.
6375The output from the StartRollBack function consists only of the field data of the two sequence fields, and a signature using the refill key. When a pre-rollback output is produced, then sequence field data in SEQ<sub>—</sub>1 (as stored in the Xfer Entry cache, which is what is passed in to the XferAmount function) is decremented by 1 and the sequence field data in SEQ<sub>—</sub>2 (as stored in the Xfer Entry cache, which is what is passed in to the XferAmount function) is decremented by 2.
6376Additional InputParameterCheck value must be provided for the parameters not included in the SIG<sub>E</sub>, if the transmission between the System and Ink Refill QA Device is error prone, and these errors are not corrected by the transimission protocol itself. InputParameterCheck is SHA-1[FieldNumL|FieldNumE], and is required to ensure the integrity of these parameters, when these inputs are received by the Ink Refill QA Device.
6377The StartRollBack function must first calculate the SHA-1[FieldNumL|FieldNumE], compare the calculated value to the value received (InputParameterCheck) and only if the values match act upon the inputs.
000027.2.2 Input Parameters
6378Table 293 describes each of the input parameters for StartRollBack function.
6379<tables id="TABLE-US-00484" num="00484"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="161pt" align="left" /><thead><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>Parameter</entry><entry>Description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>KeyRef</entry><entry>For common key input signature: KeyRef.keyNum =</entry></row><row><entry /><entry>Slot number of the key to be used for testing input</entry></row><row><entry /><entry>signature. SIG<sub>E </sub>produced using K<sub>KeyRef.keyNum </sub>by the</entry></row><row><entry /><entry>QA Device being upgraded. KeyRef.useChipId = 0</entry></row><row><entry /><entry>For variant key input signature: KeyRef.keyNum =</entry></row><row><entry /><entry>Slot number of the key to be used for generating</entry></row><row><entry /><entry>the variant key for testing input signature. SIG<sub>E</sub></entry></row><row><entry /><entry>produced using a variant of K<sub>KeyRef.keyNum </sub>by the</entry></row><row><entry /><entry>QA Device being upgraded.</entry></row><row><entry /><entry>KeyRef.useChipId = 1 KeyRef.chipId = ChipId</entry></row><row><entry /><entry>of the device which generated SIG<sub>E</sub>.</entry></row><row><entry><sub>M0</sub>OfExternal</entry><entry>All 16 words of <sub>M0 </sub>of the QA Device being upgraded</entry></row><row><entry /><entry>which failed to upgrade.</entry></row><row><entry><sub>M1</sub>OfExternal</entry><entry>All 16 words of <sub>M1 </sub>of the QA Device being upgraded</entry></row><row><entry /><entry>which failed to upgrade.</entry></row><row><entry>ChipId</entry><entry>ChipId of the QA Device being upgraded which failed</entry></row><row><entry /><entry>to upgrade.</entry></row><row><entry>FieldNumL</entry><entry><sub>M0 </sub>field number of the local (refill) device from</entry></row><row><entry /><entry>which the value was supposed to transferred.</entry></row><row><entry>FieldNumE</entry><entry><sub>M0 </sub>field number of the QA Device being upgraded to</entry></row><row><entry /><entry>which the value couldn't be transferred.</entry></row><row><entry>R<sub>E</sub></entry><entry>External random value used to verify input signature.</entry></row><row><entry /><entry>This will be the R from the input signature genera-</entry></row><row><entry /><entry>tor (i.e device generating SIG<sub>E</sub>). The input signal</entry></row><row><entry /><entry>generator in this case, is the device which failed</entry></row><row><entry /><entry>to upgrade or a translation device.</entry></row><row><entry>SIG<sub>E</sub></entry><entry>External signature required for authenticating input</entry></row><row><entry /><entry>data. The input data in this case, is the output</entry></row><row><entry /><entry>from the Read function performed on the device which</entry></row><row><entry /><entry>failed to upgrade. A correct SIG<sub>E </sub>= SIG<sub>KeyRef</sub></entry></row><row><entry /><entry>(Data | R<sub>E </sub>| R<sub>L</sub>).</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 27.2.2.1 Input Signature Verification Data Format <ul id="ul0889" list-style="none"><li id="ul0889-0001" num="0000"><ul id="ul0890" list-style="none"><li id="ul0890-0001" num="6380">Refer to Section 27.1.2.1. <br /> 27.2.3 Output Parameters </li><li id="ul0890-0002" num="6381">Table 294 describes each of the output parameters for StartRollBack function.</li></ul></li></ul>
6382<tables id="TABLE-US-00485" num="00485"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="161pt" align="left" /><thead><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>Parameter</entry><entry>Description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>ResultFlag</entry><entry>Indicates whether the function completed success-</entry></row><row><entry /><entry>fully or not. If it did not complete successfully,</entry></row><row><entry /><entry>the reason for the failure is returned here.</entry></row><row><entry /><entry>See Section 12.1, Table 292 and Table 295.</entry></row><row><entry>FieldSelect</entry><entry>Selection of fields to be written</entry></row><row><entry /><entry>In this case the bits corresponding to SEQ_1</entry></row><row><entry /><entry>and SEQ_2 are set to 1.</entry></row><row><entry /><entry>All other bits are set to 0.</entry></row><row><entry>FieldVal</entry><entry>Updated data for sequence datat field for QA Device</entry></row><row><entry /><entry>being upgraded. This must be passed as input to</entry></row><row><entry /><entry>the WriteFieldsAuth function of the QA Device</entry></row><row><entry /><entry>being upgraded.</entry></row><row><entry>R<sub>L2</sub></entry><entry>Internal random value required to generate output</entry></row><row><entry /><entry>signature. This must be passed as input to the</entry></row><row><entry /><entry>WriteFieldsAuth function or Translate function of</entry></row><row><entry /><entry>the QA Device being upgraded.</entry></row><row><entry>SIG<sub>out</sub></entry><entry>Output signature which must be passed as an input</entry></row><row><entry /><entry>to the WriteFieldsAuth function of the QA Device</entry></row><row><entry /><entry>being upgraded.</entry></row><row><entry /><entry>SIG<sub>out </sub>= SIG<sub>KeyRef</sub>(data | R<sub>L2 </sub>| R<sub>E2</sub>) as</entry></row><row><entry /><entry>per FIG. 373.</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
6383<tables id="TABLE-US-00486" num="00486"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 295</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Result definition for StartRollBack</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag</entry><entry /></row><row><entry /><entry>Definition</entry><entry>Description</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>RollBackInvalid</entry><entry>RollBack cannot be performed on the request</entry></row><row><entry /><entry /><entry>because parameters for rollback is incorrect.</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 27.2.3.1 SIG<sub>Out </sub><ul id="ul0891" list-style="none"><li id="ul0891-0001" num="0000"><ul id="ul0892" list-style="none"><li id="ul0892-0001" num="6384">Refer to Section 20.2.1 for details. <br /> 27.2.4 Function Sequence </li><li id="ul0892-0002" num="6385">The StartRollBack command is illustrated by the following pseudocode:</li></ul></li><li id="ul0891-0002" num="6386">Accept input parameters—KeyRef, M1OfExternal, ChipId, FieldNumL, FieldNumE, R<sub>E</sub>, SIG<sub>E</sub>, R<sub>E2</sub></li></ul>
6387<tables id="TABLE-US-00487" num="00487"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>Accept R<sub>E</sub>, SIG<sub>E</sub>, R<sub>E2</sub></entry></row><row><entry /><entry>#Generate message for passing into ValidateKeyRefAndSignature</entry></row><row><entry /><entry>function</entry></row><row><entry /><entry>data <img file="US7165824B2_D0636.tif" /> (RWSense|MSelect|KeyIdSelect|ChipId|WordSelect|M0|M1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry># Refer to Figure 382.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>----------------------------------------------------------------</entry></row><row><entry /><entry># Validate KeyRef, and then verify signature</entry></row><row><entry /><entry>ResultFlag = ValidateKeyRefAndSignature(KeyRef,data,R<sub>E</sub>,R<sub>L</sub>)</entry></row><row><entry /><entry>If (ResultFlag ≠ Pass)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>----------------------------------------------------------------#</entry></row><row><entry /><entry>Check Seq Fields Exist and get their Field Num</entry></row><row><entry /><entry># Get Seqdata field SEQ_1 num for the device being upgraded</entry></row><row><entry /><entry>XferSEQ_1FieldNum<img file="US7165824B2_D0637.tif" /> GetFieldNum(M1OfExternal, SEQ_1)</entry></row><row><entry /><entry># Check if the Segdata field SEQ_1 is valid</entry></row><row><entry /><entry>If(XferSEQ_1FieldNum invalid)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0638.tif" /> SeqFieldInvalid</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry># Get Segdata field SEQ_2 num for the device being upgraded</entry></row><row><entry /><entry>XferSEQ_2FieldNum<img file="US7165824B2_D0639.tif" /> GetFieldNum(M1OfExternal, SEQ_2)</entry></row><row><entry /><entry># Check if the Seqdata field SEQ_2 is valid</entry></row><row><entry /><entry>If(XferSEQ_2FieldNum invalid)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0640.tif" /> SeqFieldInvalid</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>----------------------------------------------------------------</entry></row><row><entry /><entry># Get SeqData SEQ_1 data from device being upgraded</entry></row><row><entry /><entry>GetFieldDataWords(XferSEQ_1FieldNum,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>XferSEQ_1DataFromDevice,M0OfExternal,M1OfExternal)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry># Get SeqData SEQ_2 data from device being upgraded</entry></row><row><entry /><entry>GetFieldDataWords(XferSEQ_2FieldNum,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>XferSEQ_2DataFromDevice,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>M0OfExternal,M1OfExternal)</entry></row><row><entry /><entry>----------------------------------------------------------------</entry></row><row><entry /><entry># Check Xfer Entry in cache is correct - dataset exists, Field</entry></row><row><entry /><entry>data</entry></row><row><entry /><entry># and sequence field data matches and Xfer State is correct</entry></row><row><entry /><entry>XferEntryOK <img file="US7165824B2_D0641.tif" /> CheckEntry(ChipId, FieldNumE, FieldNumL,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>XferSEQ_1DataFromDevice, XferSEQ_2DataFromDevice)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>If( XferEntryOK= 0)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0642.tif" /> RollBackInvalid</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry># Generate Seqdata for SEQ_1 and SEQ_2 fields</entry></row><row><entry /><entry>XferSEQ_1DataToDevice = XferSEQ_1DataFromDevice − 1</entry></row><row><entry /><entry>XferSEQ_2DataToDevice = XferSEQ_2DataFromDevice − 2</entry></row><row><entry /><entry># Generate FieldSelect and FieldVal for sequence fields SEQ_1 and</entry></row><row><entry /><entry>SEQ_2</entry></row><row><entry /><entry>CurrentFieldSelect<img file="US7165824B2_D0643.tif" /> 0</entry></row><row><entry /><entry>FieldVal <img file="US7165824B2_D0644.tif" /> 0</entry></row><row><entry /><entry>GenerateFieldSelectAndFieldVal(XferSEQ_1FieldNum,</entry></row><row><entry /><entry>XferSEQ_1DataToDevice, XferSEQ_2FieldNum, XferSEQ_2DataToDevice,</entry></row><row><entry /><entry>FieldSelect, FieldVal)</entry></row><row><entry /><entry>#Generate message for passing into GenerateSignature function</entry></row><row><entry /><entry>data <img file="US7165824B2_D0645.tif" /> (RWSense|FieldSelect|ChipId|FieldVal)# Refer to Figure 373.</entry></row><row><entry /><entry>#Create output signature for FieldNumE</entry></row><row><entry /><entry>SIG<sub>out</sub><img file="US7165824B2_D0646.tif" /> GenerateSignature(KeyRef,data,R<sub>L2</sub>,R<sub>E2</sub>)</entry></row><row><entry /><entry>Update R<sub>L2 </sub>to R<sub>L3</sub></entry></row><row><entry /><entry>ResultFlag <img file="US7165824B2_D0647.tif" /> Pass</entry></row><row><entry /><entry>Output ResultFlag, FieldData, R<sub>L2 ,</sub>SIG<sub>out</sub></entry></row><row><entry /><entry>Return</entry></row><row><entry /><entry>EndIf</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 27.3 RollBackAmount <ul id="ul0893" list-style="none"><li id="ul0893-0001" num="0000"><ul id="ul0894" list-style="none"><li id="ul0894-0001" num="6388">Input: KeyRef, <sub>M0</sub>OfExternal, <sub>M1</sub>OfExternal, ChipID, FieldNumL, FieldNumE, InputParameterCheck (optional), R<sub>E</sub>, SIG<sub>E </sub></li><li id="ul0894-0002" num="6389">Output: ResultFlag</li><li id="ul0894-0003" num="6390">Changes: <sub>M0 </sub>and R<sub>L </sub></li><li id="ul0894-0004" num="6391">Availablity: Ink refill QA Device <br /> 27.3.1 Function Description </li></ul></li></ul>
6392RollBackAmount function finally adjusts the value of the FieldNumL of the upgarding QA Device to a previous value before the transfer request, if the QA Device being upgraded didn't receive the transfer message correctly (and hence was not upgraded).
6393The upgrading QA Device checks that the QA Device being upgraded didn't actually receive the transfer message correctly, by comparing the sequence data field values read from the device with the values stored in the Xfer Entry cache. The sequence data field values read must match what was previously written using the StartRollBack function. After all checks are fulfilled, the upgrading QA Device adjusts its FieldNumL.
6394Additional InputParameterCheck value must be provided for the parameters not included in the SIG<sub>E</sub>, if the transmission between the System and Ink Refill QA Device is error prone, and these errors are not corrected by the transimission protocol itself. InputParameterCheck is SHA-1[FieldNumL|FieldNumE], and is required to ensure the integrity of these parameters, when these inputs are received by the Ink Refill QA Device.
6395The RollBackAmount function must first calculate the SHA-1[FieldNumL|FieldNumE], compare the calculated value to the value received (InputParameterCheck) and only if the values match act upon the inputs.
000027.3.2 Input Parameters
6396Table 296 describes each of the intput parameters for RollbackAmount function.
6397<tables id="TABLE-US-00488" num="00488"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="161pt" align="left" /><thead><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>Parameter</entry><entry>Description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>KeyRef</entry><entry>For common key input signature:</entry></row><row><entry /><entry>KeyRef.keyNum = Slot number of the key</entry></row><row><entry /><entry>to be used for testing input signature.</entry></row><row><entry /><entry>SIG<sub>E </sub>produced using K<sub>KeyRef.keyNum </sub>by the</entry></row><row><entry /><entry>QA Device being upgraded. KeyRef.useChipId = 0</entry></row><row><entry /><entry>For variant key input signature:</entry></row><row><entry /><entry>KeyRef.keyNum = Slot number of the key</entry></row><row><entry /><entry>to be used for generating the variant key</entry></row><row><entry /><entry>for testing input signature. SIG<sub>E </sub>produced</entry></row><row><entry /><entry>using a variant of K<sub>KeyRef.keyNum </sub>by the</entry></row><row><entry /><entry>QA Device being upgraded.</entry></row><row><entry /><entry>KeyRef.useChipId = 1 KeyRef.chipId =</entry></row><row><entry /><entry>ChipId of the device which generated SIG<sub>E</sub>.</entry></row><row><entry><sub>M0</sub>OfExternal</entry><entry>All 16 words of <sub>M0 </sub>of the QA Device being</entry></row><row><entry /><entry>upgraded which failed to upgrade.</entry></row><row><entry><sub>M1</sub>OfExternal</entry><entry>All 16 words of <sub>M1 </sub>of the QA Device being</entry></row><row><entry /><entry>upgraded which failed to upgrade.</entry></row><row><entry>ChipId</entry><entry>ChipId of the QA Device being upgraded</entry></row><row><entry /><entry>which failed to upgrade.</entry></row><row><entry>FieldNumL</entry><entry><sub>M0 </sub>field number of the local (refill)</entry></row><row><entry /><entry>device from which the value was supposed</entry></row><row><entry /><entry>to transferred.</entry></row><row><entry>FieldNumE</entry><entry><sub>M0 </sub>field number of the QA Device being</entry></row><row><entry /><entry>upgraded to which the value was not</entry></row><row><entry /><entry>transferred.</entry></row><row><entry>R<sub>E</sub></entry><entry>External random value used to verify input</entry></row><row><entry /><entry>signature. This will be the R from the</entry></row><row><entry /><entry>input signature generator (i.e device</entry></row><row><entry /><entry>generating SIG<sub>E</sub>). The input signal</entry></row><row><entry /><entry>generator in this case, is the device</entry></row><row><entry /><entry>which failed to upgrade or a translation</entry></row><row><entry /><entry>device.</entry></row><row><entry>SIG<sub>E</sub></entry><entry>External signature required for authenti-</entry></row><row><entry /><entry>cating input data. The input data in this case,</entry></row><row><entry /><entry>is the output from the Read function performed</entry></row><row><entry /><entry>on the device which failed to upgrade. A correct</entry></row><row><entry /><entry>SIG<sub>E </sub>= SIG<sub>KeyRef</sub>(Data | R<sub>E </sub>| R<sub>L</sub>).</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 27.3.2.1 Input Signature Generation Data Format <ul id="ul0895" list-style="none"><li id="ul0895-0001" num="0000"><ul id="ul0896" list-style="none"><li id="ul0896-0001" num="6398">Refer to Section 27.1.2.1 for details. <br /> 27.3.3 Output Parameters </li><li id="ul0896-0002" num="6399">Table 297 describes each of the output parameters for RollbackAmount.</li></ul></li></ul>
6400<tables id="TABLE-US-00489" num="00489"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="147pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>Parameter</entry><entry>Description</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>ResultFlag</entry><entry>Indicates whether the function completed</entry></row><row><entry /><entry /><entry>successfully or not. If it did not complete</entry></row><row><entry /><entry /><entry>successfully, the reason for the failure is</entry></row><row><entry /><entry /><entry>returned here. See Section 12.1, Table 292</entry></row><row><entry /><entry /><entry>and Table 295.</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 27.3.4 Function Sequence <ul id="ul0897" list-style="none"><li id="ul0897-0001" num="0000"><ul id="ul0898" list-style="none"><li id="ul0898-0001" num="6401">The RollBackAmount command is illustrated by the following pseudocode:</li></ul></li></ul>
6402<tables id="TABLE-US-00490" num="00490"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>Accept input parameters-KeyRef, M0OfExternal, M1OfExternal,</entry></row><row><entry>ChipId, FieldNumL, FieldNumE, R<sub>E</sub>,SIG<sub>E</sub></entry></row><row><entry>#Generate message for passing into ValidateKeyRefAndSignature</entry></row><row><entry>function</entry></row><row><entry>data <img file="US7165824B2_D0648.tif" /> (RWSense|MSelect|KeyIdSelect|ChipId|WordSelect|M0|M1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry># Refer to Figure 382.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>----------------------------------------------------------------</entry></row><row><entry># Validate KeyRef, and then verify signature</entry></row><row><entry>ResultFlag = ValidateKeyRefAndSignature(KeyRef,data,R<sub>E</sub>,R<sub>L</sub>)</entry></row><row><entry>If (ResultFlag ≠ Pass)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>----------------------------------------------------------------</entry></row><row><entry># Check Seq Fields Exist and get their Field Num</entry></row><row><entry># Get Seqdata field SEQ_1 num for the device being upgraded</entry></row><row><entry>XferSEQ_1FieldNum<img file="US7165824B2_D0649.tif" /> GetFieldNum(M1OfExternal, SEQ_1)</entry></row><row><entry># Check if the Seqdata field SEQ_1 is valid</entry></row><row><entry>If(XferSEQ_1FieldNum invalid)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0650.tif" /> SeqFieldInvalid</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry># Get Seqdata field SEQ_2 num for the device being upgraded</entry></row><row><entry>XferSEQ_2FieldNum<img file="US7165824B2_D0651.tif" /> GetFieldNum(M1OfExternal, SEQ_2)</entry></row><row><entry># Check if the Seqdata field SEQ_2 is valid</entry></row><row><entry>If(XferSEQ_2FieldNum invalid)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0652.tif" /> SeqFieldInvalid</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>----------------------------------------------------------------</entry></row><row><entry># Get SeqData SEQ_1 data from device being upgraded</entry></row><row><entry>GetFieldDataWords(XferSEQ_1FieldNum,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>XferSEQ_1DataFromDevice,M0OfExternal,M1OfExternal)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry># Get SeqData SEQ_2 data from device being upgraded</entry></row><row><entry>GetFieldDataWords(XferSEQ_2FieldNum,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>XferSEQ_2DataFromDevice,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>M0OfExternal,M1OfExternal)</entry></row><row><entry>----------------------------------------------------------------</entry></row><row><entry># Generate Seqdata for SEQ_1 and SEQ_2 fields with the data that</entry></row><row><entry>is read</entry></row><row><entry>XferSEQ_1Data = XferSEQ_1DataFromDevice + 1</entry></row><row><entry>XferSEQ_2Data = XferSEQ_2DataFromDevice + 2</entry></row><row><entry># Check Xfer Entry in cache is correct - dataset exists, Field</entry></row><row><entry>data</entry></row><row><entry># and sequence field data matches and Xfer State is correct</entry></row><row><entry>XferEntryOK <img file="US7165824B2_D0653.tif" /> CheckEntry(ChipId, FieldNumE, FieldNumL,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>XferSEQ_1Data, XferSEQ_2Data)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>If( XferEntryOK= 0)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0654.tif" /> RollBackInvalid</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry># Get ΔFieldDataL from DataSet</entry></row><row><entry>GetVal(ChipId, FieldNumE,ΔFieldDataL)</entry></row><row><entry># Add ΔFieldDataL to FieldNumL</entry></row><row><entry>AddValToField(FieldNumL,ΔFieldDataL)</entry></row><row><entry># Update XferState in DataSet to complete/deleted</entry></row><row><entry>UpdateXferStateToComplete(ChipId, FieldNumE)</entry></row><row><entry>ResultFlag <img file="US7165824B2_D0655.tif" /> Pass</entry></row><row><entry>Output ResultFlag</entry></row><row><entry>Return</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 28 Concepts
6403This section is very similar to Section 26. The differences between this section and Section 26 have been summarised and underlined, where required.
000028.1 Purpose
6404In a printing application, a printer contains a Printer QA Device, which stores details of the various operating parameters of a printer, some of which may be upgradeable. The upgradeable parameters must be written (initially) and changed in an authorised manner.
6405The authorisation for the write or change is achieved by using a Parameter Upgrader QA Device which contains the necessary functions to allow a write or a change of a parameter value (e.g. a print speed) into another QA Device, typically a printer QA Device. This QA Device is also referred to as an upgrading QA Device.
6406A parameter upgrader QA Device is able to perform a fixed number of upgrades, and this number is effectively a consumable value. The number of upgrades remaining is also referred to as count-remaining. With each write/change of an operating parameter in a Printer QA Device, the count-remaining decreases by 1, and can be replenished by a value upgrader QA Device.
6407The Parameter Upgrader QA Device can also be referred to as the Upgrading QA Device, and the Printer QA Device can also be referred to as the QA Device being upgraded.
6408The writing or changing of the parameter can also be referred to as a transfer of a parameter.
6409The Parameter Upgrader QA Device copies its parameter value field to the parameter value field of Printer QA Device, and decrements the count-remaining field associated with the parameter value field by 1.
000028.2 Requirements
6410The transfer of a parameter has two basic requirements: <ul id="ul0899" list-style="none"><li id="ul0899-0001" num="0000"><ul id="ul0900" list-style="none"><li id="ul0900-0001" num="6411">The transfer can only be performed if the transfer request is valid. The validity of the transfer request must be completely checked by the Parameter Upgrader QA Device, before it produces the required output for the transfer. It must not be possible to apply the transfer output to the Printer QA Device, if the Parameter Upgrader QA Device has been already been rolled back for that particular transfer. <ul id="ul0901" list-style="none"><li id="ul0901-0001" num="6412">A process of rollback is available if the transfer was not received by the Printer QA Device. A rollback is performed only if the rollback request is valid. The validity of the rollback request must be completely checked by the Parameter Upgrader QA Device, before the count-remaining value is incremented by 1. It must not be possible to rollback an Parameter Upgrader QA Device for a transfer, which has already been applied to the Printer QA Device i.e the Parameter Upgrader QA Device must only be rolled back for transfers that have actually failed. <br /> 28.3 Basic Scheme </li></ul></li></ul></li></ul>
6413The transfer and rollback process is shown in <figref idref="DRAWINGS">FIG. 383</figref>.
6414Following is a sequential description of the transfer and rollback process: <ul id="ul0902" list-style="none"><li id="ul0902-0001" num="6415">1. The System Reads the memory vectors M0 and M1 of the Printer QA Device. The output from the read which includes the M0 and M1 words of the Printer QA Device, and a signature, is passed as an input to the Transfer Request. It is essential that M0 and M1 are read together. This ensures that the field information for M0 fields are correct, and have not been modified, or substituted from another device. Entire M0 and M1 must be read to verify the correctness of the subsequent Transfer Request by the Parameter Upgrader QA Device.</li><li id="ul0902-0002" num="6416">2. The System makes a Transfer Request to the Parameter Upgrader QA Device with the field in the Parameter Upgrader QA Device whose data will be copied to the Printer QA Device, and the field in Printer QA Device to which this data will be copied to. The Transfer Request also includes the output from Read of the Printer QA Device. The Parameter Upgrader QA Device validates the Transfer Request based on the Read output, checks that it has enough count-remaining for a successful transfer, and then produces the necessary Transfer output. The Transfer Output typically consists of new field data for the field being refilled or upgraded, additional field data required to ensure the correctness of transfer/rollback, along with a signature.</li><li id="ul0902-0003" num="6417">3. The System then applies the Transfer Output on the Printer QA Device, by calling an authenticated Write on it, passing in the Transfer Output. The Write is either successful or not. If the Write is not successful, then the System will repeat calling the Write function using the same transfer output, which may be successful or not. If unsuccessful the System will initiate a rollback of the transfer. The rollback must be performed on the Parameter Upgrader QA Device, so that it can adjust its value to a previous value before the current Transfer Request was initiated.</li><li id="ul0902-0004" num="6418">4. The System starts a rollback by Reading the memory vectors M0 and M1 of the Printer QA Device.</li><li id="ul0902-0005" num="6419">5. The System makes a StartRollBack Request to the Parameter Upgrader QA Device with same input parameters as the Transfer Request, and the output from Read in (4). The Parameter Upgrader QA Device validates the StartRollBack Request based on the Read output, and then produces the necessary Pre-rollback output. The Pre-rollback output typically consists only of additional field data along with a signature.</li><li id="ul0902-0006" num="6420">6. The System then applies the Pre-rollback output on the Parameter Upgrader QA Device, by calling an authenticated Write on it, passing in the Pre-rollback output. The Write is either successful or not. If the Write is not successful, then either (6), or (5) and (6) must be repeated.</li><li id="ul0902-0007" num="6421">7. The System then Reads the memory vectors M0 and M1 of the Printer QA Device.</li><li id="ul0902-0008" num="6422">8. The System makes a RollBack Request to the Parameter Upgrader QA Device with same input parameters as the Transfer Request, and the output from Read (7). The Parameter Upgrader QA Device validates the RollBack Request based on the Read output, and then rolls back its count-remaining field by incrementing it by 1. <br /> 28.3.1 Transfer </li></ul>
6423The Printer QA Device stores upgradeable operating parameter values in M0 fields, and its corresponding M<sub>1 </sub>words contains field information for its operating parameter fields. The field information consists of the size of the field, the Type of data stored in field and the access permission to the field. See Section 8.1.1 for details.
6424The Parameter Upgrader QA Device also stores the new operating parameter values (which will be written to the Printer QA Device) in its M0 fields, and its coressponding M<sub>1 </sub>words contains field information for the new operating parameter fields. Additionally, the Parameter Upgrader QA Device has a count-remaining field associated with the new operating parameter value field. The count-remaining field occupies the higher field position when compared to its associated operating parameter value field.
000028.3.1.1 Authorisation
6425The basic authorisation for a transfer comes from a key, which has authenticated ReadWrite permission (stored in field information as KeyNum) to the operating parameter field in the Printer QA Device. We will refer to this key as the upgrade key. The same upgrade key must also have authenticated decrement-only permission to the count-remaining field (which decrements by 1 with every transfer) in the Parameter Upgrader QA Device.
6426After validating the input upgrade request, the Parameter Upgrader QA Device will decrement the value of the count-remaining field by 1, and produce data (by copying the data stored from its operating parameter field) and signature for the new operating parameter using the upgrade key. Note that the Parameter Upgrader QA Device can decrement its count-remaining field only if the upgrade key has the permission to decrement it.
6427The data and signature produced by the Parameter Upgrader QA Device is subsequently applied to the Printer QA Device. The Printer QA Device will accept the new transferred operating parameter, only if the signature is valid. Note that the signature will only be valid if it was produced using the upgrade key which has write permission to the operating parameter field being written.
6428The upgrade key has authenticated ReadWrite permission to the operating parameter field (which will change) in the Printer QA Device. The upgrade key has decrement-only permission to the the count-remaining field (which decrements by 1 with every transfer of field) in the Parameter Upgrader QA Device.
000028.3.1.2 Data Type Matching
6429The Parameter Upgrader QA Device validates the transfer request by matching the Type of the data in the field information of operating parameter field (stored in M1) of Printer QA Device to the Type of data in the field information of operating parameter field of the Parameter Upgrader QA Device. This ensures that equivalent data types are being transferred i.e Network_OEM1_printspeed<sub>—</sub>1500 is not transferred to Network_OEM1_printspeed<sub>—</sub>2000.
000028.3.1.3 Addition Validation
6430Additional validation of the transfer request must be performed before a transfer output is generated by the Parameter Upgrader QA Device. These are as follows: <ul id="ul0903" list-style="none"><li id="ul0903-0001" num="0000"><ul id="ul0904" list-style="none"><li id="ul0904-0001" num="6431">For the Printer QA Device</li></ul></li><li id="ul0903-0002" num="6432">1. Whether the field being upgraded is actually present.</li><li id="ul0903-0003" num="6433">2. Whether the field being upgraded can hold the changed value. <ul id="ul0905" list-style="none"><li id="ul0905-0001" num="6434">For the Parameter Upgrader QA Device:</li></ul></li><li id="ul0903-0004" num="6435">1. Whether the new operating parameter field and its associated count-remaining is actually present.</li><li id="ul0903-0005" num="6436">2. Whether the count-remaining field has an upgrade left for the transfer to succeed. <br /> 28.3.1.4 Rollback Facilitation </li></ul>
6437To facilitate a rollback, the Parameter Upgrade QA Device will store a list of transfer requests processed by it. This list is referred to as the Xfer Entry cache. Each record in the list consists of the transfer parameters corresponding to the transfer request.
000028.3.2 Rollback
6438A rollback request will be validated by looking through the Xfer Entry cache of the Parameter Upgrader QA Device. After the right transfer request is found the Parameter Upgrade QA Device checks that the output from the transfer request was not applied to the Printer QA Device by comparing the current Read of the Printer QA Device to the values in the Xfer Entry cache, and finally rolling back the Parameter Upgrader QA Device count-remaining field by incrementing it by 1. The Parameter Upgrader QA Device must be absolutely sure that the Printer QA Device didn't receive the transfer. This factor determines the additional fields that must be written along with new operating parameter data, and also the parameters of the transfer request that must be stored in the Xfer Entry cache to facilitate a rollback, to prove that the Printer QA Device didn't actually receive the transfer.
6439The rollback process increments the count-remaining field by 1 in the Parameter Upgrader QA Device.
000028.3.2.1 Sequence Fields
6440The rollback process must ensure that the transfer output (which was previously produced) for which the rollback is being performed, cannot be applied after the rollback has been performed.
6441How do we achieve this? There are two separate decrement-only sequence fields (SEQ<sub>—</sub>1 and SEQ<sub>—</sub>2) in the Printer QA Device which can only be decremented by the Parameter Upgrader QA Device using the upgrade key. The nature of data to be written to the sequence fields is such that either the transfer output or the pre-rollback output can be applied to the Printer QA Device, but not both i.e they must be mutually exclusive. Refer to Table 285 for details.
6442The two sequence fields are initialised to 0xFFFFFFFF using sequence key. The sequence key is different to the upgrade key, and has authenticated ReadWrite permission to both the sequence fields.
6443The transfer output consists of the new data for the field being upgraded, field data of the two sequence fields, and a signature using the upgrade key. The field data for SEQ<sub>—</sub>1 is decremented by 2 from the original value that was passed in with the transfer request. The field data for SEQ<sub>—</sub>2 is decremented by 1 from the original value that was passed in with the transfer request.
6444The pre-rollback output consists only of the field data for the two sequence fields, and a signature using the upgrade key. The field data for SEQ<sub>—</sub>1 is decremented by 1 from the original value that was passed in with the transfer request. The field data for SEQ<sub>—</sub>2 is decremented by 2 from the original value that was passed in with the transfer request.
6445Since the two sequence fields are decrement-only fields, the writing of the transfer output to QA Device being upgraded will prevent the writing of the pre-rollback output to QA Device being upgraded, since the sequence fields are decrement-only fields, and only one possible set can be written. If the writing of the transfer output fails, then pre-rollback can be written. However, the transfer output cannot be written after the pre-rollback output has been written.
6446Before a rollback is performed, the Parameter Upgrader QA Device must confirm that the sequence fields was successfully written to the pre-rollback values in the Printer QA Device. Because the sequence fields are decrement-only fields, the Printer QA Device will allow pre-rollback output to be written only if the transfer output has not been written.
000028.3.2.1.1 Field Information of the Sequence Data Field
6447For a device to be upgradeable the device must have two sequence fields SEQ<sub>—</sub>1 and SEQ<sub>—</sub>2 which are written with sequence data during the transfer sequence. Thus all upgrading QA Devices, ink QA Devices and printer QA Devices must have two sequence fields. The upgrading QA Devices must have these fields because they can be upgraded as well. The sequence field information are defined in Table 298.
6448<tables id="TABLE-US-00491" num="00491"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="98pt" align="left" /><thead><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>Attribute</entry><entry /><entry /></row><row><entry>Name</entry><entry>Value</entry><entry>Explanation</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>Type</entry><entry>TYPE_SEQ_1 or</entry><entry>See Appendix A for exact</entry></row><row><entry /><entry>TYPE_SEQ_2.</entry><entry>data.</entry></row><row><entry>KeyNum</entry><entry>Slot number of</entry><entry>Only the sequence key</entry></row><row><entry /><entry>the sequence</entry><entry>has authenticated ReadWrite</entry></row><row><entry /><entry>key.</entry><entry>access to this field.</entry></row><row><entry>Non Auth</entry><entry>0</entry><entry>Non authenticated ReadWrite</entry></row><row><entry>RW Perm<sup>b</sup></entry><entry /><entry>is not allowed to the field.</entry></row><row><entry>Auth RW</entry><entry>1</entry><entry>Authenticated (key based)</entry></row><row><entry>Perm<sup>c</sup></entry><entry /><entry>ReadWrite access is allowed</entry></row><row><entry /><entry /><entry>to the field.</entry></row><row><entry>KeyPerm</entry><entry>KeyPerms[KeyNum] =</entry><entry>KeyNum is the slot number</entry></row><row><entry /><entry>0</entry><entry>of the sequence key, which</entry></row><row><entry /><entry /><entry>has ReadWrite permission to</entry></row><row><entry /><entry /><entry>the field.</entry></row><row><entry /><entry>KeyPerms[Slot</entry><entry>Upgrade key can decrement</entry></row><row><entry /><entry>number of upgrade</entry><entry>the sequence field.</entry></row><row><entry /><entry>key] = 1</entry></row><row><entry /><entry>KeyPerms[others =</entry><entry>All other keys have</entry></row><row><entry /><entry>0 . . . 7(except</entry><entry>ReadOnly access.</entry></row><row><entry /><entry>upgrade key)] = 0</entry></row><row><entry>End Pos</entry><entry /><entry>Set as required. Size is</entry></row><row><entry /><entry /><entry>typically 1 word.</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry namest="1" nameend="3" align="left" id="FOO-00057"><sup>a</sup>This is a sample type only and is not included in the Type Map in Appendix A.</entry></row><row><entry namest="1" nameend="3" align="left" id="FOO-00058"><sup>b</sup>Non authenticated Read Write permission.</entry></row><row><entry namest="1" nameend="3" align="left" id="FOO-00059"><sup>c</sup>Authenticated Read Write permission.</entry></row></tbody></tgroup></table></tables><br /> 28.3.3 Upgrade States
6449There are three states in an transfer sequence, the first state is initiated for every transfer, while the next two states are initiated only when the transfer fails. The states are—Xfer, StartRollback, and Rollback.
000028.3.3.1 Upgrade Flow
6450<figref idref="DRAWINGS">FIG. 384</figref> shows a typical upgrade flow.
000028.3.3.2 Xfer
6451This state indicates the start of the transfer process, and is the only state required if the transfer is successful. During this state, the Parameter Upgrader QA Device adds a new record to its Xfer Entry cache, decrements its count-remaining by 1, produces new operating parameter field, new sequence data (as described in Section 28.3.2.1) and a signature based on the upgrade key.
6452The Printer QA Device will subsequently write the new operating parameter field and new sequence data, after verifying the signature. If the new operating parameter field can be successfully written to the Printer QA Device, then this will finish a successful transfer.
6453If the writing of the new amount is unsuccessful (result returned is BAD SIG), the System will re-transmit the transfer output to the Printer QA Device, by calling the authenticated Write function on it again, using the same transfer output.
6454If retrying to write the same transfer output fails repeatedly, the System will start the rollback process on Parameter Upgrader QA Device, by calling the Read function on the Printer QA Device, and subsequently calling the StartRollBack function on the Parameter Upgrader QA Device. After a successful rollback is performed, the System will invoke the transfer sequence again.
000028.3.3.3 StartRollBack
6455This state indicates the start of the rollback process. During this state, the Parameter Upgrade QA Device produces the next sequence data and a signature based on the upgrade key. This is also called a pre-rollback, as described in Section 26.3.2.
6456The pre-rollback output can only be written to the Printer QA Device, if the previous transfer output has not been written. The writing of the pre-rollback sequence data also ensures, that if the previous transfer output was captured and not applied, then it cannot be applied to the Printer QA Device in the future.
6457If the writing of the pre-rollback output is unsuccessful (result returned is BAD SIG), the System will re-transmit the pre-rollback output to the Printer QA Device, by calling the authenticated Write function on it again, using the same pre-rollback output.
6458If retrying to write the same pre-rollback output fails repeatedly, the System will call the StartRollback on the Parameter Upgrade QA Device again, and subsequently calling the authenticated Write function on the Printer QA Device using this output.
000028.3.3.4 Rollback
6459This state indicates a successful deletion (completion) of a transfer sequence. During this state, the Parameter Upgrader QA Device verifies the sequence data produced from StartRollBack has been correctly written to Printer QA Device, then rolls its count-remaining field to a previous value before the transfer request was issued.
000028.3.4 Xfer Entry Cache
6460The Xfer Entry data structure must allow for the following: <ul id="ul0906" list-style="none"><li id="ul0906-0001" num="0000"><ul id="ul0907" list-style="none"><li id="ul0907-0001" num="6461">Stores the transfer state and sequence data for a given transfer sequence.</li><li id="ul0907-0002" num="6462">Store all data corresponding to a given transfer, to facilitate a rollback to the previous value before the transfer output was generated.</li></ul></li></ul>
6463The Xfer Entry cache depth will depend on the QA Chip Logical Interface implementation. For some implementations a single Xfer Entry value will be saved. If the Parameter Upgrader QA Device has no powersafe storage of Xfer Entry cache, a power down will cause the erasure of the Xfer Entry cache and the Parameter Upgrader QA Device will not be able to rollback to a pre-power-down value.
6464A dataset in the Xfer Entry cache will consist of the following: <ul id="ul0908" list-style="none"><li id="ul0908-0001" num="0000"><ul id="ul0909" list-style="none"><li id="ul0909-0001" num="6465">Information about the Printer QA Device:</li></ul></li><li id="ul0908-0002" num="6466">a. ChipId of the device.</li><li id="ul0908-0003" num="6467">b. FieldNum of the M0 field (i.e what was being upgraded). <ul id="ul0910" list-style="none"><li id="ul0910-0001" num="6468">Information about the Parameter Upgrader QA Device:</li></ul></li><li id="ul0908-0004" num="6469">a. FieldNum of the M0 field used to transfer the count-remaining from. <ul id="ul0911" list-style="none"><li id="ul0911-0001" num="6470">Xfer State—indicating at which state the transfer sequence is. This will consist of:</li></ul></li><li id="ul0908-0005" num="6471">a. State definition which could be one of the following:—Xfer, StartRollBack and deleted (completed).</li><li id="ul0908-0006" num="6472">b. The value of sequence data fields SEQ<sub>—</sub>1 and SEQ<sub>—</sub>2.</li></ul>
6473The Xfer Entry cache stores the FieldNum of the count-remaining field of the Parameter Upgrader QA Device.
000028.3.4.1 Adding New Dataset
6474A new dataset is added to Xfer Entry cache by the Xfer function.
6475There are three methods which can be used to add new dataset to the Xfer Entry cache. The methods have been listed below in the order of their priority: <ul id="ul0912" list-style="none"><li id="ul0912-0001" num="6476">1. Replacing existing dataset in Xfer Entry cache with new dataset based on ChipId and FieldNum of the Ink QA Device in the new dataset. A matching ChipId and FieldNum could be found because a previous transfer output corresponding to the dataset stored in the Xfer Entry cache has been correctly received and processed by the Parameter Upgrader QA Device, and a new transfer request for the same Printer QA Device, same field, has come through to the Parameter Upgrader QA Device.</li><li id="ul0912-0002" num="6477">2. Replace existing dataset cache with new dataset based on the Xfer State. If the Xfer State for a dataset indicates deleted (complete), then such a dataset will not be used for any further functions, and can be overwritten by a new dataset.</li><li id="ul0912-0003" num="6478">3. Add new dataset to the end of the cache. This will automatically delete the oldest dataset from the cache regardless of the Xfer State. <br /> 28.4 Upgrading the Count-remaining Field </li></ul>
6479This section is only applicable to the Parameter Upgrader QA Device.
6480The transfer of count-remaining is similar to transfer ink-remaining because both involve transferring of amounts. Therefore, this transfer uses the XferAmount function.
6481The XferAmount function performs additional checks when transferring count-remaining. This includes checking of the operating parameter field, associated with the count-remaining. They are as follows: <ul id="ul0913" list-style="none"><li id="ul0913-0001" num="0000"><ul id="ul0914" list-style="none"><li id="ul0914-0001" num="6482">The operating parameter value of the upgrading QA Device and the QA Device being upgraded must match.</li><li id="ul0914-0002" num="6483">The operating parameter field (in both devices) must be upgradeable by one key only, and all other keys must have ReadOnly access. This key which has authenticated ReadWrite permission to the operating parameter field, must be different to the key that has authenticated Read Write permission to the count-remaining field.</li><li id="ul0914-0003" num="6484">The data Type for the operating parameter field in the upgrading QA Device must match the data Type for the operating parameter field in the QA Device being upgraded. <br /> 28.5 New Operating Parameter Field Information </li></ul></li></ul>
6485This section is only applicable to the Parameter Upgrader QA Device.
6486This field stores the operating parameter value that is copied from the Parameter Upgrader QA Device to the operating parameter field being updated in the Printer QA Device.
6487This field has a single key associated with it. This key has authenticated ReadWrite permission to this field and will be referred to as write-parameter key.
6488Table 299 shows the field information for the new operating parameter field in the Parameter Upgrader QA Device.
6489<tables id="TABLE-US-00492" num="00492"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="35pt" align="left" /><colspec colname="2" colwidth="126pt" align="left" /><colspec colname="3" colwidth="105pt" align="left" /><thead><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>Attribute</entry><entry /><entry /></row><row><entry>Name</entry><entry>Value</entry><entry>Explanation</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>Type</entry><entry>For e.g -</entry><entry>Type describing the upgrade.</entry></row><row><entry /><entry>TYPE_UPGRADE_PRINTSPEED_15<sup>a</sup></entry></row><row><entry>KeyNum</entry><entry>Slot number of the write-</entry><entry>Only the write-parameter key has</entry></row><row><entry /><entry>parameter key.</entry><entry>authenticated ReadWrite access</entry></row><row><entry /><entry /><entry>to this field.</entry></row><row><entry>Non Auth</entry><entry>0</entry><entry>Non authenticated ReadWrite</entry></row><row><entry>RW Perm<sup>b</sup></entry><entry /><entry>is not allowed to the field.</entry></row><row><entry>Auth RW</entry><entry>1</entry><entry>Authenticated (key based)</entry></row><row><entry>Perm<sup>c</sup></entry><entry /><entry>ReadWrite access is allowed</entry></row><row><entry /><entry /><entry>to the field.</entry></row><row><entry>KeyPerm</entry><entry>KeyPerms[KeyNum] = 0</entry><entry>KeyNum is the slot number of</entry></row><row><entry /><entry /><entry>the write-parameter key which</entry></row><row><entry /><entry /><entry>has ReadWrite permission to</entry></row><row><entry /><entry /><entry>the field.</entry></row><row><entry /><entry>KeyPerms[others =</entry><entry>All other keys have</entry></row><row><entry /><entry>0 . . . 7] = 0</entry><entry>ReadOnly access.</entry></row><row><entry>End Pos</entry><entry /><entry>Set as required.</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry namest="1" nameend="3" align="left" id="FOO-00060"><sup>a</sup>This is a sample type only and is not included in the Type Map in Appendix A.</entry></row><row><entry namest="1" nameend="3" align="left" id="FOO-00061"><sup>b</sup>Non authenticated Read Write permission.</entry></row><row><entry namest="1" nameend="3" align="left" id="FOO-00062"><sup>c</sup>Authenticated Read Write permission.</entry></row></tbody></tgroup></table></tables><br /> 28.6 Different Types of Transfer
6490There can be three types of transfer: <ul id="ul0915" list-style="none"><li id="ul0915-0001" num="0000"><ul id="ul0916" list-style="none"><li id="ul0916-0001" num="6491">Parameter Transfer—This is transfer of an operating parameter value from a Parameter Upgrader QA Device to a Printer QA Device. This is performed when an upgradeable operating parameter is written (for the first time) or changed.</li><li id="ul0916-0002" num="6492">Hierarchical refill—This is a transfer of count-remaining value from one Parameter Upgrader Refill QA Device to a Parameter Upgrader QA Device, where both QA Devices belong to the same OEM. This is typically performed when OEM divides the number of upgrades from one of its Parameter Upgrader QA Device to many of its Parameter Upgrader QA Devices. <ul id="ul0917" list-style="none"><li id="ul0917-0001" num="6493">Peer to Peer refill—This is a transfer of count-remaining value from one Parameter Upgrader Refill QA Device to Parameter Upgrader Refill QA Device, where the QA Devices belong to different organisations, say ComCo and OEM. This is typically performed when ComCo divides number of upgrades from its Parameter Upgrader QA Device to several Parameter Upgrader QA Device belonging to several OEMs.</li></ul></li></ul></li></ul>
6494Transfer of count-remaining between peers, and hierarchical transfer of count-remaining, is similar to an ink transfer, but additional checks on the transfer request is performed when transferring count-remaining amounts. This is described in Section 28.4.1.
6495Transfer of an operating parameter value decrements the count-remaining by 1, hence is different to a ink-transfer.
6496<figref idref="DRAWINGS">FIG. 385</figref> is a representation of various authorised upgrade paths in the printing system.
000028.6.1 Hierarchical Transfers
6497Referring to <figref idref="DRAWINGS">FIG. 385</figref>, this transfer is typically performed when count-remaining amount is transferred from ComCo's Parameter Upgrader Refill QA Device to OEM's Parameter Upgrader Refill QA Device, or from QACo's Parameter Upgrader Refill QA Device to ComCo's Parameter Upgrader Refill QA Device.
6498This transfers are made using the XferAmount function (and not with the XferField described in Section 29.1), because count-remaining transfer is similar to fill/refilling of ink amounts, where ink amount is replaced by count-remaining amount.
000028.6.1.1 Keys and Access Permission
6499We will explain this using a transfer from ComCo to OEM.
6500There is a count-remaining field associated with the ComCo's Parameter Upgrader Refill QA Device. This count-remaining field has two keys associated with: <ul id="ul0918" list-style="none"><li id="ul0918-0001" num="0000"><ul id="ul0919" list-style="none"><li id="ul0919-0001" num="6501">The first key transfers count-remaining to the device from another Parameter Upgrader Refill QA device(device is higher in the heirachy), fills/refills the device itself.</li><li id="ul0919-0002" num="6502">The second key transfers count-remaining from it to other devices (which are lower in the heirachy), fills/refills other devices from it.</li></ul></li></ul>
6503There is a count-remaining field associated with the OEM's Parameter Upgrader Refill QA Device. <ul id="ul0920" list-style="none"><li id="ul0920-0001" num="0000"><ul id="ul0921" list-style="none"><li id="ul0921-0001" num="6504">This count-remaining field has a single key associated with:</li><li id="ul0921-0002" num="6505">This key transfers count-remaining to the device from another Parameter Upgrader Refill QA device (which is higher or at the same level in the heirachy), fills/refills (upgrades) the device itself, and additionally transfers count-remaining from it to other devices (which are lower in the heirachy), fills/refills (upgrades) other devices from it.</li></ul></li></ul>
6506For a successful transfer of count-remaining from ComCo's refill device to an OEM's refill device, the ComCo's refill device and the OEM's refill device must share a common key or a variant key.
6507This key is fill/refill key with respect to the OEM's refill device and it is the transfer key with respect to the ComCo's refill device.
6508For a ComCo to successfully fill/refill its refill device from another refill device (which is higher in the heirachy possibly belonging to the QACo), the ComCo's refill device and the QACo's refill device must share a common key or a variant key. This key is fill/refill key with respect to the ComCo's refill device and it is the transfer key with respect to the QACo's refill device.
000028.6.1.1.1 Count-remaining Field Information
6509Table 300 shows the field information for an <sub>M0 </sub>field storing logical count-remaining amounts in the refill device, which has the ability to transfer down the heirachy.
6510<tables id="TABLE-US-00493" num="00493"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="35pt" align="left" /><colspec colname="2" colwidth="105pt" align="left" /><colspec colname="3" colwidth="77pt" align="left" /><thead><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>Attribute</entry><entry /><entry /></row><row><entry>Name</entry><entry>Value</entry><entry>Explanation</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>Type</entry><entry>TYPE_COUNT_REMAINING<sup>a</sup></entry><entry>Type describes that</entry></row><row><entry /><entry /><entry>the field is a count-</entry></row><row><entry /><entry /><entry>remaining field.</entry></row><row><entry>KeyNum</entry><entry>Slot number of the</entry><entry>Only the refill key</entry></row><row><entry /><entry>refill key.</entry><entry>has authenticated</entry></row><row><entry /><entry /><entry>ReadWrite access to</entry></row><row><entry /><entry /><entry>this field.</entry></row><row><entry>Non Auth</entry><entry>0</entry><entry>Non authenticated</entry></row><row><entry>RW Perm<sup>b</sup></entry><entry /><entry>ReadWrite is not</entry></row><row><entry /><entry /><entry>allowed to the field.</entry></row><row><entry>Auth RW</entry><entry>1</entry><entry>Authenticated (key</entry></row><row><entry>Perm<sup>c</sup></entry><entry /><entry>based) ReadWrite</entry></row><row><entry /><entry /><entry>access is allowed</entry></row><row><entry /><entry /><entry>to the field.</entry></row><row><entry>KeyPerm</entry><entry>KeyPerms[KeyNum] =</entry><entry>KeyNum is the slot</entry></row><row><entry /><entry>0</entry><entry>number of the refill</entry></row><row><entry /><entry /><entry>key, which has</entry></row><row><entry /><entry /><entry>ReadWrite permission</entry></row><row><entry /><entry /><entry>to the field.</entry></row><row><entry /><entry>KeyPerms[Slot Num of</entry><entry>Transfer key can</entry></row><row><entry /><entry>transfer key ] = 1</entry><entry>decrement the field.</entry></row><row><entry /><entry>KeyPerms[others =</entry><entry>All other keys have</entry></row><row><entry /><entry>0 . . . 7(except</entry><entry>ReadOnly access.</entry></row><row><entry /><entry>transfer key)] = 0</entry></row><row><entry>End Pos</entry><entry>Set as required.</entry><entry>Depends on the amount</entry></row><row><entry /><entry /><entry>of logical ink the</entry></row><row><entry /><entry /><entry>device can store and</entry></row><row><entry /><entry /><entry>storage resolution -</entry></row><row><entry /><entry /><entry>i.e in picolitres or</entry></row><row><entry /><entry /><entry>in microlitres.</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry namest="1" nameend="3" align="left" id="FOO-00063"><sup>a</sup>Refer to Type Map in Appendix A for exact value.</entry></row><row><entry namest="1" nameend="3" align="left" id="FOO-00064"><sup>b</sup>Non authenticated Read Write permission.</entry></row><row><entry namest="1" nameend="3" align="left" id="FOO-00065"><sup>c</sup>Authenticated Read Write permission.</entry></row></tbody></tgroup></table></tables><br /> 28.6.2 Peer to Peer Transfer
6511Referring to <figref idref="DRAWINGS">FIG. 385</figref>, this transfer is typically performed when count-remaining amount is transferred from OEM's Parameter Upgrader Refill QA Device to another Parameter Device Refill QA Device belonging to the same OEM.
000028.6.2.1 Keys and Access Permission
6512There is an count-remaining field associated with the refill device. This count-remaining field has a single key associated with: <ul id="ul0922" list-style="none"><li id="ul0922-0001" num="0000"><ul id="ul0923" list-style="none"><li id="ul0923-0001" num="6513">This key transfers count-remaining amount to the device from another refill device (which is higher or at the same level in the heirachy), fills/refills (upgrades) the device itself, and additionally transfers ink from it to other devices (which are lower in the heirachy), fills/refills (upgrades) other devices from it.</li></ul></li></ul>
6514This key is referred to as the fill/refill key and is used for both fill/refill and transfer. Hence, this key has both ReadWrite and Decrement-Only permission to the count-remaining field in the refill device.
000028.6.2.1.1 Count-remaining Field Information
6515Table 301 shows the field information for an <sub>M0 </sub>field storing logical count-remaining amounts in the refill device with the ability to transfer between peers.
6516<tables id="TABLE-US-00494" num="00494"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 301</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Field information for ink-remaining field for</entry></row><row><entry>refill devices transferring between peers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="35pt" align="left" /><colspec colname="2" colwidth="105pt" align="left" /><colspec colname="3" colwidth="77pt" align="left" /><tbody valign="top"><row><entry>Attribute</entry><entry /><entry /></row><row><entry>Name</entry><entry>Value</entry><entry>Explanation</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>Type</entry><entry>TYPE_COUNT_REMAINING<sup>a</sup></entry><entry>Type describes that</entry></row><row><entry /><entry /><entry>the field is a count-</entry></row><row><entry /><entry /><entry>remaining field.</entry></row><row><entry>KeyNum</entry><entry>Slot number of the</entry><entry>Only the refill key</entry></row><row><entry /><entry>refill key.</entry><entry>has authenticated</entry></row><row><entry /><entry /><entry>ReadWrite access to</entry></row><row><entry /><entry /><entry>this field.</entry></row><row><entry>Non Auth</entry><entry>0</entry><entry>Non authenticated</entry></row><row><entry>RW Perm<sup>b</sup></entry><entry /><entry>ReadWrite is not</entry></row><row><entry /><entry /><entry>allowed to the field.</entry></row><row><entry>Auth RW</entry><entry>1</entry><entry>Authenticated (key</entry></row><row><entry>Perm<sup>c</sup></entry><entry /><entry>based) ReadWrite</entry></row><row><entry /><entry /><entry>access is allowed</entry></row><row><entry /><entry /><entry>to the field.</entry></row><row><entry>KeyPerm</entry><entry>KeyPerms[KeyNum] = 1</entry><entry>KeyNum is the slot</entry></row><row><entry /><entry /><entry>number of the refill</entry></row><row><entry /><entry /><entry>key, which has</entry></row><row><entry /><entry /><entry>ReadWrite and Decre-</entry></row><row><entry /><entry /><entry>ment permission to</entry></row><row><entry /><entry /><entry>the field.</entry></row><row><entry /><entry>KeyPerms[others =</entry><entry>All other keys have</entry></row><row><entry /><entry>0 . . . 7(except</entry><entry>ReadOnly access.</entry></row><row><entry /><entry>KeyNum)] = 0</entry></row><row><entry>End Pos</entry><entry>Set as required.</entry><entry>Depends on the amount</entry></row><row><entry /><entry /><entry>of logical ink the</entry></row><row><entry /><entry /><entry>device can store and</entry></row><row><entry /><entry /><entry>storage resolution -</entry></row><row><entry /><entry /><entry>i.e in picolitres or</entry></row><row><entry /><entry /><entry>in microlitres.</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry namest="1" nameend="3" align="left" id="FOO-00066"><sup>a</sup>Refer to Type Map in Appendix A for exact value.</entry></row><row><entry namest="1" nameend="3" align="left" id="FOO-00067"><sup>b</sup>Non authenticated Read Write permission.</entry></row><row><entry namest="1" nameend="3" align="left" id="FOO-00068"><sup>c</sup>Authenticated Read Write permission.</entry></row></tbody></tgroup></table></tables><br /> 29 Functions <br /> 29.1 XferField <ul id="ul0924" list-style="none"><li id="ul0924-0001" num="0000"><ul id="ul0925" list-style="none"><li id="ul0925-0001" num="6517">Input: KeyRef, <sub>M0</sub>OfExternal, <sub>M1</sub>OfExternal, ChipID, FieldNumL, FieldNumE, InputParameterCheck (Optional), R<sub>E</sub>, SIG<sub>E</sub>, R<sub>E2 </sub></li><li id="ul0925-0002" num="6518">Output: ResultFlag, Field data, R<sub>L2</sub>, SIG<sub>out </sub></li><li id="ul0925-0003" num="6519">Changes: <sub>M0 </sub>and R<sub>L </sub></li><li id="ul0925-0004" num="6520">Availablity: Parameter Upgrader QA Device <br /> 29.1.1 Function Description </li></ul></li></ul>
6521The XferField is similar to the XferAmount function in that it produces data and signature for updating a given <sub>M0 </sub>field. This data and signature when applied to the appropriate device through the WriteFieldsAuth function, will upgrade the FieldNumE (<sub>M0 </sub>field) of a device to the same value as FieldNumL of the upgrading device.
6522The system calls the XferField function on the upgrade device with a certain FieldNumL to be transferred to the device being upgraded The FieldNumE is validated by the XferField function according to various rules as described in Section 29.1.4. If validation succeeds the XferField function produces the data and signature for subsequent passing into the WriteFieldsAuth function for the device being upgraded.
6523The transfer field output consists of the new data for the field being upgraded, field data of the two sequence fields, and a signature. When a transfer output is produced, the sequence field data in SEQ<sub>—</sub>1 is decremented by 2 from the previous value (as passed in with the input), and the sequence field data in SEQ<sub>—</sub>2 is decremented by 1 from the previous value (as passed in with the input).
6524Additional InputParameterCheck value must be provided for the parameters not included in the SIG<sub>E</sub>, if the transmission between the System and Parameter Upgrader QA Device is error prone, and these errors are not corrected by the transimission protocol itself. InputParameterCheck is SHA-1[FieldNumL|FieldNumE|XferValLength|XferVal], and is required to ensure the integrity of these parameters, when these inputs are received by the Parameter Upgrader QA Device.
6525The XferField function must first calculate the SHA-1[FieldNumL|FieldNumE], compare the calculated value to the value received (InputParameterCheck) and only if the values match act upon the inputs.
000029.1.2 Input Parameters
0000<ul id="ul0926" list-style="none"><li id="ul0926-0001" num="0000"><ul id="ul0927" list-style="none"><li id="ul0927-0001" num="6526">Table 302 describes each of the input parameters for XferField function.</li></ul></li></ul>
6527<tables id="TABLE-US-00495" num="00495"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="161pt" align="left" /><thead><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>Parameter</entry><entry>Description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>KeyRef</entry><entry>For common key input and output signature:</entry></row><row><entry /><entry>KeyRef.keyNum = Slot number of the key to</entry></row><row><entry /><entry>be used for testing input signature and</entry></row><row><entry /><entry>producing the output signature. SIG<sub>E </sub>produced</entry></row><row><entry /><entry>using K<sub>KeyRef.keyNum </sub>by the QA Device being</entry></row><row><entry /><entry>upgraded. SIGout produced using K<sub>KeyRef.keyNum</sub></entry></row><row><entry /><entry>for delivery to the QA Device being upgraded.</entry></row><row><entry /><entry>KeyRef.useChipId = 0</entry></row><row><entry /><entry>For variant key input and output signatures:</entry></row><row><entry /><entry>KeyRef.keyNum = Slot number of the key to be</entry></row><row><entry /><entry>used for generating the variant key. SIG<sub>E </sub>produced</entry></row><row><entry /><entry>using a variant of K<sub>KeyRef.keyNum </sub>by the QA Device</entry></row><row><entry /><entry>being upgraded. SIGout produced using a variant of</entry></row><row><entry /><entry>K<sub>KeyRef.keyNum </sub>for delivery to the QA Device being</entry></row><row><entry /><entry>upgraded. KeyRef.useChipId = 1 KeyRef.chipId =</entry></row><row><entry /><entry>ChipId of the device which generated SIG<sub>E </sub>and</entry></row><row><entry /><entry>will receive SIGout.</entry></row><row><entry><sub>M0</sub>OfExternal</entry><entry>All 16 words of <sub>M0 </sub>of the QA Device being upgraded</entry></row><row><entry><sub>M1</sub>OfExternal</entry><entry>All 16 words of <sub>M1 </sub>of the QA Device being upgraded.</entry></row><row><entry>ChipId</entry><entry>ChipId of the QA Device being upgraded.</entry></row><row><entry>FieldNumL</entry><entry><sub>M0 </sub>field number of the local (updating) device. The</entry></row><row><entry /><entry>data stored in this field will be copied from the</entry></row><row><entry /><entry>upgrading device.</entry></row><row><entry>FieldNumE</entry><entry><sub>M0 </sub>field number of the QA Device being upgraded.</entry></row><row><entry /><entry>This field will be updated to the value stored in</entry></row><row><entry /><entry>FieldNumL within the upgrading device.</entry></row><row><entry>R<sub>E</sub></entry><entry>External random value used to verify input</entry></row><row><entry /><entry>signature. This will be the R from the input</entry></row><row><entry /><entry>signature generator (i.e device generating SIG<sub>E</sub>).</entry></row><row><entry /><entry>The input signal generator in this case, is the</entry></row><row><entry /><entry>device being upgraded or a translation device.</entry></row><row><entry>R<sub>E2</sub></entry><entry>External random value used to produce output</entry></row><row><entry /><entry>signature. This will be the R obtained by calling</entry></row><row><entry /><entry>the Random function on the device which will</entry></row><row><entry /><entry>receive the SIG<sub>out </sub>from the XferField function.</entry></row><row><entry /><entry>The device receiving the SIG<sub>out </sub>in this case, is</entry></row><row><entry /><entry>the device being upgraded or a translation device.</entry></row><row><entry>SIG<sub>E</sub></entry><entry>External signature required for authenticating</entry></row><row><entry /><entry>input data. The input data in this case, is the</entry></row><row><entry /><entry>output from the Read function performed on the</entry></row><row><entry /><entry>device being upgraded.</entry></row><row><entry /><entry>A correct SIG<sub>E </sub>= SIG<sub>KeyRef</sub>(Data | R<sub>E </sub>| R<sub>L</sub>).</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 29.1.2.1 Input Signature Verification Data Format <ul id="ul0928" list-style="none"><li id="ul0928-0001" num="0000"><ul id="ul0929" list-style="none"><li id="ul0929-0001" num="6528">Refer to Section 27.1.2.1. <br /> 29.1.3 Output Parameters </li><li id="ul0929-0002" num="6529">Table 303 describes each of the output parameters for XferField function.</li></ul></li></ul>
6530<tables id="TABLE-US-00496" num="00496"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="154pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>Parameter</entry><entry>Description</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>ResultFlag</entry><entry>Indicates whether the function completed</entry></row><row><entry /><entry /><entry>successfully or not. If it did not complete</entry></row><row><entry /><entry /><entry>successfully, the reason for the failure is</entry></row><row><entry /><entry /><entry>returned here. See Section 12.1, Table 292</entry></row><row><entry /><entry /><entry>and Table 303.</entry></row><row><entry /><entry>FieldSelect</entry><entry>Selection of fields to be written</entry></row><row><entry /><entry /><entry>In this case the bit corresponding to SEQ_1,</entry></row><row><entry /><entry /><entry>SEQ_2 and to FieldNumE are set to 1.</entry></row><row><entry /><entry /><entry>All other bits are set to 0.</entry></row><row><entry /><entry>FieldVal</entry><entry>Updated data words for sequence data field</entry></row><row><entry /><entry /><entry>and FieldNumE for QA Device being upgraded.</entry></row><row><entry /><entry /><entry>Starts with LSW of lower field.</entry></row><row><entry /><entry /><entry>This must be passed as input to the</entry></row><row><entry /><entry /><entry>WriteFieldsAuth function of the</entry></row><row><entry /><entry /><entry>QA Device being upgraded.</entry></row><row><entry /><entry>R<sub>L2</sub></entry><entry>Internal random value required to generate</entry></row><row><entry /><entry /><entry>output signature This must be passed as input</entry></row><row><entry /><entry /><entry>to the WriteFieldsAuth function or Translate</entry></row><row><entry /><entry /><entry>function of the QA Device being upgraded.</entry></row><row><entry /><entry>SIG<sub>out</sub></entry><entry>Output signature which must be passed as an</entry></row><row><entry /><entry /><entry>input to the WriteFieldsAuth function or</entry></row><row><entry /><entry /><entry>Translate function of the QA Device being</entry></row><row><entry /><entry /><entry>upgraded.</entry></row><row><entry /><entry /><entry>SIG<sub>out </sub>= SIG<sub>KeyRef</sub>(data | R<sub>L2 </sub>| R<sub>E2</sub>) as</entry></row><row><entry /><entry /><entry>per FIG. 373</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
6531<tables id="TABLE-US-00497" num="00497"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 303</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Result Flag definitions for XferField</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="98pt" align="left" /><colspec colname="2" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry>ReultFlag Definition</entry><entry>Description</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>CountRemainingFieldInvalid</entry><entry>The count- remaining field in</entry></row><row><entry /><entry /><entry>Upgrading QA Device is invalid.</entry></row><row><entry /><entry>FieldNumEKeyPermInvalid</entry><entry>The upgrade field in the QA</entry></row><row><entry /><entry /><entry>Device being upgraded doesn't</entry></row><row><entry /><entry /><entry>have the correct authen-ticated</entry></row><row><entry /><entry /><entry>permission.</entry></row><row><entry /><entry>NoUpgradesRemaining</entry><entry>The count-remaining field</entry></row><row><entry /><entry /><entry>assocaited with the upgrade</entry></row><row><entry /><entry /><entry>field in the Upgrading</entry></row><row><entry /><entry /><entry>QA Device doesn't have any</entry></row><row><entry /><entry /><entry>more upgrades left.</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 29.1.3.1 Output Signature Generation Data Format <ul id="ul0930" list-style="none"><li id="ul0930-0001" num="0000"><ul id="ul0931" list-style="none"><li id="ul0931-0001" num="6532">Refer to Section 27.1.3.1. <br /> 29.1.4 Function Sequence </li><li id="ul0931-0002" num="6533">The XferField command is illustrated by the following pseudocode:</li></ul></li><li id="ul0930-0002" num="6534">Accept input parameters-KeyRef, M0OfExternal, M1 OfExternal, ChipID, FieldNumL, FieldNumE, R<sub>E</sub>, SIG<sub>E</sub>, R<sub>E2</sub></li></ul>
6535<tables id="TABLE-US-00498" num="00498"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>#Generate message for passing into ValidateKeyRefAndSignature</entry></row><row><entry>function</entry></row><row><entry>data <img file="US7165824B2_D0656.tif" /> (RWSense|MSelect|KeyIdSelect|ChipId|WordSelect|M0|M1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry># Refer to Figure 382.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>----------------------------------------------------------------</entry></row><row><entry># Validate KeyRef, and then verify signature</entry></row><row><entry>ResultFlag = ValidateKeyRefAndSignature(KeyRef,data,R<sub>E</sub>,R<sub>L</sub>)</entry></row><row><entry>If (ResultFlag ≠ Pass)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>----------------------------------------------------------------</entry></row><row><entry># Validatate FieldNumE</entry></row><row><entry># FieldNumE is present in the device being upgraded</entry></row><row><entry>PresentFlagFieldNumE <img file="US7165824B2_D0657.tif" /> GetFieldPresent(M1OfExternal,FieldNumE)</entry></row><row><entry># Check FieldNumE present flag</entry></row><row><entry>If(PresentFlagFieldNumE ≠ 1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0658.tif" /> FieldNumEInvalid</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>----------------------------------------------------------------</entry></row><row><entry># Check Seq fields exist and get their Field Number</entry></row><row><entry># Get Seqdata field SEQ_1 for the device being upgraded</entry></row><row><entry>XferSEQ_1FieldNum<img file="US7165824B2_D0659.tif" /> GetFieldNum(M1OfExternal, SEQ_1)</entry></row><row><entry># Check if the Seqdata field SEQ_1 is valid</entry></row><row><entry>If(XferSEQ_1FieldNum invalid)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0660.tif" /> SeqFieldInvalid</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry># Get Seqdata field SEQ_2 for the device being upgraded</entry></row><row><entry>XferSEQ_2FieldNum<img file="US7165824B2_D0661.tif" /> GetFieldNum(M1OfExternal, SEQ_2)</entry></row><row><entry># Check if the Seqdata field SEQ_2 is valid</entry></row><row><entry>If(XferSEQ_2FieldNum invalid)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0662.tif" /> SeqFieldInvalid</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>-------------------------------------------------------------------</entry></row><row><entry>---------------</entry></row><row><entry>#Check write permission for FieldNumE</entry></row><row><entry>PermOKFieldNumE <img file="US7165824B2_D0663.tif" /> CheckFieldNumEPerm(M1OfExternal,</entry></row><row><entry>FieldNumE)</entry></row><row><entry>If(PermOKFieldNumE ≠ 1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0664.tif" /> FieldNumEWritePermInvalid</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>-------------------------------------------------------------------</entry></row><row><entry>---------------</entry></row><row><entry>#Check that both SeqData fields have Decrement-Only permission</entry></row><row><entry>with the same key</entry></row><row><entry>#that has write permission on FieldNumE</entry></row><row><entry>PermOKXferSeqData <img file="US7165824B2_D0665.tif" /> CheckSeqDataFieldPerms(M1OfExternal,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>XferSEQ_1FieldNum,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>XferSEQ_2FieldNum,FieldNumE)</entry></row><row><entry>If(PermOKXferSeqData ≠ 1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0666.tif" /> SeqWritePermInvalid</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>-------------------------------------------------------------------</entry></row><row><entry>----------</entry></row><row><entry># Get SeqData SEQ_1 data from device being upgraded</entry></row><row><entry>GetFieldDataWords(XferSEQ_1FieldNum,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>XferSEQ_1DataFromDevice,M0OfExternal,M1OfExternal)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry># Get SeqData SEQ_2 data from device being upgraded</entry></row><row><entry>GetFieldDataWords(XferSEQ_2FieldNum,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>XferSEQ_2DataFromDevice,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>M0OfExternal,M1OfExternal)</entry></row><row><entry>----------------------------------------------------------------</entry></row><row><entry># FieldNumL(upgrade value)is a valid field in the upgrading</entry></row><row><entry>device</entry></row><row><entry>PresentFlagFieldNumL <img file="US7165824B2_D0667.tif" /> GetFieldPresent(M1,FieldNumL)</entry></row><row><entry>If(PresentFlagFieldNumL ≠ 1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0668.tif" /> FieldNumLInvalid</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>----------------------------------------------------------------</entry></row><row><entry>#Get the CountRemaining field associated with the upgrade</entry></row><row><entry>value</entry></row><row><entry>field</entry></row><row><entry># The CountRemaining field is the next higher field</entry></row><row><entry>from the upgrade value field</entry></row><row><entry>FieldNumCountRemaining<img file="US7165824B2_D0669.tif" /> FieldNumL + 1</entry></row><row><entry># FieldNumCountRemaining is a valid field in the</entry></row><row><entry>upgrading device</entry></row><row><entry>PresentFlagFieldNumCountRemaining</entry></row><row><entry><img file="US7165824B2_D0670.tif" /> GetFieldPresent(M1,FieldNumCountRemaining)</entry></row><row><entry>If(PresentFlagFieldNumCountRemaining ≠ 1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0671.tif" /> CountRemainingFieldInvalid</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>----------------------------------------------------------------</entry></row><row><entry>#Check permission for upgrade value field. Only one key</entry></row><row><entry>(different</entry></row><row><entry># from KeRef.keyNum) has write permissions to the field and</entry></row><row><entry>no key</entry></row><row><entry>has decrement permissions.</entry></row><row><entry>CheckOK <img file="US7165824B2_D0672.tif" /> CheckUpgradeKeyForField(FieldNumL,M1,KeyRef)</entry></row><row><entry>If(CheckOK ≠ 1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0673.tif" /> FieldNumEKeyPermInvalid</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>----------------------------------------------------------------</entry></row><row><entry>#Find the type attribute for FieldNumE</entry></row><row><entry>TypeFieldNumE <img file="US7165824B2_D0674.tif" /> FindFieldNumType(M1OfExternal,FieldNumE)</entry></row><row><entry>#Find the type attribute for FieldNumL (upgrade value)</entry></row><row><entry>TypeFieldNumL <img file="US7165824B2_D0675.tif" /> FindFieldNumType(M1,FieldNumL)</entry></row><row><entry>If(TypeFieldNumE ≠ TypeFieldNumL)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0676.tif" /> TypeMismatch</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>----------------------------------------------------------------</entry></row><row><entry># Check permissions for CountRemaining field</entry></row><row><entry># Check upgrades are available in the CountRemaining field</entry></row><row><entry>of the</entry></row><row><entry># upgrading device i.e value of CountRemaining is non-zero</entry></row><row><entry>positive number</entry></row><row><entry>CountRemainingOK <img file="US7165824B2_D0677.tif" /> CheckCountRemaining(FieldNumCountRemaining,</entry></row><row><entry>M0,</entry></row><row><entry>M1)</entry></row><row><entry>If(CountRemainingOK ≠ 1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0678.tif" /> NoUpgradesRemaining</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>----------------------------------------------------------------</entry></row><row><entry>#Get the size of the FieldNumL (upgrade value)</entry></row><row><entry>If(FieldNumL = 0)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>FieldSizeOfFieldNumL<img file="US7165824B2_D0679.tif" /> MaxWordInM− M1[FieldNumL].EndPos</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>FieldSizeOfFieldNumL<img file="US7165824B2_D0680.tif" /> M1[FieldNumL−1].EndPos−</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>M1[FieldNumL].EndPos</entry></row><row><entry>EndIf</entry></row><row><entry>#Get the size of the FieldNumE (field being updated)</entry></row><row><entry>If(FieldNumL = 0)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>FieldSizeOfFieldNumE<img file="US7165824B2_D0681.tif" /> ;MaxWordInM−</entry></row><row><entry /><entry>M1OfExternal[FieldNumE −</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>1].EndPos</entry></row><row><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>FieldSizeOfFieldNumE<img file="US7165824B2_D0682.tif" /> M1OfExternal[FieldNumE−1].EndPos</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>− M1OfExternal[FieldNumL].EndPos</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry># Check whether the device being upgraded can hold the</entry></row><row><entry>upgrade</entry></row><row><entry>value from</entry></row><row><entry># FieldNumL</entry></row><row><entry>If(FieldSizeOfFieldNumE < FieldSizeOfFieldNumL)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0683.tif" /> FieldNumESizeInsufficient</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>----------------------------------------------------------------</entry></row><row><entry># All checks complete .....</entry></row><row><entry># Generate Seqdata for SEQ_1 and SEQ_2 fields</entry></row><row><entry>XferSEQ_1DataToDevice = XferSEQ_1DataFromDevice − 2</entry></row><row><entry>XferSEQ_2DataToDevice = XferSEQ_2DataFromDevice − 1</entry></row><row><entry># Add DataSet to Xfer Entry Cache</entry></row><row><entry>AddDataSetToXferEntryCache(ChipId,FieldNumE, FieldNumL,</entry></row><row><entry>XferSEQ_1DataFromDevice, XferSEQ_2DataFromDevice)</entry></row><row><entry>#Decrement CountRemaining field by one</entry></row><row><entry>DecrementField(FieldNumCountRemaining,M0)</entry></row><row><entry>#Get the upgrade value words from FieldNumE of the</entry></row><row><entry>upgrading</entry></row><row><entry>device</entry></row><row><entry>GetFieldDataWords(FieldNumL,UpgradeValue,M0,M1)</entry></row><row><entry>#Generate new field data words for FieldNumE. The</entry></row><row><entry>upgrade value is</entry></row><row><entry>copied to</entry></row><row><entry>FieldDataE</entry></row><row><entry>FieldDataE<img file="US7165824B2_D0684.tif" /> UpgradeValue</entry></row><row><entry># Generate FieldSelect and FieldVal for SeqData field</entry></row><row><entry>SEQ_1, SEQ_2</entry></row><row><entry>and</entry></row><row><entry># FieldDataE...</entry></row><row><entry>CurrentFieldSelect<img file="US7165824B2_D0685.tif" /> 0</entry></row><row><entry>FieldVal <img file="US7165824B2_D0686.tif" /> 0</entry></row><row><entry>GenerateFieldSelectAndFieldVal(FieldNumE, FieldDataE,</entry></row><row><entry>XferSEQ_1FieldNum, XferSEQ_1DataToDevice,</entry></row><row><entry>XferSEQ_2FieldNum,</entry></row><row><entry>XferSEQ_2DataToDevice,</entry></row><row><entry>FieldSelect,FieldVal)</entry></row><row><entry>#Generate message for passing into GenerateSignature</entry></row><row><entry>function</entry></row><row><entry>data <img file="US7165824B2_D0687.tif" /> (RWSense|FieldSelect|ChipId|FieldVal)# Refer to</entry></row><row><entry>Figure 373.</entry></row><row><entry>#Create output signature for FieldNumE</entry></row><row><entry>SIG<sub>out</sub><img file="US7165824B2_D0688.tif" /> GenerateSignature(KeyRef,data,R<sub>L2</sub>,R<sub>E2</sub>)</entry></row><row><entry>Update R<sub>L2 </sub>to R<sub>L3</sub></entry></row><row><entry>ResultFlag <img file="US7165824B2_D0689.tif" /> Pass</entry></row><row><entry>Output ResultFlag, FieldSelect,FieldVal, R<sub>L2 ,</sub>SIG<sub>out</sub></entry></row><row><entry>Return</entry></row><row><entry>EndIf</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 29.1.4.1 CountRemainingOK <ul id="ul0932" list-style="none"><li id="ul0932-0001" num="0000"><ul id="ul0933" list-style="none"><li id="ul0933-0001" num="6536">CheckCountRemainingFieldNumL(FieldNumCountRemaining, M1, M0) <ul id="ul0934" list-style="none"><li id="ul0934-0001" num="6537">This functions checks permissions for CountRemaining field and also checks that upgrades are available in the CountRemaining field of the upgrading device.</li></ul></li></ul></li></ul>
6538<tables id="TABLE-US-00499" num="00499"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>AuthRW <img file="US7165824B2_D0690.tif" /> M1[FieldNumCountRemaining].AuthRW</entry></row><row><entry /><entry>NonAuthRW <img file="US7165824B2_D0691.tif" /> M1[FieldNumCountRemaining].NonAuthRW</entry></row><row><entry /><entry>DOForKeys <img file="US7165824B2_D0692.tif" /> M1[FieldNumCountRemaining].DOForKeys[KeyNum]</entry></row><row><entry /><entry>Type <img file="US7165824B2_D0693.tif" /><sub>M1</sub>[FieldNumCountRemaining].Type</entry></row><row><entry /><entry>If(AuthRW = 1 <img file="US7165824B2_D0694.tif" /> NonAuthRW = 0 <img file="US7165824B2_D0695.tif" /> (DOForKeys = 1<img file="US7165824B2_D0696.tif" /> (Type =</entry></row><row><entry /><entry>TYPE_COUNT_REMAINING)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>PermOK <img file="US7165824B2_D0697.tif" /> 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>PermOK <img file="US7165824B2_D0698.tif" /> 0</entry></row><row><entry /><entry>Return PermOK</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>#Get the count-remaining value from the upgrading device</entry></row><row><entry /><entry>GetFieldDataWords(FieldNumCountRemaining,CountRemainingValue,M0,M1</entry></row><row><entry /><entry>)</entry></row><row><entry /><entry>If(CountRemainingValue <= 0)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>PermOK <img file="US7165824B2_D0699.tif" /> 0</entry></row><row><entry /><entry>Return PermOK</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>PermOK <img file="US7165824B2_D0700.tif" /> 1</entry></row><row><entry /><entry>Return PermOK</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 29.2 RollBackField <ul id="ul0935" list-style="none"><li id="ul0935-0001" num="0000"><ul id="ul0936" list-style="none"><li id="ul0936-0001" num="6539">Input: KeyRef, <sub>M0</sub>OfExternal, <sub>M1</sub>OfExternal, ChipID, FieldNumL, FieldNumE, InputParameterCheck (optional), R<sub>E</sub>, SIG<sub>E </sub></li><li id="ul0936-0002" num="6540">Output: ResultFlag</li><li id="ul0936-0003" num="6541">Changes: <sub>M0 </sub>and R<sub>L </sub></li><li id="ul0936-0004" num="6542">Availablity: Parameter Upgrader QA Device <br /> 29.2.1 Function Description </li></ul></li></ul>
6543The RollBackField function is very similar to the RollBackAmount function, the only difference being that the RollBackField function adjusts the value of the count-remaining field associated with the upgrade value field of the upgrading device, instead of the upgrade value field itself. A successful rollback, increments the count-remaining by 1.
6544The Parameter Upgrader QA Device checks that the Printer QA Device didn't actually receive the transfer message correctly, by comparing the sequence data field values read from the device with the values stored in the Xfer Entry cache. The sequence data field values read must match what was previously written using the StartRollBack function. After all checks are fulfilled, the Parameter Upgrader QA Device adjusts its FieldNumL.
6545Additional InputParameterCheck value must be provided for the parameters not included in the SIG<sub>E</sub>, if the transmission between the System and Parameter Upgrader QA Device is error prone, and these errors are not corrected by the transimission protocol itself. InputParameterCheck is SHA-1[FieldNumL|FieldNumE], and is required to ensure the integrity of these parameters, when these inputs are received by the Parameter Upgrader QA Device.
6546The RollBackField function must first calculate the SHA-1[FieldNumL|FieldNumE], compare the calculated value to the value received (InputParameterCheck) and only if the values match act upon the inputs.
000029.2.2 Input Parameters
0000<ul id="ul0937" list-style="none"><li id="ul0937-0001" num="0000"><ul id="ul0938" list-style="none"><li id="ul0938-0001" num="6547">Table 305 describes each of the input parameters for RollBackField function.</li></ul></li></ul>
6548<tables id="TABLE-US-00500" num="00500"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="133pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>Parameter</entry><entry>Description</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>KeyRef</entry><entry>For common key input signature:</entry></row><row><entry /><entry /><entry>KeyRef.keyNum =</entry></row><row><entry /><entry /><entry>Slot number of the key to be</entry></row><row><entry /><entry /><entry>used for testing input</entry></row><row><entry /><entry /><entry>signature. SIG<sub>E </sub>produced using</entry></row><row><entry /><entry /><entry>K<sub>KeyRef.keyNum </sub>by the</entry></row><row><entry /><entry /><entry>QA Device being upgraded.</entry></row><row><entry /><entry /><entry>KeyRef.useChipId = 0</entry></row><row><entry /><entry /><entry>For variant key input signature:</entry></row><row><entry /><entry /><entry>KeyRef.keyNum =</entry></row><row><entry /><entry /><entry>Slot number of the key to be used</entry></row><row><entry /><entry /><entry>for generating</entry></row><row><entry /><entry /><entry>the variant key. SIG<sub>E </sub>produced</entry></row><row><entry /><entry /><entry>using a variant of</entry></row><row><entry /><entry /><entry>K<sub>KeyRef.keyNum </sub>by the QA Device</entry></row><row><entry /><entry /><entry>being upgraded.</entry></row><row><entry /><entry /><entry>KeyRef.useChipId = 1</entry></row><row><entry /><entry /><entry>KeyRef.chipId = ChipId</entry></row><row><entry /><entry /><entry>of the device which generated SIG<sub>E</sub>.</entry></row><row><entry /><entry><sub>M0</sub>OfExternal</entry><entry>16 words of <sub>M0 </sub>of the QA Device</entry></row><row><entry /><entry /><entry>being upgraded</entry></row><row><entry /><entry /><entry>which failed to upgrade.</entry></row><row><entry /><entry><sub>M1</sub>OfExternal</entry><entry>16 words of <sub>M1 </sub>of the QA Device</entry></row><row><entry /><entry /><entry>being upgraded</entry></row><row><entry /><entry /><entry>which failed to upgrade.</entry></row><row><entry /><entry>ChipId</entry><entry>ChipId of the QA Device being</entry></row><row><entry /><entry /><entry>upgraded which failed</entry></row><row><entry /><entry /><entry>to upgrade.</entry></row><row><entry /><entry>FieldNumL</entry><entry><sub>M0 </sub>field number of the local</entry></row><row><entry /><entry /><entry>(upgrading) device whose value</entry></row><row><entry /><entry /><entry>could not be copied to the device</entry></row><row><entry /><entry /><entry>being upgraded.</entry></row><row><entry /><entry>FieldNumE</entry><entry><sub>M0 </sub>field number of the QA Device</entry></row><row><entry /><entry /><entry>being upgraded to</entry></row><row><entry /><entry /><entry>which the upgrade value in FieldNumL</entry></row><row><entry /><entry /><entry>couldn't be copied.</entry></row><row><entry /><entry>R<sub>E</sub></entry><entry>External random value used to verify</entry></row><row><entry /><entry /><entry>input signature.</entry></row><row><entry /><entry /><entry>This will be the R from the input</entry></row><row><entry /><entry /><entry>signature genera-</entry></row><row><entry /><entry /><entry>tor (i.e device generating SIG<sub>E</sub>).</entry></row><row><entry /><entry /><entry>The input signal</entry></row><row><entry /><entry /><entry>generator in this case, is the</entry></row><row><entry /><entry /><entry>device which failed</entry></row><row><entry /><entry /><entry>to upgrade or a translation device.</entry></row><row><entry /><entry>SIG<sub>E</sub></entry><entry>External signature required for</entry></row><row><entry /><entry /><entry>authenticating input</entry></row><row><entry /><entry /><entry>data. The input data in this case,</entry></row><row><entry /><entry /><entry>is the output</entry></row><row><entry /><entry /><entry>from the Read function performed on</entry></row><row><entry /><entry /><entry>the device which</entry></row><row><entry /><entry /><entry>failed to upgrade. A correct</entry></row><row><entry /><entry /><entry>SIG<sub>E </sub>= SIG<sub>KeyRef</sub></entry></row><row><entry /><entry /><entry>(Data | R<sub>E </sub>| R<sub>L</sub>).</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 29.2.2.1 Input Signature Generation Data Format <ul id="ul0939" list-style="none"><li id="ul0939-0001" num="0000"><ul id="ul0940" list-style="none"><li id="ul0940-0001" num="6549">Refer to Section 27.1.2.1 for details. <br /> 29.2.3 Output Parameters </li><li id="ul0940-0002" num="6550">Table 306 describes each of the output parameters for RollBackField.</li></ul></li></ul>
6551<tables id="TABLE-US-00501" num="00501"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="168pt" align="left" /><thead><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>Parameter</entry><entry>Description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>ResultFlag</entry><entry>Indicates whether the function completed successfully</entry></row><row><entry /><entry>or not. If it did not complete successfully, the reason</entry></row><row><entry /><entry>for the failure is returned here.</entry></row><row><entry /><entry>See Section 12.1, Table 292, Table 304 and Table 295.</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 29.2.4 Function Sequence <ul id="ul0941" list-style="none"><li id="ul0941-0001" num="0000"><ul id="ul0942" list-style="none"><li id="ul0942-0001" num="6552">The RollBackField command is illustrated by the following pseudocode:</li></ul></li></ul>
6553<tables id="TABLE-US-00502" num="00502"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>Accept input parameters-KeyRef, M0OfExternal, M1OfExternal,</entry></row><row><entry>ChipId, FieldNumL, FieldNumE, R<sub>E</sub>,SIG<sub>E</sub></entry></row><row><entry>#Generate message for passing into GenerateSignature function</entry></row><row><entry>data <img file="US7165824B2_D0701.tif" /> (RWSense|MSelect|KeyIdSelect|ChipId|WordSelect|M0|M1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry># Refer to Figure 382.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>----------------------------------------------------------------</entry></row><row><entry># Validate KeyRef, and then verify signature</entry></row><row><entry>ResultFlag = ValidateKeyRefAndSignature(KeyRef,data,R<sub>E</sub>,R<sub>L</sub>)</entry></row><row><entry>If (ResultFlag ≠ Pass)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>----------------------------------------------------------------</entry></row><row><entry># Check Seq fields exist and get their Field Number</entry></row><row><entry># Get Seqdata field SEQ_1 num for the device being upgraded</entry></row><row><entry>XferSEQ_1FieldNum<img file="US7165824B2_D0702.tif" /> GetFieldNum(M1OfExternal, SEQ_1)</entry></row><row><entry># Check if the Seqdata field SEQ_1 is valid</entry></row><row><entry>If(XferSEQ_1FieldNum invalid)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0703.tif" /> SeqFieldInvalid</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry># Get Seqdata field SEQ_2 num for the device being upgraded</entry></row><row><entry>XferSEQ_2FieldNum<img file="US7165824B2_D0704.tif" /> GetFieldNum(M1OfExternal, SEQ_2)</entry></row><row><entry># Check if the Seqdata field SEQ_2 is valid</entry></row><row><entry>If(XferSEQ_2FieldNum invalid)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0705.tif" /> SeqFieldInvalid</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry>----------------------------------------------------------------</entry></row><row><entry># Get SeqData SEQ_1 data from device being upgraded</entry></row><row><entry>GetFieldDataWords(XferSEQ_1FieldNum,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>XferSEQ_1DataFromDevice,M0OfExternal,M1OfExternal)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry># Get SeqData SEQ_2 data from device being upgraded</entry></row><row><entry>GetFieldDataWords(XferSEQ_2FieldNum,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>XferSEQ_2DataFromDevice,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>M0OfExternal,M1OfExternal)</entry></row><row><entry># Generate Seqdata for SEQ_1 and SEQ_2 fields with the data that</entry></row><row><entry>is read</entry></row><row><entry>XferSEQ_1Data = XferSEQ_1DataFromDevice + 1</entry></row><row><entry>XferSEQ_2Data = XferSEQ_2DataFromDevice + 2</entry></row><row><entry># Check Xfer Entry in cache is correct - dataset exists, Field</entry></row><row><entry>data</entry></row><row><entry># and sequence field data matches and Xfer State is correct</entry></row><row><entry>XferEntryOK <img file="US7165824B2_D0706.tif" /> CheckEntry(ChipId, FieldNumE, FieldNumL,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>XferSEQ_1Data, XferSEQ_2Data)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>If( XferEntryOK= 0)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ResultFlag <img file="US7165824B2_D0707.tif" /> RollBackInvalid</entry></row><row><entry /><entry>Output ResultFlag</entry></row><row><entry /><entry>Return</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry># Increment associated CountRemaining by 1</entry></row><row><entry>IncrementCountRemaining(FieldNumCountRemaining)</entry></row><row><entry># Update XferState in DataSet to complete/deleted</entry></row><row><entry>UpdateXferStateToComplete(ChipId,FieldNumE)</entry></row><row><entry>ResultFlag <img file="US7165824B2_D0708.tif" /> Pass</entry></row><row><entry>Output ResultFlag</entry></row><row><entry>Return</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> Example Sequence of Operations <br /> 30 Concepts
6554The QA Chip Logical Interface interface devices do not initiate any activities themselves. Instead the System reads data and signature from various untrusted devices, and sends the data and signature to a trusted device for validation of signature, and then uses the data to perform operations required for printing, refilling, upgrading and key replacement. The system will therefore be responsible for performing the functional sequences required for printing, refilling, upgrading and key replacement. It formats all input parameters required for a particular function, then calls the function with the input parameters on the appropriate QA Chip Logical Interface instance, and then processes/stores the output parameters from the function appropriately.
6555Validation of signatures is achieved by either of the following schemes: <ul id="ul0943" list-style="none"><li id="ul0943-0001" num="0000"><ul id="ul0944" list-style="none"><li id="ul0944-0001" num="6556">Direct—the signature produced by an untrusted device is directly passed in for validation to the trusted device. The direct validation requires the untrusted device to share a common key or a variant key with the trusted device. Refer to Section 7 for further details on common and variant keys.</li><li id="ul0944-0002" num="6557">Translation—the signature produced by an untrusted is first validated by the translating device, and a new signature of the read data is produced by the translation device for validation by the trusted device. Several translation device may be chained together—the first translation device validates the signature from the untrusted device, and the last translation device produces the final signature for validation by the trusted device. The translation device must share a common key or a variant key with the trusted/untrusted device and among themselves, if several translation devices are chained together for signature validation. <br /> 30.1 Representation </li></ul></li></ul>
6558Each functional sequence consists of the following devices (refer to Section 4.3): <ul id="ul0945" list-style="none"><li id="ul0945-0001" num="0000"><ul id="ul0946" list-style="none"><li id="ul0946-0001" num="6559">System.</li><li id="ul0946-0002" num="6560">A trusted QA Device—which may be a system trusted QA Device, or an Parameter Upgrader QA Device, or a Ink Refill QA Device, or a Key Programmer QA Device depending on the function performed. This device is referred to as device A.</li><li id="ul0946-0003" num="6561">An untrusted QA Device—which may be a Printer QA Device, or an Ink QA Device. This device is referred to as device B.</li><li id="ul0946-0004" num="6562">A translation QA Device will be used if a translation scheme is used to validate signatures. This device is referred to as device C.</li></ul></li></ul>
6563The command sequence produced by the system for further sequences will be documented as shown in Table 307.
6564<tables id="TABLE-US-00503" num="00503"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 307</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Command sequence representation</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="91pt" align="left" /><tbody valign="top"><row><entry>Sequence</entry><entry /><entry /></row><row><entry>No</entry><entry>Function</entry><entry>Parameters</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>Sequence</entry><entry>Device.FunctionName</entry><entry>Input Parameters and their</entry></row><row><entry>order</entry><entry /><entry>values.</entry></row><row><entry /><entry /><entry>Output parameters and their</entry></row><row><entry /><entry /><entry>description.</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
6565Therefore, a typical direct signature validation sequence can be represented by <figref idref="DRAWINGS">FIG. 386</figref> and Table 308.
6566For a direct signature to be used, A and B must share a common or a variant key i.e B.K<sub>n1</sub>=A.K<sub>n2 </sub>or B.K<sub>n1</sub>=FormKeyVariant(A.K<sub>n2</sub>, B.ChipID).
6567<tables id="TABLE-US-00504" num="00504"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 308</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Command sequence for direct signature validation</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="42pt" align="center" /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="133pt" align="left" /><tbody valign="top"><row><entry>Sequence</entry><entry /><entry /></row><row><entry>No</entry><entry>Function</entry><entry>Parameters</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="42pt" align="char" char="." /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="133pt" align="left" /><tbody valign="top"><row><entry>1</entry><entry>A. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>A </sub>= RL</entry></row><row><entry>2</entry><entry>B. Read</entry><entry>KeyRef = n1, SigOnly = 0, MSelect =</entry></row><row><entry /><entry /><entry>Any one M, KeyIdSelect = 0,</entry></row><row><entry /><entry /><entry>WordSelectForDesiredM = Any one</entry></row><row><entry /><entry /><entry>word in the selected M, RE = R<sub>A</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then MWords =</entry></row><row><entry /><entry /><entry>SelectedWordsOfSelectedMs as per</entry></row><row><entry /><entry /><entry>input [MSelect] and</entry></row><row><entry /><entry /><entry>[WordSelectForDesiredM],</entry></row><row><entry /><entry /><entry>R<sub>B </sub>= R<sub>L</sub>, SIG<sub>B </sub>= SIGout Refer to</entry></row><row><entry /><entry /><entry>Section 15.3.1.</entry></row><row><entry>3</entry><entry>A. Test</entry><entry>KeyRef = n2, DataLength = Length</entry></row><row><entry /><entry /><entry>of MWords in words preformatted as per</entry></row><row><entry /><entry /><entry>Section 16.1, Data = MWords preformatted</entry></row><row><entry /><entry /><entry>as per Section 16.1, RE = R<sub>B</sub>,</entry></row><row><entry /><entry /><entry>SIGE = SIG<sub>B</sub></entry></row><row><entry /><entry /><entry>ResultFlag = Pass/Fail</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
6568A typical signature validation using translation can be represented by <figref idref="DRAWINGS">FIG. 387</figref> and Table 309.
6569For validating signatures using translation: <ul id="ul0947" list-style="none"><li id="ul0947-0001" num="0000"><ul id="ul0948" list-style="none"><li id="ul0948-0001" num="6570">A and C must share a common or a variant key i.e C.K<sub>n3</sub>=A.K<sub>n2 </sub>or C.K<sub>n3</sub>=FormKeyVariant(A.K<sub>2</sub>, C.ChipID).</li><li id="ul0948-0002" num="6571">B and C must share a common or a variant key i.e C.K<sub>n2</sub>=B.K<sub>n1 </sub>or B.K<sub>n1</sub>=Form KeyVariant(C.K<sub>n2</sub>, B.ChipID).</li></ul></li></ul>
6572<tables id="TABLE-US-00505" num="00505"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 309</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Command sequence for signature validation using translation</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="42pt" align="center" /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="133pt" align="left" /><tbody valign="top"><row><entry>Sequence</entry><entry /><entry /></row><row><entry>No</entry><entry>Function</entry><entry>Parameters</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="42pt" align="char" char="." /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="133pt" align="left" /><tbody valign="top"><row><entry>1</entry><entry>C. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>C </sub>= RL</entry></row><row><entry>2</entry><entry>B. Read</entry><entry>KeyRef = n1, SigOnly = 1 or 0,</entry></row><row><entry /><entry /><entry>MSelect = any, KeyIdSelect =</entry></row><row><entry /><entry /><entry>any, WordSelectForDesiredM = any,</entry></row><row><entry /><entry /><entry>RE = R<sub>C</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then</entry></row><row><entry /><entry /><entry>MWords = SelectedWordsOfSelectedMs</entry></row><row><entry /><entry /><entry>as per input [MSelect] and</entry></row><row><entry /><entry /><entry>[WordSelectForDesiredM],</entry></row><row><entry /><entry /><entry>R<sub>B </sub>= R<sub>L</sub>, SIG<sub>B </sub>= SIGout</entry></row><row><entry /><entry /><entry>Refer to Section 15.3.1.</entry></row><row><entry>3</entry><entry>A. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>A </sub>= RL</entry></row><row><entry>4</entry><entry>C. Translate</entry><entry>InputKeyRef = n2, DataLength =</entry></row><row><entry /><entry /><entry>Length of MWords in words preformatted</entry></row><row><entry /><entry /><entry>as per Section 17.1, Data = MWords</entry></row><row><entry /><entry /><entry>preformatted as per Section 17.1,</entry></row><row><entry /><entry /><entry>RE = R<sub>B</sub>, SIGE = SIG<sub>B</sub>,</entry></row><row><entry /><entry /><entry>OutputKeyRef = n3, RE2 = R<sub>A</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then</entry></row><row><entry /><entry /><entry>R<sub>C1 </sub>= R<sub>L2</sub>, SIG<sub>C </sub>= SIGOut</entry></row><row><entry /><entry /><entry>Refer to Section 15.3.1</entry></row><row><entry>5</entry><entry>A. Test</entry><entry>KeyRef = n2, DataLength = Length</entry></row><row><entry /><entry /><entry>of MWords in words preformatted as</entry></row><row><entry /><entry /><entry>per Section 16.1, Data = MWords</entry></row><row><entry /><entry /><entry>preformatted as per Section 16.1,</entry></row><row><entry /><entry /><entry>RE = R<sub>C1</sub>, SIGE = SIG<sub>C</sub></entry></row><row><entry /><entry /><entry>ResultFlag = Pass/Fail</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 31 In Field Use
6573This section covers functional sequences for printer and ink QA Devices, as they perform their usual function of printing.
000031.1 Startup Sequence
6574At startup of any operation (a printer startup or an upgrade startup), the system determines the properties of each QA Device it is going to communicate with. These properties are: <ul id="ul0949" list-style="none"><li id="ul0949-0001" num="0000"><ul id="ul0950" list-style="none"><li id="ul0950-0001" num="6575">Software version of the QA Device. This includes SoftwareReleaseIdMajor and SoftwareReleaseIdMinor. The SoftwareReleaseIdMajor identifies the functions available in the QA Device. Refer to Section 13.2 for details.</li><li id="ul0950-0002" num="6576">The number of memory vectors in the QA Device.</li><li id="ul0950-0003" num="6577">The number of keys in the QA Device.</li><li id="ul0950-0004" num="6578">The ChipId of the QA Device.</li></ul></li></ul>
6579The properties allow the system to determine which functions are available in a given QA Device, as well as the value of input parameters required to communicate with the QA Device.
6580Table 310 shows the startup sequence.
6581<tables id="TABLE-US-00506" num="00506"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 310</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Startup command sequence</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="42pt" align="center" /><colspec colname="2" colwidth="35pt" align="left" /><colspec colname="3" colwidth="140pt" align="left" /><tbody valign="top"><row><entry>Sequence</entry><entry /><entry /></row><row><entry>No</entry><entry>Function</entry><entry>Command</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>1</entry><entry>B. GetInfo</entry><entry>None</entry></row><row><entry /><entry /><entry>Major release identifier of the QA</entry></row><row><entry /><entry /><entry>Device = SoftwareReleaseIdMajor, Minor</entry></row><row><entry /><entry /><entry>release identifier of the QA Device =</entry></row><row><entry /><entry /><entry>SoftwareReleaseIdMinor, Number of memory</entry></row><row><entry /><entry /><entry>vectors in the QA Device = NumVectors,</entry></row><row><entry /><entry /><entry>Number of keys in the QA Device = NumKeys,</entry></row><row><entry /><entry /><entry>Id of the QA Device = ChipId 0 =</entry></row><row><entry /><entry /><entry>VarDataLen No VarData in case of an ink</entry></row><row><entry /><entry /><entry>or printer QA Device</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 31.1.1 Clearing the Preauthorisation Field
6582Preauthorisation of ink is one of the schemes that a printer may use to decrement logical ink as physical ink is used. This is discussed in details in Section 31.4.3.
6583If the printer uses preauthorisation, the system must read the preauthorisation field at startup. If the preauthorisation field is not clear, then the system must apply (decrement) the preauth amount to the corresponding ink field, by performing a non-authenticated write of the decremented amount to the appropriate ink field, and then clear the preauthorisation field by performing an authenticated write to the preauthorisation field.
000031.2 Presence Only Authentication
6584The purpose of presence only authentication is to determine whether the printer should or shouldn't work with the ink cartridge.
000031.2.1 Without Data Interpretation
6585This sequence is performed when the printer authenticates the ink cartridge. The authentication consists of verifying a signature generated by the untrusted ink QA Device (in the ink cartridge) using the system's trusted QA Device.
6586For signature to be valid, the trusted QA Device (A) and the untrusted ink QA Device (B) must share a common or a variant key i.e B.K<sub>n1</sub>=A.K<sub>n2 </sub>or B.K<sub>n1</sub>=FormKeyVariant(A.K<sub>n2</sub>, B.ChipID).
6587A single word of a single M is read because the system is only interested in the validity of signature for a given data.
6588If the printer wants to verify the signature and doesn't require any data from the ink cartridge (because it is cached in the printer), then the printer calls the Read function with SigOnly set to 1. The Read returns only the signature of the data as requested by the input parameters. The printer then sends its cached data and signature (from the Read function) to its trusted QA Device for verification. The printer may use this signature verification scheme if it has read the data previously from the ink QA Device, and the printer knows that the data in the ink QA Device has not changed from value that was read earlier by the printer.
6589Table 311 shows the command sequence for performing presence only authentication requiring both data and signature.
6590<tables id="TABLE-US-00507" num="00507"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="center" /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="147pt" align="left" /><thead><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>Seq</entry><entry /><entry /></row><row><entry>No</entry><entry>Function</entry><entry>Parameters</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="char" char="." /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>1</entry><entry>A. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>A </sub>= RL</entry></row><row><entry>2</entry><entry>B. Read</entry><entry>KeyRef = n1, SigOnly = 0, MSelect =</entry></row><row><entry /><entry /><entry>Any one M, KeyIdSelect = 0,</entry></row><row><entry /><entry /><entry>WordSelectForDesiredM = Any one word in</entry></row><row><entry /><entry /><entry>the selected M, RE = R<sub>A</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then MWords =</entry></row><row><entry /><entry /><entry>SelectedWordsOfSelectedMs as per input</entry></row><row><entry /><entry /><entry>[MSelect] and [WordSelectForDesiredM],</entry></row><row><entry /><entry /><entry>R<sub>B </sub>= R<sub>L</sub>, SIG<sub>B </sub>= SIGout Refer to</entry></row><row><entry /><entry /><entry>Section 15.3.1.</entry></row><row><entry>3</entry><entry>A. Test</entry><entry>KeyRef = n2, DataLength = Length of MWords</entry></row><row><entry /><entry /><entry>in words preformatted as per Section 16.1,</entry></row><row><entry /><entry /><entry>Data = MWords preformatted as per Section</entry></row><row><entry /><entry /><entry>16.1, RE = R<sub>B</sub>, SIGE = SIG<sub>B</sub></entry></row><row><entry /><entry /><entry>ResultFlag = Pass/Fail</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 31.2.2 With Data Interpretation
6591This sequence is performed when the printer reads the relevant data from the untrusted QA Device in the ink cartridge. The system validates the signature from the external ink QA Device, and then uses this data for further processing.
6592For signature to be valid, the trusted QA Device (A) and the untrusted QA Device (B) must share a common or a variant key i.e B.K<sub>n1</sub>=A.K<sub>n2 </sub>or B.K<sub>n1</sub>=FormKeyVariant(A.K<sub>n2</sub>, B.ChipID).
6593The data read assists the printer to determine the following before printing can commence: <ul id="ul0951" list-style="none"><li id="ul0951-0001" num="0000"><ul id="ul0952" list-style="none"><li id="ul0952-0001" num="6594">Which fields in <sub>M0 </sub>store logical ink amounts in the ink QA Device.</li><li id="ul0952-0002" num="6595">The size of the ink fields in the ink QA Device. Refer to Section 8.1.1.1.</li><li id="ul0952-0003" num="6596">The type of ink.</li><li id="ul0952-0004" num="6597">The amount of ink in the field.</li></ul></li></ul>
6598Table 312 shows the command sequence for performing presence only authentication (with data interpretation).
6599<tables id="TABLE-US-00508" num="00508"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="center" /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="147pt" align="left" /><thead><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>Seq</entry><entry /><entry /></row><row><entry>No</entry><entry>Function</entry><entry>Parameters</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="char" char="." /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>1</entry><entry>A. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>A </sub>= RL</entry></row><row><entry>2</entry><entry>B. Read</entry><entry>KeyRef = n1, SigOnly = 0, MSelect =</entry></row><row><entry /><entry /><entry>0x03(indicates M0 and M1), KeyIdSelect = 0xFF</entry></row><row><entry /><entry /><entry>(Read all KeyIds), WordSelectForDesiredM</entry></row><row><entry /><entry /><entry>(for <sub>M0</sub>) = 0xFFFF (Read all 16 <sub>M0</sub>words),</entry></row><row><entry /><entry /><entry>WordSelectForDesiredM (for<sub>M1</sub>) =</entry></row><row><entry /><entry /><entry>0xFFFF(Read all 16<sub>M1</sub>words), RE = R<sub>A</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then MWords =</entry></row><row><entry /><entry /><entry>SelectedWordsOfSelectedMs as per input</entry></row><row><entry /><entry /><entry>[MSelect] and [WordSelectForDesiredM],</entry></row><row><entry /><entry /><entry>All 16 words of <sub>M0 </sub>and <sub>M1</sub>. R<sub>B </sub>= RL</entry></row><row><entry /><entry /><entry>SIG<sub>B </sub>= SIGout Refer to Section 15.3.1</entry></row><row><entry>3</entry><entry>A. Test</entry><entry>Input Key = n2, DataLength = Length of</entry></row><row><entry /><entry /><entry>MWords in words preformatted as per Section</entry></row><row><entry /><entry /><entry>16.1, Data = MWords preformatted as per</entry></row><row><entry /><entry /><entry>Section 16.1, RE = R<sub>B</sub>, SIGE = SIG<sub>B</sub></entry></row><row><entry /><entry /><entry>ResultFlag = Pass/Fail</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 31.2.2.1 Locating Ink Fields and Determining Ink Amounts Remaining
6600Before printing can commence, the printer must determine the ink fields in the ink cartridge so that it can decrement these fields with the physical use of ink. The printer must also verify that the ink in the ink cartridge is suitable for use by the printer.
6601This process requires reading data from the ink QA Device and then comparing the data to what is required. To perform the comparison the printer must store a list for each ink it uses.
6602The ink list must consist of the following: <ul id="ul0953" list-style="none"><li id="ul0953-0001" num="0000"><ul id="ul0954" list-style="none"><li id="ul0954-0001" num="6603">Ink Id—A identifier for the ink</li><li id="ul0954-0002" num="6604">KeyId—The KeyId of the key used to fill/refill this ink.</li><li id="ul0954-0003" num="6605">Type—This is the type attribute of the ink.</li></ul></li></ul>
6606The ink list stored in the printer is shown in Table 313.
6607<tables id="TABLE-US-00509" num="00509"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="77pt" align="left" /><colspec colname="3" colwidth="91pt" align="left" /><thead><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>Ink Id</entry><entry>KeyId</entry><entry>Type</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>1-</entry><entry>1- represents</entry><entry>0x55</entry></row><row><entry>represents</entry><entry>KeyId of</entry><entry>TYPE_REGULAR<sub>—</sub></entry></row><row><entry>black ink</entry><entry>Network_OEM_InkFill/</entry><entry>BLACK_INK<sup>a</sup></entry></row><row><entry /><entry>Refill Key<sup>b</sup></entry></row><row><entry>2-</entry><entry>1- represents</entry><entry>0x9F</entry></row><row><entry>represents</entry><entry>KeyId of</entry><entry>TYPE_HIGHQUALITY<sub>—</sub></entry></row><row><entry>cyan ink</entry><entry>Network_OEM_InkFill/</entry><entry>CYAN_INK<sup>a</sup></entry></row><row><entry /><entry>Refill Key<sup>b</sup></entry></row><row><entry>3-</entry><entry>1- represents</entry><entry>0x9A</entry></row><row><entry>represents</entry><entry>KeyId of</entry><entry>TYPE_HIGHQUALITY<sub>—</sub></entry></row><row><entry>magenta ink</entry><entry>Network_OEM_InkFill/</entry><entry>MAGENTA_INK<sup>a</sup></entry></row><row><entry /><entry>Refill Key<sup>b</sup></entry></row><row><entry>4-</entry><entry>1- represents</entry><entry>0x9C</entry></row><row><entry>represents</entry><entry>KeyId of</entry><entry>TYPE_HIGHQUALITY<sub>—</sub></entry></row><row><entry>yellow ink</entry><entry>Network_OEM_InkFill/</entry><entry>YELLOW_INK<sup>a</sup></entry></row><row><entry /><entry>Refill Key<sup>b</sup></entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry namest="1" nameend="3" align="left" id="FOO-00069"><sup>a</sup>These Types are only used as an example.</entry></row><row><entry namest="1" nameend="3" align="left" id="FOO-00070"><sup>b</sup>These KeyIds are only used as an example.</entry></row></tbody></tgroup></table></tables>
6608The printer will perform a Read of the ink QA Device's M0, M1 and KeyIds to determine the following: <ul id="ul0955" list-style="none"><li id="ul0955-0001" num="0000"><ul id="ul0956" list-style="none"><li id="ul0956-0001" num="6609">The correct ink field (<sub>M0 </sub>field) in the ink QA Device.</li><li id="ul0956-0002" num="6610">The amount of ink-remaining in the field.</li></ul></li></ul>
6611The ink QA Device's M1 and KeyId helps the printer determine the location of the ink field and ink QA Device's M0 and M1 helps determine the amount of ink-remaining in the field.
000031.2.2.2 FieldNum FindFieldNum(keyIdRequired, typeRequired)
6612This function returns a FieldNum of an M0 field, whose authenticated ReadWrite access key's KeyId is keyIdRequired, and whose Type attribute matches typeRequired. If no matching field is found it returns a FieldNum=255. This function must be available in the printer system so that it can determine the ink field required by it.
6613The function sequence is described below.
6614<tables id="TABLE-US-00510" num="00510"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry># Get total number of fields in the ink QA Device</entry></row><row><entry>FieldSize[16] <img file="US7165824B2_D0709.tif" /> 0 # Array to hold FieldSize assuming there are 16</entry></row><row><entry>fields</entry></row><row><entry>NumFields<img file="US7165824B2_D0710.tif" /> FindNumberOfFieldsInM0(M1,FieldSize) # Refer to</entry></row><row><entry>Section 19.4.1.</entry></row><row><entry># Loop through KeyIds read assuming all KeyIds have been read</entry></row><row><entry>from</entry></row><row><entry>ink QA Device</entry></row><row><entry>For i <img file="US7165824B2_D0711.tif" /> 0 to 7</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>#Check if KeyId read matches</entry></row><row><entry /><entry>If(KeyId<sub>i </sub>= keyIdRequired # Matching KeyId found</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>KeyNum <img file="US7165824B2_D0712.tif" /> i</entry><entry># Get the KeyNum of the matching</entry></row><row><entry /><entry>KeyId</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry># Now look through the field to check which field has</entry></row><row><entry /><entry>#write permissions with this KeyNum</entry></row><row><entry /><entry>For j <img file="US7165824B2_D0713.tif" /> 0 to NumOfFields</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>AuthRW <img file="US7165824B2_D0714.tif" /><sub>M1</sub>[j].AuthRW # Isolate AuthRW for field</entry></row><row><entry /><entry># Check authenticated write is allowed to the field</entry></row><row><entry /><entry>If(AuthRW = 1)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>KeyNum<sub>j</sub><img file="US7165824B2_D0715.tif" /> <sub>M1</sub>[j].KeyNum # Isolate KeyNum of the</entry></row><row><entry /><entry>field</entry></row><row><entry /><entry>Typej <img file="US7165824B2_D0716.tif" /><sub>M1</sub>[j].Type #Islotate Type attribute of</entry></row><row><entry /><entry>the field</entry></row><row><entry /><entry># Check if Key is write key for the field and</entry></row><row><entry /><entry>type of</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Ink Id#2</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>If (KeyNum = KeyNum<sub>j</sub>) <img file="US7165824B2_D0717.tif" /> (Type<sub>j </sub>= typeRequired)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>FieldNum <img file="US7165824B2_D0718.tif" /> j</entry></row><row><entry /><entry>return FieldNum</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndFor # Loop through to next field</entry></row><row><entry /><entry>FieldNum <img file="US7165824B2_D0719.tif" /> 255 # Error - no field found</entry></row><row><entry /><entry>return FieldNum</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndFor # Loop through to next KeyId</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><ul id="ul0957" list-style="none"><li id="ul0957-0001" num="0000"><ul id="ul0958" list-style="none"><li id="ul0958-0001" num="6615">For e.g. if the printer wants to find an ink filed that matches Ink Id#2 (from Table 313) in the Ink QA Device, it must call the function FindFieldNum with keyIdRequired=KeyId of Network_OEM_InkFill/Refill Key and typeRequired=TYPE_HIGHQUALITY_CYAN_INK. <br /> 31.2.2.3 Ink-remaining Amount </li></ul></li></ul>
6616This can be determined by using the function GetFieldDataWords(FieldNum,FieldData<img file="US7165824B2_D0720.tif" />, M0,M1) described in Section 27.1.4.14. FieldNum must be set to the value returned from function in Section 31.2.2.2. FieldData returns the ink-remaining amount.
6617The function GetFieldDataWords(FieldNum,FieldData<img file="US7165824B2_D0721.tif" />, M0,M1) must be implemented in the printer system.
000031.3 Presence Only Authentication Through the Translate Function
6618This sequence is performed when the printer reads the data from the untrusted ink QA Device in the ink cartridge but uses a translating QA Device to indirectly validate the read data. The translating QA Device validates the signature using the key it shares with the untrusted QA Device, and then signs the data using the key it shares with the trusted QA Device. The trusted QA Device then validates the signature produced by the translating QA Device.
6619For validating signatures using translation: <ul id="ul0959" list-style="none"><li id="ul0959-0001" num="0000"><ul id="ul0960" list-style="none"><li id="ul0960-0001" num="6620">A and C must share a common or a variant key i.e C.K<sub>n3</sub>=A.K<sub>2 </sub>or C.K<sub>n3</sub>=FormKeyVariant(A.K<sub>n2</sub>, C.ChipID).</li><li id="ul0960-0002" num="6621">B and C must share a common or a variant key i.e C.K<sub>n2</sub>=B.K<sub>n1 </sub>or B.K<sub>n1</sub>=FormKeyVariant(C.K<sub>n2</sub>, B.ChipID).</li></ul></li></ul>
6622Table 314 shows a command sequence for presence only authentication using translation
6623<tables id="TABLE-US-00511" num="00511"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="center" /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="147pt" align="left" /><thead><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>Seq</entry><entry /><entry /></row><row><entry>No</entry><entry>Function</entry><entry>Parameters</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="char" char="." /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>1</entry><entry>C. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>C </sub>= RL</entry></row><row><entry>2</entry><entry>B. Read</entry><entry>KeyRef = n1, SigOnly = 1 or 0,</entry></row><row><entry /><entry /><entry>MSelect = any M, KeyIdSelect = 0,</entry></row><row><entry /><entry /><entry>WordSelectForDesiredM = any, RE = R<sub>C</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then MWords =</entry></row><row><entry /><entry /><entry>SelectedWordsOfSelectedMs as per input</entry></row><row><entry /><entry /><entry>[MSelect] and [WordSelectForDesiredM],</entry></row><row><entry /><entry /><entry>R<sub>B </sub>= R<sub>L</sub>, SIG<sub>B </sub>= SIGout Refer to</entry></row><row><entry /><entry /><entry>Section 15.3.1</entry></row><row><entry>3</entry><entry>A. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>A </sub>= RL</entry></row><row><entry>4</entry><entry>C. Translate</entry><entry>InputKeyRef = n2, DataLength = Length</entry></row><row><entry /><entry /><entry>of MWords in words preformatted as per</entry></row><row><entry /><entry /><entry>Section 17.1, Data = MWords preformatted</entry></row><row><entry /><entry /><entry>as per Section 17.1, RE = R<sub>B</sub>, SIGE = SIG<sub>B</sub>,</entry></row><row><entry /><entry /><entry>OutputKeyRef = n3, RE2 = R<sub>A</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then R<sub>C1 </sub>= RL1,</entry></row><row><entry /><entry /><entry>SIG<sub>C </sub>= SIGOut Refer to Section 15.3.1</entry></row><row><entry>5</entry><entry>A. Test</entry><entry>KeyRef = n2, DataLength = Length of</entry></row><row><entry /><entry /><entry>MWords in words preformatted as per</entry></row><row><entry /><entry /><entry>Section 16.1, Data = MWords preformatted</entry></row><row><entry /><entry /><entry>as per Section 16.1, RE = R<sub>C1</sub>, SIGE = SIG<sub>C</sub></entry></row><row><entry /><entry /><entry>ResultFlag = Pass/Fail</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 31.4 Updating the Ink-remaining
6624This sequence is performed when the printer is printing. The ink QA Device holds the logical amount of ink-remaining corresponding to the physical ink left in the cartridge. This logical ink amount must decrease, as physical ink from the ink cartridge is used for printing.
000031.4.1 Sequence of Update
6625The primary question is when to deduct the logical ink amount—before or after the physical ink is used. <ul id="ul0961" list-style="none"><li id="ul0961-0001" num="6626">a. Print first (use physical ink) and then update the logical ink. If the power is cut off after a physical print and before a logical update, then the logical update is not performed. Therefore, the logical ink-remaining is more than the physical ink-remaining. Performing repeated power cuts will increase the differential amount, and finally any physical ink could be used to refill the QA Device.</li><li id="ul0961-0002" num="6627">b. Update the logical ink and then print (use physical ink). This is better than (a) because other physical inks cannot be used. However, if a problem occurs during printing, after the logical amount has already been deducted, there will be a disparity between logical and physical amounts. This might result in the printer not printing even if physical ink is present in the ink cartridge. The amount of disparity can be reduced by increasing the frequency of updating logical ink i.e update after each line instead of after each page.</li><li id="ul0961-0003" num="6628">c. Preauthorise logical ink. Preauthorise certain amount of ink (depends on the frequency of logical updates) before print and clear it at the end of printing. If power is cut off after a page is printed, then on start up, the printer reads the preauthorisation field, if it has not been cleared, it applies the preauth amount to the ink-remaining amount, and then clears the preauthorisation field. <br /> 31.4.2 Basic Update </li></ul>
6629Some printers may use one of methods described in Section 31.4.1 (a) or (b) to update logical ink amounts in the ink QA Device. This method of updating the ink is termed as a basic update. The decremented amount is written to the appropriate ink field (which has been previously determined using Section 31.2.2) in <sub>M0 </sub>The printer verifies the write, by reading the signature of the written data, then passing it to the Test function of the trusted QA Device.
6630For signature to be valid, the trusted QA Device (A) and ink QA Device (B) must share a common or a variant key i.e B.K<sub>n1</sub>=A.K<sub>n2 </sub>or B.K<sub>n1</sub>=FormKeyVariant(A.K<sub>n2</sub>, B.ChipID).
6631<tables id="TABLE-US-00512" num="00512"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 315</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Command sequence for updating the ink-remaining (basic)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="center" /><colspec colname="2" colwidth="49pt" align="left" /><colspec colname="3" colwidth="140pt" align="left" /><tbody valign="top"><row><entry>Seq</entry><entry /><entry /></row><row><entry>No</entry><entry>Function</entry><entry>Parameter</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="char" char="." /><colspec colname="2" colwidth="49pt" align="left" /><colspec colname="3" colwidth="140pt" align="left" /><tbody valign="top"><row><entry>1</entry><entry>B. WriteFields</entry><entry>VectNum = 0, FieldSelect = Select</entry></row><row><entry /><entry /><entry>bits corresponding to the Ink fields, The</entry></row><row><entry /><entry /><entry>ink field locations should have been</entry></row><row><entry /><entry /><entry>determined before by using the method</entry></row><row><entry /><entry /><entry>in Section 31.2.2.1 FieldVal =</entry></row><row><entry /><entry /><entry>Decremented ink-remaining amount</entry></row><row><entry /><entry /><entry>ResultFlag = Pass/Fail</entry></row><row><entry>2</entry><entry>A. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>A </sub>= RL</entry></row><row><entry>3</entry><entry>B. Read</entry><entry>KeyRef = n1, SigOnly = 1, (We only need</entry></row><row><entry /><entry /><entry>the signature because we already know</entry></row><row><entry /><entry /><entry>the data) MSelect =<sub>M0</sub>, KeyIdSelect = 0,</entry></row><row><entry /><entry /><entry>WordSelectForDesiredM = corresponds to the</entry></row><row><entry /><entry /><entry>ink fields written in Seq No 1, RE = R<sub>A</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then</entry></row><row><entry /><entry /><entry>SelectedWordsOfSelectedMs not returned</entry></row><row><entry /><entry /><entry>because [SigOnly] = 1 in Seq 3,</entry></row><row><entry /><entry /><entry>R<sub>B </sub>= R<sub>L</sub>, SIG<sub>B </sub>= SIGout Refer to</entry></row><row><entry /><entry /><entry>Section 15.3.1</entry></row><row><entry>4</entry><entry>A. Test</entry><entry>KeyRef = n2, DataLength = length in</entry></row><row><entry /><entry /><entry>words as per Seq No 1 [MVal] preformatted</entry></row><row><entry /><entry /><entry>as per Section 16.1, Data = as per</entry></row><row><entry /><entry /><entry>Seq No 1 [MVal] preformatted as per</entry></row><row><entry /><entry /><entry>Section 16.1, RE = R<sub>B</sub>, SIGE = SIG<sub>B</sub></entry></row><row><entry /><entry /><entry>ResultFlag = Pass/Fail</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 31.4.3 Preauthorisation
6632This section describes the update of logical ink amounts using preauthorisation.
6633The basic preauthorisation sequence is as follows: <ul id="ul0962" list-style="none"><li id="ul0962-0001" num="6634">a. Preauthorise before the first print. Preauthorisation amount depends on the printer model. Example amounts could be the ink required for an fully covered A4 page or an A3 page. Value corresponding to the preauth amount is written to the preauth field in the ink QA Device.</li></ul>
6635Note: The preauth value must be correctly interpreted on different printer models i.e if a preauthorisation amount of A4 page is set in the ink cartridge in printer1(model1), and later the ink cartridge is placed in printer2(model2) with its preauth still set, printer2 must deduct an A4 page worth of ink from ink-remaining amount. <ul id="ul0963" list-style="none"><li id="ul0963-0001" num="6636">b. Print the page.</li><li id="ul0963-0002" num="6637">c. Write the deducted logical amount to the ink field of the ink QA Device and validate the write by reading the signature of the ink field.</li><li id="ul0963-0003" num="6638">d. Repeat b to c till the last page has been printed.</li><li id="ul0963-0004" num="6639">e. Clear the preauth amount.</li><li id="ul0963-0005" num="6640">f. If the power is cut off before the preauth is applied, on startup apply the preauth amount to the corresponding ink field, by performing a non authenticated write of the decremented amount and clear the preauth amount by performing an authenticated write of the preauth field. <br /> 31.4.3.1 Set Up of the Preauth Field </li></ul>
6641Only a single preauth gield must exist in an Ink QA Device. <ul id="ul0964" list-style="none"><li id="ul0964-0001" num="0000"><ul id="ul0965" list-style="none"><li id="ul0965-0001" num="6642">Preauth field will consist of a single <sub>M0 </sub>word but can be optionally extended to two <sub>M0 </sub>words by using a different value of type attribute. <figref idref="DRAWINGS">FIG. 388</figref> shows the setup of preauth field's attributes in <sub>M1</sub>.</li><li id="ul0965-0002" num="6643">The preauth field has authenticated ReadWrite access using the INK_USAGE_KEY i.e INK_USAGE_KEY can perform authenticated writes to this field. This key or its variant is shared between the ink QA Device and the printer QA Device to validate any data read from the ink cartridge. For signature to be valid, B.K<sub>n1</sub>=A.K<sub>n2 </sub>or B.K<sub>n1</sub>=FormKeyVariant(A.K<sub>n2</sub>, B.ChipID), where K<sub>n1</sub>=INK_USAGE_KEY. The system performs a WriteAuth to the preauth field using this key, to set up the preauth amount, and to clear the preauth amount.</li></ul></li></ul>
6644The preauth field is identified by two attributes: <ul id="ul0966" list-style="none"><li id="ul0966-0001" num="0000"><ul id="ul0967" list-style="none"><li id="ul0967-0001" num="6645">Type attribute—TYPE_PREAUTH. Refer to Appendix A.</li><li id="ul0967-0002" num="6646">KeyId of KeyNum attribute must be the same as the KeyId of the INK_USAGE_KEY which the printer uses to validate the any data read from the ink QA Device. <ul id="ul0968" list-style="none"><li id="ul0968-0001" num="6647">The Preauth field can be applied to a single ink field or multiple ink fields. <br /> 31.4.3.2 Preauth Applied to a Single Ink Field </li></ul></li></ul></li></ul>
6648In this case the entire preauth field is used to store the preauth amount and is only linked to one ink field.
000031.4.3.3 Preauth Applied to Multiple Ink Fields
6649Multiple preauth fields can be accommodated in a single M<sub>0 </sub>field by a scheme shown in <figref idref="DRAWINGS">FIG. 388A</figref>.
6650This scheme supports a maximum of 8 ink fields being present in the Ink QA Device.
6651The field in <sub>M0 </sub>is divided into two parts— preauth field select and preauth amount. Each bit in preauth field select corresponds to a single ink field, and the preauth amount for each ink field is the same. If an ink cartridge uses multiple inks which are preauthorised, then each of the inks will have a corresponding preauth field bit. Before a particular ink is used for printing the corresponding preauth field bit is set. The preauth amount field is also set if the previous amount is zero. At finish, the preauth field bit is cleared. If more than one ink is used, the preauth bit for each ink field is set, and at finish each bit is cleared with last bit clearing the preauth amount as well.
000031.4.3.4 Locating Preauth Fields and Determining Preauth Field Value
6652The preauth field can be located in the same manner as the ink field. If the printer wants to find the preauth field in the ink QA Device, it must call the function FindFieldNum (see Section 31.2.2.2) with keyIdRequired=KeyId of Network_OEM_Ink_Usage_Key and typeRequired=TYPE_PREAUTH.
6653The preauth field value can be read in the same manner as the ink-remaining amount. This requires using of the function GetFieldDataWords(FieldNum,FieldData<img file="US7165824B2_D0722.tif" />, M0,M1) described in Section 27.1.4.14. FieldNum must be set to the value returned from function FindFieldNum, which in this case is the field number of the preauth field. FieldData returns the value of the preauth field.
000031.4.3.5 Command Sequence
6654The command sequence can be broken up into three parts: <ul id="ul0969" list-style="none"><li id="ul0969-0001" num="0000"><ul id="ul0970" list-style="none"><li id="ul0970-0001" num="6655">Start of print sequence.</li><li id="ul0970-0002" num="6656">During print sequence.</li><li id="ul0970-0003" num="6657">End of print sequence. <br /> 31.4.3.5.1 Start of Print Sequence </li></ul></li></ul>
6658This sets up the preauth amount before the start of printing.
6659Table 316 shows the command sequence for start of print sequence. The first Random-Read-Test sequence determines the preauth field in the ink QA Device and its value. The Random-SignM-WriteFieldsAuth sequence, then writes to the preauth field the new preauth value.
6660<tables id="TABLE-US-00513" num="00513"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 316</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Updating the consumable remaining</entry></row><row><entry>(preauth) start of print sequence</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="center" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>Seq</entry><entry /><entry /></row><row><entry>No</entry><entry>Function</entry><entry>Parameters</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Random-Read -Test sequence to determine the location of the</entry></row><row><entry>preauth field in the ink QA Device and its value</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="char" char="." /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>1</entry><entry>A. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>A </sub>= RL</entry></row><row><entry>2</entry><entry>B. Read</entry><entry>KeyRef = n1, SigOnly = 0,</entry></row><row><entry /><entry /><entry>WordSelectForDesiredM (for <sub>M0</sub>) =</entry></row><row><entry /><entry /><entry>all 16 words of M0 and all 16 words of</entry></row><row><entry /><entry /><entry>M1 MSelect = 0x03(indicates M0 and</entry></row><row><entry /><entry /><entry>M1), KeyIdSelect = 0xFF (Read all</entry></row><row><entry /><entry /><entry>KeyIds), WordSelectForDesiredM</entry></row><row><entry /><entry /><entry>(for <sub>M0</sub>) = 0xFFFF (Read all 16 <sub>M0</sub>words),</entry></row><row><entry /><entry /><entry>WordSelectForDesiredM (for<sub>M1</sub>) =</entry></row><row><entry /><entry /><entry>0xFFFF(Read all 16 <sub>M1</sub>words), RE = R<sub>A</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then MWords =</entry></row><row><entry /><entry /><entry>SelectedWordsOfSelectedMs as per</entry></row><row><entry /><entry /><entry>input [MSelect] and</entry></row><row><entry /><entry /><entry>[WordSelectForDesiredM], R<sub>B </sub>= R<sub>L</sub>,</entry></row><row><entry /><entry /><entry>SIG<sub>B </sub>= SIGout Refer to Section 15.3.1</entry></row><row><entry>3</entry><entry>A. Test</entry><entry>KeyRef = n2, DataLength = length</entry></row><row><entry /><entry /><entry>of MWords in words preformatted as per</entry></row><row><entry /><entry /><entry>Section 16.1, Data = MWords as per</entry></row><row><entry /><entry /><entry>Seq No 2 preformatted as per Section</entry></row><row><entry /><entry /><entry>16.1, RE = R<sub>B</sub>, SIGE = SIG<sub>B</sub></entry></row><row><entry /><entry /><entry>ResultFlag = Pass/Fail</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Random-SignM-WriteFieldsAuth sequence to write the new preauth value</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="char" char="." /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>4</entry><entry>B. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>B1 </sub>= RL</entry></row><row><entry>5</entry><entry>A. SignM</entry><entry>KeyRef = n2, FieldSelect = Select</entry></row><row><entry /><entry /><entry>bit corresponding to the Preauth field,</entry></row><row><entry /><entry /><entry>FieldVal = new preauth value,</entry></row><row><entry /><entry /><entry>ChipId = ChipId of B, R<sub>E </sub>= R<sub>B1</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then R<sub>A1 </sub>= R<sub>L</sub></entry></row><row><entry /><entry /><entry>SIG<sub>A </sub>= SIGout Refer to Section 27.1.3.1</entry></row><row><entry>6</entry><entry>B. WriteFieldsAuth</entry><entry>KeyRef = n1, FieldSelect = same</entry></row><row><entry /><entry /><entry>as Seq 5 [FieldSelect], FieldVal =</entry></row><row><entry /><entry /><entry>same as Seq 5 [FieldVal], RE = R<sub>A1</sub>,</entry></row><row><entry /><entry /><entry>SIGE = SIG<sub>A</sub></entry></row><row><entry /><entry /><entry>ResultFlag = Pass/Fail</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 31.4.3.5.2 <br /> During Print Sequence
6661This set of commands are repeated at equal intervals to update logical ink amounts to the ink QA Device during printing.
6662Table 317 shows the command sequence for the print sequence. The WriteFields writes the updated value to the ink field. Random-Read-Test reads back the value written and tests whether the value read matches the value written.
6663<tables id="TABLE-US-00514" num="00514"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 317</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Updating the consumable remaining</entry></row><row><entry>(preauth) during print sequence</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="21pt" align="center" /><colspec colname="2" colwidth="49pt" align="left" /><colspec colname="3" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>Seq</entry><entry /><entry /></row><row><entry>No</entry><entry>Function</entry><entry>Parameters</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Write the decremented ink-remaining account.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="21pt" align="char" char="." /><colspec colname="2" colwidth="49pt" align="left" /><colspec colname="3" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>7</entry><entry>B. WriteFields</entry><entry>FieldSelect = Select bits corresponding</entry></row><row><entry /><entry /><entry>to the Ink fields, FieldVal = Decremented</entry></row><row><entry /><entry /><entry>ink-remaining amount for a single ink or</entry></row><row><entry /><entry /><entry>multiple ink fields as per FieldSelect.</entry></row><row><entry /><entry /><entry>ResultFlag = Pass/Fail</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Random-Read-Test sequence to read and verify the ink-</entry></row><row><entry>remaining amount written</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="21pt" align="char" char="." /><colspec colname="2" colwidth="49pt" align="left" /><colspec colname="3" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>8</entry><entry>A. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>A </sub>= RL</entry></row><row><entry>9</entry><entry>B. Read</entry><entry>KeyRef = n1, SigOnly = 1 -(We only</entry></row><row><entry /><entry /><entry>need the signature because we already know the</entry></row><row><entry /><entry /><entry>data), MSelect = 0x01 (only <sub>M0</sub>),</entry></row><row><entry /><entry /><entry>KeyIdSelect = 0, WordSelectForDesiredM =</entry></row><row><entry /><entry /><entry>corresponds to the ink fields written in Seq</entry></row><row><entry /><entry /><entry>No 7, RE = R<sub>A</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then</entry></row><row><entry /><entry /><entry>SelectedWordsOfSelectedMs not returned because</entry></row><row><entry /><entry /><entry>[SigOnly] = 1 in Seq 9 R<sub>B </sub>= R<sub>L</sub>,</entry></row><row><entry /><entry /><entry>SIG<sub>B </sub>= SIGout Refer to Section 15.3.1.</entry></row><row><entry>10</entry><entry>A. Test</entry><entry>KeyRef = n2, DataLength = length in</entry></row><row><entry /><entry /><entry>words as per Seq No 7 [MVal] preformatted</entry></row><row><entry /><entry /><entry>as per Section 16.1, Data = as per Seq No 7</entry></row><row><entry /><entry /><entry>[MVal] preformatted as per Section 16.1,</entry></row><row><entry /><entry /><entry>RE = R<sub>B</sub>, SIGE = SIG<sub>B</sub></entry></row><row><entry /><entry /><entry>ResultFlag = Pass/Fail</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 31.4.3.5.3 End of Print Sequence
6664This sequence clears preauth amount before the print sequence is completed.
6665Table 318 shows the command sequence for the end of print sequence.
6666The preauth field is read using the Random-Read-Test sequence. And the preauth field is cleared using the Random-SignM-WriteFieldsAuth sequence.
6667<tables id="TABLE-US-00515" num="00515"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 318</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Updating the consumable remaining</entry></row><row><entry>(preauth) end of print sequence</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>Seq</entry><entry /><entry /></row><row><entry>No</entry><entry>Function</entry><entry>Parameters</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Random-Read-Test sequence to read the preauth field and verify the</entry></row><row><entry>preauth data</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>11</entry><entry>A. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>A </sub>= R<sub>L</sub></entry></row><row><entry>12</entry><entry>B. Read</entry><entry>KeyRef = n1, SigOnly = 1,</entry></row><row><entry /><entry /><entry>MSelect = 0x01(only M0),</entry></row><row><entry /><entry /><entry>KeyIdSelect = 0,</entry></row><row><entry /><entry /><entry>WordSelectForDesiredM (for <sub>M0</sub>) =</entry></row><row><entry /><entry /><entry>Words corresponding to the Preauthfield</entry></row><row><entry /><entry /><entry>that has been written to in Seq 5</entry></row><row><entry /><entry /><entry>[FieldSelect] in Table 317. RE = R<sub>A</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then</entry></row><row><entry /><entry /><entry>MWords = SelectedWordsOfSelectedMs</entry></row><row><entry /><entry /><entry>as per Seq No 12 [MSelect] and</entry></row><row><entry /><entry /><entry>[WordSelectForDesiredM], R<sub>B </sub>=</entry></row><row><entry /><entry /><entry>R<sub>L</sub>, SIG<sub>B </sub>= SIGout Refer to</entry></row><row><entry /><entry /><entry>Section 15.3.1</entry></row><row><entry>13</entry><entry>A. Test</entry><entry>KeyRef = n2, DataLength = length</entry></row><row><entry /><entry /><entry>of MWords in words as per Seq No</entry></row><row><entry /><entry /><entry>12 preformatted as per Section 16.1,</entry></row><row><entry /><entry /><entry>Data = MWords as per Seq No 12</entry></row><row><entry /><entry /><entry>preformatted as per Section 16.1,</entry></row><row><entry /><entry /><entry>RE = R<sub>B</sub>, SIGE = SIG<sub>B</sub></entry></row><row><entry /><entry /><entry>ResultFlag = Pass/Fail</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Random-SignM-WriteFieldsAuth sequence clears the preauth field</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>14</entry><entry>B. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>B1 </sub>= R<sub>L</sub></entry></row><row><entry>15</entry><entry>A. SignM</entry><entry>KeyRef = n2, FieldSelect =</entry></row><row><entry /><entry /><entry>Select bit corresponding to Pre authfield,</entry></row><row><entry /><entry /><entry>FieldVal = Clear the preauth field,</entry></row><row><entry /><entry /><entry>ChipId = ChipId of B, R<sub>E </sub>= R<sub>B1</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then R<sub>A1 </sub>=</entry></row><row><entry /><entry /><entry>R<sub>L </sub>SIG<sub>A </sub>= SIGout Refer to Section</entry></row><row><entry /><entry /><entry>27.1.3.1</entry></row><row><entry>16</entry><entry>B. WriteFieldsAuth</entry><entry>KeyRef = n1, FieldNum = same as</entry></row><row><entry /><entry /><entry>Seq 5 [FieldSelect], FieldData =</entry></row><row><entry /><entry /><entry>same as Seq 5 [FieldVal], RE =</entry></row><row><entry /><entry /><entry>R<sub>B1</sub>, SIGE = SIG<sub>A</sub></entry></row><row><entry /><entry /><entry>ResultFlag = Pass/Fail</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 31.4.4 Preauthorisation Through the Translate Function
6668This is performed when the system trusted QA Device doesn't share a key with the ink QA Device, and uses a translating QA Device to Translate a Read from the ink QA Device, and to Translate a SignM to the ink QA Device.
6669The basic translate principle involves translating the Read data from the untrusted QA Device, to the Test data of the trusted QA Device, and translating the SignM data from the trusted QA Device, to the WriteFieldsAuth data of the untrusted QA Device.
6670For validating signatures using translation: <ul id="ul0971" list-style="none"><li id="ul0971-0001" num="0000"><ul id="ul0972" list-style="none"><li id="ul0972-0001" num="6671">The trusted QA Device (A) and the translating QA Device (C) must share a common or a variant key i.e C.K<sub>n3</sub>=A.K<sub>n2 </sub>or C.K<sub>3</sub>=FormKeyVariant(A.K<sub>n2</sub>, C.ChipID).</li><li id="ul0972-0002" num="6672">The ink QA Device (B) and the translating QA Device (C) must share a common or a variant key i.e C.K<sub>m2</sub>=B.K<sub>n1 </sub>or B.K<sub>n1</sub>=FormKeyVariant(C.K<sub>n2</sub>, B.ChipID).</li></ul></li></ul>
6673Only the start of print sequence is described using Translate. The rest of the sequences in preauthorisation can be modified to apply translation using this example.
6674Table 319 shows the command sequence for preauth (start of print sequence) using translation.
6675<tables id="TABLE-US-00516" num="00516"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 319</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Preauth(start of print sequence) using translate command</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="center" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>Seq</entry><entry /><entry /></row><row><entry>No</entry><entry>Function</entry><entry>Parameter</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Random-Read-Random-Translate-Test sequence reads the location</entry></row><row><entry>of the preauth field and its value using the translating QA</entry></row><row><entry>Device C</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="char" char="." /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>1</entry><entry>C. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>C </sub>= RL</entry></row><row><entry>2</entry><entry>B. Read</entry><entry>KeyRef = n1, SigOnly = 0,</entry></row><row><entry /><entry /><entry>MSelect = 0x03(indicates M0</entry></row><row><entry /><entry /><entry>and M1), KeyIdSelect = 0xFF</entry></row><row><entry /><entry /><entry>(Read all KeyIds),</entry></row><row><entry /><entry /><entry>WordSelectForDesiredM</entry></row><row><entry /><entry /><entry>(for<sub>M0</sub>) = 0xFFFF (Read all</entry></row><row><entry /><entry /><entry>16 <sub>M0</sub>words), WordSelectForDesiredM</entry></row><row><entry /><entry /><entry>(for <sub>M1</sub>) = 0xFFFF(Read all</entry></row><row><entry /><entry /><entry>16 <sub>M1</sub>words), RE = R<sub>A</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then</entry></row><row><entry /><entry /><entry>MWords = SelectedWordsOfSelectedMs</entry></row><row><entry /><entry /><entry>as per input [MSelect] and</entry></row><row><entry /><entry /><entry>[WordSelectForDesiredM],</entry></row><row><entry /><entry /><entry>R<sub>B </sub>= R<sub>L</sub>, SIG<sub>B </sub>= SIGout</entry></row><row><entry /><entry /><entry>Refer to Section 15.3.1</entry></row><row><entry>3</entry><entry>A. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>A </sub>= RL</entry></row><row><entry>4</entry><entry>C. Translate</entry><entry>InputKeyRef = n2, DataLength</entry></row><row><entry /><entry /><entry>(in words) = length of MWords</entry></row><row><entry /><entry /><entry>in words as per Seq No 2 pre-</entry></row><row><entry /><entry /><entry>formatted as per Section 17.1,</entry></row><row><entry /><entry /><entry>Data = MWords as returned</entry></row><row><entry /><entry /><entry>from Seq No 2 preformatted</entry></row><row><entry /><entry /><entry>as per Section 17.1, RE = R<sub>B</sub>,</entry></row><row><entry /><entry /><entry>SIGE = SIG<sub>B </sub>OutputKeyRef =</entry></row><row><entry /><entry /><entry>n3, RE2 = R<sub>A</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then</entry></row><row><entry /><entry /><entry>R<sub>C1 </sub>= RL2, SIG<sub>C </sub>= SIGOut</entry></row><row><entry /><entry /><entry>Refer to FIG. 15.3.1</entry></row><row><entry>5</entry><entry>A. Test</entry><entry>KeyRef = n2, DataLength =</entry></row><row><entry /><entry /><entry>length of MWords in words as</entry></row><row><entry /><entry /><entry>per Seq No 2 preformatted as</entry></row><row><entry /><entry /><entry>per Section 16.1, Data =</entry></row><row><entry /><entry /><entry>MWords as returned from Seq</entry></row><row><entry /><entry /><entry>No 2 parameter preformatted as</entry></row><row><entry /><entry /><entry>per Section 16.1, RE = R<sub>C1</sub>,</entry></row><row><entry /><entry /><entry>SIGE = SIG<sub>C</sub></entry></row><row><entry /><entry /><entry>ResultFlag = Pass/Fail</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Random-SignM-Random-Translate-WriteFieldAuth sequence to write</entry></row><row><entry>the new preauth value using the translating QA Device C</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="char" char="." /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>6</entry><entry>C. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>C2 </sub>= R<sub>L</sub></entry></row><row><entry>7</entry><entry>A. SignM</entry><entry>KeyRef = n2, FieldSelect =</entry></row><row><entry /><entry /><entry>Select bit corresponding to Pre</entry></row><row><entry /><entry /><entry>authfield, FieldVal = new</entry></row><row><entry /><entry /><entry>value of preauth field, ChipId =</entry></row><row><entry /><entry /><entry>ChipId of B, R<sub>E </sub>= R<sub>C2</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then</entry></row><row><entry /><entry /><entry>R<sub>A1 </sub>= R<sub>L </sub>SIG<sub>A </sub>= SIGout</entry></row><row><entry /><entry /><entry>Refer to Section 27.1.3.1</entry></row><row><entry>8</entry><entry>B. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>B1 </sub>= R<sub>L</sub></entry></row><row><entry>9</entry><entry>C. Translate</entry><entry>InputKeyRef = n3, DataLength</entry></row><row><entry /><entry /><entry>(in words) = length in words</entry></row><row><entry /><entry /><entry>as per Seq 7 [FieldSelect]</entry></row><row><entry /><entry /><entry>preformatted as per Section</entry></row><row><entry /><entry /><entry>17.1, Data = same as Seq 7</entry></row><row><entry /><entry /><entry>[FieldVal] preformatted</entry></row><row><entry /><entry /><entry>as per Section 17.1, RE = R<sub>A1</sub>,</entry></row><row><entry /><entry /><entry>SIGE = SIG<sub>A</sub>, OutputKeyRef =</entry></row><row><entry /><entry /><entry>n2, RE2 = R<sub>B1</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then</entry></row><row><entry /><entry /><entry>R<sub>C3 </sub>= R<sub>L2</sub>, SIG<sub>C </sub>= SIGOut</entry></row><row><entry /><entry /><entry>Refer to FIG. 15.3.1</entry></row><row><entry>10</entry><entry>B. WriteFieldsAuth</entry><entry>KeyRef = n1, FieldNum =</entry></row><row><entry /><entry /><entry>same as Seq 7 [FieldSelect],</entry></row><row><entry /><entry /><entry>FieldData = same as Seq 7</entry></row><row><entry /><entry /><entry>[FieldVal], RE = R<sub>C3</sub>,</entry></row><row><entry /><entry /><entry>SIGE = SIG<sub>C</sub></entry></row><row><entry /><entry /><entry>ResultFlag = Pass/Fail,</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 31.5 Upgrading the Printer Parameters
6676This sequence is performed when a printer's operating parameter is upgraded.
6677The Parameter Upgrader QA Device stores the upgrade value which is copied to the operating parameter field of the Printer QA Device, and the count-remaining associated with upgrade value is decremented by 1 in the Parameter Upgrader QA Device.
6678The Parameter Upgrader QA Device output the data and signature only after completing all necessary checks for the upgrade.
000031.5.1 Basic
6679The basic upgrade is used when the Parameter Upgrader QA Device and Printer QA Device being upgraded share a common key or a variant key i.e B.K<sub>n1</sub>=A.K<sub>n2 </sub>or B.K<sub>n1</sub>=FormKeyVariant(A.K<sub>n2</sub>, B.ChipID), where B is the Printer QA Device and A is the Parameter Upgrader QA Device.
6680Therefore, the messages and their signatures, generated by each of them can be correctly interpreted by the other.
6681The transfer sequence is performed using Random-Read-Random-XferField-WriteFieldsAuth. Table 320 shows the command sequence for a basic upgrade.
6682<tables id="TABLE-US-00517" num="00517"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 320</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Basic upgrade command sequence</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>Seq</entry><entry /><entry /></row><row><entry>No</entry><entry>Function</entry><entry>Parameter</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Random-Read-Random-XferField-WriteFieldsAuth reads M0 and M1</entry></row><row><entry>of the QA Device being upgraded, Parameter Upgrader QA Device</entry></row><row><entry>produces the upgrade value for FieldNumE and Sequence data</entry></row><row><entry>fields SEQ_1 and SEQ_2, then these values are written to the</entry></row><row><entry>Printer QA Device.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>1</entry><entry>A. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>A </sub>= R<sub>L</sub></entry></row><row><entry>2</entry><entry>B. Read</entry><entry>KeyRef = n1, SigOnly = 0,</entry></row><row><entry /><entry /><entry>MSelect = 3 (indicates <sub>M0</sub></entry></row><row><entry /><entry /><entry>and <sub>M1</sub>), KeyIdSelect = 0x00</entry></row><row><entry /><entry /><entry>(no KeyIds required),</entry></row><row><entry /><entry /><entry>WordSelectForDesiredM</entry></row><row><entry /><entry /><entry>(for <sub>M0</sub>) = 0xFFFF (Read all</entry></row><row><entry /><entry /><entry><sub>M0 </sub>words), WordSelectForDesiredM</entry></row><row><entry /><entry /><entry>(for <sub>M1</sub>) = 0xFFFF(Read all</entry></row><row><entry /><entry /><entry><sub>M1 </sub>words), RE = R<sub>A</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then MWords =</entry></row><row><entry /><entry /><entry>SelectedWordsOfSelectedMs, as per</entry></row><row><entry /><entry /><entry>input [MSelect] and</entry></row><row><entry /><entry /><entry>[WordSelectForDesiredM],</entry></row><row><entry /><entry /><entry>R<sub>B </sub>= RL,. SIG<sub>B </sub>= SIGout</entry></row><row><entry /><entry /><entry>Refer to Section 15.3.1</entry></row><row><entry>3</entry><entry>B. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>B1 </sub>= R<sub>L</sub></entry></row><row><entry>4</entry><entry>A. XferField</entry><entry>KeyRef = n2, <sub>M0</sub>OfExternal =</entry></row><row><entry /><entry /><entry>First 16 words of MWords,</entry></row><row><entry /><entry /><entry><sub>M1</sub>OfExternal = Last 16 words of</entry></row><row><entry /><entry /><entry>MWords, ChipId = ChipId of B,</entry></row><row><entry /><entry /><entry>FieldNumL = The field storing</entry></row><row><entry /><entry /><entry>the upgrade value in the Parameter</entry></row><row><entry /><entry /><entry>Upgrader QA Device. The value of</entry></row><row><entry /><entry /><entry>this field will be copied to</entry></row><row><entry /><entry /><entry>FieldNumE. FieldNumE = The</entry></row><row><entry /><entry /><entry>field which will be upgraded in</entry></row><row><entry /><entry /><entry>the Printer QA Device. RE = R<sub>B</sub>,</entry></row><row><entry /><entry /><entry>R<sub>E2 </sub>= R<sub>B1</sub>, SIG<sub>E </sub>= SIG<sub>B</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then</entry></row><row><entry /><entry /><entry>FieldSelectB1 = FieldSelect −</entry></row><row><entry /><entry /><entry>Select bits for FieldNumE and Seq</entry></row><row><entry /><entry /><entry>data fields SEQ_1 and SEQ_2 field,</entry></row><row><entry /><entry /><entry>FieldValB1 = FieldVal − New</entry></row><row><entry /><entry /><entry>Value for FieldNumE (Copied from</entry></row><row><entry /><entry /><entry>FieldNumL of the Parameter Upgrader</entry></row><row><entry /><entry /><entry>QA Device) and sequence data fields</entry></row><row><entry /><entry /><entry>R<sub>A1 </sub>= R<sub>L2</sub>, SIG<sub>A </sub>= SIGout =</entry></row><row><entry /><entry /><entry>Refer to Section 27.1.3.1.</entry></row><row><entry>5</entry><entry>B. WriteFieldsAuth</entry><entry>KeyRef = n1, FieldSelect =</entry></row><row><entry /><entry /><entry>FieldSelectB1, FieldData =</entry></row><row><entry /><entry /><entry>FieldValB1, RE = R<sub>A1</sub>, SIGE = SIG<sub>A</sub></entry></row><row><entry /><entry /><entry>ResultFlag = Pass/Fail</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 31.5.2 Using the Translate Function
6683The upgrade through the Translate function is used when the Parameter Upgrader QA Device and the Printer QA Device don't share a key between them. The translating QA Device shares a key with the Parameter Upgrader QA Device and a second key with the Printer QA Device. Therefore the messages and their signatures, generated by the Parameter Upgrader QA Device and the Printer QA Device are translated appropriately by the translating QA Device. The translating QA Device validates the Read from the Printer QA Device, and translates it for input to the XferField function. The translating QA Device will validate the output from the XferField function, and then translate it for input to WriteFieldsAuth message of the Printer QA Device.
6684For validating signatures using translation: <ul id="ul0973" list-style="none"><li id="ul0973-0001" num="0000"><ul id="ul0974" list-style="none"><li id="ul0974-0001" num="6685">The Parameter Upgrader QA Device (A) and the translating QA Device (C) must share a common or a variant key i.e C.K<sub>n3</sub>=A.K<sub>n2 </sub>or C.K<sub>n3</sub>=FormKeyVariant(A.K<sub>n2</sub>, C.ChipID).</li><li id="ul0974-0002" num="6686">The Printer QA Device (B) and the translating QA Device (C) must share a common or a variant key i.e C.K<sub>n2</sub>=B.K<sub>n1 </sub>or B.K<sub>n1</sub>=FormKeyVariant(C.K<sub>n2</sub>, B.ChipID). <ul id="ul0975" list-style="none"><li id="ul0975-0001" num="6687">Table 321 shows the command sequence for a basic refill using translation.</li></ul></li></ul></li></ul>
6688<tables id="TABLE-US-00518" num="00518"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 321</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>An upgrade with translate command sequence</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="center" /><colspec colname="2" colwidth="70pt" align="left" /><colspec colname="3" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>Seq</entry><entry /><entry /></row><row><entry>No</entry><entry>Function</entry><entry>Command</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Random-Read-Random-Translate-Random-XferField-Random-</entry></row><row><entry>Translate-Random-WriteFieldsAuth reads M0 and M1 of</entry></row><row><entry>the Printer QA Device using the translating QA Device</entry></row><row><entry>C and then does a write of the upgrade value to</entry></row><row><entry>FieldNumE and new sequence data to the seq data</entry></row><row><entry>fields SEQ_1 and SEQ_2 field of the Printer QA</entry></row><row><entry>Device using the translating QA Device C.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="char" char="." /><colspec colname="2" colwidth="70pt" align="left" /><colspec colname="3" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>1</entry><entry>C. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>C </sub>= R<sub>L</sub></entry></row><row><entry>2</entry><entry>B. Read</entry><entry>KeyRef = n1, SigOnly = 0,</entry></row><row><entry /><entry /><entry>MSelect = 0x03(indicates <sub>M0</sub></entry></row><row><entry /><entry /><entry>and <sub>M1</sub>), KeyIdSelect = 0x00</entry></row><row><entry /><entry /><entry>(no KeyIds required),</entry></row><row><entry /><entry /><entry>WordSelectForDesiredM (for <sub>M0</sub>)=</entry></row><row><entry /><entry /><entry>0xFFFF (Read all <sub>M0 </sub>words),</entry></row><row><entry /><entry /><entry>WordSelectForDesiredM</entry></row><row><entry /><entry /><entry>(for <sub>M1</sub>) = 0xFFFF(Read all</entry></row><row><entry /><entry /><entry><sub>M1 </sub>words), R<sub>E </sub>= R<sub>C</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then</entry></row><row><entry /><entry /><entry>MWords =</entry></row><row><entry /><entry /><entry>SelectedWordsOfSelectedMs as per</entry></row><row><entry /><entry /><entry>input [MSelect] and</entry></row><row><entry /><entry /><entry>[WordSelectForDesiredM],</entry></row><row><entry /><entry /><entry>R<sub>B </sub>= RL, SIG<sub>B </sub>= SIGout</entry></row><row><entry /><entry /><entry>Refer to Section 15.3.1</entry></row><row><entry>3</entry><entry>A. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>A </sub>= R<sub>L</sub></entry></row><row><entry>4</entry><entry>C. Translate</entry><entry>InputKeyRef = n2,</entry></row><row><entry /><entry /><entry>DataLength = MWords</entry></row><row><entry /><entry /><entry>length in words as per Seq No 2</entry></row><row><entry /><entry /><entry>preformatted as per Section</entry></row><row><entry /><entry /><entry>17.1, Data = MWords as</entry></row><row><entry /><entry /><entry>returned from Seq No 2 pre-</entry></row><row><entry /><entry /><entry>formatted as per Section 17.1,</entry></row><row><entry /><entry /><entry>RE = R<sub>B</sub>, SIGE = SIG<sub>B</sub>,</entry></row><row><entry /><entry /><entry>OutputKeyRef = n3, RE2 = R<sub>A</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then</entry></row><row><entry /><entry /><entry>R<sub>C1</sub>, = RL2, SIG<sub>C </sub>= SIGOut</entry></row><row><entry /><entry /><entry>Refer to Section 17.3.1</entry></row><row><entry>5</entry><entry>C. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>C2 </sub>= R<sub>L</sub></entry></row><row><entry>6</entry><entry>A. XferField</entry><entry>KeyRef = n2, <sub>M0</sub>OfExternal =</entry></row><row><entry /><entry /><entry>First 16 words of MWords,</entry></row><row><entry /><entry /><entry><sub>M1</sub>OfExternal = Last 16 words</entry></row><row><entry /><entry /><entry>of MWords, ChipId = ChipId of</entry></row><row><entry /><entry /><entry>B, FieldNumL = The field</entry></row><row><entry /><entry /><entry>storing the upgrade value in the</entry></row><row><entry /><entry /><entry>Parameter Upgrader QA Device.</entry></row><row><entry /><entry /><entry>FieldNumE = The field which</entry></row><row><entry /><entry /><entry>will be upgraded in the Printer</entry></row><row><entry /><entry /><entry>QA Device. R<sub>E </sub>= R<sub>C1</sub>, R<sub>E2 </sub>=</entry></row><row><entry /><entry /><entry>R<sub>C2</sub>, SIG<sub>E </sub>= SIG<sub>C</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then</entry></row><row><entry /><entry /><entry>FieldSelectB1 =</entry></row><row><entry /><entry /><entry>FieldSelect − Select bits for</entry></row><row><entry /><entry /><entry>FieldNumE and sequence fields,</entry></row><row><entry /><entry /><entry>FieldValB1 = FieldVal −</entry></row><row><entry /><entry /><entry>New Value for FieldNumE (Copied</entry></row><row><entry /><entry /><entry>from FieldNumL of the Parameter</entry></row><row><entry /><entry /><entry>Upgrader QA Device) and sequence</entry></row><row><entry /><entry /><entry>fields SEQ_1 and SEQ_2, R<sub>A1 </sub>=</entry></row><row><entry /><entry /><entry>R<sub>L2</sub>, SIG<sub>A </sub>= SIGout Refer to</entry></row><row><entry /><entry /><entry>Section 27.1.3.1</entry></row><row><entry>7</entry><entry>B. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>B1 </sub>= R<sub>L</sub></entry></row><row><entry>8</entry><entry>C. Translate</entry><entry>InputKeyRef = n3,</entry></row><row><entry /><entry /><entry>DataLength = FieldValB1 length</entry></row><row><entry /><entry /><entry>in words as per Seq No 6 pre-</entry></row><row><entry /><entry /><entry>formatted as per Section 17.1,</entry></row><row><entry /><entry /><entry>Data = FieldValB1 as returned</entry></row><row><entry /><entry /><entry>from Seq No 6 preformatted as</entry></row><row><entry /><entry /><entry>per Section 17.1, RE = R<sub>A1</sub>,</entry></row><row><entry /><entry /><entry>SIGE = SIG<sub>A</sub>, OutputKeyRef =</entry></row><row><entry /><entry /><entry>n2, RE2 = R<sub>B1</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then</entry></row><row><entry /><entry /><entry>R<sub>C3 </sub>= R<sub>L2</sub>, SIG<sub>C </sub>= SIGOut</entry></row><row><entry /><entry /><entry>Refer to Section 17.3.1</entry></row><row><entry>19</entry><entry>B. WriteFieldsAuth</entry><entry>KeyRef = n1, FieldSelect =</entry></row><row><entry /><entry /><entry>FieldSelectB1, FieldVal =</entry></row><row><entry /><entry /><entry>FieldValB1, RE = R<sub>C3</sub>,</entry></row><row><entry /><entry /><entry>SIGE = SIG<sub>C</sub></entry></row><row><entry>10</entry><entry /><entry>ResultFlag = Pass/Fail</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 31.6 Recovering from a Failed Upgrade
6689This sequence is performed if the upgrade failed (for e.g Printer QA Device didn't receive the upgrade message correctly and hence didn't upgrade successfully). The Parameter Upgrader QA Device therefore needs to be rolled back to the previous value before the upgrade. In this case, the count-remaining associated with the upgrade value in the Parameter Upgrader QA Device is increased by one.
6690The Parameter Upgrader QA Device checks that the Printer QA Device didn't actually receive the message correctly using the StartRollBack function. The RollBackField performs further comparisons on sequence fields and FieldNumE of the Printer QA Device to values stored in the XferEntry cache. After performing all checks, the Parameter Upgrader QA Device increments the count remaining field associated with the upgrade value field by one. Refer to Section 26 and Section 28 for details.
6691The rollback is started using the Random-Read-Random-StartRollBack-WriteFieldsAuth and the rollback of the Parameter Upgrader QA Device is performed using Random-Read-RollBackField sequence.
6692Table 322 shows the command sequence for a rollback upgrade.
6693<tables id="TABLE-US-00519" num="00519"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="126pt" align="left" /><thead><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>Seq</entry><entry /><entry /></row><row><entry>No</entry><entry>Function</entry><entry>Command</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Random-Read-Random-StartRollBack-WriteFieldsAuth starts</entry></row><row><entry>the rollback and updates data for the sequence fields.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>1</entry><entry>A. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>A </sub>= RL</entry></row><row><entry>2</entry><entry>B. Read</entry><entry>KeyRef = n1 , SigOnly = 0,</entry></row><row><entry /><entry /><entry>MSelect = 0x03(indicates <sub>M0</sub></entry></row><row><entry /><entry /><entry>and <sub>M1</sub>), KeyIdSelect = 0x00</entry></row><row><entry /><entry /><entry>(no KeyIds required),</entry></row><row><entry /><entry /><entry>WordSelectForDesiredM</entry></row><row><entry /><entry /><entry>(for <sub>M0</sub>) = 0xFFFF (Read all</entry></row><row><entry /><entry /><entry><sub>M0</sub>words), WordSelectForDesiredM</entry></row><row><entry /><entry /><entry>(for <sub>M1</sub>) = 0xFFFF(Read all</entry></row><row><entry /><entry /><entry><sub>M1</sub>words), R<sub>E </sub>= R<sub>A</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then</entry></row><row><entry /><entry /><entry>MWords =</entry></row><row><entry /><entry /><entry>SelectedWordsOfSelectedMs as per</entry></row><row><entry /><entry /><entry>input [MSelect] and</entry></row><row><entry /><entry /><entry>[WordSelectForDesiredM],</entry></row><row><entry /><entry /><entry>R<sub>B </sub>= R<sub>L</sub>, SIG<sub>B </sub>= SIGout</entry></row><row><entry /><entry /><entry>Refer to Section 15.3.1</entry></row><row><entry>3</entry><entry>B. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>B1 </sub>= R<sub>L</sub></entry></row><row><entry>4</entry><entry>A. StartRoll</entry><entry>KeyRef = n2, <sub>M0</sub>OfExternal =</entry></row><row><entry /><entry>Back</entry><entry>First 16 words of MWords,</entry></row><row><entry /><entry /><entry><sub>M1</sub>OfExternal = Last 16 words</entry></row><row><entry /><entry /><entry>of MWords, ChipId = ChipId</entry></row><row><entry /><entry /><entry>of B, FieldNumE = The field</entry></row><row><entry /><entry /><entry>which was not upgraded in the</entry></row><row><entry /><entry /><entry>Printer QA Device, FieldNumL =</entry></row><row><entry /><entry /><entry>The upgrade value in the Parameter</entry></row><row><entry /><entry /><entry>Upgrader QA Device which couldn't</entry></row><row><entry /><entry /><entry>be copied to FieldNumE of the</entry></row><row><entry /><entry /><entry>Printer QA Device, R<sub>E </sub>= R<sub>B</sub>,</entry></row><row><entry /><entry /><entry>R<sub>E2 </sub>= R<sub>B1</sub>, SIG<sub>E </sub>= SIG<sub>B</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then</entry></row><row><entry /><entry /><entry>FieldSelectB = FieldSelect −</entry></row><row><entry /><entry /><entry>Select bits for sequence data</entry></row><row><entry /><entry /><entry>fields SEQ_1 and SEQ_2,</entry></row><row><entry /><entry /><entry>FieldValB = FieldVal − New</entry></row><row><entry /><entry /><entry>values for SEQ_1 and SEEQ_2 fields</entry></row><row><entry /><entry /><entry>R<sub>A1 </sub>= R<sub>L2 </sub>SIG<sub>A </sub>= SIGout</entry></row><row><entry /><entry /><entry>Refer to Section 27.1.3.1.</entry></row><row><entry>5</entry><entry>B. WriteFieldsAuth</entry><entry>KeyRef = n1, FieldSelect =</entry></row><row><entry /><entry /><entry>FieldSelectB, FieldData =</entry></row><row><entry /><entry /><entry>FieldValB, RE = R<sub>A1</sub>, SIGE =</entry></row><row><entry /><entry /><entry>SIG<sub>A</sub></entry></row><row><entry /><entry /><entry>ResultFlag = Pass/Fail</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Random-Read-RollBackField performs a read of the QA Device</entry></row><row><entry>being upgraded, checks its values are as per Xfer Entry</entry></row><row><entry>cache, and then adjusts its count-remaining field.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>6</entry><entry>A. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>A2 </sub>= RL</entry></row><row><entry>7</entry><entry>B. Read</entry><entry>KeyRef = n1, SigOnly = 0,</entry></row><row><entry /><entry /><entry>MSelect = 0x03 (indicates <sub>M0</sub></entry></row><row><entry /><entry /><entry>and <sub>M1</sub>), KeyIdSelect = 0x00</entry></row><row><entry /><entry /><entry>(no KeyIds required),</entry></row><row><entry /><entry /><entry>WordSelectForDesiredM (for <sub>M0</sub>) =</entry></row><row><entry /><entry /><entry>0xFFFF (Read all <sub>M0 </sub>words),</entry></row><row><entry /><entry /><entry>WordSelectForDesiredM (for <sub>M1</sub>) =</entry></row><row><entry /><entry /><entry>0xFFFF(Read all <sub>M1 </sub>words),</entry></row><row><entry /><entry /><entry>R<sub>E </sub>= R<sub>A2</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then</entry></row><row><entry /><entry /><entry>MWords = SelectedWordsOfSelectedMs</entry></row><row><entry /><entry /><entry>as per input [MSelect] and</entry></row><row><entry /><entry /><entry>[WordSelectForDesiredM],</entry></row><row><entry /><entry /><entry>R<sub>B2 </sub>= RL, SIG<sub>B </sub>= SIGout Refer</entry></row><row><entry /><entry /><entry>to Section 15.3.1</entry></row><row><entry>8</entry><entry>A. Roll Back</entry><entry>KeyRef = n2, <sub>M0</sub>OfExternal = First</entry></row><row><entry /><entry>Field</entry><entry>16 words of MWords, <sub>M1</sub>OfExternal =</entry></row><row><entry /><entry /><entry>Last 16 words of MWords,</entry></row><row><entry /><entry /><entry>ChipId = ChipId of B,</entry></row><row><entry /><entry /><entry>FieldNumE = The field which was</entry></row><row><entry /><entry /><entry>not upgraded in the Printer QA Device,</entry></row><row><entry /><entry /><entry>FieldNumL = The upgrade value in</entry></row><row><entry /><entry /><entry>the Parameter Upgrader QA Device which</entry></row><row><entry /><entry /><entry>couldn't be copied to FieldNumE of</entry></row><row><entry /><entry /><entry>the Printer QA Device, R<sub>E </sub>= R<sub>B2</sub>,</entry></row><row><entry /><entry /><entry>SIG<sub>E </sub>= SIG<sub>B</sub></entry></row><row><entry /><entry /><entry>ResultFlag = Pass/Fail</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 31.7 Re/Filling the Consumable (Ink)
6694This sequence is performed when an ink cartridge is first manufactured or after all the physical ink has been used, it can be filled or refilled. The re/fill protocol is used to transfer the logical ink from the Ink Refill QA Device to the Ink QA Device in the ink cartridge.
6695The Ink Refill QA Device stores the amount of logical ink corresponding to the physical ink in the refill station. During the refill, the required logical amount (corresponding to the physical transfer amount) is transferred from the Ink Refill QA Device to the Ink QA Device.
6696The Ink Refill QA Device output the transfer data only after completing all necessary checks to ensure that correct logical ink type is being transferred e.g Network_OEM1_infrared ink is not transferred to Network_OEM2_cyan ink. Refer to the XferAmount command in Section 27.1.
000031.7.1 Basic Refill
6697The basic refill is used when the Ink Refill QA Device and the Ink QA Device share a common key or a variant key i.e B.K<sub>n1</sub>=A.K<sub>n2 </sub>or B.K<sub>n1</sub>=FormKeyVariant(A.K<sub>n2</sub>, B.ChipID) where B is the Ink QA Device and A is the Ink Refill QA Device. Therefore, the messages and their signatures, generated by each of them can be correctly interpreted by the other.
6698The Xfer Sequence is started using Random-Read-Random-StartXfer-WriteAuth and the the Xfer Amount is written to the QA Device being refilled using Random-Read-Random-XferAmount-WriteFieldsAuth sequence.
6699<tables id="TABLE-US-00520" num="00520"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 323</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>the command sequence for a basic refill.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="70pt" align="left" /><colspec colname="3" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>Seq</entry><entry /><entry /></row><row><entry>No</entry><entry>Function</entry><entry>Parameter</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Random-Read-Random-XferAmount-WriteFieldsAuth reads M0 and M1</entry></row><row><entry>of the Ink QA Device being refilled, produce updated amount</entry></row><row><entry>for FieldNumE and sequence datat field by calling XferAmount</entry></row><row><entry>on Ink Refill QA Device, and finally writing the updated</entry></row><row><entry>value to Ink QA Device using WriteFieldsAuth.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="70pt" align="left" /><colspec colname="3" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>1</entry><entry>A. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>A </sub>= R<sub>L</sub></entry></row><row><entry>2</entry><entry>B. Read</entry><entry>KeyRef = n1, SigOnly = 0,</entry></row><row><entry /><entry /><entry>MSelect = 0x03(indicates <sub>M0</sub></entry></row><row><entry /><entry /><entry>and <sub>M1</sub>), KeyIdSelect = 0x00</entry></row><row><entry /><entry /><entry>(no KeyIds required),</entry></row><row><entry /><entry /><entry>WordSelectForDesiredM (for <sub>M0</sub>) =</entry></row><row><entry /><entry /><entry>0xFFFF (Read all <sub>M0</sub>words),</entry></row><row><entry /><entry /><entry>WordSelectForDesiredM (for <sub>M1</sub>) =</entry></row><row><entry /><entry /><entry>0xFFFF(Read all <sub>M1</sub>words),</entry></row><row><entry /><entry /><entry>RE = R<sub>A</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then</entry></row><row><entry /><entry /><entry>MWords =</entry></row><row><entry /><entry /><entry>SelectedWordsOfSelectedMs as per</entry></row><row><entry /><entry /><entry>input [MSelect] and</entry></row><row><entry /><entry /><entry>[WordSelectForDesiredM],</entry></row><row><entry /><entry /><entry>R<sub>B </sub>= RL, SIG<sub>B </sub>= SIGout Refer</entry></row><row><entry /><entry /><entry>to Section 15.3.1</entry></row><row><entry>3</entry><entry>B. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>B1 </sub>= R<sub>L</sub></entry></row><row><entry>4</entry><entry>AxferAmount</entry><entry>KeyRef = n2, <sub>M0</sub>OfExternal = First</entry></row><row><entry /><entry /><entry>16 words of MWords, <sub>M1</sub>OfExternal =</entry></row><row><entry /><entry /><entry>Last 16 words of MWords, ChipId =</entry></row><row><entry /><entry /><entry>ChipId of B, FieldNumL = ink-</entry></row><row><entry /><entry /><entry>remaining field of the Ink Refill</entry></row><row><entry /><entry /><entry>QA Device, FieldNumE = ink-</entry></row><row><entry /><entry /><entry>remaining field of the Ink QA</entry></row><row><entry /><entry /><entry>Device, XferValLength = length</entry></row><row><entry /><entry /><entry>in words of XferVal XferVal =</entry></row><row><entry /><entry /><entry>Value to be transferred from</entry></row><row><entry /><entry /><entry>Ink Refill QA Device to Ink QA</entry></row><row><entry /><entry /><entry>Device being refilled, R<sub>E </sub>=</entry></row><row><entry /><entry /><entry>R<sub>B</sub>, R<sub>E2 </sub>= R<sub>B1</sub></entry></row><row><entry /><entry /><entry>SIG<sub>E </sub>= SIG<sub>B</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then</entry></row><row><entry /><entry /><entry>FieldSelectB1 = FieldSelect −</entry></row><row><entry /><entry /><entry>Select bits for FieldNumE and</entry></row><row><entry /><entry /><entry>sequence data field SEQ_1 and</entry></row><row><entry /><entry /><entry>SEQ_2, FieldValB1 = FieldVal −</entry></row><row><entry /><entry /><entry>New Value for FieldNumE</entry></row><row><entry /><entry /><entry>(transferred from FieldNumL of</entry></row><row><entry /><entry /><entry>the Ink Refill QA Device) and</entry></row><row><entry /><entry /><entry>sequence data fields SEQ_1 and</entry></row><row><entry /><entry /><entry>SEQ_2, R<sub>A1 </sub>= R<sub>L2</sub>,</entry></row><row><entry /><entry /><entry>SIG<sub>A </sub>= SIGout Refer to</entry></row><row><entry /><entry /><entry>Section 27.1.3.1.</entry></row><row><entry>5</entry><entry>B. WriteFieldsAuth</entry><entry>KeyRef = n1, FieldSelect =</entry></row><row><entry /><entry /><entry>FieldSelectB, FieldData =</entry></row><row><entry /><entry /><entry>FieldValB, RE = R<sub>A1</sub>,</entry></row><row><entry /><entry /><entry>SIGE = SIG<sub>A</sub></entry></row><row><entry /><entry /><entry>ResultFlag = Pass/Fail</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 31.7.2 Using the Translate Function
6700The refill through the Translate function is used when the Ink Refill QA Device and the Ink QA Device don't share a key between them. The translating QA Device shares a key with the Ink Refill QA Device and a second key with the Ink QA Device. Therefore the messages and their signatures, generated by the Ink Refill QA Device and the Ink QA Device, are translated appropriately by the translating QA Device. The translating QA Device validates the Read from the Ink QA Device, and translates it for input to the XferAmount function. The translating QA Device will validate the output from the XferAmount function, and then translate it for input to WriteFieldsAuth message of the Ink QA Device.
6701For validating signatures using translation: <ul id="ul0976" list-style="none"><li id="ul0976-0001" num="0000"><ul id="ul0977" list-style="none"><li id="ul0977-0001" num="6702">The Ink Refill QA Device (A) and the translating QA Device (C) must share a common or a variant key i.e C.K<sub>n3</sub>=A.K<sub>n2 </sub>or C.K<sub>n3</sub>=FormKeyVariant(A.K<sub>n2</sub>, C.ChipID).</li><li id="ul0977-0002" num="6703">The Ink Refill QA Device being refilled (B) and the translating QA Device (C) must share a common or a variant key i.e C.K<sub>n2</sub>=B.K<sub>n1 </sub>or B.K<sub>n1</sub>=FormKeyVariant(C.K<sub>n2</sub>, B.ChipID).</li></ul></li></ul>
6704<tables id="TABLE-US-00521" num="00521"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 324</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>A basic refill using translation command sequence</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="35pt" align="left" /><colspec colname="2" colwidth="70pt" align="left" /><colspec colname="3" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>Seq</entry><entry /><entry /></row><row><entry>No</entry><entry>Function</entry><entry>Command</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Random-Read-Random-Translate-Random-XferAmount-Random-</entry></row><row><entry>Translate-Random-WriteFieldsAuth - reads M0 and M1 of</entry></row><row><entry>the Ink QA Device being refilled using the translating</entry></row><row><entry>QA Device C, produce updated amount for FieldNumE and</entry></row><row><entry>sequence data field by calling XferAmount on Ink</entry></row><row><entry>Refill QA Device, and finally writing the updated</entry></row><row><entry>value to Ink QA Device using the translating</entry></row><row><entry>QA Device.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="35pt" align="left" /><colspec colname="2" colwidth="70pt" align="left" /><colspec colname="3" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>1</entry><entry>C. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>C </sub>= R<sub>L</sub></entry></row><row><entry>2</entry><entry>B. Read</entry><entry>KeyRef = n1, SigOnly = 0,</entry></row><row><entry /><entry /><entry>MSelect = 0x03(indicates <sub>M0</sub></entry></row><row><entry /><entry /><entry>and <sub>M1</sub>), KeyIdSelect =</entry></row><row><entry /><entry /><entry>0x00 no KeyIds required),</entry></row><row><entry /><entry /><entry>WordSelectForDesiredM</entry></row><row><entry /><entry /><entry>(for <sub>M0</sub>) = 0xFFFF (Read</entry></row><row><entry /><entry /><entry>all <sub>M0 </sub>words),</entry></row><row><entry /><entry /><entry>WordSelectForDesiredM (for</entry></row><row><entry /><entry /><entry><sub>M1</sub>) = 0xFFFF(Read all</entry></row><row><entry /><entry /><entry><sub>M1</sub>words), R<sub>E </sub>= R<sub>C</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass</entry></row><row><entry /><entry /><entry>then MWords =</entry></row><row><entry /><entry /><entry>SelectedWordsOfSelectedMs</entry></row><row><entry /><entry /><entry>as per input [MSelect] and</entry></row><row><entry /><entry /><entry>[WordSelectForDesiredM], R<sub>B </sub>=</entry></row><row><entry /><entry /><entry>R<sub>L</sub>, SIG<sub>B </sub>= SIGout Refer to</entry></row><row><entry /><entry /><entry>Section 15.3.1</entry></row><row><entry>3</entry><entry>A. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>A </sub>= R<sub>L</sub></entry></row><row><entry>4</entry><entry>C. Translate</entry><entry>InputKeyRef = n2, DataLength =</entry></row><row><entry /><entry /><entry>MWords length in words as per</entry></row><row><entry /><entry /><entry>Seq No 2 preformatted as per</entry></row><row><entry /><entry /><entry>Section 17.1, Data = MWords</entry></row><row><entry /><entry /><entry>as returned from Seq No 2</entry></row><row><entry /><entry /><entry>preformatted as per</entry></row><row><entry /><entry /><entry>Section 17.1, RE =</entry></row><row><entry /><entry /><entry>R<sub>B</sub>, SIGE = SIG<sub>B</sub>,</entry></row><row><entry /><entry /><entry>OutputKeyRef = n3,</entry></row><row><entry /><entry /><entry>RE2 = R<sub>A</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then</entry></row><row><entry /><entry /><entry>R<sub>C1 </sub>= R<sub>L2</sub>, SIG<sub>C </sub>= SIGOut</entry></row><row><entry /><entry /><entry>Refer to Section 17.3.1</entry></row><row><entry>5</entry><entry>C. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>L </sub>= R<sub>C2</sub></entry></row><row><entry>6</entry><entry>A. XferAmount</entry><entry>KeyRef = n2, <sub>M0</sub>OfExternal =</entry></row><row><entry /><entry /><entry>First 16 words of MWords,</entry></row><row><entry /><entry /><entry><sub>M1</sub>OfExternal = Last 16 words</entry></row><row><entry /><entry /><entry>of MWords, ChipId =</entry></row><row><entry /><entry /><entry>ChipId of B, FieldNumL =</entry></row><row><entry /><entry /><entry>ink-remaining field of the</entry></row><row><entry /><entry /><entry>Ink Refill QA Device,</entry></row><row><entry /><entry /><entry>FieldNumE = ink-remaining</entry></row><row><entry /><entry /><entry>field of the Ink QA Device,</entry></row><row><entry /><entry /><entry>XferValLength = length</entry></row><row><entry /><entry /><entry>in words of XferVal</entry></row><row><entry /><entry /><entry>XferVal = Value to be</entry></row><row><entry /><entry /><entry>transferred from Ink Refill QA</entry></row><row><entry /><entry /><entry>Device to Ink QA Device being</entry></row><row><entry /><entry /><entry>refilled, R<sub>E </sub>= R<sub>C1</sub>, R<sub>E2 </sub>=</entry></row><row><entry /><entry /><entry>R<sub>C2</sub>, SIG<sub>E </sub>= SIG<sub>C</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then</entry></row><row><entry /><entry /><entry>FieldSelectB1 = FieldSelect −</entry></row><row><entry /><entry /><entry>Select bits for FieldNumE and</entry></row><row><entry /><entry /><entry>sequence data field SEQ_1 and</entry></row><row><entry /><entry /><entry>SEQ_2, FieldValB1 = FieldVal −</entry></row><row><entry /><entry /><entry>New Value or FieldNumE</entry></row><row><entry /><entry /><entry>(transferred from FieldNumL of</entry></row><row><entry /><entry /><entry>the Ink Refill QA Device) and</entry></row><row><entry /><entry /><entry>sequence data fields</entry></row><row><entry /><entry /><entry>SEQ_1 and SEQ_2, R<sub>A1 </sub>= R<sub>L2</sub>,</entry></row><row><entry /><entry /><entry>SIG<sub>A </sub>= SIGout Refer to</entry></row><row><entry /><entry /><entry>Section 27.1.3.1</entry></row><row><entry>7</entry><entry>B. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>B1 </sub>= R<sub>L</sub></entry></row><row><entry>8</entry><entry>C. Translate</entry><entry>InputKeyRef = n3, DataLength =</entry></row><row><entry /><entry /><entry>FieldValB length in words as</entry></row><row><entry /><entry /><entry>per Seq No 6 preformatted as</entry></row><row><entry /><entry /><entry>per Section 17.1, Data =</entry></row><row><entry /><entry /><entry>FieldValB as returned from</entry></row><row><entry /><entry /><entry>Seq No 6 preformatted as</entry></row><row><entry /><entry /><entry>per Section 17.1, RE = R<sub>A1</sub>,</entry></row><row><entry /><entry /><entry>SIGE = SIG<sub>A</sub>, OutputKeyRef =</entry></row><row><entry /><entry /><entry>n2, RE2 = R<sub>B1</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then R<sub>C3 </sub>=</entry></row><row><entry /><entry /><entry>RL2, SIG<sub>C </sub>= SIGOut</entry></row><row><entry /><entry /><entry>Refer to Section 17.3.1</entry></row><row><entry>9</entry><entry>B. WriteFieldsAuth</entry><entry>KeyRef = n1, FieldSelect =</entry></row><row><entry /><entry /><entry>FieldSelectB, FieldData =</entry></row><row><entry /><entry /><entry>FieldValB, RE = R<sub>C3</sub>, SIGE =</entry></row><row><entry /><entry /><entry>SIG<sub>C</sub></entry></row><row><entry /><entry /><entry>ResultFlag = Pass/Fail</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 31.8 Recovering from a Failed Refill
6705This sequence is performed if the refill failed (for e.g Ink QA Device didn't receive the refill message correctly and hence didn't refill successfully). The Ink Refill QA Device therefore needs to be rolled back to the previous value before the refill.
6706The Ink Refill QA Device checks that the Ink QA Device didn't actually receive the message correctly using the StartRollBack function. The RollBackAmount performs further comparisons on sequence data field and FieldNumE of the Ink QA Device, to values stored in the XferEntry cache. After performing all checks, the Ink Refill QA Device adjusts its ink field to a previous value before the transfer request was processed by it. Refer to Section 26 and Section 28 for details.
6707The rollback is started using the Random-Read-Random-StartRollBack-WriteFieldsAuth and the rollback of the Ink Refill QA Device is performed using Random-Read-RollBackAmount sequence.
6708<tables id="TABLE-US-00522" num="00522"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 325</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Rollback amount command sequence</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="center" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>Seq</entry><entry /><entry /></row><row><entry>No</entry><entry>Function</entry><entry>Command</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Random-Read-Random-StartRollBack-WriteAuth starts the rollback and</entry></row><row><entry>updates data for the sequence data fields SEQ_1 and SEQ_2.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="char" char="." /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>1</entry><entry>A. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>A </sub>= RL</entry></row><row><entry>2</entry><entry>B. Read</entry><entry>KeyRef = n1, SigOnly = 0,</entry></row><row><entry /><entry /><entry>MSelect = 0x03(indicates <sub>M0 </sub>and <sub>M1</sub>),</entry></row><row><entry /><entry /><entry>KeyIdSelect = 0x00 no KeyIds</entry></row><row><entry /><entry /><entry>required), WordSelectForDesiredM</entry></row><row><entry /><entry /><entry>(for <sub>M0</sub>) = 0xFFFF (Read all</entry></row><row><entry /><entry /><entry><sub>M0</sub>words), WordSelectForDesiredM</entry></row><row><entry /><entry /><entry>(for<sub>M1</sub>) = 0xFFFF(Read all</entry></row><row><entry /><entry /><entry><sub>M1</sub>words), R<sub>E </sub>= R<sub>A</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then</entry></row><row><entry /><entry /><entry>MWords = Selected</entry></row><row><entry /><entry /><entry>WordsOfSelectedMs as per</entry></row><row><entry /><entry /><entry>input [MSelect] and</entry></row><row><entry /><entry /><entry>[WordSelectForDesiredM],</entry></row><row><entry /><entry /><entry>R<sub>B </sub>= RL, SIG<sub>B </sub>=</entry></row><row><entry /><entry /><entry>SIGout Refer to</entry></row><row><entry /><entry /><entry>Section 15.3.1</entry></row><row><entry>3</entry><entry>B. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>B1 </sub>= R<sub>L</sub></entry></row><row><entry>4</entry><entry>A. StartRollBack</entry><entry>KeyRef = n2, <sub>M0</sub>Of</entry></row><row><entry /><entry /><entry>External = First 16</entry></row><row><entry /><entry /><entry>words of MWords, <sub>M1</sub>OfExternal</entry></row><row><entry /><entry /><entry>Last 16 words of MWords,</entry></row><row><entry /><entry /><entry>ChipId = ChipId of B,</entry></row><row><entry /><entry /><entry>FieldNumL = ink-remaining</entry></row><row><entry /><entry /><entry>field of the Ink Refill</entry></row><row><entry /><entry /><entry>QA Device which will be</entry></row><row><entry /><entry /><entry>adjusted to the value</entry></row><row><entry /><entry /><entry>before the failed refill,</entry></row><row><entry /><entry /><entry>FieldNumE = ink-remaining</entry></row><row><entry /><entry /><entry>field of the Ink QA Device</entry></row><row><entry /><entry /><entry>which failed to refill,</entry></row><row><entry /><entry /><entry>R<sub>E </sub>= R<sub>B</sub>,</entry></row><row><entry /><entry /><entry>R<sub>E2 </sub>= R<sub>B1</sub></entry></row><row><entry /><entry /><entry>SIG<sub>E </sub>= SIG<sub>B</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then</entry></row><row><entry /><entry /><entry>FieldSelectB = FieldSelect −</entry></row><row><entry /><entry /><entry>Select bits for sequence data</entry></row><row><entry /><entry /><entry>fields- SEQ_1 and SEQ_2,</entry></row><row><entry /><entry /><entry>FieldValB = FieldVal −</entry></row><row><entry /><entry /><entry>New value for sequence data</entry></row><row><entry /><entry /><entry>fields SEQ_1 and SEQ_2 R<sub>A1 </sub>= R<sub>L2</sub>,</entry></row><row><entry /><entry /><entry>SIG<sub>A </sub>= SIGout Refer to</entry></row><row><entry /><entry /><entry>Section 27.1.3.1.</entry></row><row><entry>5</entry><entry>B. WriteFieldsAuth</entry><entry>KeyRef = n1, FieldSelect =</entry></row><row><entry /><entry /><entry>FieldSelectB in Seq No 4,</entry></row><row><entry /><entry /><entry>FieldData = FieldValB in</entry></row><row><entry /><entry /><entry>Seq No 4 RE = R<sub>A1</sub>,</entry></row><row><entry /><entry /><entry>SIGE = SIG<sub>A</sub></entry></row><row><entry>10</entry><entry /><entry>ResultFlag = Pass/Fail</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Random-Read-RollBackAmount performs a read of the Ink QA</entry></row><row><entry>Device, checks its values are as per Xfer Entry cache,</entry></row><row><entry>and then adjusts its ink-remaining field.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="char" char="." /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>11</entry><entry>A. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>A2</sub>. = RL</entry></row><row><entry>12</entry><entry>B. Read</entry><entry>KeyRef = n1, SigOnly = 0,</entry></row><row><entry /><entry /><entry>MSelect = 0x03(indicates <sub>M0</sub></entry></row><row><entry /><entry /><entry>and <sub>M1</sub>), KeyIdReq = 0 (not</entry></row><row><entry /><entry /><entry>required), KeyIdSelect = 0x00</entry></row><row><entry /><entry /><entry>(no KeyIds required),</entry></row><row><entry /><entry /><entry>WordSelectForDesiredM</entry></row><row><entry /><entry /><entry>(for <sub>M0</sub>) = 0xFFFF (Read all</entry></row><row><entry /><entry /><entry><sub>M0</sub>words), WordSelectForDesiredM</entry></row><row><entry /><entry /><entry>(for <sub>M1</sub>) = 0xFFFF(Read all</entry></row><row><entry /><entry /><entry><sub>M1 </sub>words), RE = R<sub>A2</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then MWords =</entry></row><row><entry /><entry /><entry>SelectedWordsOf SelectedMs as per input</entry></row><row><entry /><entry /><entry>[MSelect] and [WordSelect</entry></row><row><entry /><entry /><entry>ForDesiredM], R<sub>B2 </sub>= R<sub>L</sub>, SIG<sub>B </sub>=</entry></row><row><entry /><entry /><entry>SIGout Refer to Section 15.3.1</entry></row><row><entry>13</entry><entry>A. RollBackAmount</entry><entry>KeyRef = n2, <sub>M0</sub>OfExternal = First</entry></row><row><entry /><entry /><entry>16 words of MWords, <sub>M1</sub>OfExternal =</entry></row><row><entry /><entry /><entry>Last 16 words of MWords, ChipId =</entry></row><row><entry /><entry /><entry>ChipId of B, FieldNumL = ink-</entry></row><row><entry /><entry /><entry>remaining field of Ink Refill</entry></row><row><entry /><entry /><entry>QA Device which will be</entry></row><row><entry /><entry /><entry>adjusted to the value before</entry></row><row><entry /><entry /><entry>the failed refill, FieldNumE =</entry></row><row><entry /><entry /><entry>ink-remaining field of Ink</entry></row><row><entry /><entry /><entry>QA Device which failed to</entry></row><row><entry /><entry /><entry>refill, R<sub>E </sub>= R<sub>B2</sub>,</entry></row><row><entry /><entry /><entry>SIG<sub>E </sub>= SIG<sub>B</sub></entry></row><row><entry /><entry /><entry>ResultFlag = Pass/Fail</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 31.9 Upgrading/Refilling/Filling the Upgrader
6709This sequence is performed when a count-remaining field in the Parameter QA Device must be updated or when the ink-remaining field in the Ink Refill QA Device requires re/filling.
6710In case of the Parameter QA Device, another Parameter Upgrader Refill QA Device transfers its count-remaining value to the Parameter QA Device using the transfer sequence described in Section 31.4. Also refer to Section 28.6. This means the count-remaining in the Paramater Upgrader Refill QA Device must be decremented by the same amount that Parameter Upgrader QA Device is incremented by i.e a credit transfer occurs.
6711In case of the Ink Refill QA Device, another Ink Refill QA Device transfers its ink-remaining value to the Ink Refill QA Device using the transfer sequence described in Section 31.4. Also refer to Section 26.4. This means the logical ink-remaining in the Ink Refill QA Device must be decremented by the same amount that QA Device being refilled is incremented by i.e a credit transfer occurs.
000032 Setting Up for Field Use
6712This section consists of setting up the data structures in the QA Device correctly for field use. All data structures are first programmed to factory values. Some of the data structures can then be changed to application specific values at the ComCo or the OEM, while others are set to fixed values.
000032.1 Instantiating the QA Chip Logical Interface
6713This sequence is performed when the QA Device is first created. Table 326 shows the data structure on final program load.
6714<tables id="TABLE-US-00523" num="00523"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 326</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Data structure set up during final program load</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="119pt" align="left" /><colspec colname="3" colwidth="56pt" align="left" /><tbody valign="top"><row><entry>Data</entry><entry /><entry /></row><row><entry>Structure</entry><entry /><entry>Fixed or</entry></row><row><entry>Name</entry><entry>Value Set to</entry><entry>Updatable</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>ChipId</entry><entry>Unique Identifier for QA Device</entry><entry>Fixed</entry></row><row><entry>NumKey</entry><entry>Number of keys the QA Device</entry><entry>Fixed</entry></row><row><entry /><entry>can hold</entry></row><row><entry>K<sub>n</sub></entry><entry>All K<sub>n </sub>= K<sub>batch</sub>. The K <sub>batch </sub>is</entry><entry>Updateable if</entry></row><row><entry /><entry>unique for a production batch<sup>a</sup>.</entry><entry>previous value is</entry></row><row><entry /><entry /><entry>known</entry></row><row><entry>KeyId</entry><entry>All KeyIds = KeyId of K<sub>batch</sub>.</entry><entry>Updateable along</entry></row><row><entry /><entry /><entry>with K<sub>n</sub>.</entry></row><row><entry>KeyLock</entry><entry>All KeyLock = unlocked</entry><entry>Updateable</entry></row><row><entry>NumVectors</entry><entry>Number of memory vectors in the QA</entry><entry>Fixed</entry></row><row><entry /><entry>Device.</entry></row><row><entry><sub>M0</sub></entry><entry>Set to zeros</entry><entry>Updateable</entry></row><row><entry><sub>M0</sub></entry><entry>Set to zeros</entry><entry>Updateable</entry></row><row><entry>M<sub>2+</sub></entry><entry>Set to zeros</entry><entry>Updateable</entry></row><row><entry>P<sub>n</sub></entry><entry>Set to ones</entry><entry>Updateable</entry></row><row><entry>R</entry><entry>Set to an initial random value</entry><entry>Updateable</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
6715Each key slot has the same K<sub>batch</sub>. If each key slot had a different K<sub>batch</sub>, and any one of the K<sub>batch </sub>was compromised then the entire batch would be compromised till the K<sub>batch </sub>was replaced to another key. Hence, each key slot having a different K<sub>batch </sub>doesn't have any security advantages but requires more keys to be managed.
000032.2 Setting Up Application Specific Data
6716The section defines the sequences for configuring the data structures in the QA Device to application specific data.
000032.2.1 Replacing Keys
6717The QA Devices are programmed with production batch keys at final program load. The COMCO keys replace the production batch keys before the QA Devices are shipped to the ComCo. The ComCo replaces the COMCO keys to COMCO_OEM when shipping QA Devices to its OEMs. The OEM replaces the COMCO_OEM to COMCO_OEM app as the QA Devices are placed in ink cartridges or printers.
6718The replacement occurs without the ComCo or the OEM knowing the actual value of the key. The actual value of the keys is only to known to QACo. The ComCo or the OEM is able to perform these replacements because the QACo provides them with a key programming QA Device with keys appropriately set which can generate the necessary messages and signatures to replace the old key with the new key.
6719Table 327 shows the command sequence for ReplaceKey. The GetProgramKey gets the new encrypted key from the key programming QA Device, and the encrypted new key is passed into the QA Device whose key is being replaced through the ReplaceKey function. Depending on the OldKeyRef and NewKeyRef objects a common encrypted key or a variant encrypted key can be produced for the ReplaceKey function
6720<tables id="TABLE-US-00524" num="00524"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 327</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>ReplaceKey command sequence</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>Seq</entry><entry /><entry /></row><row><entry>No</entry><entry>Function</entry><entry>Command</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>1</entry><entry>B. Random</entry><entry>None</entry></row><row><entry /><entry /><entry>R<sub>B </sub>= R<sub>L</sub></entry></row><row><entry>2</entry><entry>A. GetProgramKey</entry><entry>OldKeyRef = Key Num of the old</entry></row><row><entry /><entry /><entry>key. This key must be changed to the</entry></row><row><entry /><entry /><entry>NewKeyRef in the QA Device whose key</entry></row><row><entry /><entry /><entry>s being replaced. ChipId = Chip</entry></row><row><entry /><entry /><entry>identifier of the QA Device whose</entry></row><row><entry /><entry /><entry>key is being replaced. RE = R<sub>B</sub></entry></row><row><entry /><entry /><entry>KeyLock = Set depending on</entry></row><row><entry /><entry /><entry>whether the new key is the final key</entry></row><row><entry /><entry /><entry>for the key slot or it will be</entry></row><row><entry /><entry /><entry>replaced further. NewKeyRef = Key</entry></row><row><entry /><entry /><entry>Num of the new key. This key will</entry></row><row><entry /><entry /><entry>change the OldKeyRef in the QA</entry></row><row><entry /><entry /><entry>Device whose key is being replaced.</entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then R<sub>A </sub>=</entry></row><row><entry /><entry /><entry>RL, KeyId<sub>new </sub>= KeyIdOfNewKey</entry></row><row><entry /><entry /><entry>EncryptedNewKey = EncryptedKey</entry></row><row><entry /><entry /><entry>SIGA = SIGout Refer to</entry></row><row><entry /><entry /><entry>Section 22.2.1.</entry></row><row><entry>3</entry><entry>B. ReplaceKey</entry><entry>KeyNumToBeReplaced = Old key</entry></row><row><entry /><entry /><entry>number, the old key could be a</entry></row><row><entry /><entry /><entry>common key or a variant key,</entry></row><row><entry /><entry /><entry>KeyId = KeyId<sub>new</sub>,</entry></row><row><entry /><entry /><entry>EncryptedKey = EncryptedNewKey,</entry></row><row><entry /><entry /><entry>RE = RA, SIGE = SIGA</entry></row><row><entry /><entry /><entry>ResultFlag = Pass/Fail</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 32.2.2 Setting Up ReadOnly Data
6721This sets the permanent functional parameters of the application where the QA Device has been placed. These parameters remain unchanged for the lifetime of the QA Device. In case of the ink cartridge such parameters are colour and viscosity of the ink. These values are written to M<sub>2+</sub> memory vectors using the WriteM1+ function, and its permissions are set to ReadOnly by SetPerm function. These values are typically set at the OEM.
6722Table 328 shows the command sequence for setting up ReadOnly data.
6723<tables id="TABLE-US-00525" num="00525"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 328</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>ReadOnly data setup command sequence</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="49pt" align="left" /><colspec colname="3" colwidth="140pt" align="left" /><tbody valign="top"><row><entry>Seq</entry><entry /><entry /></row><row><entry>No</entry><entry>Function</entry><entry>Command</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>1</entry><entry>B. WriteM1+</entry><entry>VectNum = 2 or 3, WordSelect = the</entry></row><row><entry /><entry /><entry>selected words to be written, MVal = words</entry></row><row><entry /><entry /><entry>corresponding to word select starting</entry></row><row><entry /><entry /><entry>from LSW</entry></row><row><entry /><entry /><entry>ResultFlag = Pass/Fail</entry></row><row><entry>2</entry><entry>B. SetPerm</entry><entry>(VectNum = same as Seq No 1 parameter</entry></row><row><entry /><entry /><entry>[VectNum], PermVal = same as Seq No 1</entry></row><row><entry /><entry /><entry>parameter [WordSelect])</entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then CurrPerm =</entry></row><row><entry /><entry /><entry>NewPerm Current permission value after</entry></row><row><entry /><entry /><entry>applying PermVal</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
6724In case of the SBR4320, the values written to M<sub>2+</sub> memory vectors is write-once only i.e they are set to ReadOnly as soon as they are written to once, therefore the command sequence consists only of Seq No 1 in Table 329.
000032.2.3 Defining Fields in <sub>M0 </sub>
6725The QACo must determine the field definitions for M0 depending on the application of the QA Device. These field definitions will consist of the following: <ul id="ul0978" list-style="none"><li id="ul0978-0001" num="0000"><ul id="ul0979" list-style="none"><li id="ul0979-0001" num="6726">Number of fields and the size of each field.</li><li id="ul0979-0002" num="6727">The Type attribute of each field.</li><li id="ul0979-0003" num="6728">The access permission for each field.</li></ul></li></ul>
6729Following fields have been presently defined in an ink QA Device: <ul id="ul0980" list-style="none"><li id="ul0980-0001" num="0000"><ul id="ul0981" list-style="none"><li id="ul0981-0001" num="6730">ink-remaining field. See Section 26 for details.</li></ul></li><li id="ul0980-0002" num="6731">Preauthorisation field. See Section 31.4.3 for details. <ul id="ul0982" list-style="none"><li id="ul0982-0001" num="6732">Sequence data fields SEQ<sub>—</sub>1 and SEQ<sub>—</sub>2. See Section 26 for details.</li></ul></li></ul>
6733Following fields have been presently defined in a printer QA Device: <ul id="ul0983" list-style="none"><li id="ul0983-0001" num="0000"><ul id="ul0984" list-style="none"><li id="ul0984-0001" num="6734">Operating parameter field. See Section 28 for details.</li><li id="ul0984-0002" num="6735">Sequence data fields SEQ<sub>—</sub>1 and SEQ<sub>—</sub>2. See Section 26 for details.</li></ul></li></ul>
6736After the field definitions are determined, they are formatted as per Section 8.1.1.4. These formatted values are then written to <sub>M1 </sub>using a WriteM1+ function.
6737<tables id="TABLE-US-00526" num="00526"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 329</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Defining M0 fields command sequence</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="49pt" align="left" /><colspec colname="3" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>Sequence</entry><entry /><entry /></row><row><entry>No</entry><entry>Function</entry><entry>Command</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>1</entry><entry>B. WriteM1+</entry><entry>VectNum = 1, WordSelect = The selected</entry></row><row><entry /><entry /><entry>words corresponding to the attribute</entry></row><row><entry /><entry /><entry>field/fields of <sub>M0</sub>, MVal = words</entry></row><row><entry /><entry /><entry>corresponding to word select starting</entry></row><row><entry /><entry /><entry>from LSW)</entry></row><row><entry /><entry /><entry>ResultFlag = Pass/Fail</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 32.2.4 Writing Values to Fields in <sub>M0 </sub>
6738The writing of <sub>M0 </sub>fields for an Ink QA Device will typically occur when the ink cartridge is filled with physical ink for the first time, and the equivalent logical ink is written to the Ink QA Device. Refer to Section 31.7 for details.
6739The writing of <sub>M0 </sub>fields for a Printer QA Device will typically occur when the printer parameters are written for the first time. The procedure for writing of a printer parameter for the first time or upgrading a printer parameters is exactly the same. Refer to Section 31.5 for details.
6740Before any value is written to a field, the key slot containing the key which has authenticated ReadWrite access to the field must be locked.
6741Both Ink QA Device and Printer QA Device has a sequence data fields SEQ<sub>—</sub>1 and SEQ<sub>—</sub>2 as described in Section 27. These two fields must be initialised to 0xFFFFFFFF, refer to Section 27 for details.
6742The Ink QA Device/Printer QA Device and the trusted QA Device writing to it, share the sequence key or a variant sequence key between them i.e B.K<sub>n1</sub>=A.K<sub>n2 </sub>or B.K<sub>n1</sub>=FormKeyVariant(A.K<sub>n2</sub>, B.ChipId), where B is the Ink QA Device/Printer QA Device and A is the trusted QA Device. The command sequence used is described in Table 330.
6743<tables id="TABLE-US-00527" num="00527"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 330</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Command sequence for writing sequence</entry></row><row><entry>data fields to the QA Devices.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="35pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="119pt" align="left" /><tbody valign="top"><row><entry>Sequence</entry><entry /><entry /></row><row><entry>No</entry><entry>Function</entry><entry>Parameters</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>1</entry><entry>B. Random</entry><entry /></row><row><entry /><entry /><entry>R<sub>B </sub>= R<sub>L</sub></entry></row><row><entry>2</entry><entry>A. SignM</entry><entry>KeyRef = n2, FieldSelect = Select</entry></row><row><entry /><entry /><entry>bit correponding to SEQ_1 and SEQ-2</entry></row><row><entry /><entry /><entry>FieldVal = both fields set</entry></row><row><entry /><entry /><entry>0xFFFFFFFF.</entry></row><row><entry /><entry /><entry>Refer to Section 31.4.3.3</entry></row><row><entry /><entry /><entry>ChipId = ChipId of B, R<sub>E </sub>= R<sub>B</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then</entry></row><row><entry /><entry /><entry>R<sub>A </sub>= R<sub>L </sub>SIG<sub>A </sub>= SIGout</entry></row><row><entry /><entry /><entry>Refer to Section 27.1.3.1</entry></row><row><entry>3</entry><entry>B. WriteFieldsAuth</entry><entry>KeyRef = n1, FieldSelect =</entry></row><row><entry /><entry /><entry>same as Seq 2[FieldSelect],</entry></row><row><entry /><entry /><entry>FieldVal = same as Seq 2[FieldVal],</entry></row><row><entry /><entry /><entry>RE = R<sub>A</sub>, SIGE = SIG<sub>A</sub></entry></row><row><entry /><entry /><entry>ResultFlag = Pass/Fail</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 32.3 Setting Up the Upgrading QA Device
6744The upgrading QA Device must be set up either as an Ink Refill QA Device or as a Parameter Upgrader QA Device.
6745Each upgrading QA Device must go through the following set up: <ul id="ul0985" list-style="none"><li id="ul0985-0001" num="0000"><ul id="ul0986" list-style="none"><li id="ul0986-0001" num="6746">The upgrading QA Device must be set to factory defaults. Refer to Section 32.1. At the end of this process the upgrading QA Device is either an Ink Refill QA Device or a Parameter Upgrader QA Device with production batch keys and M0 fields set to deafult.</li><li id="ul0986-0002" num="6747">The upgrading QA Device must be programmed with the appropriate keys and upgrade data before it can start upgrading other QA Devices. Following must be performed on each upgrade QA Device:</li></ul></li><li id="ul0985-0002" num="6748">a. The upgrading QA Device must be programmed with the appropriate keys required to upgrade other QA Devices and to upgrade itself when necessary.</li><li id="ul0985-0003" num="6749">b. The M0 fields must be correctly defined and set in M1. <ul id="ul0987" list-style="none"><li id="ul0987-0001" num="6750">For a Ink Refill QA Device the ink-remaining field must be defined and set. For a printer upgrade QA Device the upgrade value field and the count-remaining field must be defined and set. All upgrade QA Devices must also have a sequence datat fields SEQ<sub>—</sub>1 and SEQ<sub>—</sub>2 which are used to upgrade the upgrading QA Device itself.</li></ul></li><li id="ul0985-0004" num="6751">c. Finally, M0 fields defined in b must be written with appropriate values so that the upgrade QA Device can perform upgrades. <ul id="ul0988" list-style="none"><li id="ul0988-0001" num="6752">An Ink Refill QA Device will typically store the logical ink equivalent to the physical ink in a refill station, hence the Ink Refill QA Device's ink-remaining field must be written with the equivalent logical ink amount.</li><li id="ul0988-0002" num="6753">For a Parameter Upgrader QA Device the upgrade value field and the count-remaining field must be written. The upgrade value depends on the type of upgrade the Parameter Upgrader QA Device can perform i.e one Parameter Upgrader QA Device can upgrade to 10 ppm (pages per minute) while another Parameter Upgrader QA Device can upgrade to 5 ppm. The count-remaining is the number of times the Parameter Upgrader QA Device is permitted to write the associated upgrade value to other QA Devices. The count-remaining field must be written to a positive non-zero value for the Parameter Upgrader QA Device to perform successful upgrades. Refer to Section 32.3.1 and Section 32.3.2 for details. <br /> 32.3.1 Setting Up the Ink Refill QA Device <br /> 32.3.1.1 Setting Up the Keys </li></ul></li></ul>
6754The Ink Refill QA DeviceQA Device could be transferring ink between peers or transferring ink down the heirachy, accordingly the peer to peer Ink Refill QA Device has two keys (fill/refill key and sequence key) as described in Section 27, and a Ink Refill QA Device transferring down the heirachy has three keys (fill/refill key, transfer key and sequence key). These keys must be programmed into the Ink Refill QA Device using the sequence described in Section 32.2.1.
6755The Key Programming QA Device must be programmed with the appropriate production batch keys, and the fill/refill, transfer key and sequence key
6756The GetProgramKey function is called on the Key Programming QA Device with OldKeyRef (OldKeyRef—refer to Section 32.2.1) pointing to a production batch key, and the NewKeyRef (NewKeyRef—refer to Section 32.2.1) pointing to either a fill/refill key or a transfer key or a sequence key. The outputs from the GetProgramKey (signature and encrypted New Key) is passed in to ReplaceKey function of the Ink Refill QA Device.
6757The GetProgramKey function must be called (on the Key Programming QA Device) for replacing each of the production batch keys in the Ink Refill QA Device. The output of the GetProgramKey will be passed in to the ReplaceKey function called on the Ink Refill QA Device. The successful processing of the ReplaceKey function will replace an old key(production keys) to a corresponding new key (either a fill/refill key or a transfer key or a sequence key).
000032.3.1.2 Setting Up the M0 Field Information in <sub>M1 </sub>
6758The ink-remaining field and the sequence data fields SEQ<sub>—</sub>1 and SEQ<sub>—</sub>2 must be defined and set in the Ink Refill QA Device using the sequence described in Section 32.2.3.
000032.3.1.3 Transferring Ink Amounts
6759Finally, the logical ink amounts are transferred to the ink-remaining field using the sequence described in Section 31.7.
6760The QACo will transfer to the ComCo Ink Refill QA Device at the top of the heirachy using the command sequence in Table 331.
6761For a successful transfer from QACo to ComCo, ComCo and QACo must share a common key or a variant key be i.e ComCo.K<sub>n1</sub>=QACo.K<sub>n2 </sub>or ComCo.K<sub>n1</sub>=FormKeyVariant(QACo.K<sub>n2</sub>,ComCo.ChipID)K<sub>n1 </sub>is the fill/refill key for the ComCo refill QA Device.
6762<tables id="TABLE-US-00528" num="00528"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 331</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Command sequence for writing ink-remaining amounts</entry></row><row><entry>to the highest QA Device in the heirachy.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>Sequence</entry><entry /><entry /></row><row><entry>No</entry><entry>Function</entry><entry>Parameters</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>1</entry><entry>B. Random</entry><entry /></row><row><entry /><entry /><entry>R<sub>B </sub>= RL</entry></row><row><entry>2</entry><entry>A. SignM</entry><entry>KeyRef = n2, FieldSelect = Select</entry></row><row><entry /><entry /><entry>bit correponding to the ink-remaining</entry></row><row><entry /><entry /><entry>field, FieldVal = Ink amount to</entry></row><row><entry /><entry /><entry>be transferred, Refer to Section</entry></row><row><entry /><entry /><entry>31.4.3.3 ChipId = ChipId of B,</entry></row><row><entry /><entry /><entry>R<sub>E </sub>= R<sub>B</sub></entry></row><row><entry /><entry /><entry>If ResultFlag = Pass then</entry></row><row><entry /><entry /><entry>R<sub>A </sub>= R<sub>L </sub>SIG<sub>A </sub>= SIGout</entry></row><row><entry /><entry /><entry>Refer to Section 27.1.3.1</entry></row><row><entry>3</entry><entry>B. WriteFieldsAuth</entry><entry>KeyRef = n1, FieldSelect = same</entry></row><row><entry /><entry /><entry>as Seq 2[FieldSelect],</entry></row><row><entry /><entry /><entry>FieldVal = same as Seq</entry></row><row><entry /><entry /><entry>2[FieldVal], RE = R<sub>A</sub>,</entry></row><row><entry /><entry /><entry>SIGE = SIG<sub>A</sub></entry></row><row><entry /><entry /><entry>ResultFlag = Pass/Fail</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 32.3.1.4 Setting Up Sequence Data Fields
6763The Ink Refill QA Device has sequence data fields SEQ<sub>—</sub>1 and SEQ<sub>—</sub>2 (as described in Section 27) because its ink-remaining fields can be refilled as well. These two fields must be initialised to 0xFFFFFFFF, refer to Section 27 for details.
6764The Ink Refill QA Device and the trusted QA Device writing to it, share the sequence key or a variant sequence key between them i.e B.K<sub>n1</sub>=A.K<sub>n2 </sub>or B.K<sub>n1</sub>=FormKeyVariant(A.K<sub>n2</sub>, B.ChipID), where B is the Ink Refill QA Device and A is the trusted QA Device. The command sequence used is described in Table 331.
000032.3.2 Setting Up the Parameter Upgrader QA Device
000032.3.2.1 Setting Up the Keys
6765The Parameter Upgrader QA Device could be transferring upgrades between peers or transferring upgrades down the heirachy, accordingly the peer to peer Parameter Upgrader QA Device has three keys (write-parameter key, fill/refill key and sequence key) as described in Section 28.6 and Section 26, and a Parameter Upgrader QA Device transferring down the heirachy has four keys (write-parameter key, fill/refill key, transfer key and sequence Key). These keys must be programmed into the Parameter Upgrader QA Device using the sequence described in Section 32.2.1.
6766The Key Programming QA Device must be programmed with the appropriate production batch keys, and write-parameter key, fill/refill key, transfer key and sequence key
6767The GetProgramKey function is called on the Key Programming QA Device with OldKeyRef (OldKeyRef—refer to Section 32.2.1) pointing to a production batch key, and the NewKeyRef (NewKeyRef—refer to Section 32.2.1) pointing to either a write-parameter key, or a fill/refill key, or a transfer key, or a sequence key. The outputs from the GetProgramKey (signature and encrypted New Key) is passed in to ReplaceKey function of the Parameter Upgrader QA Device.
000032.3.2.2 Setting Up the M0 Field in <sub>M1 </sub>
6768The upgrade value field and the count-remaining field must be defined and set in the upgrade QA Device using the sequence described in Section 32.2.3.
000032.3.2.3 Writing Upgrade Value to the Upgrade Field
6769The upgrade value is written to upgrade field using the write-parameter key. The upgrade QA Device and the trusted QA Device writing to it, share the write-parameter key or a variant write-parameter key between them i.e B.K<sub>n1</sub>=A.K<sub>n2 </sub>or B.K<sub>n1</sub>=FormKeyVariant(A.K<sub>n2</sub>, B.ChipID), where B is the upgrade QA Device and A is the trusted QA Device. The command sequence used is described in Table 331.
000032.3.2.4 Transferring Count-remaining Amounts
6770Finally, the logical count-remaining amounts are transferred to the count-remaining field using the sequence described in Section 31.7.
6771The QACo will also transfer to the ComCo's upgrade QA Device using the command sequence in Table 331.
6772For a successful transfer from QACo to ComCo, ComCo and QACo must share a common key or a variant key be i.e ComCo.K<sub>n1</sub>=QACo.K<sub>n2 </sub>or ComCo.K<sub>n1</sub>=FormKeyVariant(QACo.K<sub>n2</sub>,ComCo.ChipID). K<sub>n1 </sub>is the fill/refill key for the ComCo upgrade QA Device.
000032.3.2.5 Setting Up Sequence Data Fields
6773The Parameter Upgrader QA Device has sequence data fields SEQ<sub>—</sub>1 and SEQ<sub>—</sub>2 (as described in Section 27) because its count-remaining fields can be refilled as well. These two fields must be initialised to 0xFFFFFFFF, refer to Section 27 for details.
6774The Parameter Upgrader QA Device and the trusted QA Device writing to it, share the sequence key or a variant sequence key between them i.e B.K<sub>n1</sub>=A.K<sub>n2 </sub>or B.K<sub>n1</sub>=FormKeyVariant(A.K<sub>n2</sub>, B.ChipID), where B is the Parameter Upgrader QA Device and A is the trusted QA Device. The command sequence used is described in Table 331.
000032.4 Setting Up the Key Programmer
6775The key programming QA Device is set up to replace keys in other QA Devices.
6776Each key programming QA Device must go through the following set up: <ul id="ul0989" list-style="none"><li id="ul0989-0001" num="0000"><ul id="ul0990" list-style="none"><li id="ul0990-0001" num="6777">The key programming QA Device must be instantiated to factory defaults. Refer to Section 32.1. At the end of instantiation the key programming QA Device has production batch keys and no key replacement data.</li><li id="ul0990-0002" num="6778">The key programming QA Device must be programmed with the appropriate keys and key replacement map before it can start to replace keys in other QA Devices. <br /> 32.4.1 Setting Up the Keys </li></ul></li></ul>
6779The key programming QA Device must be programmed with the key replacement map key. The key replacement map key is described in details in Section 24.
6780The key programming QA Device must programmed with the old and new keys for the QA Devices it is going to perform key replacement on.
6781Each of the keys is set in the key programming QA Device using the sequence described in Section 32.2.1.
000032.4.2 Setting Up Key Replacement Map Field Information
6782First the key replacement map field information is worked out as per Section 24.1. This field information is set in M1 as per the sequence described Section 32.2.3.
000032.4.3 Setting Up Key Replacement Map
6783Finally, the key replacement map field must be written with the valid mapping using the key replacement map key. The key programming QA Device and the trusted QA Device writing to it must share the key replacement map key or a variant of the key replacement map key between them.
6784For a successful write of the key replacement map B.K<sub>n1</sub>=A.K<sub>n2 </sub>or B.K<sub>n1</sub>=FormKeyVariant(A.K<sub>n2</sub>, B.ChipID), where B is the key replacement QA Device and A is the trusted QA Device. The command sequence used is described in Table 331.
6785Appendix A: Field Types
6786Table 332 lists the field types that are specifically required by the QA Chip Logical Interface and therefore apply across all applications. Additional field types are application specific, and are defined in the relevant application documentation.
6787<tables id="TABLE-US-00529" num="00529"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 332</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Predefined Field Types</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="35pt" align="left" /><colspec colname="2" colwidth="70pt" align="left" /><colspec colname="3" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry>Value</entry><entry>Type</entry><entry>Description</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row><row><entry /><entry>0x0000</entry><entry>0</entry><entry>Non-initialised (default</entry></row><row><entry /><entry /><entry /><entry>value after final</entry></row><row><entry /><entry /><entry /><entry>program load)</entry></row><row><entry /><entry>0x0001</entry><entry>TYPE_PREAUTH</entry><entry>Defines a preauth field</entry></row><row><entry /><entry /><entry /><entry>in an Ink QA Device</entry></row><row><entry /><entry>0x0002</entry><entry>TYPE_COUNT<sub>—</sub></entry><entry>Defines a countRemaining</entry></row><row><entry /><entry /><entry>REMAINING</entry><entry>field in an Parameter</entry></row><row><entry /><entry /><entry /><entry>Upgrader QA Device</entry></row><row><entry /><entry>0x0003</entry><entry>TYPE_SEQ_1</entry><entry>Defines a sequence data</entry></row><row><entry /><entry /><entry /><entry>field SEQ_1 in an Ink QA</entry></row><row><entry /><entry /><entry /><entry>Device or in a Printer</entry></row><row><entry /><entry /><entry /><entry>QA Device or in an</entry></row><row><entry /><entry /><entry /><entry>upgrader QA Device</entry></row><row><entry /><entry>0x0004</entry><entry>TYPE_SEQ_2</entry><entry>Defines a sequence data</entry></row><row><entry /><entry /><entry /><entry>fields SEQ_2 in an Ink QA</entry></row><row><entry /><entry /><entry /><entry>Device or in a Printer QA</entry></row><row><entry /><entry /><entry /><entry>Device or in an upgrader</entry></row><row><entry /><entry /><entry /><entry>QA Device</entry></row><row><entry /><entry>0x0005</entry><entry>TYPE_KEY_MAP</entry><entry>Defines a key replacement</entry></row><row><entry /><entry /><entry /><entry>map in a Key Programmer</entry></row><row><entry /><entry /><entry /><entry>QA Device</entry></row><row><entry /><entry>0x0006</entry><entry>reserved</entry><entry>reserved for future use</entry></row><row><entry /><entry>and</entry></row><row><entry /><entry>above</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
6788Appendix B: Key and field definition for different QA Devices
0000B.1 Parameter Upgrader QA Device
0000B.1.1 Peer to Peer QA Device
6789<tables id="TABLE-US-00530" num="00530"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 333</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Key definitions for a peer to peer Parameter Upgrader QA Device</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>Key</entry><entry /></row><row><entry /><entry>Name</entry><entry>Purpose</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>Fill/refill</entry><entry>This key has is used for upgrading</entry></row><row><entry /><entry>Key</entry><entry>count-remaining values when the</entry></row><row><entry /><entry /><entry>upgrade QA Device is upgraded by</entry></row><row><entry /><entry /><entry>another upgrade QA Device and is</entry></row><row><entry /><entry /><entry>also used to decrement the count-</entry></row><row><entry /><entry /><entry>remaining when upgrading other</entry></row><row><entry /><entry /><entry>QA Devices.</entry></row><row><entry /><entry>Sequence</entry><entry>This key is used to initialise</entry></row><row><entry /><entry>Key</entry><entry>sequence data fields SEQ_1 and</entry></row><row><entry /><entry /><entry>SEQ_2 to 0xFFFFFFF.</entry></row><row><entry /><entry>Write</entry><entry>This key is used to write the</entry></row><row><entry /><entry>Parameter</entry><entry>upgrade value to the Parameter</entry></row><row><entry /><entry>Key</entry><entry>Upgrader QA Device.</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
6790<tables id="TABLE-US-00531" num="00531"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="406pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 334</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Field definitions for a peer to peer Parameter Upgrader QA Device</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="112pt" align="left" /><colspec colname="1" colwidth="294pt" align="center" /><tbody valign="top"><row><entry /><entry>Field Attrinutes</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="8"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="56pt" align="left" /><colspec colname="3" colwidth="98pt" align="left" /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="21pt" align="center" /><colspec colname="6" colwidth="21pt" align="center" /><colspec colname="7" colwidth="56pt" align="left" /><colspec colname="8" colwidth="49pt" align="left" /><tbody valign="top"><row><entry>Field</entry><entry /><entry /><entry /><entry>A<sup>a</sup></entry><entry>NA<sup>b</sup></entry><entry /><entry>EndPos</entry></row><row><entry>Name</entry><entry>Purpose</entry><entry>Type</entry><entry>KeyNum</entry><entry>RW</entry><entry>RW</entry><entry>KPerms<sup>c</sup></entry><entry>(Size)</entry></row><row><entry namest="1" nameend="8" align="center" rowsep="1" /></row><row><entry>CountRemaining</entry><entry>The field stores</entry><entry>TYPE_COUNT_REMAINING</entry><entry>SN<sup>f </sup>fill/</entry><entry>1</entry><entry>0</entry><entry>KPerms[KN<sup>e</sup>] = 1</entry><entry>Depends on</entry></row><row><entry /><entry>the number of</entry><entry /><entry>refill key</entry><entry /><entry /><entry>Rest are 0</entry><entry>the maximum</entry></row><row><entry /><entry>times the</entry><entry /><entry /><entry /><entry /><entry /><entry>number of</entry></row><row><entry /><entry>Parameter</entry><entry /><entry /><entry /><entry /><entry /><entry>upgrades</entry></row><row><entry /><entry>Upgrader QA</entry><entry /><entry /><entry /><entry /><entry /><entry>that can</entry></row><row><entry /><entry>Device is</entry><entry /><entry /><entry /><entry /><entry /><entry>be stored.</entry></row><row><entry /><entry>permitted to</entry></row><row><entry /><entry>upgrade a printer</entry></row><row><entry /><entry>QA Device.</entry></row><row><entry>UpgradeValue</entry><entry>This stores the</entry><entry>Must define the</entry><entry>SN<sup>f </sup>write-</entry><entry>1</entry><entry>0</entry><entry>KPerms[KN<sup>e</sup>] = 0</entry><entry>Set as per</entry></row><row><entry /><entry>value that is</entry><entry>type of the</entry><entry>parameter</entry><entry /><entry /><entry>Rest are 0</entry><entry>upgrade</entry></row><row><entry /><entry>copied from the</entry><entry>upgrade value i.e</entry><entry>key</entry><entry /><entry /><entry>as well</entry><entry>value.</entry></row><row><entry /><entry>Parameter</entry><entry>TYPE_PRINT_SPEED<sup>d</sup></entry></row><row><entry /><entry>Upgrader QA</entry></row><row><entry /><entry>Device to the</entry></row><row><entry /><entry>field being</entry></row><row><entry /><entry>upgraded on the</entry></row><row><entry /><entry>printer QA</entry></row><row><entry /><entry>Device during the</entry></row><row><entry /><entry>upgrade</entry></row><row><entry>SEQ_1</entry><entry>This field holds</entry><entry>TYPE_SEQ_1</entry><entry>SN<sup>f</sup></entry><entry>1</entry><entry>0</entry><entry>KPerms[KN<sup>e</sup>] = 0</entry><entry>Typically</entry></row><row><entry /><entry>the data for</entry><entry /><entry>sequence</entry><entry /><entry /><entry>KPerms[fill/</entry><entry>32 bit.</entry></row><row><entry /><entry>sequence data</entry><entry /><entry>key</entry><entry /><entry /><entry>refill<sup>g</sup>] = 1</entry></row><row><entry /><entry>field SEQ_1</entry><entry /><entry /><entry /><entry /><entry>Rest are 0</entry></row><row><entry /><entry>when the</entry><entry /><entry /><entry /><entry /><entry>as well.</entry></row><row><entry /><entry>Parameter</entry></row><row><entry /><entry>Upgrader QA</entry></row><row><entry /><entry>Device is being</entry></row><row><entry /><entry>upgraded by</entry></row><row><entry /><entry>another</entry></row><row><entry /><entry>Parameter</entry></row><row><entry /><entry>Upgrader Refill</entry></row><row><entry /><entry>QA Device.</entry></row><row><entry>SEQ_2</entry><entry>This field holds</entry><entry>TYPE_SEQ_2</entry><entry>SN<sup>f </sup>sequence</entry><entry>1</entry><entry>0</entry><entry>KPerms[KN<sup>e</sup>] = 0</entry><entry>Typically</entry></row><row><entry /><entry>the data for</entry><entry /><entry>key</entry><entry /><entry /><entry>KPerms[fill/</entry><entry>32 bit.</entry></row><row><entry /><entry>sequence data</entry><entry /><entry /><entry /><entry /><entry>refill<sup>g</sup>] = 1</entry></row><row><entry /><entry>fieldsSEQ_2</entry><entry /><entry /><entry /><entry /><entry>Rest are 0</entry></row><row><entry /><entry>when the</entry><entry /><entry /><entry /><entry /><entry>as well.</entry></row><row><entry /><entry>Parameter</entry></row><row><entry /><entry>Upgrader QA</entry></row><row><entry /><entry>Device is being</entry></row><row><entry /><entry>upgraded by</entry></row><row><entry /><entry>another</entry></row><row><entry /><entry>Parameter</entry></row><row><entry /><entry>Upgrader Refill</entry></row><row><entry /><entry>QA Device.</entry></row><row><entry namest="1" nameend="8" align="center" rowsep="1" /></row><row><entry namest="1" nameend="8" align="left" id="FOO-00071"><sup>a</sup>Authenticated ReadWrite permission</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00072"><sup>b</sup>Non-authenticated ReadWrite permission</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00073"><sup>c</sup>KeyPerms</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00074"><sup>d</sup>This is a sample type only</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00075"><sup>e</sup>KeyNum</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00076"><sup>f</sup>Key Slot Number</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00077"><sup>g</sup>Fill/Refill key has authenticated decrement-only permission to the sequence data fields</entry></row></tbody></tgroup></table></tables><br /> B.1.2 Heirarchical Transfer QA Device <br /> Key Definitions
6791<tables id="TABLE-US-00532" num="00532"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 335</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Key definitions for a Parameter Upgrader QA</entry></row><row><entry>Device (transferring down the heirachy)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="126pt" align="left" /><tbody valign="top"><row><entry /><entry>Key</entry><entry /></row><row><entry /><entry>Name</entry><entry>Purpose</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>Transfer</entry><entry>This key is used to decrement</entry></row><row><entry /><entry>Key</entry><entry>the count-remaining when</entry></row><row><entry /><entry /><entry>upgrading other QA Devices.</entry></row><row><entry /><entry>Fill/refill</entry><entry>This key has is used for</entry></row><row><entry /><entry>Key</entry><entry>upgrading count-remaining</entry></row><row><entry /><entry /><entry>values when the Parameter</entry></row><row><entry /><entry /><entry>Upgrader QA Device is</entry></row><row><entry /><entry /><entry>upgraded by another Parameter</entry></row><row><entry /><entry /><entry>Upgrader QA Device Refill</entry></row><row><entry /><entry /><entry>QA Device.</entry></row><row><entry /><entry>Sequence</entry><entry>This key is used to</entry></row><row><entry /><entry>Key</entry><entry>initialise sequence data</entry></row><row><entry /><entry /><entry>fields SEQ_1 and SEQ_2 to</entry></row><row><entry /><entry /><entry>0xFFFFFFF.</entry></row><row><entry /><entry>Write</entry><entry>This key is used to write</entry></row><row><entry /><entry>Parameter</entry><entry>the upgrade value to the</entry></row><row><entry /><entry>Key</entry><entry>Parameter Upgrader QA</entry></row><row><entry /><entry /><entry>Device.</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> Field Definitions
6792<tables id="TABLE-US-00533" num="00533"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="406pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 336</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Field definitions for Parameter Upgrader QA Device transferring down the hierachy</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="98pt" align="left" /><colspec colname="1" colwidth="308pt" align="center" /><tbody valign="top"><row><entry /><entry>Field Attrinutes</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="8"><colspec colname="1" colwidth="35pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="98pt" align="left" /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="21pt" align="center" /><colspec colname="6" colwidth="21pt" align="center" /><colspec colname="7" colwidth="63pt" align="left" /><colspec colname="8" colwidth="56pt" align="left" /><tbody valign="top"><row><entry>Field</entry><entry /><entry /><entry /><entry>A<sup>a</sup></entry><entry>NA<sup>b</sup></entry><entry /><entry>EndPos</entry></row><row><entry>Name</entry><entry>Purpose</entry><entry>Type</entry><entry>KeyNum</entry><entry>RW</entry><entry>RW</entry><entry>KPerms<sup>c</sup></entry><entry>(Size)</entry></row><row><entry namest="1" nameend="8" align="center" rowsep="1" /></row><row><entry>Count</entry><entry>The field stores the</entry><entry>TYPE_COUNT_REMAINING</entry><entry>SN<sup>f </sup>fill/</entry><entry>1</entry><entry>0</entry><entry>KPerms[KN<sup>e</sup>] = 0</entry><entry>Depends on the</entry></row><row><entry>Remaining</entry><entry>number of times</entry><entry /><entry>refill key</entry><entry /><entry /><entry>KPerms[Transfer</entry><entry>maximum number</entry></row><row><entry /><entry>the Parameter</entry><entry /><entry /><entry /><entry /><entry>Key] = 1</entry><entry>of upgrades</entry></row><row><entry /><entry>Upgrader QA</entry><entry /><entry /><entry /><entry /><entry>Rest are 0</entry><entry>that can be</entry></row><row><entry /><entry>Device is permitted</entry><entry /><entry /><entry /><entry /><entry /><entry>stored.</entry></row><row><entry /><entry>to upgrade a printer</entry></row><row><entry /><entry>QA Device.</entry></row><row><entry>Upgrade</entry><entry>This stores the</entry><entry>Must define the type of</entry><entry>SN<sup>f </sup>write-</entry><entry>1</entry><entry>0</entry><entry>KeyPerms[KN<sup>e</sup>] = 0</entry><entry>Set as per</entry></row><row><entry>Value</entry><entry>value that is</entry><entry>the upgrade value</entry><entry>parameter</entry><entry /><entry /><entry>Rest are 0</entry><entry>upgrade value.</entry></row><row><entry /><entry>copied from the</entry><entry>i.e</entry><entry>key</entry></row><row><entry /><entry>Parameter</entry><entry>TYPE_PRINT_SPEED<sup>d</sup></entry></row><row><entry /><entry>Upgrader QA</entry></row><row><entry /><entry>Device to the</entry></row><row><entry /><entry>field being</entry></row><row><entry /><entry>upgraded on the</entry></row><row><entry /><entry>printer QA</entry></row><row><entry /><entry>Device during the</entry></row><row><entry /><entry>upgrade</entry></row><row><entry>SEQ_1</entry><entry>This field holds</entry><entry>TYPE_SEQ_1</entry><entry>SN<sup>f </sup>sequence</entry><entry>1</entry><entry>0</entry><entry>KPerms[KN<sup>e</sup>] = 0</entry><entry>Typically</entry></row><row><entry /><entry>the data for</entry><entry /><entry>key</entry><entry /><entry /><entry>KPerms[fill/</entry><entry>32 bit.</entry></row><row><entry /><entry>sequence data</entry><entry /><entry /><entry /><entry /><entry>refill<sup>g</sup>] = 1</entry></row><row><entry /><entry>fields SEQ_1</entry><entry /><entry /><entry /><entry /><entry>Rest are 0 as</entry></row><row><entry /><entry>when the</entry><entry /><entry /><entry /><entry /><entry>well.</entry></row><row><entry /><entry>Parameter</entry></row><row><entry /><entry>Upgrader QA</entry></row><row><entry /><entry>Device is being</entry></row><row><entry /><entry>upgraded by</entry></row><row><entry /><entry>another</entry></row><row><entry /><entry>Parameter</entry></row><row><entry /><entry>Upgrader Refill</entry></row><row><entry /><entry>QA Device.</entry></row><row><entry>SEQ_2</entry><entry>This field holds</entry><entry>TYPE_SEQ_2</entry><entry>SN<sup>f </sup>sequence</entry><entry>1</entry><entry>0</entry><entry>KPerms[KN<sup>e</sup>] = 0</entry><entry>Typically</entry></row><row><entry /><entry>the data for</entry><entry /><entry>key</entry><entry /><entry /><entry>KPerms[fill/</entry><entry>32 bit.</entry></row><row><entry /><entry>sequence data</entry><entry /><entry /><entry /><entry /><entry>refill<sup>g</sup>] = 1</entry></row><row><entry /><entry>fields SEQ_2</entry><entry /><entry /><entry /><entry /><entry>Rest are 0 as</entry></row><row><entry /><entry>when the</entry><entry /><entry /><entry /><entry /><entry>well.</entry></row><row><entry /><entry>Parameter</entry></row><row><entry /><entry>Upgrader QA</entry></row><row><entry /><entry>Device is being</entry></row><row><entry /><entry>upgraded by</entry></row><row><entry /><entry>another</entry></row><row><entry /><entry>Parameter</entry></row><row><entry /><entry>Upgrader Refill</entry></row><row><entry /><entry>QA Device.</entry></row><row><entry namest="1" nameend="8" align="center" rowsep="1" /></row><row><entry namest="1" nameend="8" align="left" id="FOO-00078"><sup>a</sup>Authenticated ReadWrite permission</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00079"><sup>b</sup>Non-authenticated ReadWrite permission</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00080"><sup>c</sup>KeyPerms</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00081"><sup>d</sup>This is a sample type only</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00082"><sup>e</sup>KeyNum</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00083"><sup>f</sup>Key Slot Number</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00084"><sup>g</sup>Fill/Refill key has authenticated decrement-only permission to the sequence data fields</entry></row></tbody></tgroup></table></tables><br /> B.2 Ink Refill QA Device <br /> B.2.1 Peer to Peer QA Device <br /> Key Definitions
6793<tables id="TABLE-US-00534" num="00534"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 337</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Key definitions for a peer to peer Ink Refill QA Device</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>Key</entry><entry /></row><row><entry /><entry>Name</entry><entry>Purpose</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>Fill/refill</entry><entry>This key has is used for filling/</entry></row><row><entry /><entry>Key</entry><entry>refilling ink-remaining values when</entry></row><row><entry /><entry /><entry>the Ink Refill QA Device is upgraded</entry></row><row><entry /><entry /><entry>by another Ink Refill QA Device and</entry></row><row><entry /><entry /><entry>is also used to decrement from the</entry></row><row><entry /><entry /><entry>ink-remaining when transferring ink</entry></row><row><entry /><entry /><entry>to other QA Devices (typically Ink</entry></row><row><entry /><entry /><entry>QA Device).</entry></row><row><entry /><entry>Sequence</entry><entry>This key is used to initialise</entry></row><row><entry /><entry>Key</entry><entry>sequence data fields SEQ_1 and SEQ_2</entry></row><row><entry /><entry /><entry>to 0xFFFFFFF.</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> Field Definitions
6794<tables id="TABLE-US-00535" num="00535"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="399pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 338</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Field definitions for a peer to peer Ink Refill QA Device</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="105pt" align="left" /><colspec colname="1" colwidth="294pt" align="center" /><tbody valign="top"><row><entry /><entry>Field Attrinutes</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="8"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="56pt" align="left" /><colspec colname="3" colwidth="84pt" align="left" /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="21pt" align="center" /><colspec colname="6" colwidth="21pt" align="center" /><colspec colname="7" colwidth="63pt" align="left" /><colspec colname="8" colwidth="56pt" align="left" /><tbody valign="top"><row><entry>Field</entry><entry /><entry /><entry>Key</entry><entry>A<sup>a</sup></entry><entry>NA<sup>b</sup></entry><entry /><entry>EndPos</entry></row><row><entry>Name</entry><entry>Purpose</entry><entry>Type</entry><entry>Num</entry><entry>RW</entry><entry>RW</entry><entry>KeyPerms<sup>c</sup></entry><entry>(Size)</entry></row><row><entry namest="1" nameend="8" align="center" rowsep="1" /></row><row><entry>InkRemaining</entry><entry>The field</entry><entry>Must define the</entry><entry>SN<sup>f </sup>fill/</entry><entry>1</entry><entry>1</entry><entry>KeyPerms[KN<sup>e</sup>] = 1</entry><entry>Depends on the</entry></row><row><entry /><entry>stores the</entry><entry>type of Ink e.g</entry><entry>refill key</entry><entry /><entry /><entry>Rest are 0</entry><entry>maximum amount</entry></row><row><entry /><entry>amount of</entry><entry>TYPE_HIGHQUALITY<sub>—</sub></entry><entry /><entry /><entry /><entry /><entry>of ink that</entry></row><row><entry /><entry>logical ink-</entry><entry>BLACK_INK<sup>d</sup></entry><entry /><entry /><entry /><entry /><entry>can be stored</entry></row><row><entry /><entry>remaining in</entry><entry /><entry /><entry /><entry /><entry /><entry>and the storage</entry></row><row><entry /><entry>the ink refill</entry><entry /><entry /><entry /><entry /><entry /><entry>resolution i.e</entry></row><row><entry /><entry>QA Device.</entry><entry /><entry /><entry /><entry /><entry /><entry>in pico litres</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>or in micro</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>litres.</entry></row><row><entry>SEQ_1</entry><entry>This field</entry><entry>TYPE_SEQ_1</entry><entry>SN<sup>f </sup>sequence</entry><entry>1</entry><entry>0</entry><entry>KPerms[KN<sup>e</sup>] = 0</entry><entry>Typically</entry></row><row><entry /><entry>holds the</entry><entry /><entry>key</entry><entry /><entry /><entry>KPerms[fill/</entry><entry>32 bit.</entry></row><row><entry /><entry>data for</entry><entry /><entry /><entry /><entry /><entry>refill<sup>g</sup>] = 1</entry></row><row><entry /><entry>sequence data</entry><entry /><entry /><entry /><entry /><entry>Rest are 0 as</entry></row><row><entry /><entry>field SEQ_1</entry><entry /><entry /><entry /><entry /><entry>well.</entry></row><row><entry /><entry>when the Ink</entry></row><row><entry /><entry>Refill QA</entry></row><row><entry /><entry>Device is</entry></row><row><entry /><entry>being filled/</entry></row><row><entry /><entry>refilled by</entry></row><row><entry /><entry>another Ink</entry></row><row><entry /><entry>Refill QA</entry></row><row><entry /><entry>Device.</entry></row><row><entry>SEQ_2</entry><entry>This field</entry><entry>TYPE_SEQ_2</entry><entry>SN<sup>f </sup>sequence</entry><entry>1</entry><entry>0</entry><entry>KPerms[KN<sup>e</sup>] = 0</entry><entry>Typically</entry></row><row><entry /><entry>holds the data</entry><entry /><entry>key</entry><entry /><entry /><entry>KPerms[fill/</entry><entry>32 bit.</entry></row><row><entry /><entry>for sequence</entry><entry /><entry /><entry /><entry /><entry>refill<sup>g</sup>] = 1</entry></row><row><entry /><entry>data field</entry><entry /><entry /><entry /><entry /><entry>Rest are 0 as</entry></row><row><entry /><entry>SEQ_2 when the</entry><entry /><entry /><entry /><entry /><entry>well.</entry></row><row><entry /><entry>Ink Refill QA</entry></row><row><entry /><entry>Device is being</entry></row><row><entry /><entry>filled/refilled</entry></row><row><entry /><entry>by another Ink</entry></row><row><entry /><entry>Refill QA</entry></row><row><entry /><entry>Device.</entry></row><row><entry namest="1" nameend="8" align="center" rowsep="1" /></row><row><entry namest="1" nameend="8" align="left" id="FOO-00085"><sup>a</sup>Authenticated ReadWrite permission</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00086"><sup>b</sup>Non-authenticated ReadWrite permission</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00087"><sup>c</sup>Decrement-Only For Keys</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00088"><sup>d</sup>This is a sample type only</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00089"><sup>e</sup>KeyNum</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00090"><sup>f</sup>Key Slot Number</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00091"><sup>g</sup>Fill/Refill key has authenticated decrement-only permission to the sequence data fields</entry></row></tbody></tgroup></table></tables><br /> B.2.2 Heirarchical Transfer QA Device <br /> Key Definitions
6795<tables id="TABLE-US-00536" num="00536"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 339</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Key definitions for a ink refill QA Device</entry></row><row><entry>(transferring down the heirachy)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>Key</entry><entry /></row><row><entry /><entry>Name</entry><entry>Purpose</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>Transfer</entry><entry>This key is used to decrement from the</entry></row><row><entry /><entry>Key</entry><entry>ink-remaining when transferring ink</entry></row><row><entry /><entry /><entry>to other QA Devices.</entry></row><row><entry /><entry>Fill/refill</entry><entry>This key has is used for filling/</entry></row><row><entry /><entry>Key</entry><entry>refilling ink-remaining values when the</entry></row><row><entry /><entry /><entry>Ink Refill QA Device is upgraded by</entry></row><row><entry /><entry /><entry>another Ink Refill QA Device.</entry></row><row><entry /><entry>Sequence</entry><entry>This key is used to initialise sequence</entry></row><row><entry /><entry>Key</entry><entry>data fields SEQ_1 and SEQ_2 to</entry></row><row><entry /><entry /><entry>0xFFFFFFF.</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> Field Definitions
6796<tables id="TABLE-US-00537" num="00537"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="385pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 340</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Field definitions for a Ink Refill QA Device (transferring down the heirachy)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="98pt" align="left" /><colspec colname="1" colwidth="287pt" align="center" /><tbody valign="top"><row><entry /><entry>Field Attrinutes</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="8"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="49pt" align="left" /><colspec colname="3" colwidth="84pt" align="left" /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="21pt" align="center" /><colspec colname="6" colwidth="21pt" align="center" /><colspec colname="7" colwidth="56pt" align="left" /><colspec colname="8" colwidth="56pt" align="left" /><tbody valign="top"><row><entry>Field</entry><entry /><entry /><entry /><entry>A<sup>a</sup></entry><entry>NA<sup>b</sup></entry><entry /><entry>EndPos</entry></row><row><entry>Name</entry><entry>Purpose</entry><entry>Type</entry><entry>KeyNum</entry><entry>RW</entry><entry>RW</entry><entry>KeyPerms<sup>c</sup></entry><entry>(Size)</entry></row><row><entry namest="1" nameend="8" align="center" rowsep="1" /></row><row><entry>InkRemaining</entry><entry>The field</entry><entry>Must define</entry><entry>SN<sup>f </sup>fill/</entry><entry>1</entry><entry>0</entry><entry>KPerms[KN<sup>e</sup>] = 0</entry><entry>Depends on the</entry></row><row><entry /><entry>stores the</entry><entry>the type of</entry><entry>refill key</entry><entry /><entry /><entry>KPerms[Transfer</entry><entry>maximum amount</entry></row><row><entry /><entry>amount of</entry><entry>Ink e.g-</entry><entry /><entry /><entry /><entry>Key] = 1</entry><entry>of ink that</entry></row><row><entry /><entry>logical ink-</entry><entry>TYPE_HIGHQUALITY<sub>—</sub></entry><entry /><entry /><entry /><entry>Rest are 0</entry><entry>can be stored</entry></row><row><entry /><entry>remaining in</entry><entry>BLACK_INK<sup>d</sup></entry><entry /><entry /><entry /><entry /><entry>and the storage</entry></row><row><entry /><entry>the Ink</entry><entry /><entry /><entry /><entry /><entry /><entry>resolution i.e</entry></row><row><entry /><entry>Refill QA</entry><entry /><entry /><entry /><entry /><entry /><entry>in pico litres</entry></row><row><entry /><entry>Device.</entry><entry /><entry /><entry /><entry /><entry /><entry>or in micro</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>litres.</entry></row><row><entry>SEQ_1</entry><entry>This field</entry><entry>TYPE_SEQ_1</entry><entry>SN<sup>f </sup>sequence</entry><entry>1</entry><entry>0</entry><entry>KPerms[KN<sup>e</sup>] = 0</entry><entry>Typically</entry></row><row><entry /><entry>holds the</entry><entry /><entry>key</entry><entry /><entry /><entry>KPerms[fill/</entry><entry>32 bit.</entry></row><row><entry /><entry>data for</entry><entry /><entry /><entry /><entry /><entry>refill<sup>g</sup>] = 1</entry></row><row><entry /><entry>sequence</entry><entry /><entry /><entry /><entry /><entry>Rest are 0.</entry></row><row><entry /><entry>data field</entry></row><row><entry /><entry>SEQ_1 when</entry></row><row><entry /><entry>the Ink Refill</entry></row><row><entry /><entry>QA Device is</entry></row><row><entry /><entry>being filled/</entry></row><row><entry /><entry>refilled by</entry></row><row><entry /><entry>another Ink</entry></row><row><entry /><entry>Refill QA</entry></row><row><entry /><entry>Device.</entry></row><row><entry>SEQ_2</entry><entry>This field</entry><entry>TYPE_SEQ_2</entry><entry>SN<sup>f </sup>sequence</entry><entry>1</entry><entry>0</entry><entry>KPerms[KN<sup>e</sup>] = 0</entry><entry>Typically</entry></row><row><entry /><entry>holds the</entry><entry /><entry>key</entry><entry /><entry /><entry>KPerms[fill/</entry><entry>32 bit.</entry></row><row><entry /><entry>data for</entry><entry /><entry /><entry /><entry /><entry>refill<sup>g</sup>] = 1</entry></row><row><entry /><entry>sequence</entry><entry /><entry /><entry /><entry /><entry>Rest are 0.</entry></row><row><entry /><entry>data field</entry></row><row><entry /><entry>SEQ_2 when</entry></row><row><entry /><entry>the Ink Refill</entry></row><row><entry /><entry>QA Device</entry></row><row><entry /><entry>is being</entry></row><row><entry /><entry>filled/refilled</entry></row><row><entry /><entry>by another Ink</entry></row><row><entry /><entry>Refill QA</entry></row><row><entry /><entry>Device.</entry></row><row><entry namest="1" nameend="8" align="center" rowsep="1" /></row><row><entry namest="1" nameend="8" align="left" id="FOO-00092"><sup>a</sup>Authenticated ReadWrite permission</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00093"><sup>b</sup>Non-authenticated ReadWrite permission</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00094"><sup>c</sup>KeyPerms</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00095"><sup>d</sup>This is a sample type only</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00096"><sup>e</sup>KeyNum</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00097"><sup>f</sup>Key Slot Number</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00098"><sup>g</sup>Fill/Refill key has authenticated decrement-only permission to the sequence data fields</entry></row></tbody></tgroup></table></tables><br /> B.3 Key Programming QA Device <br /> B.3.1 Key Definitions
6797<tables id="TABLE-US-00538" num="00538"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 341</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Key definitions for a Key Programming QA Device</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="161pt" align="left" /><tbody valign="top"><row><entry>Key</entry><entry /></row><row><entry>Name</entry><entry>Purpose</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>Key</entry><entry>This key is used to write the key replacement map.</entry></row><row><entry>replacement</entry></row><row><entry>map</entry></row><row><entry>Key</entry></row><row><entry>Old Keys</entry><entry>These are the old keys of the QA Device whose</entry></row><row><entry /><entry>keys will be replaced by the Key Programming</entry></row><row><entry /><entry>QA Device.</entry></row><row><entry>New Keys</entry><entry>These are the new keys of the QA Device whose old</entry></row><row><entry /><entry>keys will be replaced by the Key Programming QA</entry></row><row><entry /><entry>Device.</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> B.3.2 Field Definitions
6798<tables id="TABLE-US-00539" num="00539"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="336pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 342</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Field definitions for a key replacement QA Device</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="91pt" align="left" /><colspec colname="1" colwidth="245pt" align="center" /><tbody valign="top"><row><entry /><entry>Field Attrinutes</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="8"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="49pt" align="left" /><colspec colname="3" colwidth="63pt" align="left" /><colspec colname="4" colwidth="49pt" align="left" /><colspec colname="5" colwidth="21pt" align="center" /><colspec colname="6" colwidth="21pt" align="center" /><colspec colname="7" colwidth="63pt" align="left" /><colspec colname="8" colwidth="28pt" align="left" /><tbody valign="top"><row><entry>Field</entry><entry /><entry /><entry /><entry>A<sup>a</sup></entry><entry>NA<sup>b</sup></entry><entry /><entry>EndPos</entry></row><row><entry>Name</entry><entry>Purpose</entry><entry>Type</entry><entry>KeyNum</entry><entry>RW</entry><entry>RW</entry><entry>KPerms<sup>c</sup></entry><entry>(Size)</entry></row><row><entry namest="1" nameend="8" align="center" rowsep="1" /></row><row><entry>Key</entry><entry>This defines</entry><entry>TYPE_KEY_MAP</entry><entry>Key Replace-</entry><entry>1</entry><entry>0</entry><entry>KPerms[KN<sup>d</sup>] = 0</entry><entry>2 words</entry></row><row><entry>replacement</entry><entry>the mapping</entry><entry /><entry>ment Map key</entry><entry /><entry /><entry>Rest are 0</entry><entry>(64 bits)</entry></row><row><entry>map</entry><entry>between the</entry></row><row><entry /><entry>old key and</entry></row><row><entry /><entry>the new key</entry></row><row><entry /><entry>for the QA</entry></row><row><entry /><entry>Device whose</entry></row><row><entry /><entry>old key will</entry></row><row><entry /><entry>be replaced by</entry></row><row><entry /><entry>the new key.</entry></row><row><entry namest="1" nameend="8" align="center" rowsep="1" /></row><row><entry namest="1" nameend="8" align="left" id="FOO-00099"><sup>a</sup>Authenticated ReadWrite permission</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00100"><sup>b</sup>Non-authenticated ReadWrite permission</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00101"><sup>c</sup>KeyPerms</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00102"><sup>d</sup>KeyNum</entry></row></tbody></tgroup></table></tables><br /> B.4 Ink QA Device <br /> B.4.1 Key Definitions
6799<tables id="TABLE-US-00540" num="00540"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 343</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Key definitions for a link QA Device</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>Key</entry><entry /></row><row><entry /><entry>Name</entry><entry>Purpose</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>Fill/refill key</entry><entry>This key is used for fiil/refilling</entry></row><row><entry /><entry /><entry>ink-remaining amount in the ink QA</entry></row><row><entry /><entry /><entry>Device.</entry></row><row><entry /><entry>Ink usage Key</entry><entry>This key is verifying the data read</entry></row><row><entry /><entry /><entry>from the ink QA Device and for writing</entry></row><row><entry /><entry /><entry>preauth data.</entry></row><row><entry /><entry>Sequence Key</entry><entry>This key is used to initialise</entry></row><row><entry /><entry /><entry>sequence data fields SEQ_1 and SEQ_2</entry></row><row><entry /><entry /><entry>to 0×FFFFFFF.</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> B.4.2 Field Definitions
6800<tables id="TABLE-US-00541" num="00541"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="336pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 344</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Field definitions for a Ink QA Device</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="84pt" align="left" /><colspec colname="1" colwidth="252pt" align="center" /><tbody valign="top"><row><entry /><entry>Field Attrinutes</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="8"><colspec colname="1" colwidth="35pt" align="left" /><colspec colname="2" colwidth="49pt" align="left" /><colspec colname="3" colwidth="63pt" align="left" /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="21pt" align="center" /><colspec colname="6" colwidth="21pt" align="center" /><colspec colname="7" colwidth="56pt" align="left" /><colspec colname="8" colwidth="56pt" align="left" /><tbody valign="top"><row><entry>Field</entry><entry /><entry /><entry>Key</entry><entry>A<sup>a</sup></entry><entry>NA<sup>b</sup></entry><entry /><entry>EndPos</entry></row><row><entry>Name</entry><entry>Purpose</entry><entry>Type</entry><entry>Num</entry><entry>RW</entry><entry>RW</entry><entry>KPerms<sup>c</sup></entry><entry>(Size)</entry></row><row><entry namest="1" nameend="8" align="center" rowsep="1" /></row><row><entry>Ink</entry><entry>The amount of</entry><entry>Must define</entry><entry>SN<sup>f </sup>fill/</entry><entry>1</entry><entry>1</entry><entry>KPerms[KN<sup>e</sup>] = 1</entry><entry>Depends on the</entry></row><row><entry>Remaining</entry><entry>logical ink-</entry><entry>the type of</entry><entry>refill key</entry><entry /><entry /><entry>Rest are 0</entry><entry>maximum amount</entry></row><row><entry /><entry>remaining in</entry><entry>Ink i.e</entry><entry /><entry /><entry /><entry /><entry>of ink that</entry></row><row><entry /><entry>the ink QA</entry><entry>TYPE_HQ<sub>—</sub></entry><entry /><entry /><entry /><entry /><entry>can be stored</entry></row><row><entry /><entry>Device. More</entry><entry>BLACK_INK<sup>d</sup></entry><entry /><entry /><entry /><entry /><entry>and the storage</entry></row><row><entry /><entry>than one ink-</entry><entry /><entry /><entry /><entry /><entry /><entry>resolution i.e</entry></row><row><entry /><entry>remaining</entry><entry /><entry /><entry /><entry /><entry /><entry>in pico litres</entry></row><row><entry /><entry>field may</entry><entry /><entry /><entry /><entry /><entry /><entry>or in micro</entry></row><row><entry /><entry>be present</entry><entry /><entry /><entry /><entry /><entry /><entry>litres.</entry></row><row><entry /><entry>depending on</entry></row><row><entry /><entry>the number of</entry></row><row><entry /><entry>physical inks</entry></row><row><entry /><entry>stored in the</entry></row><row><entry /><entry>ink cartridge.</entry></row><row><entry>Preauth</entry><entry>This field</entry><entry>TYPE_PREAUTH</entry><entry>SN<sup>f </sup>ink</entry><entry>0</entry><entry>1</entry><entry>KPerms[KN<sup>e</sup>] = 0</entry><entry>Depends on</entry></row><row><entry /><entry>defines the</entry><entry /><entry>usage key</entry><entry /><entry /><entry>Rest are 0</entry><entry>preauth amount.</entry></row><row><entry /><entry>preauth value.</entry><entry /><entry /><entry /><entry /><entry /><entry>Typically 32</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>bits, may be</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>64 bits to</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>accomodate</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>larger preauth</entry></row><row><entry /><entry /><entry /><entry /><entry /><entry /><entry /><entry>amounts.</entry></row><row><entry>SEQ_1</entry><entry>This field</entry><entry>TYPE_SEQ_1</entry><entry>SN<sup>f</sup></entry><entry>1</entry><entry>0</entry><entry>KPerms[KN<sup>e</sup>] = 0</entry><entry>Typically</entry></row><row><entry /><entry>holds the</entry><entry /><entry>sequence</entry><entry /><entry /><entry>KPerms[fill/</entry><entry>32 bit.</entry></row><row><entry /><entry>data for</entry><entry /><entry>key</entry><entry /><entry /><entry>refill<sup>g</sup>] = 1</entry></row><row><entry /><entry>sequence</entry><entry /><entry /><entry /><entry /><entry>Rest are 0.</entry></row><row><entry /><entry>data field</entry></row><row><entry /><entry>SEQ_1 when</entry></row><row><entry /><entry>the Ink QA</entry></row><row><entry /><entry>Device is</entry></row><row><entry /><entry>being filled/</entry></row><row><entry /><entry>refilled by a</entry></row><row><entry /><entry>Ink Refill</entry></row><row><entry /><entry>QA Device.</entry></row><row><entry>SEQ_2</entry><entry>This field</entry><entry>TYPE_SEQ_2</entry><entry>SN<sup>f</sup></entry><entry>1</entry><entry>0</entry><entry>KPerms[KN<sup>e</sup>] = 0</entry><entry>Typically</entry></row><row><entry /><entry>holds the</entry><entry /><entry>sequence</entry><entry /><entry /><entry>KPerms[fill/</entry><entry>32 bit.</entry></row><row><entry /><entry>data for</entry><entry /><entry>key</entry><entry /><entry /><entry>refill<sup>g</sup>] = 1</entry></row><row><entry /><entry>sequence</entry><entry /><entry /><entry /><entry /><entry>Rest are 0.</entry></row><row><entry /><entry>data field</entry></row><row><entry /><entry>SEQ_2 when</entry></row><row><entry /><entry>the Ink QA</entry></row><row><entry /><entry>Device is</entry></row><row><entry /><entry>being filled/</entry></row><row><entry /><entry>refilled by</entry></row><row><entry /><entry>another Ink</entry></row><row><entry /><entry>Refill QA</entry></row><row><entry /><entry>Device.</entry></row><row><entry namest="1" nameend="8" align="center" rowsep="1" /></row><row><entry namest="1" nameend="8" align="left" id="FOO-00103"><sup>a</sup>Authenticated ReadWrite permission</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00104"><sup>b</sup>Non-authenticated ReadWrite permission</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00105"><sup>c</sup>KeyPerms</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00106"><sup>d</sup>This is a sample type only</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00107"><sup>e</sup>KeyNum</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00108"><sup>f</sup>Key Slot Number</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00109"><sup>g</sup>Fill/Refill key has authenticated decrement-only permission to the sequence data fields</entry></row></tbody></tgroup></table></tables><br /> B.5 Printer QA Device <br /> B.5.1 Key Definition
6801<tables id="TABLE-US-00542" num="00542"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 345</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Key definitions for a Printer QA Device</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>Key</entry><entry /></row><row><entry /><entry>Name</entry><entry>Purpose</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>Upgrade key</entry><entry>This key is used for writing/upgrading</entry></row><row><entry /><entry>(fill/refill key)</entry><entry>the functional parameter.</entry></row><row><entry /><entry>Ink usage Key</entry><entry>This key is verifying the data read</entry></row><row><entry /><entry /><entry>from the Ink QA Device.</entry></row><row><entry /><entry>Sequence Key</entry><entry>This key is used to initialise sequence</entry></row><row><entry /><entry /><entry>data fields SEQ_1 and SEQ_2 to</entry></row><row><entry /><entry /><entry>0xFFFFFFF.</entry></row><row><entry /><entry>PECID/SOPECID</entry><entry>This key is used to verify the data</entry></row><row><entry /><entry>Key</entry><entry>read from the printer QA Device. This</entry></row><row><entry /><entry /><entry>key is unique to each printer. Also</entry></row><row><entry /><entry /><entry>used to translate data from the ink QA</entry></row><row><entry /><entry /><entry>Device to the trusted printer system</entry></row><row><entry /><entry /><entry>QA Device.</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> B.5.2 Field Definition
6802<tables id="TABLE-US-00543" num="00543"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="357pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 346</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Field definitions for a Printer QA Device</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="98pt" align="left" /><colspec colname="1" colwidth="259pt" align="center" /><tbody valign="top"><row><entry /><entry>Field Attrinutes</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="8"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="56pt" align="left" /><colspec colname="3" colwidth="77pt" align="left" /><colspec colname="4" colwidth="35pt" align="left" /><colspec colname="5" colwidth="21pt" align="center" /><colspec colname="6" colwidth="21pt" align="center" /><colspec colname="7" colwidth="70pt" align="left" /><colspec colname="8" colwidth="35pt" align="left" /><tbody valign="top"><row><entry /><entry /><entry /><entry /><entry>A<sup>a</sup></entry><entry>NA<sup>b</sup></entry><entry /><entry>EndPos</entry></row><row><entry>Field Name</entry><entry>Purpose</entry><entry>Type</entry><entry>Key Num</entry><entry>RW</entry><entry>RW</entry><entry>KPerms<sup>c</sup></entry><entry>(Size)</entry></row><row><entry namest="1" nameend="8" align="center" rowsep="1" /></row><row><entry>Functional</entry><entry>The field</entry><entry>Must define</entry><entry>SN<sup>f </sup>fill/</entry><entry>1</entry><entry>0</entry><entry>KPerms[KN<sup>e</sup>] = 0</entry><entry>Set as per</entry></row><row><entry>parameter</entry><entry>stores an</entry><entry>the type of</entry><entry>refill key</entry><entry /><entry /><entry>Rest are 0</entry><entry>functional</entry></row><row><entry /><entry>upgradeable</entry><entry>print speed</entry><entry /><entry /><entry /><entry /><entry>parameter.</entry></row><row><entry /><entry>functional</entry><entry>i.e</entry></row><row><entry /><entry>parameter.</entry><entry>TYPE_PRINT_SPEED<sup>d</sup></entry></row><row><entry /><entry>More than one</entry></row><row><entry /><entry>functional</entry></row><row><entry /><entry>parameter can</entry></row><row><entry /><entry>be stored in</entry></row><row><entry /><entry>the printer</entry></row><row><entry /><entry>QA Device.</entry></row><row><entry>SEQ_1</entry><entry>This field</entry><entry>TYPE_SEQ_1</entry><entry>SN<sup>f</sup></entry><entry>1</entry><entry>0</entry><entry>KPerms[KN<sup>e</sup>] = 0</entry><entry>Typically</entry></row><row><entry /><entry>holds the</entry><entry /><entry>sequence</entry><entry /><entry /><entry>KPerms[fill/refill<sup>g</sup>] = 1</entry><entry>32 bit.</entry></row><row><entry /><entry>data for</entry><entry /><entry>key</entry><entry /><entry /><entry>Rest are 0.</entry></row><row><entry /><entry>sequence data</entry></row><row><entry /><entry>field SEQ_1</entry></row><row><entry /><entry>when the</entry></row><row><entry /><entry>Printer QA</entry></row><row><entry /><entry>Device is</entry></row><row><entry /><entry>being filled/</entry></row><row><entry /><entry>refilled by</entry></row><row><entry /><entry>a Parameter</entry></row><row><entry /><entry>Upgrader QA</entry></row><row><entry /><entry>Device.</entry></row><row><entry>SEQ_2</entry><entry>This field</entry><entry>TYPE_SEQ_2</entry><entry>SN<sup>f</sup></entry><entry>1</entry><entry>0</entry><entry>KPerms[KN<sup>e</sup>] = 0</entry><entry>Typically</entry></row><row><entry /><entry>holds the data</entry><entry /><entry>sequence</entry><entry /><entry /><entry>KPerms[fill/refill<sup>g</sup>] = 1</entry><entry>32 bit.</entry></row><row><entry /><entry>for sequence</entry><entry /><entry>key</entry><entry /><entry /><entry>Rest are 0.</entry></row><row><entry /><entry>data field</entry></row><row><entry /><entry>SEQ_2 when the</entry></row><row><entry /><entry>Printer QA</entry></row><row><entry /><entry>Device is</entry></row><row><entry /><entry>being filled/</entry></row><row><entry /><entry>refilled by</entry></row><row><entry /><entry>another</entry></row><row><entry /><entry>Parameter</entry></row><row><entry /><entry>Upgrader</entry></row><row><entry /><entry>QA Device.</entry></row><row><entry namest="1" nameend="8" align="center" rowsep="1" /></row><row><entry namest="1" nameend="8" align="left" id="FOO-00110"><sup>a</sup>Authenticated ReadWrite permission</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00111"><sup>b</sup>Non-authenticated ReadWrite permission</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00112"><sup>c</sup>KeyPerms</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00113"><sup>d</sup>This is a sample type only</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00114"><sup>e</sup>KeyNum</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00115"><sup>f</sup>Key Slot Number</entry></row><row><entry namest="1" nameend="8" align="left" id="FOO-00116"><sup>g</sup>Fill/Refill key has authenticated decrement-only permission to the sequence data fields</entry></row></tbody></tgroup></table></tables><br /> B.6 Trusted Printer System QA Device <br /> B.6.1 Key Definition
6803<tables id="TABLE-US-00544" num="00544"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="140pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="2" rowsep="1">TABLE 347</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>Key Name</entry><entry>Purpose</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>PECID/SOPECID</entry><entry>This key is used to verify the data read from</entry></row><row><entry /><entry>Key</entry><entry>the printer QA Device.</entry></row><row><entry /><entry /><entry>This key is unique to each printer.</entry></row><row><entry /><entry /><entry>This key is also used for verifying translated</entry></row><row><entry /><entry /><entry>data from the ink QA Device.</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> Introduction <br /> 1 Background
6804This document describes a QA Chip that can be used to hold contains authentication keys together with circuitry specially designed to prevent copying. The chip is manufactured using a standard Flash memory manufacturing process, and is low cost enough to be included in consumables such as ink and toner cartridges. The implementation is approximately 1 mm<sup>2 </sup>in a 0.25 micron flash process, and has an expected die manufacturing cost of approximately 10 cents in 2003.
6805Once programmed, the QA Chips as described here are compliant with the NSA export guidelines since they do not constitute a strong encryption device. They can therefore be practically manufactured in the USA (and exported) or anywhere else in the world.
6806Note that although the QA Chip is designed for use in authentication systems, it is microcoded, and can therefore be programmed for a variety of applications.
00002 Nomenclature
6807The following symbolic nomenclature is used throughout this document:
6808<tables id="TABLE-US-00545" num="00545"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 348</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Summary of symbolic nomenclature</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>Symbol</entry><entry>Description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>F[X]</entry><entry>Function F, taking a single parameter X</entry></row><row><entry>F[X, Y]</entry><entry>Function F, taking two parameters, X and Y</entry></row><row><entry>X | Y</entry><entry>X concatenated with Y</entry></row><row><entry>X <img file="US7165824B2_D0723.tif" /> Y</entry><entry>Bitwise X AND Y</entry></row><row><entry>X <img file="US7165824B2_D0724.tif" /> Y</entry><entry>Bitwise X OR Y (inclusive-OR)</entry></row><row><entry>X ⊕ Y</entry><entry>Bitwise X XOR Y (exclusive-OR)</entry></row><row><entry><img file="US7165824B2_D0725.tif" /> X</entry><entry>Bitwise NOT X (complement)</entry></row><row><entry>X <img file="US7165824B2_D0726.tif" /> Y</entry><entry>X is assigned the value Y</entry></row><row><entry>X <img file="US7165824B2_D0727.tif" /> {Y, Z}</entry><entry>The domain of assignment inputs to X is Y and Z</entry></row><row><entry>X = Y</entry><entry>X is equal to Y</entry></row><row><entry>X ≠ Y</entry><entry>X is not equal to Y</entry></row><row><entry><img file="US7165824B2_D0728.tif" /> X</entry><entry>Decrement X by 1 (floor 0)</entry></row><row><entry><img file="US7165824B2_D0729.tif" /> X</entry><entry>Increment X by 1 (modulo register length)</entry></row><row><entry>Erase X</entry><entry>Erase Flash memory register X</entry></row><row><entry>SetBits[X, Y]</entry><entry>Set the bits of the Flash memory register X based</entry></row><row><entry /><entry>on Y</entry></row><row><entry>Z <img file="US7165824B2_D0730.tif" /> ShiftRight[X, Y]</entry><entry>Shift register X right one bit position, taking input</entry></row><row><entry /><entry>bit from Y and placing the output bit in Z</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 3 Pseudocode <br /> 3.1 Asynchronous <ul id="ul0991" list-style="none"><li id="ul0991-0001" num="0000"><ul id="ul0992" list-style="none"><li id="ul0992-0001" num="6809">The following pseudocode:</li></ul></li><li id="ul0991-0002" num="6810">var=expression <ul id="ul0993" list-style="none"><li id="ul0993-0001" num="6811">means the var signal or output is equal to the evaluation of the expression. <br /> 3.2 Synchronous </li><li id="ul0993-0002" num="6812">The following pseudocode:</li></ul></li><li id="ul0991-0003" num="6813">var←expression <ul id="ul0994" list-style="none"><li id="ul0994-0001" num="6814">means the var register is assigned the result of evaluating the expression during this cycle. <br /> 3.3 Expression </li><li id="ul0994-0002" num="6815">Expressions are defined using the nomenclature in Table 348 above. Therefore: <br /><i>var</i>=(<i>a=b</i>)</li><li id="ul0994-0003" num="6816">is interpreted as the var signal is 1 if a is equal to b, and 0 otherwise. <br /> 4 Diagrams </li></ul></li></ul>
6817Black lines are used to denote data, while red lines are used to denote 1-bit control-signal lines.
0000Logical Interface
00005 Introduction
6818The QA Chip has a physical and a logical external interface. The physical interface defines how the QA Chip can be connected to a physical System, while the logical interface determines how that System can communicate with the QA Chip. This section deals with the logical interface.
00005.1 Operating Modes
6819The QA Chip has four operating modes—Idle Mode, Program Mode, Trim Mode and Active Mode. <ul id="ul0995" list-style="none"><li id="ul0995-0001" num="0000"><ul id="ul0996" list-style="none"><li id="ul0996-0001" num="6820">Active Mode is entered on power-on Reset when the fuse has been blown, and whenever a specific authentication command arrives from the System. Program code is only executed in Active Mode. When the reset program code has finished, or the results of the command have been returned to the System, the chip enters Idle Mode to wait for the next instruction.</li><li id="ul0996-0002" num="6821">Idle Mode is used to allow the chip to wait for the next instruction from the System.</li><li id="ul0996-0003" num="6822">Trim Mode is used to determine the clock speed of the chip and to trim the frequency during the initial programming stage of the chip (when Flash memory is garbage). The clock frequency must be trimmed via Trim Mode before Program Mode is used to store the program code.</li><li id="ul0996-0004" num="6823">Program Mode is used to load up the operating program code, and is required because the operating program code is stored in Flash memory instead of ROM (for security reasons).</li></ul></li></ul>
6824Apart from while the QA Chip is executing Reset program code, it is always possible to interrupt the QA Chip and change from one mode to another.
00005.1.1 Active Mode
6825Active Mode is entered in any of the following three situations: <ul id="ul0997" list-style="none"><li id="ul0997-0001" num="0000"><ul id="ul0998" list-style="none"><li id="ul0998-0001" num="6826">power-on Reset when the fuse has been blown</li><li id="ul0998-0002" num="6827">receiving a command consisting of a global id write byte (0x00) followed by the ActiveMode command byte (0x06)</li><li id="ul0998-0003" num="6828">receiving a command consisting of a local id byte write followed by some number of bytes representing opcode and data.</li></ul></li></ul>
6829In all cases, Active Mode causes execution of program code previously stored in the flash memory via Program Mode.
6830If Active Mode is entered by power-on Reset or the global id mechanism, the QA Chip executes specific reset startup code, typically setting up the local id and other IO specific data. The reset startup code cannot be interrupted except by a power-down condition. The power-on reset startup mechanism cannot be used before the fuse has been blown since the QA Chip cannot tell whether the flash memory is valid or not. In this case the globalid mechanism must be used instead.
6831If Active Mode is entered by the local id mechanism, the QA Chip executes specific code depending on the following bytes, which function as opcode plus data. The interpretation of the following bytes depends on whatever software happens to be stored in the QA Chip.
00005.1.2 Idle Mode
6832The QA Chip starts up in Idle Mode when the fuse has not yet been blown, and returns to Idle Mode after the completion of another mode. When the QA Chip is in Idle Mode, it waits for a command from the master by watching the low speed serial line for an id that matches either the global id (0x00), or the chip's local id. <ul id="ul0999" list-style="none"><li id="ul0999-0001" num="0000"><ul id="ul1000" list-style="none"><li id="ul1000-0001" num="6833">If the primary id matches the global id (0x00, common to all QA Chips), and the following byte from the master is the Trim Mode id byte, and the fuse has not yet been blown, the QA Chip enters Trim Mode and starts counting the number of internal clock cycles until the next byte is received. Trim Mode cannot be entered if the fuse has been blown.</li><li id="ul1000-0002" num="6834">If the primary id matches the global id (0x00, common to all QA Chips), and the following byte from the master is the Program Mode id byte, and the fuse has not yet been blown, the QA Chip enters Program Mode. Program Mode cannot be entered if the fuse has been blown.</li><li id="ul1000-0003" num="6835">If the primary id matches the global id (0x00, common to all QA Chips), and the following byte from the master is the Active Mode id bytes, the QA Chip enters Active Mode and executes startup code, allowing the chip to set itself into a state to subsequently receive authentication commands (includes setting a local id and a trim value).</li><li id="ul1000-0004" num="6836">If the primary id matches the chip's local ID, the QA Chip enters Active Mode, allowing the subsequent command to be executed. <ul id="ul1001" list-style="none"><li id="ul1001-0001" num="6837">The valid 8-bit serial mode values sent after a global id are as shown in Table 349:</li></ul></li></ul></li></ul>
6838<tables id="TABLE-US-00546" num="00546"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 349</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Command byte values to place chip in specific mode</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>Value</entry><entry>Interpretation</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>10101011</entry><entry>Trim Mode (only functions when the</entry></row><row><entry /><entry>(0xAB)</entry><entry>fuse has not been blown)</entry></row><row><entry /><entry>10001101</entry><entry>Program Mode (only functions when</entry></row><row><entry /><entry>(0xAD)</entry><entry>the fuse has not been blown)</entry></row><row><entry /><entry>00000110</entry><entry>Active Mode (resets the chip & loads</entry></row><row><entry /><entry>(0x06)</entry><entry>the localId)</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 5.1.3 Trim Mode
6839Trim Mode is enabled by sending a global id byte (0x00) followed by the Trim Mode command byte (0xAB). Trim Mode can only be entered while the fuse has not yet been blown.
6840The purpose of Trim Mode is to set the trim value (an internal register setting) of the internal ring oscillator so that Flash erasures and writes are of the correct duration. This is necessary due to the 2:1 variation of the clock speed due to process variations. If writes an erasures are too long, the Flash memory will wear out faster than desired, and in some cases can even be damaged. Note that the 2:1 variation due to temperature still remains, so the effective operating speed of the chip is 7–14 MHz around a nominal 10 MHz.
6841Trim Mode works by measuring the number of system clock cycles that occur inside the chip from the receipt of the Trim Mode command byte until the receipt of a data byte. When the data byte is received, the data byte is copied to the trim register and the current value of the count is transmitted to the outside world.
6842Once the count has been transmitted, the QA Chip returns to Idle Mode.
6843At reset, the internal trim register setting is set to a known value r. The external user can now perform the following operations: <ul id="ul1002" list-style="none"><li id="ul1002-0001" num="0000"><ul id="ul1003" list-style="none"><li id="ul1003-0001" num="6844">send the global id+write followed by the Trim Mode command byte</li><li id="ul1003-0002" num="6845">send the 8-bit value v over a specified time t</li><li id="ul1003-0003" num="6846">send a stop bit to signify no more data</li><li id="ul1003-0004" num="6847">send the global id+read followed by the Trim Mode command byte</li><li id="ul1003-0005" num="6848">receive the count c</li><li id="ul1003-0006" num="6849">send a stop bit to signify no more data</li></ul></li></ul>
6850At the end of this procedure, the trim register will be v, and the external user will know the relationship between external time t and internal time c. Therefore a new value for v can be calculated.
6851The Trim Mode procedure can be repeated a number of times, varying both t and v in known ways, measuring the resultant c. At the end of the process, the final value for v is established (and stored in the trim register for subsequent use in Program Mode). This value v must also be written to the flash for later use (every time the chip is placed in Active Mode for the first time after power-up). For more information about the internal workings of Trim Mode and the accuracy of trim in the QA Chip, see Section 11.2 on page 967.
00005.1.4 Program Mode
6852Program Mode is enabled by sending a global id byte (0x00) followed by the Program Mode command byte.
6853If the QA Chip knows already that the fuse has been blown, it simply does not enter Program Mode. If the QA Chip does not know the state of the fuse, it determines whether or not the internal fuse has been blown by reading 32-bit word 0 of the information block of flash memory. If the fuse has been blown the remainder of data from the Program Mode command is ignored, and the QA Chip returns to Idle Mode.
6854If the fuse is still intact, the chip enters Program Mode and erases the entire contents of Flash memory. The QA Chip then validates the erasure. If the erasure was successful, the QA Chip receives up to 4096 bytes of data corresponding to the new program code and variable data. The bytes are transferred in order byte<sub>0 </sub>to byte<sub>4095</sub>.
6855Once all bytes of data have been loaded into Flash, the QA Chip returns to Idle Mode.
6856Note that Trim Mode functionality must be performed before a chip enters Program Mode for the first time. Otherwise the erasure and write durations could be incorrect.
6857Once the desired number of bytes have been downloaded in Program Mode, the LSS Master must wait for 80 μs (the time taken to write two bytes to flash at nybble rates) before sending the new transaction (e.g. Active Mode). Otherwise the last nybbles may not be written to flash.
00005.1.5 After Manufacture
6858Directly after manufacture the flash memory will be invalid and the fuse will not have been blown. Therefore power-on-reset will not cause Active Mode. Trim Mode must therefore be entered first, and only after a suitable trim value is found, should Program Mode be entered to store a program. Active Mode can be entered if the program is known to be valid.
0000Logical View of CPU
00006 Introduction
6859The QA Chip is a 32-bit microprocessor with on-board RAM for scratch storage, on-board flash for program storage, a serial interface, and specific security enhancements.
6860The high level commands that a user of an QA Chip sees are all implemented as small programs written in the CPU instruction set.
6861The following sections describe the memory model, the various registers, and the instruction set of the CPU.
00007 Memory Model
6862The QA Chip has its own internal memory, broken into the following conceptual regions: <ul id="ul1004" list-style="none"><li id="ul1004-0001" num="0000"><ul id="ul1005" list-style="none"><li id="ul1005-0001" num="6863">RAM variables (3 Kbits=96 entries at 32-bits wide), used for scratch storage (e.g. HMAC-SHA1processing).</li><li id="ul1005-0002" num="6864">Flash memory (8 Kbytes main block+128 bytes info block) used to hold the non-volatile authentication variables (including program keys etc), and program code. Only 4 KBytes+64 bytes is visible to the program addressing space due to shadowing. Shadowing is where half of each byte is used to validate and verify the other half, thus protecting against certain forms of physical and logical attacks. As a result, two bytes are read to obtain a single byte of data (this happens transparently). <br /> 7.1 RAM </li></ul></li></ul>
6865The RAM region consists of 96×32-bit words required for the general functioning of the QA Chip, but only during the operation of the chip. RAM is volatile memory: once power is removed, the values are lost. Note that in actual fact memory retains its value for some period of time after power-down, but cannot be considered to be available upon power-up. This has issues for security that are addressed in other sections of this document.
6866RAM is typically used for temporary storage of variables during chip operation. Short programs can also be stored and executed from the RAM.
6867RAM is addressed from 0 to 5F. Since RAM is in an unknown state upon a RESET (RstL), program code should not assume the contents to be 0. Program code can, however, set the RAM to be a particular known state during execution of the reset command (guaranteed to be received before any other commands).
00007.2 Flash Variables
6868The flash memory region contains the non-volatile information in the QA Chip. Flash memory retains its value after a RESET or if power is removed, and can be expected to be unchanged when the power is next turned on.
6869Byte <b>0</b> of main memory is the first byte of the program run for the command dispatcher. Note that the command dispatcher is always run with shadows enabled.
6870Bytes <b>0</b>–<b>7</b> of the information block flash memory is reserved as follows: <ul id="ul1006" list-style="none"><li id="ul1006-0001" num="0000"><ul id="ul1007" list-style="none"><li id="ul1007-0001" num="6871">byte <b>0</b>–<b>3</b>=fuse. A value of 0x5555AAAA indicates that the fuse has been blown (think of a physical fuse whose wire is no longer intact).</li><li id="ul1007-0002" num="6872">bytes <b>4</b>–<b>7</b>=random number used to XOR all data for RAM and flash memory accesses</li></ul></li></ul>
6873After power-on reset (when the fuse is blown) or upon receipt of a globalId Active command, the 32-bit data from bytes <b>4</b>–<b>7</b> in the information block of Flash memory is loaded into an internal ChipMask register. In Active Mode (the chip is executing program code), all data read from the flash and RAM is XORed with the ChipMask register, and all data written to the flash and RAM is XORed with the ChipMask register before being written out. This XORing happens completely transparently to the program code. Main flash memory byte <b>0</b> onward is the start of program code. Note that byte <b>0</b> onward needs to be valid after being XORed with the appropriate bytes of ChipMask.
6874Even though CPU access is in 8-bit and 32-bit quantities, the data is actually stored in flash a nybble-at-a-time. Each nybble write is written as a byte containing 4 sets of b/<img file="US7165824B2_D0731.tif" />b pairs. Thus every byte write to flash is writing a nybble to real and shadow. A write mask allows the individual targetting of nybble-at-a-time writes.
6875The checking of flash vs shadow flash is automatically carried out each read (each byte contains both flash and shadow flash). If all 8 bits are 1, the byte is considered to be in its erased form<sup>1</sup>, and returns 0 as the nybble. Otherwise, the value returned for the nybble depends on the size of the overall access and the setting of bit <b>0</b> of the 8-bit WriteMask. <sup>1</sup>TSMC's flash memory has an erased state of all 1s <ul id="ul1008" list-style="none"><li id="ul1008-0001" num="0000"><ul id="ul1009" list-style="none"><li id="ul1009-0001" num="6876">All 8-bit accesses (i.e. instruction and program code fetches) are checked to ensure that each byte read from flash is 4 sets of b/<img file="US7165824B2_D0732.tif" />b pairs. If the data is not of this form, the chip hangs until a new command is issued over the serial interface.</li><li id="ul1009-0002" num="6877">With 32-bit accesses (i.e. data used by program code), each byte read from flash is checked to ensure that it is 4 sets of b/<img file="US7165824B2_D0733.tif" />b pairs. A setting of WriteMask<sub>0</sub>=0 means that if the data is not valid, then the chip will hang until a new command is issued over the serial interface. A setting of WriteMask<sub>0</sub>=1 means that each invalid nybble is replaced by the upper nybble of the WriteMask. This allows recovery after a write or erasure is interrupted by a power-down. <br /> 8 Registers </li></ul></li></ul>
6878A number of registers are defined for use by the CPU. They are used for control, temporary storage, arithmetic functions, counting and indexing, and for I/O.
6879These registers do not need to be kept in non-volatile (Flash) memory. They can be read or written without the need for an erase cycle (unlike Flash memory). Temporary storage registers that contain secret information still need to be protected from physical attack by Tamper Prevention and Detection circuitry and parity checks.
6880All registers are cleared to 0 on a RESET. However, program code should not assume any RAM contents have any particular state, and should set up register values appropriately. In particular, at the startup entry point, the various address registers need to be set up from unknown states.
8.1 GO
6881A 1-bit GO register is 1 when the program is executing, and 0 when it is not. Programs can clear the GO register to halt execution of program code once the command has finished executing.
00008.2 Accumulator and Z Flag
6882The Accumulator is a 32-bit general-purpose register that can be thought of as the single data register. It is used as one of the inputs to all arithmetic operations, and is the register used for transferring information between memory registers.
6883The Z register is a 1-bit flag, and is updated each time the Accumulator is written to. The Z register contains the zero-ness of the Accumulator. Z=1 if the last value written to the Accumulator was 0, and 0 if the last value written was non-0.
6884Both the Accumulator and Z registers are directly accessible from the instruction set.
00008.3 Address Registers
00008.3.1 Program Counter Array and Stack Pointer
6885A 12-level deep 12-bit Program Counter Array (PCA) is defined. It is indexed by a 4-bit Stack Pointer (SP). The current Program Counter (PC), containing the address of the currently executing instruction, is effectively PCA[SP]. A single register bit, PCRamSel determines whether the program is executing from flash or RAM (0=flash, 1=RAM).
6886The PC is affected by calling subroutines or returning from them, and by executing branching instructions. The SP is affected by calling subroutines or returning from them. There is no bounds checking on calling too many subroutines: the oldest entry in the execution stack will be lost.
6887The entry point for program code is defined to be address 0 in Flash. This entry point is used whenever the master signals a new transaction.
8.3.2 A0–A3
6888There are 4 8-bit address registers Each register has an associated memory mode bit designating the address as in Flash (0) or RAM (1).
6889When an An register is pointing to an address in RAM, it holds the word number. When it is pointing to an address in Flash, it points to a set of 32-bit words that start at a 128-bit (16 byte) alignment. The A0 register has a special use of direct offset e.g. access is possible to (A0),0–7 which is the 32-bit word pointed to by A0 offset by the specified number of words.
00008.3.3 WriteMask
6890The WriteMask register is used to determine how many nybbles will be written during a 32-bit write to Flash, and whether or not an invalid nybble will be replaced during a read from Flash.
6891During writes to flash, bit n (of 8) determines whether nybble n is written. The unit of writing is a nybble since half of each byte is used for shadow data. A setting of 0xFF means that all 32-bits will be written to flash (as 8 sets of nybble writes).
6892During 32-bit reads from flash (occurs as 8 reads), the value of WriteMask<sub>0 </sub>is used to determine whether a read of invalid data is replaced by the upper nybble of WriteMask. If 0, a read of invalid data is not replaced, and the chip hangs until a new command is issued over the serial interface. If 1, a read of invalid data is replaced by the upper nybble of the WriteMask.
6893Thus a WriteMask setting of 0 (reset setting) means that no writes will occur to flash, and all reads are not replaced (causing the program to hang if an invalid value is encountered).
00008.4 Counters
6894A number of special purpose counters/index registers are defined:
6895<tables id="TABLE-US-00547" num="00547"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 350</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Counter/Index registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="28pt" align="left" /><colspec colname="3" colwidth="28pt" align="left" /><colspec colname="4" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>Register</entry><entry /><entry /></row><row><entry>Name</entry><entry>Size</entry><entry>Bits</entry><entry>Description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry>C1</entry><entry>1 × 3</entry><entry>3</entry><entry>Counter used to index arrays and general</entry></row><row><entry /><entry /><entry /><entry>purpose counter</entry></row><row><entry>C2</entry><entry>1 × 6</entry><entry>6</entry><entry>General purpose counter and can be used to</entry></row><row><entry /><entry /><entry /><entry>index arrays</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
6896All these counter registers are directly accessible from the instruction set. Special instructions exist to load them with specific values, and other instructions exist to decrement or increment them, or to branch depending on the whether or not the specific counter is zero.
6897There are also 2 special flags (not registers) associated with C1 and C2, and these flags hold the zero-ness of C1 or C2. The flags are used for loop control, and are listed here, for although they are not registers, they can be tested like registers.
6898<tables id="TABLE-US-00548" num="00548"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 351</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Flags for testing C1 and C2</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="35pt" align="left" /><colspec colname="2" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>Name</entry><entry>Description</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>C1Z</entry><entry>1 = C1 is current zero, 0 = C1 is currently non-zero.</entry></row><row><entry /><entry>C2Z</entry><entry>1 = C2 is current zero, 0 = C2 is currently non-zero.</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 8.5 RTMP
6899The single bit register RTMP allows the implementation of LFSRs and multiple precision shift registers.
6900During a rotate right (ROR) instruction with operand of RB, the bit shifted out (formally bit <b>0</b>) is written to the RTMP register. The bit currently in the RTMP register becomes the new bit <b>31</b> of the Accumulator. Performing multiple ROR RB commands over several 32-bit values implements a multiple precision rotate/shift right.
6901The XRB operand operates in the same way as RB, in that the current value in the RTMP register becomes the new bit <b>31</b> of the Accumulator. However with the XRB instruction, the bit formally known as bit <b>0</b> does not simply replace RTMP (as in the RB instruction). Instead, it is XORed with RTMP, and the result stored in RTMP, thereby allowing the implementation of long LFSRs.
00008.6 Registers Used for I/O
6902Several registers are defined for communication between the master and the QA Chip. These registers are LocalId, InByte and OutByte.
6903LocalId (7 bits) defines the chip-specific id that this particular QA Chip will accept commands for.
6904InByte (8 bits) provides the means for the QA Chip to obtain the next byte from the master. OutByte (8 bits) provides the means for the QA Chip to send a byte of data to the master.
6905From the QA Chip's point of view: <ul id="ul1010" list-style="none"><li id="ul1010-0001" num="0000"><ul id="ul1011" list-style="none"><li id="ul1011-0001" num="6906">Reads from InByte will hang until there is 1 byte of data present from the master.</li><li id="ul1011-0002" num="6907">Writes to OutByte will hang if the master has not already consumed the last OutByte.</li></ul></li></ul>
6908When the master begins a new command transaction, any existing data in InByte and OutByte is lost, and the PC is reset to the entry point in the code, thus ensuring correct framing of data.
00008.7 Registers Used for Trimming Clock Speed
6909A single 8-bit Trim register is used to trim the ring oscillaor clock speed. The register has a known value of 0x00 during reset to ensure that reads from flash will succeed at the fastest process corners, and can be set in one of two ways: <ul id="ul1012" list-style="none"><li id="ul1012-0001" num="0000"><ul id="ul1013" list-style="none"><li id="ul1013-0001" num="6910">via Trim Mode, which is necessary before the QA Chip is programmed for the first time; or</li><li id="ul1013-0002" num="6911">via the CPU, which is necessary every time the QA Chip is powered up before any flash write or erasure accesses can be carried out. <br /> 8.8 Registers Used for Testing Flash </li></ul></li></ul>
6912There are a number of registers specifically for testing the flash implementation. A single 32-bit write to an appropriate RAM address allows the setting of any combination of these flash test registers.
6913RAM consists of 96×32-bit words, and can be pointed to by any of the standard An address registers. A write to a RAM address in the range 97–127 does nothing with the RAM (reads return 0), but a write to a RAM address in the range 0x80–0x87 will write to specific groupings of registers according to the low 3 bits of the RAM address. A 1 in the address bit means the appropriate part of the 32-bit Accumulator value will be written to the appropriate flash test registers. A 0 in the address bit means the register bits will be unaffected.
6914The registers and address bit groupings are listed in Table 352:
6915<tables id="TABLE-US-00549" num="00549"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 352</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Flash test registers settable from CPU in RAM address range 0x80–0x87<sup>2</sup></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="91pt" align="center" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="63pt" align="left" /><colspec colname="4" colwidth="84pt" align="left" /><tbody valign="top"><row><entry>adr</entry><entry>data</entry><entry /><entry /></row><row><entry>bitSuperscriptparanumonly</entry><entry>bits</entry><entry>name</entry><entry>description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="91pt" align="center" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="63pt" align="left" /><colspec colname="4" colwidth="84pt" align="left" /><tbody valign="top"><row><entry>0</entry><entry>0</entry><entry>shadowsOff</entry><entry>0 = shadowing applies</entry></row><row><entry /><entry /><entry /><entry>(nybble based flash access)</entry></row><row><entry /><entry /><entry /><entry>1 = shadowing disabled,</entry></row><row><entry /><entry /><entry /><entry>8-bit direct accesses to</entry></row><row><entry /><entry /><entry /><entry>flash.</entry></row><row><entry /><entry>1</entry><entry>hiFlashAdr</entry><entry>Only valid when</entry></row><row><entry /><entry /><entry /><entry>shadowsOff = 1</entry></row><row><entry /><entry /><entry /><entry>0 = accesses are to</entry></row><row><entry /><entry /><entry /><entry>lower 4 Kbytes of flash</entry></row><row><entry /><entry /><entry /><entry>1 = accesses are to</entry></row><row><entry /><entry /><entry /><entry>upper 4 Kbytes of flash</entry></row><row><entry /><entry>2</entry></row><row><entry>1</entry><entry>3</entry><entry>enableFlashTest</entry><entry>0 = keep flash test</entry></row><row><entry /><entry /><entry /><entry>register within the TSMC</entry></row><row><entry /><entry /><entry /><entry>flash IP in its reset state</entry></row><row><entry /><entry /><entry /><entry>1 = enable flash test</entry></row><row><entry /><entry /><entry /><entry>register to take on non-</entry></row><row><entry /><entry /><entry /><entry>reset values.</entry></row><row><entry /><entry> 8–4</entry><entry>flashTest</entry><entry>Internal 5-bit flash test</entry></row><row><entry /><entry /><entry /><entry>register within the</entry></row><row><entry /><entry /><entry /><entry>TSMC flash IP</entry></row><row><entry /><entry /><entry /><entry>(SFC008_08B9_HE).</entry></row><row><entry /><entry /><entry /><entry>If this is written with</entry></row><row><entry /><entry /><entry /><entry>0x1E, then subsequent</entry></row><row><entry /><entry /><entry /><entry>writes will be according</entry></row><row><entry /><entry /><entry /><entry>to the TSMC write test</entry></row><row><entry /><entry /><entry /><entry>mode. You must write a</entry></row><row><entry /><entry /><entry /><entry>non-0x1E value or</entry></row><row><entry /><entry /><entry /><entry>reset the register to</entry></row><row><entry /><entry /><entry /><entry>exit this mode.</entry></row><row><entry>2</entry><entry>28–9</entry><entry>flashTime</entry><entry>When timerSel is 1, this</entry></row><row><entry /><entry /><entry /><entry>value is used for the</entry></row><row><entry /><entry /><entry /><entry>duration of the program</entry></row><row><entry /><entry /><entry /><entry>cycle within a</entry></row><row><entry /><entry /><entry /><entry>standard flash write or</entry></row><row><entry /><entry /><entry /><entry>erasure. 1 unit = 16</entry></row><row><entry /><entry /><entry /><entry>clock cycles</entry></row><row><entry /><entry /><entry /><entry>(16 × 100 ns typical).</entry></row><row><entry /><entry /><entry /><entry>Regardless of timerSel,</entry></row><row><entry /><entry /><entry /><entry>this value is also used</entry></row><row><entry /><entry /><entry /><entry>for the timeout following</entry></row><row><entry /><entry /><entry /><entry>power down detection</entry></row><row><entry /><entry /><entry /><entry>before the QA Chip resets</entry></row><row><entry /><entry /><entry /><entry>itself. 1 unit = 1</entry></row><row><entry /><entry /><entry /><entry>clock cycle (= 100 ns</entry></row><row><entry /><entry /><entry /><entry>typical).</entry></row><row><entry /><entry /><entry /><entry>Note that this means the</entry></row><row><entry /><entry /><entry /><entry>programmer should set</entry></row><row><entry /><entry /><entry /><entry>this to an appropriate</entry></row><row><entry /><entry /><entry /><entry>value (e.g. 5 μs),</entry></row><row><entry /><entry /><entry /><entry>just as the localId needs</entry></row><row><entry /><entry /><entry /><entry>to be set.</entry></row><row><entry /><entry>29</entry><entry>timerSel</entry><entry>0 = use internal</entry></row><row><entry /><entry /><entry /><entry>(default) timings for flash</entry></row><row><entry /><entry /><entry /><entry>writes & erasures</entry></row><row><entry /><entry /><entry /><entry>1 = use flashTime for</entry></row><row><entry /><entry /><entry /><entry>flash writes and erasures</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
6916When none of the address register bits <b>0</b>–<b>2</b> are set (e.g. a write to RAM address 0x80), then invalid writes will clear the illChip and retryCount registers.
6917For example, set the A0 register to be 0x80 in RAM. A write to (A0),0 will write to none of the flash test registers, but will clear the illChip and retryCount registers. A write to (A0),7 will write to all of the flash test registers. A write to (A0),2 will write to the enableFlashTest and flashTest registers only. A write to (A0),4 will write to the flashTime and bmerSel registers etc.
6918Finally, a write to address 0x88 in RAM will cause a device erasure. If infoBlockSel is 0, then the device erasure will only be of main memory. If infoBlockSel is 1, then the device erasure is of both main memory and the information block (which will also clear the ChipMask and the Fuse).
6919Reads of invalid RAM areas will reveal information as follows: <ul id="ul1014" list-style="none"><li id="ul1014-0001" num="0000"><ul id="ul1015" list-style="none"><li id="ul1015-0001" num="6920">all invalid addresses in RAM (e.g. 0x80) will return the illChip flag in the low bit (illChip is set whenever 16 consecutive bad reads occur for a single byte in memory)</li><li id="ul1015-0002" num="6921">all invalid addresses in RAM with the low address bit set (e.g. 0x81, or (A0),1 when A0 holds 0x80), will additionally return the most recent retryCount setting (only updated by the chip when a bad read occurs). i.e. bit <b>0</b>=illChip, bits <b>4</b>–<b>1</b>=retryCount. <br /> 8.9 Register Summary </li><li id="ul1015-0003" num="6922">Table 353 provides a summary of the registers used in the CPU.</li></ul></li></ul>
6923<tables id="TABLE-US-00550" num="00550"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 353</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Register summary</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="112pt" align="left" /><colspec colname="3" colwidth="42pt" align="center" /><tbody valign="top"><row><entry>Register name</entry><entry>Description</entry><entry>#bits</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>A[0–3]</entry><entry>address registers</entry><entry>49 = 36</entry></row><row><entry>Acc</entry><entry>Accumulator</entry><entry>32</entry></row><row><entry>C1</entry><entry>general purpose counter and index</entry><entry>3</entry></row><row><entry>C2</entry><entry>general purpose counter and index</entry><entry>6</entry></row><row><entry>IllChip</entry><entry>gets set whenever more than 15</entry><entry>1</entry></row><row><entry /><entry>consecutive bad reads from flash</entry></row><row><entry /><entry>occurred (and any program</entry></row><row><entry /><entry>executing has hung)</entry></row><row><entry>InByte</entry><entry>input byte from outside world</entry><entry>8</entry></row><row><entry>Go</entry><entry>determines whether CPU is executing</entry><entry>1</entry></row><row><entry>LocalId</entry><entry>determines id for this chip's IO</entry><entry>7</entry></row><row><entry>OutByte</entry><entry>output byte to outside world</entry><entry>8</entry></row><row><entry>Z</entry><entry>zero flag for last xfer to Acc</entry><entry>1</entry></row><row><entry>PCA</entry><entry>program counter array</entry><entry>1212 = 144 </entry></row><row><entry>PCRamSel</entry><entry>Program code is executing in flash</entry><entry>1</entry></row><row><entry /><entry>(0) or ram (1)</entry></row><row><entry>RetryCount</entry><entry>counts the number of retries for</entry><entry>4</entry></row><row><entry /><entry>bad reads</entry></row><row><entry>RTMP</entry><entry>bit used to alow multi-word rotations</entry><entry>1</entry></row><row><entry>SP</entry><entry>stack pointer into PCA</entry><entry>4</entry></row><row><entry>Trim</entry><entry>trims ring oscillator frequency</entry><entry>8</entry></row><row><entry>flash test registers</entry><entry>various registers in the embedded</entry><entry>30</entry></row><row><entry /><entry>flash and flash access logic</entry></row><row><entry /><entry>specifically for testing the flash</entry></row><row><entry /><entry>memory</entry><entry /></row><row><entry /><entry>TOTAL (bits)</entry><entry>295</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 8.10 Startup
6924Whenever the chip is powered up, or receives a ‘write’ command over the serial interface, the PC and PCRamSel get set to 0 and execution begins at 0 in Flash memory. The program (starting at 0) needs to determine how the program was started by reading the InByte register.
6925If the first byte read is 0xFF, the chip is being requested to perform software reset tasks. Execution of software reset can only be interrupted by a power down. The reset tasks include setting up RAM to contain known startup state information, setting up Trim and localID registers etc. The CPU signals that it is now ready to receive commands from an external device by writing to the OutByte register. An external Master is able to read the OutByte (and any further outbytes that the CPU decides to send) if it so wishes by a read using the localId.
6926Otherwise the first byte read will be of the form where the least significant bit is <b>0</b>, and bits <b>7</b>–<b>1</b> contain the localId of the device as read over the serial interface. This byte is usually discarded since it nominally only has a value of differentiation against a software reset request. The second and subsequent bytes contain the data message of a write using the localId. The CPU can prevent interruption during execution by writing 0 to the localId and then restoring the desired localId at the later stage.
00009 Instruction Set
6927The CPU operates on 8-bit instructions and typically on 32-bit data items. Each instruction typically consists of an opcode and operand, although the number of bits allocated to opcode and operand varies between instructions.
00009.1 Basic Opcodes (Summary)
0000<ul id="ul1016" list-style="none"><li id="ul1016-0001" num="0000"><ul id="ul1017" list-style="none"><li id="ul1017-0001" num="6928">The opcodes are summarized in Table 354:</li></ul></li></ul>
6929<tables id="TABLE-US-00551" num="00551"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 354</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Opcode bit pattern map</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="133pt" align="left" /><tbody valign="top"><row><entry>Opcode</entry><entry>Mnemonic</entry><entry>Simple Description</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>0000xxxx</entry><entry>JMP</entry><entry>Jump</entry></row><row><entry>0001xxxx</entry><entry>JSR</entry><entry>Jump subroutine</entry></row><row><entry>0010xxxx</entry><entry>TBR</entry><entry>Test and branch</entry></row><row><entry>0011xxxx</entry><entry>DBR</entry><entry>Decrement and branch</entry></row><row><entry>0100xxxx</entry><entry>SC</entry><entry>Set counter to a value</entry></row><row><entry>0101xxxx</entry><entry>ST</entry><entry>Store Accumulator in specified location</entry></row><row><entry>0110000x</entry><entry>—</entry><entry>reserved</entry></row><row><entry>01100010</entry><entry>JPZ</entry><entry>Jump to 0</entry></row><row><entry>01100011</entry><entry>JPI</entry><entry>Jump indirect</entry></row><row><entry>011001xx</entry><entry>—</entry><entry>reserved</entry></row><row><entry>01101xxx</entry><entry>—</entry><entry>reserved</entry></row><row><entry>01110000</entry><entry>—</entry><entry>reserved</entry></row><row><entry>01110001</entry><entry>ERA</entry><entry>Erase page of flash memory pointed to</entry></row><row><entry /><entry /><entry>by Accumulator</entry></row><row><entry>01110010</entry><entry>JSZ</entry><entry>Jump to subroutine at at 0</entry></row><row><entry>01110011</entry><entry>JSI</entry><entry>Jump subroutine indirect</entry></row><row><entry>01110100</entry><entry>RTS</entry><entry>Return from subroutine</entry></row><row><entry>01110101</entry><entry>HALT</entry><entry>Stop the CPU</entry></row><row><entry>0111011x</entry><entry>—</entry><entry>reserved</entry></row><row><entry>01111xxx</entry><entry>LIA</entry><entry>Load immediate value into address</entry></row><row><entry /><entry /><entry>register</entry></row><row><entry>10000xxx</entry><entry>AND</entry><entry>Bitwise AND Accumulator</entry></row><row><entry>10001xxx</entry><entry>OR</entry><entry>Bitwise OR Accumulator</entry></row><row><entry>1001xxxx</entry><entry>XOR</entry><entry>Exclusive-OR Accumulator</entry></row><row><entry>1010xxxx</entry><entry>ADD</entry><entry>Add a 32 bit value to the Accumulator</entry></row><row><entry>1011xxxx</entry><entry>LD</entry><entry>Load Accumulator</entry></row><row><entry>1100xxxx</entry><entry>ROR</entry><entry>Rotate Accumulator right</entry></row><row><entry>11010xxx</entry><entry>AND</entry><entry>Bitwise AND Accumulator<sup>5</sup></entry></row><row><entry>11011xxx</entry><entry>OR</entry><entry>Bitwise OR</entry></row><row><entry /><entry /><entry>Accumulator<sup>Superscriptparanumonly</sup></entry></row><row><entry>11100xxx</entry><entry>XOR</entry><entry>Bitwise XOR</entry></row><row><entry /><entry /><entry>Accumulator<sup>Superscriptparanumonly</sup></entry></row><row><entry>11101xxx</entry><entry>ADD</entry><entry>Add a 32 bit value to the</entry></row><row><entry /><entry /><entry>Accumulator<sup>Superscriptparanumonly</sup></entry></row><row><entry>11110xxx</entry><entry>LD</entry><entry>Load Accumulator<sup>Superscriptparanumonly</sup></entry></row><row><entry>11111xxx</entry><entry>RIA</entry><entry>Rotate Accumulator into address register</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry namest="1" nameend="3" align="left" id="FOO-00118"><sup>5</sup>immediate form of instruction</entry></row></tbody></tgroup></table></tables>
6930Table 355 is a summary of valid operands for each opcode. The table is ordered alphabetically by opcode mnemonic. The binary value for each operand can be found in the subsequent sections.
6931<tables id="TABLE-US-00552" num="00552"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 355</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Valid operands for opcodes</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="175pt" align="left" /><tbody valign="top"><row><entry>Opcode</entry><entry>Valid operands</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>ADD</entry><entry>immediate value</entry></row><row><entry /><entry>(A0), offset</entry></row><row><entry /><entry>(An), {C1, C2} [where n = 0–3]</entry></row><row><entry>AND</entry><entry>immediate value</entry></row><row><entry /><entry>(A0), offset</entry></row><row><entry>DBR</entry><entry>{C1, C2}, offset</entry></row><row><entry>ERA</entry></row><row><entry>HALT</entry></row><row><entry>JMP</entry><entry>address</entry></row><row><entry>JPI</entry></row><row><entry>JPZ</entry></row><row><entry>JSI</entry></row><row><entry>JSR</entry><entry>address</entry></row><row><entry>JSZ</entry></row><row><entry>LIA</entry><entry>{Flash, Ram}, An [where n = 0–3], {immediate value}</entry></row><row><entry>LD</entry><entry>immediate value</entry></row><row><entry /><entry>(A0), offset</entry></row><row><entry /><entry>(An), {C1, C2} [where n = 0–3]</entry></row><row><entry>OR</entry><entry>immediate value</entry></row><row><entry /><entry>(A0), offset</entry></row><row><entry>RIA</entry><entry>{Flash, Ram}, An [where n = 0–3]</entry></row><row><entry>ROR</entry><entry>{InByte, OutByte, WriteMask, ID, C1, C2, RB, XRB,</entry></row><row><entry /><entry>1, 3, 8, 24, 31}</entry></row><row><entry>RTS</entry></row><row><entry>SC</entry><entry>{C1, C2}, {immediate value}</entry></row><row><entry>ST</entry><entry>(A0), offset</entry></row><row><entry /><entry>(An), {C1, C2} [where n = 0–3]</entry></row><row><entry>TBR</entry><entry>{0, 1}, offset</entry></row><row><entry>XOR</entry><entry>immediate value</entry></row><row><entry /><entry>(A0), offset</entry></row><row><entry /><entry>(An), {C1, C2} [where n = 0–3]</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><ul id="ul1018" list-style="none"><li id="ul1018-0001" num="0000"><ul id="ul1019" list-style="none"><li id="ul1019-0001" num="6932">Additional pseduo-opcodes (for programming convenience) are as follows: <ul id="ul1020" list-style="none"><li id="ul1020-0001" num="6933">DEC=ADD 0xFF . . .</li><li id="ul1020-0002" num="6934">INC=ADD 0x01</li><li id="ul1020-0003" num="6935">NOT=XOR 0xFF . . .</li><li id="ul1020-0004" num="6936">LDZ=LD0</li><li id="ul1020-0005" num="6937">SC {C1, C2}, Acc=ROR {C1, C2}</li><li id="ul1020-0006" num="6938">RD=ROR Inbyte</li><li id="ul1020-0007" num="6939">WR=ROR OutByte</li><li id="ul1020-0008" num="6940">LDMASK=ROR WriteMask</li><li id="ul1020-0009" num="6941">LDID=ROR Id</li><li id="ul1020-0010" num="6942">NOP=XOR 0 <br /> 9.2 Addressing Modes </li></ul></li><li id="ul1019-0002" num="6943">The CPU supports a set of addressing modes as follows: <ul id="ul1021" list-style="none"><li id="ul1021-0001" num="6944">immediate</li><li id="ul1021-0002" num="6945">accumulator indirect</li><li id="ul1021-0003" num="6946">indirect fixed</li><li id="ul1021-0004" num="6947">indirect indexed <br /> 9.2.1 Immediate </li></ul></li></ul></li></ul>
6948In this form of addressing, the operand itself supplies the 32-bit data.
6949Immediate addressing relies on 3 bits of operand, plus an optional 8 bits at PC+1 to determine an 8-bit base value. Bits <b>0</b> to <b>1</b> of the opcode byte determine whether the base value comes from the opcode byte itself, or from PC+1, as shown in Table 356.
6950<tables id="TABLE-US-00553" num="00553"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 356</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Selection for base value in immediate mode</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="91pt" align="center" /><colspec colname="2" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>Opcode<sub>1−0</sub></entry><entry>Base value</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>00</entry><entry>00000000</entry></row><row><entry>01</entry><entry>00000001</entry></row><row><entry>10</entry><entry>From PC + 1 (i.e. MIUData<sub>7−0</sub>)</entry></row><row><entry>11</entry><entry>11111111</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
6951The base value is computed by using CMD<sub>0 </sub>as bit <b>0</b>, and copying CMD<sub>1 </sub>into the upper 7 bits.
6952The resultant 8 bit base value is then used as a 32-bit value, with 0s in the upper 24 bits, or the 8-bit value is replicated into the upper 32 bits. The selection is determined by bit <b>2</b> of the opcode byte, as follows:
6953<tables id="TABLE-US-00554" num="00554"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 357</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Replicate bits selection</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="70pt" align="center" /><colspec colname="2" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>Opcode<sub>2</sub></entry><entry>Data</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>0</entry><entry>No replication. Data has 0 in upper 24 bits</entry></row><row><entry /><entry>and baseVal in lower 8 bits</entry></row><row><entry>1</entry><entry>Replicated. Data is 32-bit value formed by</entry></row><row><entry /><entry>replicating baseVal.</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
6954Opcodes that support immediate addressing are LD, ADD, XOR, AND, OR. The SC and LIA instructions are also immediate in that they store the data with the opcode, but they are not in the same form as that described here. See the detail on the individual instructions for more information. Single byte examples include: <ul id="ul1022" list-style="none"><li id="ul1022-0001" num="0000"><ul id="ul1023" list-style="none"><li id="ul1023-0001" num="6955">LD 0</li><li id="ul1023-0002" num="6956">ADD 1</li><li id="ul1023-0003" num="6957">ADD 0xFF . . . # this subtracts 1 from the acc</li><li id="ul1023-0004" num="6958">XOR 0xFF . . . # this performs an effective logical NOT operation</li></ul></li></ul>
6959Double byte examples include: <ul id="ul1024" list-style="none"><li id="ul1024-0001" num="0000"><ul id="ul1025" list-style="none"><li id="ul1025-0001" num="6960">LD 0x05 # a constant</li><li id="ul1025-0002" num="6961">AND 0x0F # isolates the lower nybble</li><li id="ul1025-0003" num="6962">LD 0x36 . . . # useful for HMAC processing <br /> 9.2.2 Accumulator Indirect </li></ul></li></ul>
6963In this form of addressing, the Accumulator holds the effective address.
6964Opcodes that support Accumulator indirect addressing are JPI, JSI and ERA. In the case of JPI and JSI, the Accumulator holds the address to jump to. In the case of ERA, the Accumulator holds the address of the page in flash memory to be erased.
6965Examples include: <ul id="ul1026" list-style="none"><li id="ul1026-0001" num="0000"><ul id="ul1027" list-style="none"><li id="ul1027-0001" num="6966">JPI</li><li id="ul1027-0002" num="6967">JSI</li><li id="ul1027-0003" num="6968">ERA <br /> 9.2.3 Indirect Fixed </li></ul></li></ul>
6969In this form of addressing, address register A0 is used as a base address, and then a specific fixed offset is added to the base address to give the effective address.
6970Bits <b>2</b>–<b>0</b> of the opcode byte specify the fixed offset from A0, which means the fixed offset has a range of 0 to 7.
6971Opcodes that support indirect indexed addressing are LD, ST, ADD, XOR, AND, OR. <ul id="ul1028" list-style="none"><li id="ul1028-0001" num="0000"><ul id="ul1029" list-style="none"><li id="ul1029-0001" num="6972">Examples include: <ul id="ul1030" list-style="none"><li id="ul1030-0001" num="6973">LD (A0),2</li><li id="ul1030-0002" num="6974">ADD (A0), 3</li><li id="ul1030-0003" num="6975">AND (A0), 4</li><li id="ul1030-0004" num="6976">ST (A0), 7 <br /> 9.2.4 Indirect Indexed </li></ul></li></ul></li></ul>
6977In this form of addressing, an address register is used as a base address, and then an index register is used to offset from that base address to give the effective address.
6978The address register is one of 4, and is selected via bits <b>2</b>–<b>1</b> of the opcode byte as follows:
6979<tables id="TABLE-US-00555" num="00555"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 358</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Address register selection</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="126pt" align="center" /><colspec colname="2" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry>address register</entry></row><row><entry>Opcode<sub>2−1</sub></entry><entry>selected</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>00</entry><entry>A0</entry></row><row><entry>01</entry><entry>A1</entry></row><row><entry>10</entry><entry>A2</entry></row><row><entry>11</entry><entry>A3</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
6980Bit <b>0</b> of the opcode byte selects whether index register C1 or C2 is used:
6981The counter is selected as follows:
6982<tables id="TABLE-US-00556" num="00556"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 359</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Interpretation of counter for DBR</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="42pt" align="center" /><colspec colname="2" colwidth="133pt" align="center" /><tbody valign="top"><row><entry /><entry>Opcode<sub>0</sub></entry><entry>interpretion</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>0</entry><entry>C1</entry></row><row><entry /><entry>1</entry><entry>C2</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><ul id="ul1031" list-style="none"><li id="ul1031-0001" num="0000"><ul id="ul1032" list-style="none"><li id="ul1032-0001" num="6983">Opcodes that support indirect indexed addressing are LD, ST, ADD, XOR.</li><li id="ul1032-0002" num="6984">Examples include: <ul id="ul1033" list-style="none"><li id="ul1033-0001" num="6985">LD (A2), C1</li><li id="ul1033-0002" num="6986">ADD (A1), C1</li><li id="ul1033-0003" num="6987">ST (A3), C2</li></ul></li></ul></li></ul>
6988Since C1 and C2 can only decement, processing of data structures typically works by loading Cn with some number n and decrementing to 0. Thus (Ax),n is the first word accessed, and (Ax),0 is the last 32-bit word accessed in the loop.
00009.3 ADD—Add to Accumulator
0000<ul id="ul1034" list-style="none"><li id="ul1034-0001" num="0000"><ul id="ul1035" list-style="none"><li id="ul1035-0001" num="6989">Mnemonic: ADD</li><li id="ul1035-0002" num="6990">Opcode: 1010xxxx, and 11101xxx</li><li id="ul1035-0003" num="6991">Usage: ADD effective-address, or ADD immediate-value</li></ul></li></ul>
6992The ADD instruction adds the specified 32-bit value to the Accumulator via modulo 2<sup>32 </sup>addition.
6993The <b>11101</b>xxx form of the opcode follows the immediate addressing rules (see Section 9.2.1 on page 946). The 1010xxxx form of the opcode defines an effective address as follows:
6994<tables id="TABLE-US-00557" num="00557"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 360</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Interpretation of operand for ADD (1010xxxx)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="21pt" align="center" /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="154pt" align="left" /><tbody valign="top"><row><entry>bit 3</entry><entry>interpretion</entry><entry>comment</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>0</entry><entry>(A0), offset</entry><entry>indirect fixed addressing (see Section 9.2.3 on page</entry></row><row><entry /><entry /><entry>948)</entry></row><row><entry>1</entry><entry>(An), Cn</entry><entry>indirect indexed addressing (see Section 9.2.4 on</entry></row><row><entry /><entry /><entry>page 948)</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><ul id="ul1036" list-style="none"><li id="ul1036-0001" num="0000"><ul id="ul1037" list-style="none"><li id="ul1037-0001" num="6995">The Z flag is also set during this operation, depending on whether the result (loaded into the Accumulator) is zero or not. <br /> 9.4 AND—Bitwise AND </li><li id="ul1037-0002" num="6996">Mnemonic: AND</li><li id="ul1037-0003" num="6997">Opcode: 10000xxx, and 11010xxx</li><li id="ul1037-0004" num="6998">Usage: AND effective-address, or AND immediate-value</li></ul></li></ul>
6999The AND instruction performs a 32-bit bitwise AND operation on the Accumulator.
7000The 11010xxx form of the opcode follows the immediate addressing rules (see Section 9.2.1 on page 946). The 10000xxx form of the opcode follows the indirect fixed addressing rules (see Section 9.2.3 on page 948).
7001The Z flag is also set during this operation, depending on whether the resultant 32-bit value (loaded into the Accumulator) is zero or not.
00009.5 DBR—Decrement and Branch
0000<ul id="ul1038" list-style="none"><li id="ul1038-0001" num="0000"><ul id="ul1039" list-style="none"><li id="ul1039-0001" num="7002">Mnemonic: DBR</li><li id="ul1039-0002" num="7003">OpCode: 0011xxxx</li><li id="ul1039-0003" num="7004">Usage: DBR Counter, Offset</li></ul></li></ul>
7005This instruction provides the mechanism for building simple loops.
7006The counter is selected from bit <b>0</b> of the opcode byte as follows:
7007<tables id="TABLE-US-00558" num="00558"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 361</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Interpretation of counter for DBR</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="28pt" align="center" /><colspec colname="2" colwidth="140pt" align="center" /><tbody valign="top"><row><entry /><entry>bit 0</entry><entry>interpretion</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>0</entry><entry>C1</entry></row><row><entry /><entry>1</entry><entry>C2</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7008If the specified counter is non-zero, then the counter is decremented and the designated offset is added to the current instruction address (PC for 1-byte instructions, PC+1 for 2-byte instructions). If the specified counter is zero, it is decremented (all bits in the counter become set) and processing continues at the next instruction (PC+1 or PC+2). The designated offset will typically be negative for use in loops.
7009The instruction is either 1 or two bytes, as determined by bits <b>3</b>–<b>1</b> of the opcode byte: <ul id="ul1040" list-style="none"><li id="ul1040-0001" num="0000"><ul id="ul1041" list-style="none"><li id="ul1041-0001" num="7010">If bits <b>3</b>–<b>1</b>=000, the instruction consumes 2 bytes. The 8 bits at PC+1 are treated as a signed number and used as the offset amount. Thus 0xFF is treated as −1, and 0x01 is treated as +1.</li><li id="ul1041-0002" num="7011">If bits <b>3</b>–<b>1</b>≠000, the instruction consumes 1 byte. Bits <b>3</b>–<b>1</b> are treated as a negative number (the sign bit is implied) and used as the offset amount. Thus 111 is treated as −1, and 001 is treated as −7. This is useful for small loops.</li></ul></li></ul>
7012The effect is that if the branch is back 1–7 bytes (1 byte is not particularly useful), then the single byte form of the instruction can be used. If the branch is forward, or backward more than 7 bytes, then the 2-byte instruction is required.
00009.6 ERA—Erase
0000<ul id="ul1042" list-style="none"><li id="ul1042-0001" num="0000"><ul id="ul1043" list-style="none"><li id="ul1043-0001" num="7013">Mnemonic: ERA</li><li id="ul1043-0002" num="7014">Opcode: 01110001</li><li id="ul1043-0003" num="7015">Usage: ERA</li></ul></li></ul>
7016This instruction causes an erasure of the 256-byte page of flash memory pointed to by the Accumulator. The Accumulator is assumed to contain an 8-bit pointer to a 128-bit (16 byte) aligned structure (same structure as the address registers). The page number to be erased comes from bits <b>7</b>–<b>4</b>, and the lower 4 bits are ignored.
7017Note that the size of the flash memory page being erased is actually 512 bytes, but in terms of data storage and addressing from the point of view of the CPU, there is only 256 bytes in the page.
00009.7 HALT—Halt CPU Operation
0000<ul id="ul1044" list-style="none"><li id="ul1044-0001" num="0000"><ul id="ul1045" list-style="none"><li id="ul1045-0001" num="7018">Mnemonic: HALT</li><li id="ul1045-0002" num="7019">Opcode: 01110101</li><li id="ul1045-0003" num="7020">Usage: HALT</li></ul></li></ul>
7021The HALT instruction writes a 0 to the internal GO register, thereby causing the CPU to terminate the currently executing program. The CPU will only be restarted with a new localId transaction from the Master or by a globalId plus Active Mode byte.
00009.8 JMP—Jump
0000<ul id="ul1046" list-style="none"><li id="ul1046-0001" num="0000"><ul id="ul1047" list-style="none"><li id="ul1047-0001" num="7022">Mnemonic: JMP</li><li id="ul1047-0002" num="7023">Opcode: 0000xxxx</li><li id="ul1047-0003" num="7024">Usage: JMP effective-address</li></ul></li></ul>
7025The JMP instruction provides for a method of branching to a specified address. The instruction loads the PC with the effective address.
7026The new PC is loaded as follows: bits <b>11</b>–<b>8</b> are obtained from bits <b>3</b>–<b>0</b> of the JMP opcode byte, and bits <b>7</b>–<b>0</b> are obtained from PC+1.
00009.9 JPI—Jump Indirect
0000<ul id="ul1048" list-style="none"><li id="ul1048-0001" num="0000"><ul id="ul1049" list-style="none"><li id="ul1049-0001" num="7027">Mnemonic: JPI</li><li id="ul1049-0002" num="7028">Opcode: 01100011</li><li id="ul1049-0003" num="7029">Usage: JPI</li></ul></li></ul>
7030The JPI instruction loads the PC with the lower 12 bits of the Accumulator, and sets the PCRamSel register with bit <b>15</b> of the Accumulator. Note that the stack is unaffected (unlike JSI).
00009.10 JPZ—Jump to Zero
0000<ul id="ul1050" list-style="none"><li id="ul1050-0001" num="0000"><ul id="ul1051" list-style="none"><li id="ul1051-0001" num="7031">Mnemonic: JPZ</li><li id="ul1051-0002" num="7032">Opcode: 01100010</li><li id="ul1051-0003" num="7033">Usage: JPZ</li></ul></li></ul>
7034The JPZ instruction loads the PC and PCRamSel with 0, thereby causing a jump to address 0 in Flash memory.
7035Programmers will not typically use the JPZ command. However the CPU executes this instruction whenever a new command arrives over the serial interface, so that the code entry point is known i.e. every time the chip receives a new command, execution begins at address 0 in flash. This does not change the status of any other internal register settings (e.g. the flash test registers).
00009.11 JSI—Jump Subroutine Indirect
0000<ul id="ul1052" list-style="none"><li id="ul1052-0001" num="0000"><ul id="ul1053" list-style="none"><li id="ul1053-0001" num="7036">Mnemonic: JSI</li><li id="ul1053-0002" num="7037">Opcode: 01110011</li><li id="ul1053-0003" num="7038">Usage: JSI</li></ul></li></ul>
7039The JSI instruction allows the jumping to a subroutine whose address is obtained from the Accumulator. The instruction pushes the current PC onto the stack, loads the PC with the lower 12 bits of the Accumulator, and sets the PCRamSel register with bit <b>15</b> of the Accumulator.
7040The stack provides for 12 levels of execution (11 subroutines deep). It is the responsibility of the programmer to ensure that this depth is not exceeded or the deepest return value will be overwritten (since the stack wraps). Programs can take advantage of the fact that the stack wraps.
00009.12 JSR—Jump Subroutine
0000<ul id="ul1054" list-style="none"><li id="ul1054-0001" num="0000"><ul id="ul1055" list-style="none"><li id="ul1055-0001" num="7041">Mnemonic: JSR</li><li id="ul1055-0002" num="7042">Opcode: 0001xxxx</li><li id="ul1055-0003" num="7043">Usage: JSR effective-address</li></ul></li></ul>
7044The JSR instruction provides for the most common usage of the subroutine construct. The instruction pushes the current PC onto the stack, and loads the PC with the effective address.
7045The new PC is loaded as follows: bits <b>11</b>–<b>8</b> are obtained from bits <b>3</b>–<b>0</b> of the JSR opcode byte, and bits <b>7</b>–<b>0</b> are obtained from PC+1.
7046The stack provides for 12 levels of execution (11 subroutines deep). It is the responsibility of the programmer to ensure that this depth is not exceeded or the return value will be overwritten (since the stack wraps). Programs can take advantage of the fact that the stack wraps.
00009.13 JSZ—Jump to Subroutine at Zero
0000<ul id="ul1056" list-style="none"><li id="ul1056-0001" num="0000"><ul id="ul1057" list-style="none"><li id="ul1057-0001" num="7047">Mnemonic: JSZ</li><li id="ul1057-0002" num="7048">Opcode: 01110010</li><li id="ul1057-0003" num="7049">Usage: JSZ</li></ul></li></ul>
7050The JSZ instruction jumps to the subroutine at flash address 0 (i.e. it pushes the current PC onto the stack, and loads the PC and PCRamSel with 0).
7051Programmers will not typically use the JSZ command. It exists merely as a result of opcode decoding minimization and can be used to assist with the testing of the chip.
00009.14 LD—Load Accumulator
0000<ul id="ul1058" list-style="none"><li id="ul1058-0001" num="0000"><ul id="ul1059" list-style="none"><li id="ul1059-0001" num="7052">Mnemonic: LD</li><li id="ul1059-0002" num="7053">Opcode: 1011xxxx, and 11110xxx <ul id="ul1060" list-style="none"><li id="ul1060-0001" num="7054">Usage: LD effective-address, or LD immediate-value</li></ul></li></ul></li></ul>
7055The LD instruction loads the Accumulator with the 32-bit value.
7056The 11110xxx form of the opcode follows the immediate addressing rules (see Section 9.2.1 on page 946). The 1011xxxx form of the opcode defines an effective address as follows:
7057<tables id="TABLE-US-00559" num="00559"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 362</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Interpretation of operand for LD (1011xxxx)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="21pt" align="center" /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="154pt" align="left" /><tbody valign="top"><row><entry>bit 3</entry><entry>interpretion</entry><entry>comment</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>0</entry><entry>(A0), offset</entry><entry>indirect fixed addressing (see Section 9.2.3 on page</entry></row><row><entry /><entry /><entry>948)</entry></row><row><entry>1</entry><entry>(An), Cn</entry><entry>indirect indexed addressing (see Section 9.2.4 on</entry></row><row><entry /><entry /><entry>page 948)</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7058The Z flag is also set during this operation, depending on whether the value loaded into the Accumulator is zero or not.
00009.15 LIA—Load Immediate Address
0000<ul id="ul1061" list-style="none"><li id="ul1061-0001" num="0000"><ul id="ul1062" list-style="none"><li id="ul1062-0001" num="7059">Mnemonic: LIA</li><li id="ul1062-0002" num="7060">Opoode: 01111xxx</li><li id="ul1062-0003" num="7061">Usage: LIAF AddressRegister, Value # for flash addresses <ul id="ul1063" list-style="none"><li id="ul1063-0001" num="7062">LIAR AddressRegister, Value # for ram addresses</li></ul></li></ul></li></ul>
7063The LIA instruction transfers the data from PC+1 into the designated address register (A0–A3), and sets the memory mode bit for that address register.
7064Bit <b>0</b> specifies whether the address is in flash or ram, as follows:
7065<tables id="TABLE-US-00560" num="00560"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 363</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Interpretation of memory mode for LIA</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="126pt" align="center" /><colspec colname="2" colwidth="91pt" align="left" /><tbody valign="top"><row><entry>bit 0</entry><entry>interpretion</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>0</entry><entry>Flash</entry></row><row><entry>1</entry><entry>Ram</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7066The address register to be targetted is selected via bits <b>2</b>–<b>1</b> of the instruction.
00009.16 OR—Bitwise OR
0000<ul id="ul1064" list-style="none"><li id="ul1064-0001" num="0000"><ul id="ul1065" list-style="none"><li id="ul1065-0001" num="7067">Mnemonic: OR</li><li id="ul1065-0002" num="7068">Opcode: 10001xxx, and 11011xxx</li><li id="ul1065-0003" num="7069">Usage: OR effective-address, or OR immediate-value</li></ul></li></ul>
7070The OR instruction performs a 32-bit bitwise OR operation on the Accumulator.
7071The 11011xxx form of the opcode follows the immediate addressing rules (see Section 9.2.1 on page 946). The 10001xxx form of the opcode follows the indirect fixed addressing rules (see Section 9.2.3 on page 948).
7072The Z flag is also set during this operation, depending on whether the resultant 32-bit value (loaded into the Accumulator) is zero or not.
00009.17 RIA—Rotate in Address
0000<ul id="ul1066" list-style="none"><li id="ul1066-0001" num="0000"><ul id="ul1067" list-style="none"><li id="ul1067-0001" num="7073">Mnemonic: RIA</li><li id="ul1067-0002" num="7074">Opcode: 11111xxx</li><li id="ul1067-0003" num="7075">Usage: RIAF AddressRegister # for flash addresses <ul id="ul1068" list-style="none"><li id="ul1068-0001" num="7076">RIAR AddressRegister # for ram addresses</li></ul></li></ul></li></ul>
7077The RIA instruction transfers the lower 8 bits of the Accumulator into the designated address register (A0–A3), sets the memory mode bit for that address register, and rotates the Accumulator right by 8 bits.
7078Bit <b>0</b> specifies whether the address is in flash or ram, as follows:
7079<tables id="TABLE-US-00561" num="00561"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 364</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Interpretation of memory mode for RIA</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="126pt" align="center" /><colspec colname="2" colwidth="91pt" align="left" /><tbody valign="top"><row><entry>bit 0</entry><entry>interpretion</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>0</entry><entry>Flash</entry></row><row><entry>1</entry><entry>Ram</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7080The address register to be targetted is selected via bits <b>2</b>–<b>1</b> of the instruction.
00009.18 ROR—Rotate Right
0000<ul id="ul1069" list-style="none"><li id="ul1069-0001" num="0000"><ul id="ul1070" list-style="none"><li id="ul1070-0001" num="7081">Mnemonic: ROR</li><li id="ul1070-0002" num="7082">Opcode: 1100xxxx</li><li id="ul1070-0003" num="7083">Usage: ROR Value</li></ul></li></ul>
7084The ROR instruction provides a way of rotating the Accumulator right a set number of bits. The bit(s) coming in at the top of the Accumulator (to become bit <b>31</b>) can either come from the previous lower bits of the Accumulator, from the serial connection, or from external flags. The bit(s) rotated out can also be output from the serial connection, or combined with an external flag.
7085The allowed operands are as follows:
7086<tables id="TABLE-US-00562" num="00562"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 365</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Interpretation of operand for ROR</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="126pt" align="center" /><colspec colname="2" colwidth="91pt" align="left" /><tbody valign="top"><row><entry>bits 3–0</entry><entry>interpretion</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>0000</entry><entry>RB</entry></row><row><entry>0001</entry><entry>XRB</entry></row><row><entry>0010</entry><entry>WriteMask</entry></row><row><entry>0011</entry><entry>1</entry></row><row><entry>0100</entry><entry>- (reserved)</entry></row><row><entry>0101</entry><entry>3</entry></row><row><entry>0110</entry><entry>31</entry></row><row><entry>0111</entry><entry>24</entry></row><row><entry>1000</entry><entry>C1</entry></row><row><entry>1001</entry><entry>C2</entry></row><row><entry>1010</entry><entry>- (reserved)</entry></row><row><entry>1011</entry><entry>- (reserved)</entry></row><row><entry>1100</entry><entry>8</entry></row><row><entry>1101</entry><entry>ID</entry></row><row><entry>1110</entry><entry>InByte</entry></row><row><entry>1111</entry><entry>OutByte</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><ul id="ul1071" list-style="none"><li id="ul1071-0001" num="0000"><ul id="ul1072" list-style="none"><li id="ul1072-0001" num="7087">The Z flag is also set during this operation, depending on whether resultant 32-bit value (loaded into the Accumulator) is zero or not.</li></ul></li></ul>
7088In its simplest form, the operand for the ROR instruction is one of 1, 3, 8, 24, 31, indicating how many bit positions the Accumulator should be rotated. For these operands, there is no external input or output—the bits of the Accumulator are merely rotated right. Note that these values are the equivalent to rotating left 31, 29, 24, 8, 1 bit positions.
7089With operand WriteMask, the lower 8 bits of the Accumulator are transferred to the WriteMask register, and the Accumulator is rotated right by 1 bit. This conveniently allows successive nybbles to be masked during Flash writes if the Accumulator has been preloaded with an appropriate value (eg 1x01).
7090With operands C1 and C2, the lower appropriate number of bits of the Accumulator (3 for C1, 6 for C2) are transferred to the C1 or C2 register and the lower 6 bits of the Accumulator are loaded with the previous value of the Cn register. The remaining upper bits of the Accumulator are set as follows: bit <b>31</b>–<b>24</b> are copied from previous bits <b>7</b>–<b>0</b>, and bits <b>23</b>–<b>6</b> are copied from previous bits <b>31</b>–<b>14</b> (effectively junk). As a result, the Accumulator should be subsequently masked if the programmer wants to compare for specific values).
7091With operand ID, the 7 low-order bits are transferred from the Accumulator to the LocalId register, the low-order 8 bits of the Accumulator are copied to the Trim register if the Trim register has not already been written to after power-on reset, and the Accumulator is rotated right by 8 bits. This means that the ROR ID instruction needs to be performed twice, typically during Global Active Mode—once to set Trim, and once to set LocalId. Note there is no way to read the contents of the localId or Trim registers directly. However the LocalId sent to the program for a command is available as bits <b>7</b>–<b>1</b> of the first byte obtained from InByte after program startup.
7092With operand InByte, the next serial input byte is transferred to the highest 8 bits of the Accumulator. The InByteValid bit is also cleared. If there is no input byte available from the client yet, execution is suspended until there is one. The remainder of the Accumulator is shifted right 8 bit positions (bit <b>31</b> becomes bit <b>23</b> etc.), with lowest bits of the Accumulator shifted out.
7093With operand OutByte, the Accumulator is shifted right 8 bit positions. The byte shifted out from bits <b>7</b>–<b>0</b> is stored in the OutByte register and the OutByteValid flag is set. It is therefore ready for a client to read. If the OutByteValid flag is already set, execution of the instruction stalls until the OutByteValid flag cleared (when the OutByte byte has been read by the client). The new data shifted in to the upper 8 bits of the Accumulator is what was transferred to the OutByte register (i.e. from the Accumulator). Finally, the RB and XRB operands allow the implementation of LFSRs and multiple precision shift registers. With RB, the bit shifted out (formally bit <b>0</b>) is written to the RTMP register. The register currently in the RTMP register becomes the new bit <b>31</b> of the Accumulator. Performing multiple ROR RB commands over several 32-bit values implements a multiple precision rotate/shift right. The XRB operates in the same way as RB, in that the current value in the RTMP register becomes the new bit <b>31</b> of the Accumulator. However with the XRB instruction, the bit formally known as bit <b>0</b> does not simply replace RTMP (as in the RB instruction). Instead, it is XORed with RTMP, and the result stored in RTMP. This allows the implementation of long LFSR<sub>S</sub>, as required by the authentication protocol.
00009.19 RTS—Return from Subroutine
0000<ul id="ul1073" list-style="none"><li id="ul1073-0001" num="0000"><ul id="ul1074" list-style="none"><li id="ul1074-0001" num="7094">Mnemonic: RTS</li><li id="ul1074-0002" num="7095">Opcode: 01110100</li><li id="ul1074-0003" num="7096">Usage: RTS</li></ul></li></ul>
7097The RTS instruction pulls the saved PC from the stack, adds 1, and resumes execution at the resultant address. The effect is to cause execution to resume at the instruction after the most recently executed JSR or JSI instruction.
7098Although 12 levels of execution are provided for (11 subroutines), it is the responsibility of the programmer to balance each JSR and JSI instruction with an RTS. A RTS executed with no previous JSR will cause execution to begin at whatever address happens to be pulled from the stack. Of course this may be desired behaviour in specific circumstances.
00009.20 SC—Set Counter
0000<ul id="ul1075" list-style="none"><li id="ul1075-0001" num="0000"><ul id="ul1076" list-style="none"><li id="ul1076-0001" num="7099">Mnemonic: SC</li><li id="ul1076-0002" num="7100">Opcode: 0100xxxx</li><li id="ul1076-0003" num="7101">Usage: SC Counter Value</li></ul></li></ul>
7102The SC instruction is used to transfer a 3-bit Value into the specified counter. The operand determines which of counters C1 and C2 is to be loaded as well as the value to be loaded. Value is stored in bits <b>3</b>–<b>1</b> of the 8-bit opcode, and the counter is specified by bit <b>0</b> as follows:
7103<tables id="TABLE-US-00563" num="00563"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 366</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Interpretation of counter for SC</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="28pt" align="center" /><colspec colname="2" colwidth="140pt" align="center" /><tbody valign="top"><row><entry /><entry>bit 0</entry><entry>interpretion</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>0</entry><entry>C1</entry></row><row><entry /><entry>1</entry><entry>C2</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7104Since counter C1 is 3 bits, Value is copied directly into C1.
7105For counter C2, C2<sub>2-0 </sub>are copied to C2<sub>5-3</sub>, and Value is copied to C2<sub>2-0</sub>. Two SC C2 instructions are therefore required to load C2 with a given 6-bit value. For example, to load C2 with 0x0C, we would have SC C2 1 followed by SC C2 4.
00009.21 ST—Store Accumulator
0000<ul id="ul1077" list-style="none"><li id="ul1077-0001" num="0000"><ul id="ul1078" list-style="none"><li id="ul1078-0001" num="7106">Mnemonic: ST</li><li id="ul1078-0002" num="7107">Opcode: 0101xxxx</li><li id="ul1078-0003" num="7108">Usage: ST effective-address</li></ul></li></ul>
7109The ST instruction stores the 32-bit Accumulator at the effective address. The effective address is determined as follows:
7110<tables id="TABLE-US-00564" num="00564"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 367</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Interpretation of operand for ST (0101xxxx)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="56pt" align="center" /><colspec colname="2" colwidth="56pt" align="left" /><colspec colname="3" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>bit 3</entry><entry>interpretion</entry><entry>comment</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>0</entry><entry>(A0), offset</entry><entry>indirect fixed addressing</entry></row><row><entry /><entry /><entry>(see Section 9.2.3 on page</entry></row><row><entry /><entry /><entry>948)</entry></row><row><entry>1</entry><entry>(An), Cn</entry><entry>indirect indexed addressing</entry></row><row><entry /><entry /><entry>(see Section 9.2.4 on</entry></row><row><entry /><entry /><entry>page 948)</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7111If the effective address in Flash memory, only those nybbles whose corresponding WriteMask bit is set will be written to Flash. Programmers should be very aware of flash characteristics (write time, longevity, page size etc. when storing data in flash).
7112There is always the possibility that power could be removed during a write to Flash. If this occurs, the flash will be in an indeterminate state. If the QA Chip is warned by the external system that power is about to be removed (via the master causing a transition to Idle Mode), the write will be aborted cleanly at the nearest nybble boundary (writes occur in the order of least significant to most significant).
00009.22 TBR—Test and Branch
0000<ul id="ul1079" list-style="none"><li id="ul1079-0001" num="0000"><ul id="ul1080" list-style="none"><li id="ul1080-0001" num="7113">Mnemonic: TBR</li><li id="ul1080-0002" num="7114">Opcode: 0010xxxx</li><li id="ul1080-0003" num="7115">Usage: TBR Value Offset</li></ul></li></ul>
7116The Test and Branch instruction tests the status of the Z flag (the zero-ness of the Accumulator), and then branches if a match ocurs.
7117The zero-ness is selected from bit <b>0</b> of the opcode byte as follows:
7118<tables id="TABLE-US-00565" num="00565"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 368</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Interpretation of zero-ness for TBR</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="91pt" align="center" /><colspec colname="2" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>bit 0</entry><entry>interpretion</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>0</entry><entry>true if Acc is zero (Z = 1)</entry></row><row><entry>1</entry><entry>true if Acc is non-zero (Z = 0)</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7119If the specified zero-test matches, then the designated offset is added to the current instruction address (PC for 1-byte instructions, PC+1 for 2-byte instructions). If the zero-test does not match, processing continues at the next instruction (PC+1 or PC+2). The instruction is either 1 or two bytes, as determined by bits <b>3</b>–<b>1</b> of the opcode byte: <ul id="ul1081" list-style="none"><li id="ul1081-0001" num="0000"><ul id="ul1082" list-style="none"><li id="ul1082-0001" num="7120">If bits <b>3</b>–<b>1</b>=000, the instruction consumes 2 bytes. The 8 bits at PC+1 are treated as a signed number and used as the offset amount to be added to PC+1. Thus 0xFF is treated as −1, and 0x01 is treated as +1.</li><li id="ul1082-0002" num="7121">If bits <b>3</b>–<b>1</b>≠000, the instruction consumes 1 byte. Bits <b>3</b>–<b>1</b> are treated as a positive number (the sign bit is implied) and used as the offset amount to be added to PC. Thus 111 is treated as 7, and 001 is treated as 1. This is useful for skipping over a small number of instructions.</li></ul></li></ul>
7122The effect is that if the branch is forward 1–7 bytes (1 byte is not particularly useful), then the single byte form of the instruction can be used. If the branch is backward, or forward more than 7 bytes, then the 2-byte instruction is required.
00009.23 XOR—Bitwise Exclusive OR
0000<ul id="ul1083" list-style="none"><li id="ul1083-0001" num="0000"><ul id="ul1084" list-style="none"><li id="ul1084-0001" num="7123">Mnemonic: XOR</li><li id="ul1084-0002" num="7124">Opcode: 1001xxxx, and 11100xxx</li><li id="ul1084-0003" num="7125">Usage: XOR effective-address, or XOR immediate-value</li></ul></li></ul>
7126The XOR instruction performs a 32-bit bitwise XOR operation on the Accumulator.
7127The 11100xxx form of the opcode follows the immediate addressing rules (see Section 9.2.1 on page 946). The 1001xxxx form of the opcode has an effective address as follows:
7128<tables id="TABLE-US-00566" num="00566"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 369</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Interpretation of operand for XOR (1001xxxx)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="56pt" align="center" /><colspec colname="2" colwidth="56pt" align="left" /><colspec colname="3" colwidth="105pt" align="left" /><tbody valign="top"><row><entry>bit 3</entry><entry>interpretion</entry><entry>comment</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>0</entry><entry>(A0), offset</entry><entry>indirect fixed addressing</entry></row><row><entry /><entry /><entry>(see Section 9.2.3 on page</entry></row><row><entry /><entry /><entry>948)</entry></row><row><entry>1</entry><entry>(An), Cn</entry><entry>indirect indexed addressing</entry></row><row><entry /><entry /><entry>(see Section 9.2.4 on page</entry></row><row><entry /><entry /><entry>948)</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7129The Z flag is also set during this operation, depending on whether the result (loaded into the Accumulator) is zero or not.
0000Implementation
000010 Introduction
7130This chapter provides the high-level definition of a CPU capable of implementing the functionalityrequired of an QA Chip.
000010.1 Physical Interface
000010.1.1 Pin Connections
7131The pin connections are described in Table 370.
7132<tables id="TABLE-US-00567" num="00567"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 370</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Pin connections to QA Chip</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>pin</entry><entry>direction</entry><entry>description</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>Vdd</entry><entry>In</entry><entry>Nominal voltage. If the voltage deviates from</entry></row><row><entry /><entry /><entry>this by more than a fixed amount, the chip will</entry></row><row><entry /><entry /><entry>RESET.</entry></row><row><entry>GND</entry><entry>In</entry></row><row><entry>SClk</entry><entry>In</entry><entry>Serial clock</entry></row><row><entry>SDa</entry><entry>In/Out</entry><entry>Serial data</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7133The system operating clock SysClk is different to SClk. SysClk is derived from an internal ring oscillator based on the process technology. In the FPGA implementation SysClk is obtained via a 5th pin.
000010.1.2 Size and Cost
7134The QA Chip uses a 0.25 μm CMOS Flash process for an area of 1 mm<sup>2 </sup>yielding a 10 cent manufacturing cost in 2002. A breakdown of area is listed in Table 371.
7135<tables id="TABLE-US-00568" num="00568"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 371</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Breakdown of Area for QA Chip</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="77pt" align="center" /><colspec colname="2" colwidth="140pt" align="left" /><tbody valign="top"><row><entry>approximate</entry><entry /></row><row><entry>area (mm<sup>2</sup>)</entry><entry>description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="77pt" align="char" char="." /><colspec colname="2" colwidth="140pt" align="left" /><tbody valign="top"><row><entry>0.49</entry><entry>8 KByte flash memory</entry></row><row><entry /><entry>TSMC: SFC0008_08B9_HE</entry></row><row><entry /><entry>(8K × 8-bits, erase page size = 512 bytes)</entry></row><row><entry /><entry>Area = 724.688 μm × 682.05 μm.</entry></row><row><entry>0.08</entry><entry>3072 bits of static RAM</entry></row><row><entry>0.38</entry><entry>General logic</entry></row><row><entry>0.05</entry><entry>Analog circuitry</entry></row><row><entry>1</entry><entry>TOTAL (approximate)</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7136Note that there is no specific test circuitry (scan chains or BIST) within the QA Chip (see Section 10.3.10 on page 965), so the total transistor count is as shown in Table 371.
000010.1.3 Reset
0000<ul id="ul1085" list-style="none"><li id="ul1085-0001" num="0000"><ul id="ul1086" list-style="none"><li id="ul1086-0001" num="7137">The chip performs a RESET upon power-up. In addition, tamper detection and prevention circuitry in the chip will cause the chip to either RESET or erase Flash memory (depending on the attack detected) if an attack is detected. <br /> 10.2 Operating Speed </li></ul></li></ul>
7138The base operating system clock SysClk is generated internally from a ring oscillator (process dependant). Since the frequency varies with operating temperature and voltage, the clock is passed through a temperature-based clock filter before use (see Section 10.3.3 on page 961). The frequency is built into the chip during manufacture, and cannot be changed. The frequency is in the range 7–14 MHz.
000010.3 General Manufacturing Comments
7139Manufacturing comments are not normally made when normally describing the architecture of a chip. However, in the case of the QA Chip, the physical implementation of the chip is very much tied to the security of the key. Consequently a number of specialized circuits and components are necessary for implementation of the QA Chip. They are listed here. <ul id="ul1087" list-style="none"><li id="ul1087-0001" num="0000"><ul id="ul1088" list-style="none"><li id="ul1088-0001" num="7140">Flash process</li><li id="ul1088-0002" num="7141">Internal randomized clock</li><li id="ul1088-0003" num="7142">Temperature based clock filter</li><li id="ul1088-0004" num="7143">Noise generator</li><li id="ul1088-0005" num="7144">Tamper Prevention and Detection circuitry</li><li id="ul1088-0006" num="7145">Protected memory with tamper detection</li><li id="ul1088-0007" num="7146">Boot-strap circuitry for loading program code</li><li id="ul1088-0008" num="7147">Data connections in polysilicon layers where possible</li><li id="ul1088-0009" num="7148">OverUnderPower Detection Unit</li><li id="ul1088-0010" num="7149">No scan-chains or BIST <br /> 10.3.1 Flash Process </li></ul></li></ul>
7150The QA Chip is implemented with a standard Flash manufacturing process. It is important that a Flash process be used to ensure that good endurance is achieved (parts of the Flash memory can be erased/written many times).
000010.3.2 Internal Randomized Clock
7151To prevent clock glitching and external clock-based attacks, the operating clock of the chip should be generated internally. This can be conveniently accomplished by an internal ring oscillator. The length of the ring depends on the process used for manufacturing the chip.
7152Due to process and temperature variations, the clock needs to be trimmed to bring it into a range usable for timing of Flash memory writes and erases.
7153The internal clock should also contain a small amount of randomization to prevent attacks where light emissions from switching events are captured, as described below.
7154Finally, the generated clock must be passed through a temperature-based clock filter before being used by the rest of the chip (see Section 10.3.3 on page 961).
7155The normal situation for FET implementation for the case of a CMOS inverter (which involves a pMOS transistor combined with an nMOS transistor) as shown in <figref idref="DRAWINGS">FIG. 353</figref>.
7156During the transition, there is a small period of time where both the nMOS transistor and the pMOS transistor have an intermediate resistance. The resultant power-ground short circuit causes a temporary increase in the current, and in fact accounts for around 20% of current consumed by a CMOS device. A small amount of infrared light is emitted during the short circuit, and can be viewed through the silicon substrate (silicon is transparent to infrared light). A small amount of light is also emitted during the charging and discharging of the transistor gate capacitance and transmission line capacitance.
7157For circuitry that manipulates secret key information, such information must be kept hidden.
7158Fortunately, IBM's PICA system and LVP (laser voltage probe) both have a requirement for repeatability due to the fact that the photo emissions are extremely weak (one photon requires more than 10<sup>5 </sup>switching events). PICA requires around 10<sup>9 </sup>pases to build a picture of the optical waveform. Similarly the LVP requires multiple passes to ensure an adequate SNR.
7159Randomizing the clock stops repeatability (from the point of view of collecting information about the same position in time), and therefore reduces the possibility of this attack.
000010.3.3 Temperature Based Clock Filter
7160The QA Chip circuitry is designed to operate within a specific clock speed range. Although the clock is generated by an internal ring oscillator, the speed varies with temperature and power. Since the user supplies the temperature and power, it is possible for an attacker to attempt to introduce race-conditions in the circuitry at specific times during processing. An example of this is where a low temperature causes a clock speed higher than the circuitry is designed for, and this may prevent an XOR from working properly, and of the two inputs, the first may always be returned. These styles of transient fault attacks are documented further in [1]. The lesson to be learned from this is that the input power and operating temperature cannot be trusted.
7161Since the chip contains a specific power filter, we must also filter the clock. This can be achieved with a temperature sensor that allows the clock pulses through only when the temperature range is such that the chip can function correctly.
7162The filtered clock signal would be further divided internally as required.
000010.3.4 Noise Generator
7163Each QA Chip should contain a noise generator that generates continuous circuit noise. The noise will interfere with other electromagnetic emissions from the chip's regular activities and add noise to the I<sub>dd </sub>signal. Placement of the noise generator is not an issue on an QA Chip due to the length of the emission wavelengths.
7164The noise generator is used to generate electronic noise, multiple state changes each clock cycle, and as a source of pseudo-random bits for the Tamper Prevention and Detection circuitry (see Section 10.3.5 on page 962).
7165A simple implementation of a noise generator is a 64-bit maximal period LFSR seeded with a non-zero number.
000010.3.5 Tamper Prevention and Detection Circuitry
7166A set of circuits is required to test for and prevent physical attacks on the QA Chip. However what is actually detected as an attack may not be an intentional physical attack. It is therefore important to distinguish between these two types of attacks in an QA Chip: <ul id="ul1089" list-style="none"><li id="ul1089-0001" num="0000"><ul id="ul1090" list-style="none"><li id="ul1090-0001" num="7167">where you can be certain that a physical attack has occurred.</li><li id="ul1090-0002" num="7168">where you cannot be certain that a physical attack has occurred.</li></ul></li></ul>
7169The two types of detection differ in what is performed as a result of the detection. In the first case, where the circuitry can be certain that a true physical attack has occurred, erasure of flash memory key information is a sensible action. In the second case, where the circuitry cannot be sure if an attack has occurred, there is still certainly something wrong. Action must be taken, but the action should not be the erasure of secret key information. A suitable action to take in the second case is a chip RESET. If what was detected was an attack that has permanently damaged the chip, the same conditions will occur next time and the chip will RESET again. If, on the other hand, what was detected was part of the normal operating environment of the chip, a RESET will not harm the key.
7170A good example of an event that circuitry cannot have knowledge about, is a power glitch. The glitch may be an intentional attack, attempting to reveal information about the key. It may, however, be the result of a faulty connection, or simply the start of a power-down sequence. It is therefore best to only RESET the chip, and not erase the key. If the chip was powering down, nothing is lost.
7171If the System is faulty, repeated RESETs will cause the consumer to get the System repaired. In both cases the consumable is still intact.
7172A good example of an event that circuitry can have knowledge about, is the cutting of a data line within the chip. If this attack is somehow detected, it could only be a result of a faulty chip (manufacturing defect) or an attack. In either case, the erasure of the secret information is a sensible step to take.
7173Consequently each QA Chip should have 2 Tamper Detection Lines—one for definite attacks, and one for possible attacks. Connected to these Tamper Detection Lines would be a number of Tamper Detection test units, each testing for different forms of tampering. In addition, we want to ensure that the Tamper Detection Lines and Circuits themselves cannot also be tampered with.
7174At one end of the Tamper Detection Line is a source of pseudo-random bits (clocking at high speed compared to the general operating circuitry). The Noise Generator circuit described above is an adequate source. The generated bits pass through two different paths—one carries the original data, and the other carries the inverse of the data. The wires carrying these bits are in the layer above the general chip circuitry (for example, the memory, the key manipulation circuitry etc.). The wires must also cover the random bit generator. The bits are recombined at a number of places via an XOR gate. If the bits are different (they should be), a 1 is output, and used by the particular unit (for example, each output bit from a memory read should be ANDed with this bit value). The lines finally come together at the Flash memory Erase circuit, where a complete erasure is triggered by a 0 from the XOR. Attached to the line is a number of triggers, each detecting a physical attack on the chip. Each trigger has an oversize nMOS transistor attached to GND. The Tamper Detection Line physically goes through this nMOS transistor. If the test fails, the trigger causes the Tamper Detect Line to become 0. The XOR test will therefore fail on either this clock cycle or the next one (on average), thus RESETing or erasing the chip.
7175<figref idref="DRAWINGS">FIG. 349</figref> illustrates the basic principle of a Tamper Detection Line in terms of tests and the XOR connected to either the Erase or RESET circuitry.
7176The Tamper Detection Line must go through the drain of an output transistor for each test, as illustrated by <figref idref="DRAWINGS">FIG. 350</figref>.
7177It is not possible to break the Tamper Detect Line since this would stop the flow of 1 s and 0s from the random source. The XOR tests would therefore fail. As the Tamper Detect Line physically passes through each test, it is not possible to eliminate any particular test without breaking the Tamper Detect Line.
7178It is important that the XORs take values from a variety of places along the Tamper Detect Lines in order to reduce the chances of an attack. <figref idref="DRAWINGS">FIG. 351</figref> illustrates the taking of multiple XORs from the Tamper Detect Line to be used in the different parts of the chip. Each of these XORs can be considered to be generating a ChipOK bit that can be used within each unit or sub-unit.
7179A typical usage would be to have an OK bit in each unit that is ANDed with a given ChipOK bit each cycle. The OK bit is loaded with 1 on a RESET. If OK is 0, that unit will fail until the next RESET. If the Tamper Detect Line is functioning correctly, the chip will either RESET or erase all key information. If the RESET or erase circuitry has been destroyed, then this unit will not function, thus thwarting an attacker.
7180The destination of the RESET and Erase line and associated circuitry is very context sensitive. It needs to be protected in much the same way as the individual tamper tests. There is no point generating a RESET pulse if the attacker can simply cut the wire leading to the RESET circuitry.
7181The actual implementation will depend very much on what is to be cleared at RESET, and how those items are cleared.
7182Finally, <figref idref="DRAWINGS">FIG. 352</figref> shows how the Tamper Lines cover the noise generator circuitry of the chip. The generator and NOT gate are on one level, while the Tamper Detect Lines run on a level above the generator.
000010.3.6 Protected Memory with Tamper Detection
7183It is not enough to simply store secret information or program code in flash memory. The Flash memory and RAM must be protected from an attacker who would attempt to modify (or set) a particular bit of program code or key information. The mechanism used must conform to being used in the Tamper Detection Circuitry (described above).
7184The first part of the solution is to ensure that the Tamper Detection Line passes directly above each flash or RAM bit. This ensures that an attacker cannot probe the contents of flash or RAM. A breach of the covering wire is a break in the Tamper Detection Line. The breach causes the Erase signal to be set, thus deleting any contents of the memory. The high frequency noise on the Tamper Detection Line also obscures passive observation.
7185The second part of the solution for flash is to always store the data with its inverse. In each byte, 4 bits contains the data, and 4 bits (the shadow) contains the inverse of the data. If both are 0, this is a valid erase state, and the value is 0. Otherwise, the memory is only valid if the 4 bits of shadow are the inverse of the main 4 bits. The reasoning is that it is possible to add electrons to flash via a FIB, but not take electrons away. If it is possible to change a 0 to 1 for example, it is not possible to do the same to its inverse, and therefore regardless of the sense of flash, an attack can be detected.
7186The second part of the solution for RAM is to use a parity bit. The data part of the register can be checked against the parity bit (which will not match after an attack).
7187The bits coming from Flash and RAM can therefore be validated by a number of test units (one per bit) connected to the common Tamper Detection Line. The Tamper Detection circuitry would be the first circuitry the data passes through (thus stopping an attacker from cutting the data lines).
7188In addition, the data and program code should be stored in different locations for each chip, so an attacker does not know where to launch an attack. Finally, XORing the data coming in and going to Flash with a random number that varies for each chip means that the attacker cannot learn anything about the key by setting or clearing an individual bit that has a probability of being the key (the inverse of the key must also be stored somewhere in flash).
7189Finally, each time the chip is called, every flash location is read before performing any program code. This allows the flash tamper detection to be activated in a common spot instead of when the data is actually used or program code executed. This reduces the ability of an attacker to know exactly what was written to.
000010.3.7 Boot-strap Circuitry for Loading Program Code
7190Program code should be kept in protected flash instead of ROM, since ROM is subject to being altered in a non-testable way. A boot-strap mechanism is therefore required to load the program code into flash memory (flash memory is in an indeterminate state after manufacture).
7191The boot-strap circuitry must not be in a ROM—a small state-machine suffices. Otherwise the boot code could be trivially modified in an undetectable way.
7192The boot-strap circuitry must erase all flash memory, check to ensure the erasure worked, and then load the program code.
7193The program code should only be executed once the flash program memory has been validated via Program Mode.
7194Once the final program has been loaded, a fuse can be blown to prevent further programming of the chip.
000010.3.8 Connections in Polysilicon Layers where Possible
7195Wherever possible, the connections along which the key or secret data flows, should be made in the polysilicon layers. Where necessary, they can be in metal 1, but must never be in the top metal layer (containing the Tamper Detection Lines).
000010.3.9 OverUnder Power Detection Unit
7196Each QA Chip requires an OverUnder Power Detection Unit (PDU) to prevent Power Supply Attacks. A PDU detects power glitches and tests the power level against a Voltage Reference to ensure it is within a certain tolerance. The Unit contains a single Voltage Reference and two comparators. The PDU would be connected into the RESET Tamper Detection Line, thus causing a RESET when triggered.
7197A side effect of the PDU is that as the voltage drops during a power-down, a RESET is triggered, thus erasing any work registers.
000010.3.10 No Scan Chains or BIST
7198Test hardware on an QA Chip could very easily introduce vulnerabilities. In addition, due to the small size of the QA Chip logic, test hardware such as scan paths and BIST units could in fact take a sizeable chunk of the final chip, lowering yield and causing a situation where an error in the test hardware causes the chip to be unusable. As a result, the QA Chip should not contain any BIST or scan paths. Instead, the program memory must first be validated via the Program Mode mechanism, and then a series of program tests run to verify the remaining parts of the chip.
000011 Architecture
7199<figref idref="DRAWINGS">FIG. 389</figref> shows a high level block diagram of the QA Chip. Note that the tamper prevention and detection circuitry is not shown.
000011.1 Analogue Unit
7200<figref idref="DRAWINGS">FIG. 390</figref> shows a block diagram of the Analogue Unit. Blocks shown in yellow provide additional protection against physical and electrical attack and, depending on the level of security required, may optionally be implemented.
000011.1.1 Ring Oscillator
7201The operating clock of the chip (SysClk) is generated by an internal ring oscillator whose frequency can be trimmed to reduce the variation from 4:1 (due to process and temperature) down to 2:1 (temperature variations only) in order to satisfy the timing requirements of the Flash memory.
7202The length of the ring depends on the process used for manufacturing the chip. A nominal operating frequency range of 10 MHz is sufficient. This clock should contain a small amount of randomization to prevent attacks where light emissions from switching events are captured.
7203Note that this is different to the input SClk which is the serial clock for external communication.
7204The ring oscillator is covered by both Tamper Detection and Prevention lines so that if an attacker attempts to tamper with the unit, the chip will either RESET or erase all secret information.
7205FPGA Note: the FPGA does not have an internal ring oscillator. An additional pin (SysClk) is used instead. This is replaced by an internal ring oscillator in the final ASIC.
000011.1.2 Voltage Reference
7206The voltage reference block maintains an output which is substantially independent of process, supply voltage and temperature. It provides a reference voltage which is used by the PDU and a reference current to stabilise the ring oscillator. It may also be used as part of the temperature based clock filter described in Section 10.3.3 on page 961.
000011.1.3 OverUnder Power Detection Unit
7207The OverUnder Power Detection Unit (PDU) is the same as that described in Section 10.3.9 on page 965.
7208The Under Voltage Detection Unit provides the signal PwrFailing which, if asserted, indicates that the power supply may be turning off. This signal is used to rapidly terminate any Flash write that may be in progress to avoid accidentally writing to an indeterminate memory location.
7209Note that the PDU triggers the RESET Tamper Detection Line only. It does not trigger the Erase Tamper Detection Line.
7210The PDU can be implemented with regular CMOS, since the key does not pass through this unit. It does not have to be implemented with non-flashing CMOS.
7211The PDU is covered by both Tamper Detection and Prevention lines so that if an attacker attempts to tamper with the unit, the chip will either RESET or erase all secret information.
000011.1.4 Power-on Reset and Tamper Detect Unit
7212The Power-on Reset unit (POR) detects a power-on condition and generates the PORstL signal that is fed to all the validation units, including the two inside the Tamper Detect Unit (TDU).
7213All other logic is connected to RstL, which is the PORstL gated by the VAL unit attached to the Reset tamper detection lines (see Section 10.3.5 on page 962) within the TDU. Therefore, if the Reset tamper line is asserted, the validation will drive RstL low, and can only be cleared by a power-down. If the tamper line is not asserted, then RstL=PORstL.
7214The TDU contains a second VAL unit attached to the Erase tamper detection lines (see Section 10.3.5 on page 962) within the TDU. It produces a TamperEraseOK signal that is output to the MIU (1=the tamper lines are all OK, 0=force an erasure of Flash).
000011.1.5 Noise Generator
7215The Noise Generator (NG) is the same as that described in Section 10.3.4 on page 961. It is based on a 64-bit maximal period LFSR loaded with a set non-zero bit pattern on RESET.
7216The NG must be protected by both Tamper Detection and Prevention lines so that if an attacker attempts to tamper with the unit, the chip will either RESET or erase all secret information.
7217In addition, the bits in the LFSR must be validated to ensure they have not been tampered with (i.e. a parity check). If the parity check fails, the Erase Tamper Detection Line is triggered.
7218Finally, all 64 bits of the NG are ORed into a single bit. If this bit is 0, the Erase Tamper Detection Line is triggered. This is because 0 is an invalid state for an LFSR.
000011.2 Trim Unit
7219The 8-bit Trim register within the Trim Unit has a reset value of 0x00(to enable the flash reads to succeed even in the fastest process corners), and is written to either by the PMU during Trim Mode or by the CPU in Active Mode. Note that the CPU is only able to write once to the Trim register between power-on-reset due to the TrimDone flag which provides overloading of LocalidWE.
7220The reset value of Trim (0) means that the chip has a nominal frequency of 2.7 MHz-10 MHz. The upper of the range is when we cannot trim it lower than this (or we could allow some spread on the acceptable trimmed frequency but this will reduce our tolerance to ageing, voltage and temperature which is the range 7 MHz to 14 MHz). The 2.7 MHz value is determined by a chip whose oscillator runs at 10 MHz when the trim register is set to its maximum value, so then it must run at 2.7 MHz when trim=0. This is based on the non-linear frequency-current characteristic of the oscillator. Chips found outside of these limits will be rejected.
7221The frequency of the ring oscillator is measured by counting cycles<sup>6</sup>, in the PMU, over the byte period of the serial interface. The frequency of the serial clock, SClk, and therefore the byte period will be accurately controlled during the measurement. The cycle count (Fineas) at the end of the period is read over the serial bus and the Trim register updated (Trimval) from its power on default (POD) value. The steps are shown in <figref idref="DRAWINGS">FIG. 391</figref>. Multiple measure—read—trim cycles are possible to improve the accuracy of the trim procedure. 6Note that the PMU counts using 12-bits, saturates at 0xFFF, and returns the cycle count divided by 2 as an 8-bit value. This means that multiple measure-read-trim cycles may be necessary to resolve any amibguity. In any case, multiple cycles are necessary to test the correctness of the trim circuitry during manufacture test.
7222A single byte for both Fineas and Trimval provide sufficient accuracy for measurement and trimming of the frequency. If the bus operates at 400 kHz, a byte (8 bits) can be sent in 20 μs. By dividing the maximum oscillator frequency, expected to be 20 MHz, by 2 results in a cycle count of 200 and 50 for the minimum frequency of 5 MHz resulting in a worst case accuracy of 2%.
7223<figref idref="DRAWINGS">FIG. 392</figref> shows a block diagram of the Trim Unit: <sup>6</sup>Note that the PMU counts using 12-bit, saturated at0xFFF, and returns the cycle count divided by 2 as an 8-bit value. This means that multiple measure-read-trim cycles may be necesary to resolve any amibguity. In any case, multiple cycles are necesary to test the correctness of the trim circuitry during manufacture test.
7224The 8-bit Trim value is used in the analog Trim Block to adjust the frequency of the ring oscillator by controlling its bias current. The two lsbs are used as a voltage trim, and the 6 msbs are used as a frequency trim.
7225The analog Trim Clock circuit also contains a Temperature filter as described in Section 10.3.3 on page 961.
000011.310 Unit
7226The QA Chip acts as a slave device, accepting serial data from an external master via the IO Unit (IOU). Although the IOU actually transmits data over a 1-bit line, the data is always transmitted and received in 1-byte chunks.
7227The IOU receives commands from the master to place it in a specific operating mode, which is one of: <ul id="ul1091" list-style="none"><li id="ul1091-0001" num="0000"><ul id="ul1092" list-style="none"><li id="ul1092-0001" num="7228">Idle Mode: is the startup mode for the IOU if the fuse has not yet been blown. Idle Mode is the mode where the QA Chip is waiting for the next command from the master. Input signals from the CPU are ignored.</li><li id="ul1092-0002" num="7229">Program Mode: is where the QA Chip erases all currently stored data in the Flash memory (program and secret key information) and then allows new data to be written to the Flash. The IOU stays in Program Mode until told to enter another mode.</li><li id="ul1092-0003" num="7230">Active Mode: is the startup mode for the IOU if the fuse has been blown (the program is safe to run). Active Mode is where the QA Chip allows the program code to be executed to process the master's specific command. The IOU returns to Idle Mode automatically when the command has been processed, or if the time taken between consuming input bytes (while the master is writing the data) or generating output bytes (while the master is reading the results) is too great.</li><li id="ul1092-0004" num="7231">Trim Mode: is where the QA Chip allows the generation and setting of a trim value to be used on the internal ring oscillator clock value. This must be done for safety reasons before a program can be stored in the Flash memory. <ul id="ul1093" list-style="none"><li id="ul1093-0001" num="7232">See Section 12 on page 970 for detailed information about the IOU. <br /> 11.4 Central Processing Unit </li></ul></li></ul></li></ul>
7233The Central Processing Unit (CPU) block provides the majority of the circuitry of the 4-bit microprocessor. <figref idref="DRAWINGS">FIG. 393</figref> shows a high level view of the block.
000011.5 Memory Interface Unit
7234The Memory Interface Unit (MIU) provides the interface to flash and RAM. The MIU contains a Program Mode Unit that allows flash memory to be loaded via the IOU, a Memory Request Unit that maps 8-bit and 32-bit requests into multiple byte based requests, and a Memory Access Unit that generates read/write strobes for individual accesses to the memory.
7235<figref idref="DRAWINGS">FIG. 394</figref> shows a high level view of the MIU block.
000011.6 Memory Components
7236The Memory Components block isolates the memory implementation from the rest of the QA Chip. The entire contents of the Memory Components block must be protected from tampering. Therefore the logic must be covered by both Tamper Detection Lines. This is to ensure that program code, keys, and intermediate data values cannot be changed by an attacker. The 8-bit wide RAM also needs to be parity-checked.
7237<figref idref="DRAWINGS">FIG. 395</figref> shows a high level view of the Memory Components block. It consists of 8 KBytes of flash memory and 3072 bits of parity checked RAM.
11.6.1 RAM
7238The RAM block is shown here as a simple 96×32-bit RAM (plus parity included for verification).
7239The parity bit is generated during the write.
7240The RAM is in an unknown state after RESET, so program code cannot rely on RAM being 0 at startup.
7241The initial version of the ASIC has the RAM implemented by Artisan component RA1SH (96×32-bit RAM without parity). Note that the RAMOutEn port is active low i.e. when 0, the RAM is enabled, and when 1, the RAM is disabled.
000011.6.2 Flash Memory
7242A single Flash memory block is used to hold all non-volatile data. This includes program code and variables. The Flash memory block is implemented by TSMC component SFC0008<sub>—</sub>08B9_HE [4], which has the following characteristics: <ul id="ul1094" list-style="none"><li id="ul1094-0001" num="0000"><ul id="ul1095" list-style="none"><li id="ul1095-0001" num="7243">8 K×8-bit main memory, plus 128×8-bit information memory</li><li id="ul1095-0002" num="7244">512 byte page erase</li><li id="ul1095-0003" num="7245">Endurance of 20,000 cycles (min)</li><li id="ul1095-0004" num="7246">Greater than 100 years data retention at room temperature</li><li id="ul1095-0005" num="7247">Access time: 20 ns (max)</li><li id="ul1095-0006" num="7248">Byte write time: 20 μs (min)</li><li id="ul1095-0007" num="7249">Page erase time: 20 ms (min)</li><li id="ul1095-0008" num="7250">Device erase time: 200 ms (min)</li><li id="ul1095-0009" num="7251">Area of 0.494 mm<sup>2 </sup>(724.66 μm×682.05 μm)</li></ul></li></ul>
7252The FlashCtrl line are the various inputs on the SFC0008<sub>—</sub>08B9_HE required to read and write bytes, erase pages and erase the device. A total of 9 bits are required (see [4] for more information).
7253Flash values are unchanged by a RESET. After manufacture, the Flash contents must be considered to be garbage. After an erasure, the Flash contents in the SFC0008<sub>—</sub>08B9_HE is all 1 s.
000011.6.3 VAL Blocks
7254The two VAL units are validation units connected to the Tamper Prevention and Detection circuitry (described in Section 10.3.5 on page 962), each with an OK bit. The OK bit is set to 1 on PORstL, and ORed with the ChipOK values from both Tamper Detection Lines each cycle. The OK bit is ANDed with each data bit that passes through the unit.
7255In the case of VAL<sub>1</sub>, the effective byte output from the flash will always be 0 if the chip has been tampered with. This will cause shadow tests to fail, program code will not execute, and the chip will hang.
7256In the case of VAL<sub>2</sub>, the effective byte from RAM will always be 0 if the chip has been tampered with, thus resulting in no temporary storage for use by an attacker.
000012 I/O Unit
7257The I/O Unit (IOU) is responsible for providing the physical implementation of the logical interface described in Section 5.1 on page 933, moving between the various modes (Idle, Program, Trim and Active) according to commands sent by the master.
7258The IOU therefore contains the circuitry for communicating externally with the external world via the SClk and SDa pins. The IOU sends and receives data in 8-bit chunks. Data is sent serially, most significant bit (bit <b>7</b>) first through to least significant bit (bit <b>0</b>) last. When a master sends a command to an QA Chip, the command commences with a single byte containing an id in bits <b>7</b>–<b>1</b>, and a read/write sense in bit <b>0</b>, as shown in <figref idref="DRAWINGS">FIG. 396</figref>.
7259The IOU recognizes a global id of 0x00 and a local id of LocalId (set after the CPU has executed program code at reset or due to a global id/ActiveMode command on the serial bus). Subsequent bytes contain modal information in the case of global ID, and command/data bytes in the case of a match with the local id.
7260If the master sends data too fast, then the IOU will miss data, since the IOU never holds the bus.
7261The meaning of too fast depends on what is running. In Program Mode, the master must send data a little slower than the time it takes to write the byte to flash (actually written as 2×8-bit writes, or 40 μs). In ActiveMode, the master is permitted to send and request data at rates up to 500 KHz.
7262None of the latches in the IOU need to be parity checked since there is no advantage for an attacker to destroy or modify them.
7263The IOU outputs 0s and inputs 0s if either of the Tamper Detection Lines is broken. This will only come into effect if an attacker has disabled the RESET and/or erase circuitry, since breaking either Tamper Detection Lines should result in a RESET or the erasure of all Flash memory.
7264The IOU's InByte, InByteValid, OutByte, and OutByteValid registers are used for communication between the master and the QA Chip. InByte and InByteValid provide the means for clients to pass commands and data to the QA Chip. OutByte and OutByteValid provide the means for the master to read data from the QA Chip. <ul id="ul1096" list-style="none"><li id="ul1096-0001" num="0000"><ul id="ul1097" list-style="none"><li id="ul1097-0001" num="7265">Reads from InByte should wait until InByteValid is set. InByteValid will remain clear until the master has written the next input byte to the QA Chip. When the IOU is told (by the FEU or MU) that InByte has been read, the IOU clears the InByteValid bit to allow the next byte to be read from the client.</li><li id="ul1097-0002" num="7266">Writes to OutByte should wait until OutByteValid is clear. Writing OutByte sets the OutByteValid bit to signify that data is available to be transmitted to the master. OutByteValid will then remain set until the master has read the data from OutByte. If the master requests a byte but OutByteValid is clear, the IOU sends a NAck to indicate the data is not yet ready.</li></ul></li></ul>
7267When the chip is reset via RstL, the IOU enters ActiveMode to allow the PMU to run to load the fuse. Once the fuse has been loaded (when MIUAvail transitions from 0 to 1) the IOU checks to see if the program is known to be safe. If it is not safe, the IOU reverts to IdleMode. If it is safe (FuseBlown=1), the IOU stays in ActiveMode to allow the program to load up the localId and do any other reset initialization, and will not process any further serial commands until the CPU has written a byte to the OutByte register (which may be read or not at the discretion of the master using a localId read). In both cases the master is then able to send commands to the QA Chip as described in Section 5.1 on page 933.
7268<figref idref="DRAWINGS">FIG. 397</figref> shows a block diagram of the IOU.
7269With regards to InByteValid inputs, set has priority over reset, although both set and reset in correct operation should never be asserted at the same time. With regards to IOSetInByte and IOLoadInByte, if IOSetInByte is asserted, it will set InByte to be 0xFF regardless of the setting of IOLoadInByte.
7270The two VAL units are validation units connected to the Tamper Prevention and Detection circuitry (described in Section 10.3.5 of the Architecture Overview chapter), each with an OK bit. The OK bit is set to 1 on PORstL, and ORed with the ChipOK values from both Tamper Detection Lines each cycle. The OK bit is ANDed with each data bit that passes through the unit.
7271In the case of VAL<sub>1</sub>, the effective byte output from the chip will always be 0 if the chip has been tampered with. Thus no useful output can be generated by an attacker. In the case of VAL2, the effective byte input to the chip will always be 0 if the chip has been tampered with. Thus no useful input can be chosen by an attacker.
7272There is no need to verify the registers in the IOU since an attacker does not gain anything by destroying or modifying them.
7273The current mode of the IOU is output as a 2-bit IOMode to allow the other units within the QA Chip to take correct action. IOMode is defined as shown in Table 372:
7274<tables id="TABLE-US-00569" num="00569"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 372</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>IOMode values</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="119pt" align="center" /><colspec colname="2" colwidth="98pt" align="left" /><tbody valign="top"><row><entry>Value</entry><entry>Interpretation</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>00</entry><entry>Idle Mode</entry></row><row><entry>01</entry><entry>Program Mode</entry></row><row><entry>10</entry><entry>Active Mode</entry></row><row><entry>11</entry><entry>Trim Mode</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7275The Logic blocks generate a 1 if the current IOMode is in Program Mode, Active Mode or Trim Mode respectively. The logic blocks are:
7276<tables id="TABLE-US-00570" num="00570"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="112pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>Logic<sub>1</sub></entry><entry>IOMode = 01 (Program)</entry></row><row><entry /><entry>Logic<sub>2</sub></entry><entry>IOMode = 10 (Active)</entry></row><row><entry /><entry>Logic<sub>3</sub></entry><entry>IOMode = 11 (Trim)</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.1 State Machine
7277There are two state machines in the IOU running in parallel. The first is a byte-oriented state machine, the second is a bit-oriented state machine. The byte-oriented state machine keeps track of the operating mode of the QA Chip while the bit-oriented state machine keeps track of the low-level bit Rx/Tx protocol.
7278The SDa and SClk lines are connected to the respective pads on the QA Chip. The IOU passes each of the signals from the pads through 2 D-types to compensate for metastability on input, and then a further latch and comparitor to ensure that signals are only used if stable for 2 consecutive internal clock cycles. The circuit is shown in Section 12.1.1 below.
000012.1.1 Start/Stop Control Signals
7279The StartDetected and StopDetected control signals are generated based upon monitoring SDa synchronized to SClk. The StartDetected condition is asserted on the falling edge of SDa synchronized to SClk, and the StopDetected condition is asserted on the rising edge of SDa synchronized to SClk.
7280In addition we generate feSClk which is asserted on the falling edge of SClk, and reSClk which is asserted on the rising edge of SClk. Finally, feSclkPrev is the value of feSClk delayed by a single cycle. <figref idref="DRAWINGS">FIG. 398</figref> shows the relationship of inputs and the generation of SDaReg, reSClk, feSClk, feSclkPrev, StartDetected and StopDetected.
7281The SDaRegSelect logic compensates for the 2:1 variation in clock frequency. It uses the length of the high period of the SClk (from the saturating counter) to select between sda5, sda6 and sda7 as the valid data from 300 ns before the falling edge of SClk as follows.
7282The minimum time for the high period of SClk is 600 ns. If the counter <=4 (i.e. 5 or fewer cycles with SClk=1) then SDaReg output=sda5 (sample point is equidistant from rising and falling edges). If the counter=5 or 6 (i.e. 6 or 7 samples where SClk=1), then SDaReg output=sda6. If the counter=7 (the counter saturates when there are 8 samples of SClk=1), then SDaReg output=sda7. This is shown in pseducode below:
7283<tables id="TABLE-US-00571" num="00571"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>If ((counter<sub>2 </sub>= 0) <img file="US7165824B2_D0734.tif" /> (counter = 4))</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="84pt" align="left" /><colspec colname="1" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>SDaReg = sda5</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>ElseIf (counter = 7)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="84pt" align="left" /><colspec colname="1" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>SDaReg = sda7</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="84pt" align="left" /><colspec colname="1" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>SDaReg = sda6</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7284The counter also provides a means of enabling start and stop detection. There is a minimum of a 600 ns setup and 600 ns hold time for start and stop conditions. At 14 MHz this means samples 4 and 5 after the rising edge (sample 1 is considered to be the first sample where SClk=1) could potentially include a valid start or stop condition. At 7 MHz samples 4 and 5 represent 284 and 355 ns respectively, although this is after the rising edge of SClk, which itself is 100 ns after the setup of data (i.e. 384 and 455 ns respectively and therefore safe for sampling). Thus the data will be stable (although not a start or stop). Since we detect stops and starts using sda5 and sda6, we can only validly detect starts and stops 6 cycles after a rising edge, and we need to not-detect starts and stops 4 cycles before the falling edge. We therefore only detect starts and stops when the counter is >=6 (i.e. when sclk3 and scik2 are 0 and 1 respectively, sda2 holds sample 1 coincident with the rising edge, sda1 holds sample 2, sda0 holds sample 3, we load the counter with 0 and sample SDa to obtain the new sda0 which will hold sample 4 at the end of the cycle. Thus while the counter is incrementing from 0 to 1, sda0 will hold sample 4. Therefore sample 4 will be in sda6 when the counter is 6.
000012.1.2 Control of SDa and SClk Pins
7285The SClk line is always driven by the master. The SDa line is driven low whenever we want to transmit an ACK (SDa is active low) or a 0-bit from OutByte. The generation of the SDa pin is shown in the following pseudocode:
7286<tables id="TABLE-US-00572" num="00572"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>TxAck = (bitSM_state = ack) <img file="US7165824B2_D0735.tif" /> ((byteSM_state = doWrite) <img file="US7165824B2_D0736.tif" /></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>(((byteSM_state = getGlobalCmd) <img file="US7165824B2_D0737.tif" /> (byteSM_state = checkId)) <img file="US7165824B2_D0738.tif" /></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>AckCmd))</entry></row><row><entry>TxBit <img file="US7165824B2_D0739.tif" /> (byteSM_state = doRead) <img file="US7165824B2_D0740.tif" /> (bitSM_state = xferBit) <img file="US7165824B2_D0741.tif" /></entry></row><row><entry><img file="US7165824B2_D0742.tif" /> OutByte<img file="US7165824B2_D0743.tif" /><sub>bitcount</sub></entry></row><row><entry>SDa = <img file="US7165824B2_D0744.tif" /> (TxAck <img file="US7165824B2_D0745.tif" /> TxBit) # only drive the line when we are xmitting</entry></row><row><entry>a 0</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7287The slew rate of the SDa line should be restricted to minimise ground bounce. The pad must guarantee a fall time >20 ns. The rise time will be controlled by the external pull up resistor and bus capacitance.
000012.1.3 Bit-oriented State Machine
0000<ul id="ul1098" list-style="none"><li id="ul1098-0001" num="0000"><ul id="ul1099" list-style="none"><li id="ul1099-0001" num="7288">The bit-oriented state machine keeps track of the general flow of serial transmission including start/data/ack/stop as shown in the following pseudocode:</li></ul></li></ul>
7289<tables id="TABLE-US-00573" num="00573"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>idle</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndByte = FALSE</entry></row><row><entry /><entry>EndAck = FALSE</entry></row><row><entry /><entry>If (StartDetected)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0746.tif" /> starting</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0747.tif" /> idle</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>starting</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndByte = FALSE</entry></row><row><entry /><entry>EndAck = FALSE</entry></row><row><entry /><entry>NAck <img file="US7165824B2_D0748.tif" /> 0</entry></row><row><entry /><entry>If (StopDetected)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0749.tif" /> idle</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ElseIf (feSClkPrev)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>bitCount <img file="US7165824B2_D0750.tif" /> 0</entry></row><row><entry /><entry>state <img file="US7165824B2_D0751.tif" /> xferBit</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0752.tif" /> starting# includes StartDetected</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>xferBit</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndAck = FALSE</entry></row><row><entry /><entry>EndByte = (feSclkPrev <img file="US7165824B2_D0753.tif" /> (bitCount = 0)) # after feSclk bitCount</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>must be 1..8</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>If (feSClk)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>shiftLeft[ioByte, SDaReg] # capture the bit in the</entry></row><row><entry /><entry> ioByte</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>shift register</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>bitCount <img file="US7165824B2_D0754.tif" /> bitCount + 1 # modulo count due to 3 bit</entry></row><row><entry /><entry>bitCount</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>If (StopDetected)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0755.tif" /> idle</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ElseIf (StartDetected)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0756.tif" /> starting</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ElseIf (EndByte)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0757.tif" /> ack</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0758.tif" /> xferBit</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>ack</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndByte = FALSE</entry></row><row><entry /><entry>EndAck = feSclkPrev</entry></row><row><entry /><entry>If (StopDetected)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0759.tif" /> idle</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Elself (StartDetected)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0760.tif" /> starting</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Elself (EndAck)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0761.tif" /> xferBit # bitCount is already 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>If (feSClk)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry>NAck <img file="US7165824B2_D0762.tif" /> SDaReg</entry><entry># active low, so 0 = ACK,</entry></row><row><entry /><entry>1 = NACK</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>state <img file="US7165824B2_D0763.tif" /> ack</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 12.1.4 Byte-oriented State Machine
7290The following pseudocode illustrates the general startup state of the IOU and the receipt of a transmission from the master.
7291<tables id="TABLE-US-00574" num="00574"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="35pt" align="left" /><colspec colname="2" colwidth="182pt" align="left" /><thead><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>rstL</entry><entry># setup state of registers on reset</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>IOMode <img file="US7165824B2_D0764.tif" /> ActiveMode # to force the fuse to be loaded</entry></row><row><entry /><entry>OutByteValid <img file="US7165824B2_D0765.tif" /> 0</entry></row><row><entry /><entry>OutByte <img file="US7165824B2_D0766.tif" /> 0</entry></row><row><entry /><entry>InByteValid <img file="US7165824B2_D0767.tif" /> 1 # required</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>InByte <img file="US7165824B2_D0768.tif" /> 0xFF</entry><entry># byte = FF = the ‘reset’ command</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>localId <img file="US7165824B2_D0769.tif" /> 0 # loads localId with the globalId so no localId</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>exists</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0770.tif" /> wait4fuse</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>wait4fuse</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>If (MIUAvail)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>If (FuseBlown) # this must be done same cycle as seeing</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>MIUAvail go high</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0771.tif" /> wait4cpu</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>IOMode <img file="US7165824B2_D0772.tif" /> IdleMode # CPU will now require an external</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>ActiveMode to start</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0773.tif" /> idle</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0774.tif" /> wait4fuse</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>wait4cpu</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="84pt" align="left" /><colspec colname="2" colwidth="119pt" align="left" /><tbody valign="top"><row><entry /><entry>If (CPUOutByteWE)</entry><entry># wait for CPU reset activities to finish</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="119pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0775.tif" /> idle</entry><entry># note: we're still in ActiveMode</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0776.tif" /> wait4cpu</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>idle</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>If (StartDetected)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0777.tif" /> checkId</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0778.tif" /> Idle</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7292The first byte received must be checked to ensure it is meant for everyone (globaild of 0) or specifically for us (localid matches). We only send an ACK to a read when there is data available to send. In addition, writes to the general call address (0) are always ACKed, but reads from the general call address are only ACKed before the fuse has been blown.
7293<tables id="TABLE-US-00575" num="00575"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>checkId</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>isWrite = (ioByte<sub>0 </sub>= 0)</entry></row><row><entry /><entry>isRead = (ioByte<sub>0 </sub>= 1)</entry></row><row><entry /><entry>isGlobal = (ioByte<sub>7−1 </sub>= 0)</entry></row><row><entry /><entry>globalW = isGlobal <img file="US7165824B2_D0779.tif" /> isWrite</entry></row><row><entry /><entry>localW = (ioByte<sub>7−1 </sub>= localID) <img file="US7165824B2_D0780.tif" /> isWrite <img file="US7165824B2_D0781.tif" /> <img file="US7165824B2_D0782.tif" /> isGlobal</entry></row><row><entry /><entry>localR = (ioByte<sub>7−1 </sub>= localID) <img file="US7165824B2_D0783.tif" /> isRead <img file="US7165824B2_D0784.tif" /> (<img file="US7165824B2_D0785.tif" /> GlobalW <img file="US7165824B2_D0786.tif" /></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>FuseBlown)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>If (StopDetected)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0787.tif" /> idle</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ElseIf (EndByte)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>AckCmd_in = (globalW <img file="US7165824B2_D0788.tif" /> localW) <img file="US7165824B2_D0789.tif" /> (localR <img file="US7165824B2_D0790.tif" /> OutByteValid)</entry></row><row><entry /><entry>AckCmd <img file="US7165824B2_D0791.tif" /> AckCmd_in</entry></row><row><entry /><entry>If (localW)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>IOMode <img file="US7165824B2_D0792.tif" /> IdleMode # jic - any output was pending</entry></row><row><entry /><entry>IOOutByteUsed = 1</entry></row><row><entry /><entry>IOClearInByte = 1 # ensure there is nothing</entry></row><row><entry /><entry>hanging around</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>from before</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ElseIf (EndAck)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>If (globalW) # globalW and localW are mutually</entry></row><row><entry /><entry>exclusive</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0793.tif" /> getGlobalCmd</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>ElseIf (localW)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>IOMode <img file="US7165824B2_D0794.tif" /> ActiveMode</entry></row><row><entry /><entry>IOLoadInByte = 1 # will set inByte to localW</entry></row><row><entry /><entry>(lsb will be</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>0)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0795.tif" /> doWrite</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>ElseIf (localR <img file="US7165824B2_D0796.tif" /> IOMode<sub>1 </sub><img file="US7165824B2_D0797.tif" /> AckCmd) # Active mode</entry></row><row><entry /><entry>(or Trim</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>when fuse intact)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0798.tif" /> doRead</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0799.tif" /> idle # ignore reads unless first in active or</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>trim mode</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0800.tif" /> checkId</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7294With a new global command the IOU waits for the mode byte (see Table page6 on page 934) to determine the new operating mode:
7295<tables id="TABLE-US-00576" num="00576"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>getGlobalCmd</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>wantProg = ((ioByte = ProgramModeId) <img file="US7165824B2_D0801.tif" /> <img file="US7165824B2_D0802.tif" /> FuseBlown)</entry></row><row><entry /><entry>wantTrim = ((ioByte = TrimModeId) <img file="US7165824B2_D0803.tif" /> <img file="US7165824B2_D0804.tif" /> FuseBlown)</entry></row><row><entry /><entry>wantActive = (ioByte = ActiveModeId)</entry></row><row><entry /><entry>If (StopDetected)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0805.tif" /> idle</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ElseIf (StartDetected)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0806.tif" /> checkId</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ElseIf (EndByte)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>AckCmd_in = wantActive <img file="US7165824B2_D0807.tif" /> wantProg <img file="US7165824B2_D0808.tif" /> wantTrim # only</entry></row><row><entry /><entry>ACK cmds</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>we can do</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>AckCmd <img file="US7165824B2_D0809.tif" /> AckCmd_in</entry></row><row><entry /><entry>If (AckCmd_in)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>IOMode <img file="US7165824B2_D0810.tif" /> IdleMode # jic - any output was pending</entry></row><row><entry /><entry>IOOutByteUsed = 1</entry></row><row><entry /><entry>IOClearInByte = 1 # ensure there is nothing</entry></row><row><entry /><entry>hanging around</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>from before</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ElseIf (EndAck)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>If (wantProg)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>IOMode <img file="US7165824B2_D0811.tif" /> ProgramMode # don't load inByte (we only</entry></row><row><entry /><entry>want the</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>data)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0812.tif" /> doWrite</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>ElseIf (wantTrim)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>IOMode <img file="US7165824B2_D0813.tif" /> TrimMode # don't load InByte (we only</entry></row><row><entry /><entry>want the</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>next byte)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0814.tif" /> doWrite</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>ElseIf (wantActive) # must be Active</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>IOMode <img file="US7165824B2_D0815.tif" /> ActiveMode</entry></row><row><entry /><entry>IOSetInByte = 1 # 0 for all other cases & states.</entry></row><row><entry /><entry>1 = sets</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>inByte to 0xFF</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>IOLoadInByte = 1 # sets InByteValid (InByte is set</entry></row><row><entry /><entry>to 0xFF</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>(‘reset’ cmd))</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0816.tif" /> wait4cpu# don't do anything til the cpu has</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>completed this task</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0817.tif" /> idle # unknown id, so ignore remainder</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0818.tif" /> getGlobalCmd</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7296When the master writes bytes to the QA Chip (e.g. parameters for a command), the program must consume the byte fast enough (i.e. during the sending of the ACK) or subsequent bits may be lost.
7297The process of receiving bytes is shown in the following pseudocode:
7298<tables id="TABLE-US-00577" num="00577"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>doWrite</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>If (StopDetected)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="126pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0819.tif" /> idle</entry><entry># stay in whatever IOMode we</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>were in</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ElseIf (StartDetected)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0820.tif" /> checkId</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>If (EndByte)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>IOLoadInByte = <img file="US7165824B2_D0821.tif" /> InByteValid</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>If (EndByte <img file="US7165824B2_D0822.tif" /> InByteValid) # will only be when master sends</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>data too quickly</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0823.tif" /> idle</entry><entry># ACK will not</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>be sent when in idle state</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0824.tif" /> doWrite # ACK will be sent automatically after</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>byte is Rxed</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7299When the master wants to read, the IOU sends one byte at a time as requested. The process is shown in the following pseudocode:
7300<tables id="TABLE-US-00578" num="00578"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>doRead</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="63pt" align="left" /><colspec colname="1" colwidth="154pt" align="left" /><tbody valign="top"><row><entry /><entry>If (StopDetected)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="77pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0825.tif" /> idle</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="63pt" align="left" /><colspec colname="1" colwidth="154pt" align="left" /><tbody valign="top"><row><entry /><entry>ElseIf (StartDetected)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="77pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0826.tif" /> checkId</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="63pt" align="left" /><colspec colname="1" colwidth="154pt" align="left" /><tbody valign="top"><row><entry /><entry>ElseIf (EndAck)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="77pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>If (NAck <img file="US7165824B2_D0827.tif" /> <img file="US7165824B2_D0828.tif" /> OutByteValid)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="91pt" align="left" /><colspec colname="1" colwidth="126pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0829.tif" /> idle</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="77pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="91pt" align="left" /><colspec colname="1" colwidth="126pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0830.tif" /> doRead</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="77pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="63pt" align="left" /><colspec colname="1" colwidth="154pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="77pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>If (EndByte)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="91pt" align="left" /><colspec colname="1" colwidth="126pt" align="left" /><tbody valign="top"><row><entry /><entry>IOOutByteUsed = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="77pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>state <img file="US7165824B2_D0831.tif" /> doRead</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="63pt" align="left" /><colspec colname="1" colwidth="154pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 13 Fetch and Execute Unit <br /> 13.1 Introduction
7301The QA Chip does not require the high speeds and throughput of a general purpose CPU. It must operate fast enough to perform the authentication protocols, but not faster. Rather than have specialized circuitry for optimizing branch control or executing opcodes while fetching the next one (and all the complexity associated with that), the state machine adopts a simplistic view of the world. This helps to minimize design time as well as reducing the possibility of error in implementation.
7302The FEU is responsible for generating the operating cycles of the CPU, stalling appropriately during long command operations due to memory latency.
7303When a new transaction begins, the FEU will generate a JPZ (jump to zero) instruction.
7304The general operation of the FEU is to generate sets of cycles: <ul id="ul1100" list-style="none"><li id="ul1100-0001" num="0000"><ul id="ul1101" list-style="none"><li id="ul1101-0001" num="7305">Cycle 0: fetch cycles. This is where the opcode is fetched from the program memory, and the effective address from the fetched opcode is generated. The Fetch output flag is set during the final cycle 0 (i.e. when the opcode is finally valid).</li><li id="ul1101-0002" num="7306">Cycle 1: execute cycle. This is where the operand is (potentially) looked up via the generated effective address (from Cycle 0) and the operation itself is executed. The Exec output flag is set during the final cycle 1 (i.e. when the operand is finally valid).</li></ul></li></ul>
7307Under normal conditions, the state machine generates multiple Cycle=0 followed by multiple Cycle=1. This is because the program is stored in flash memory, and may take multiple cycles to read. In addition, writes to and erasures of flash memory take differing numbers of cycles to perform. The FEU will stall, generating multiple instances of the same Cycle value with Fetch and Exec both 0 until the input MIURdy=1, whereupon a Fetch or Exec pulse will be generated in that same cycle.
7308There are also two cases for stalling due to serial I/O operations: <ul id="ul1102" list-style="none"><li id="ul1102-0001" num="0000"><ul id="ul1103" list-style="none"><li id="ul1103-0001" num="7309">The opcode is ROR OutByte, and OutByteValid=1. This means that the current operation requires outputting a byte to the master, but the master hasn't read the last byte yet.</li><li id="ul1103-0002" num="7310">The operation is ROR InByte, and InByteValid=0. This means that the current operation requires reading a byte from the master, but the master hasn't supplied the byte yet.</li></ul></li></ul>
7311In both these cases, the FEU must stall until the stalling condition has finished.
7312Finally, the FEU must stop executing code if the IOU exits Active Mode.
7313The local Cmd opcode/operand latch needs to be parity-checked. The logic and registers contained in the FEU must be covered by both Tamper Detection Lines. This is to ensure that the instructions to be executed are not changed by an attacker.
000013.2 State Machine
7314The Fetch and Execute Unit (FEU) is combinatorial logic with the following registers:
7315<tables id="TABLE-US-00579" num="00579"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 373</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>FEU Registers</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="42pt" align="center" /><colspec colname="3" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>Name</entry><entry>#bits</entry><entry>Description</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Output registers (visible outside the FEU)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="42pt" align="char" char="." /><colspec colname="3" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>Cycle</entry><entry>1</entry><entry>0 if the FEU is currently fetching an</entry></row><row><entry /><entry /><entry>opcode, 1 if the FEU is currently</entry></row><row><entry /><entry /><entry>executing the opcode.</entry></row><row><entry>NewMemTrans</entry><entry>1</entry><entry>Is asserted during the start of a</entry></row><row><entry /><entry /><entry>potential new memory access.</entry></row><row><entry /><entry /><entry>0 = this is not the first cycle</entry></row><row><entry /><entry /><entry>of a set of Cycle 0 or Cycle 1</entry></row><row><entry /><entry /><entry>1 = this is the first cycle of a</entry></row><row><entry /><entry /><entry>set of Cycle 0 or Cycle 1 (previous</entry></row><row><entry /><entry /><entry>cycle must have been a Fetch or</entry></row><row><entry /><entry /><entry>an Exec).</entry></row><row><entry>Go</entry><entry>1</entry><entry>1 if the FEU is currently fetching and</entry></row><row><entry /><entry /><entry>executing program code (i.e. a program</entry></row><row><entry /><entry /><entry>is currently running), 0 if it is not.</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Local registers (not visible outside the FEU)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="42pt" align="center" /><colspec colname="3" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>CurrCmd</entry><entry>8 + p</entry><entry>Holds the currently executing</entry></row><row><entry /><entry /><entry>instruction (parity checked).</entry></row><row><entry>PendingKill</entry><entry>1</entry><entry>The currently executing program is</entry></row><row><entry /><entry /><entry>waiting to be halted (waiting due</entry></row><row><entry /><entry /><entry>to memory access)</entry></row><row><entry>PendingStart</entry><entry>1</entry><entry>A new transaction is waiting to be</entry></row><row><entry /><entry /><entry>started (waiting due to memory access</entry></row><row><entry /><entry /><entry>or an existing transaction not yet</entry></row><row><entry /><entry /><entry>stopped)</entry></row><row><entry>WasIdle</entry><entry>1</entry><entry>The previous cycle had an IOMode</entry></row><row><entry /><entry /><entry>of IdleMode.</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><ul id="ul1104" list-style="none"><li id="ul1104-0001" num="0000"><ul id="ul1105" list-style="none"><li id="ul1105-0001" num="7316">In addition, the following externally visible outputs are generated asynchronously:</li></ul></li></ul>
7317<tables id="TABLE-US-00580" num="00580"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 374</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Externally visible asynchronous FEU outputs</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="168pt" align="left" /><tbody valign="top"><row><entry>Name</entry><entry>#bits</entry><entry>Description</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>Fetch</entry><entry>1</entry><entry>1 if the FEU is performing the final cycle of a fetch (i.e.</entry></row><row><entry /><entry /><entry>Cycle will also be 0). It is set when the NextCmd</entry></row><row><entry /><entry /><entry>output is valid. The local Cmd register is latched during</entry></row><row><entry /><entry /><entry>the Fetch cycle with either the incoming MIU8Data or</entry></row><row><entry /><entry /><entry>an FEU-generated command.</entry></row><row><entry>Exec</entry><entry>1</entry><entry>1 if the FEU is performing the final cycle of an execute</entry></row><row><entry /><entry /><entry>(i.e. Cycle will also be 1). It is set when the data</entry></row><row><entry /><entry /><entry>required by the opcode from the MIU is valid. Other</entry></row><row><entry /><entry /><entry>units can execute the Cmd and latch data from the</entry></row><row><entry /><entry /><entry>MIU (e.g. from MIUData) during the Exec cycle.</entry></row><row><entry>Cmd</entry><entry>8</entry><entry>When Cycle = 0, this holds the next instruction to be</entry></row><row><entry /><entry /><entry>executed (during the next Cycle = 1). Is generated</entry></row><row><entry /><entry /><entry>based on incoming MIU8Data or substituted FEU</entry></row><row><entry /><entry /><entry>command (e.g. JSR 0).</entry></row><row><entry /><entry /><entry>When Cycle = 1, this holds the current instruction</entry></row><row><entry /><entry /><entry>being executed (based on theCmd).</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7318The Cycle and currCmd registers are not used directly. Instead, their outputs are passed through a VAL unit before use. The VAL units are designed to validate the data that passes through them. Each contains an OK bit connected to both Tamper Prevention and Detection Lines. The OK bit is set to 1 on PORstL, and ORed with the ChipOK values from both Tamper Detection Lines each cycle. The OK bit is ANDed with each data bit that passes through the unit.
7319In the case of VAL<sub>1</sub>, the effective Cycle will always be 0 if the chip has been tampered with. Thus no program code will execute.
7320In the case of VAL<sub>2</sub>, the effective 8-bit currCmd value will always be 0 if the chip has been tampered with. Multiple 0s will be interpreted as the JSR 0 instruction, and this will effectively hang the CPU. VAL<sub>2 </sub>also performs a parity check on the bits from currCmd to ensure that currCmd has not been tampered with. If the parity check fails, the Erase Tamper Detection Line is triggered. For more information on Tamper Prevention and Detection circuitry, see Section 10.3.5 on page 962.
000013.2.1 Pseudocode
7321<tables id="TABLE-US-00581" num="00581"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>reset conditions:</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Fetch = 0</entry></row><row><entry /><entry>Exec = 0</entry></row><row><entry /><entry>Cycle <img file="US7165824B2_D0832.tif" /> 0</entry></row><row><entry /><entry>currCmd <img file="US7165824B2_D0833.tif" /> 0</entry></row><row><entry /><entry>Go <img file="US7165824B2_D0834.tif" /> 0</entry></row><row><entry /><entry>pendingKill <img file="US7165824B2_D0835.tif" /> 0</entry></row><row><entry /><entry>pendingStart <img file="US7165824B2_D0836.tif" /> 0</entry></row><row><entry /><entry>newMemTrans <img file="US7165824B2_D0837.tif" /> 0</entry></row><row><entry /><entry>wasIdle <img file="US7165824B2_D0838.tif" /> 1 # required to detect if IOU starts in a non-idle</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>state</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><ul id="ul1106" list-style="none"><li id="ul1106-0001" num="0000"><ul id="ul1107" list-style="none"><li id="ul1107-0001" num="7322">The cycle by cycle combinatorial logic behaviour is shown in the following pseudocode:</li></ul></li></ul>
7323<tables id="TABLE-US-00582" num="00582"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>isActive = (IOMode = ActiveMode)</entry></row><row><entry /><entry>wasIdle <img file="US7165824B2_D0839.tif" /> (IOMode = IdleMode)</entry></row><row><entry /><entry>wantToStart = (pendingStart <img file="US7165824B2_D0840.tif" /> wasIdle) <img file="US7165824B2_D0841.tif" /> isActive</entry></row><row><entry /><entry>newTrans = wantToStart <img file="US7165824B2_D0842.tif" /> <img file="US7165824B2_D0843.tif" /> Go <img file="US7165824B2_D0844.tif" /> MIUAvail</entry></row><row><entry /><entry>pendingStart <img file="US7165824B2_D0845.tif" /> wantToStart <img file="US7165824B2_D0846.tif" /> <img file="US7165824B2_D0847.tif" /> newTrans</entry></row><row><entry /><entry>killTrans = Go <img file="US7165824B2_D0848.tif" /> (<img file="US7165824B2_D0849.tif" /> isActive <img file="US7165824B2_D0850.tif" /> pendingKill)</entry></row><row><entry /><entry>Fetch = newTrans <img file="US7165824B2_D0851.tif" /> (Go <img file="US7165824B2_D0852.tif" /> <img file="US7165824B2_D0853.tif" /> Cycle <img file="US7165824B2_D0854.tif" /> MIURdy <img file="US7165824B2_D0855.tif" /> <img file="US7165824B2_D0856.tif" /> killTrans)</entry></row><row><entry /><entry>inDelay = (currCmd = ROR InByte) <img file="US7165824B2_D0857.tif" /> <img file="US7165824B2_D0858.tif" /> InByteValid</entry></row><row><entry /><entry>outDelay = (currCmd = ROR OutByte) <img file="US7165824B2_D0859.tif" /> OutByteValid</entry></row><row><entry /><entry>ioDelay = inDelay <img file="US7165824B2_D0860.tif" /> outDelay</entry></row><row><entry /><entry>Exec = Go <img file="US7165824B2_D0861.tif" /> Cycle <img file="US7165824B2_D0862.tif" /> MIURdy <img file="US7165824B2_D0863.tif" /> <img file="US7165824B2_D0864.tif" /> ioDelay</entry></row><row><entry /><entry>If (Cycle)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Cmd = currCmd</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ElseIf (newTrans)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Cmd = JPZ # jump to 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Cmd = MIU8Data</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>resetGo = (MIURdy <img file="US7165824B2_D0865.tif" /> killTrans) <img file="US7165824B2_D0866.tif" /> (Fetch <img file="US7165824B2_D0867.tif" /> (Cmd = HALT))</entry></row><row><entry /><entry>pendingKill <img file="US7165824B2_D0868.tif" /> killTrans <img file="US7165824B2_D0869.tif" /> <img file="US7165824B2_D0870.tif" /> resetGo</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="105pt" align="left" /><colspec colname="2" colwidth="98pt" align="left" /><tbody valign="top"><row><entry /><entry>changeCycle = Fetch <img file="US7165824B2_D0871.tif" /> Exec</entry><entry># will only be 1 when Go = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Cycle <img file="US7165824B2_D0872.tif" /> newTrans <img file="US7165824B2_D0873.tif" /> ((Cycle ⊕ changeCycle) <img file="US7165824B2_D0874.tif" /> <img file="US7165824B2_D0875.tif" /> resetGo)</entry></row><row><entry /><entry>newMemTrans <img file="US7165824B2_D0876.tif" /> newTrans <img file="US7165824B2_D0877.tif" /> (changeCycle <img file="US7165824B2_D0878.tif" /> <img file="US7165824B2_D0879.tif" /> resetGo)</entry></row><row><entry /><entry>If (Fetch)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>currCmd <img file="US7165824B2_D0880.tif" /> Cmd</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>If (resetGo)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Go <img file="US7165824B2_D0881.tif" /> 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ElseIf (newTrans)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Go <img file="US7165824B2_D0882.tif" /> 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 14 ALU
7324The Arithmetic Logic Unit (ALU) contains a 32-bit Acc (Accumulator) register as well as the circuitry for simple arithmetic and logical operations.
7325The logic and registers contained in the ALU must be covered by both Tamper Detection Lines. This is to ensure that keys and intermediate calculation values cannot be changed by an attacker. In addition, the Accumulator must be parity-checked.
7326A 1-bit Z signal represents the state of zero-ness of the Accumulator. The Accumulator is cleared to 0 upon a RstL, and the Z signal is set to 1. The Accumulator is updated for any of the commands: AND, OR, XOR, ADD, ROR, and RIA, and the Z signal is updated whenever the Accumulator is updated. Note that the Z signal is actually implemented as a nonZ register whose output is passed through an inverter and used as Z.
7327Each arithmetic and logical block operates on two 32-bit inputs: the current value of the Accumulator, and the current 32-bit output of the DataSel block (either the 32 bit value from MIUData or an immediate value). The AND, OR, XOR and ADD blocks perform the standard 32-bit operations. The remaining blocks are outlined below.
7328<figref idref="DRAWINGS">FIG. 399</figref> shows a block diagram of the ALU:
7329The Accumulator is updated for all instructions where the high bit of the opcode is set:
7330<tables id="TABLE-US-00583" num="00583"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="98pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>Logic<sub>1</sub></entry><entry>Exec <img file="US7165824B2_D0883.tif" /> Cmd<sub>7</sub></entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7331Since the WriteEnables of Acc and nonZ takes Cmd7 and Exec into account (due to Logic<sub>1</sub>), these two bits are not required by the multiplexor MX<sub>1 </sub>in order to select the output. The output selection for MX<sub>1 </sub>only requires bits <b>6</b>–<b>3</b> of the Cmd and is therefore simpler as a result (as shown in Table 375).
7332<tables id="TABLE-US-00584" num="00584"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 375</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Selection for multiplexor MX<sub>1</sub></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry>Output</entry><entry>Cmd<sub>6−3</sub></entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="56pt" align="left" /><colspec colname="3" colwidth="105pt" align="left" /><tbody valign="top"><row><entry /><entry>MX<sub>1</sub></entry><entry>immOut</entry><entry>011x <img file="US7165824B2_D0884.tif" /> 1110 (LD)</entry></row><row><entry /><entry /><entry>rorOut</entry><entry>100x <img file="US7165824B2_D0885.tif" /> 1111 (RIA, ROR)</entry></row><row><entry /><entry /><entry>from XOR</entry><entry>001x <img file="US7165824B2_D0886.tif" /> 1100 (XOR)</entry></row><row><entry /><entry /><entry>from ADD</entry><entry>010x <img file="US7165824B2_D0887.tif" /> 1101 (ADD)</entry></row><row><entry /><entry /><entry>from AND</entry><entry>0000 <img file="US7165824B2_D0888.tif" /> 1010 (AND)</entry></row><row><entry /><entry /><entry>from OR</entry><entry>0001 <img file="US7165824B2_D0889.tif" /> 1011 (OR)</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7333The two VAL units are validation units connected to the Tamper Prevention and Detection circuitry (described in Section 10.3.5 on page 962), each with an OK bit. The OK bit is set to 1 on PORstL, and ORed with the ChipOK values from both Tamper Detection Lines each cycle. The OK bit is ANDed with each data bit that passes through the unit.
7334In the case of VAL<sub>1</sub>, the effective bit output from the Accumulator will always be 0 if the chip has been tampered with. This prevents an attacker from processing anything involving the Accumulator. VAL<sub>1 </sub>also performs a parity check on the Accumulator, setting the Erase Tamper Detection Line if the check fails.
7335In the case of VAL<sub>2</sub>, the effective Z status of the Accumulator will always be true if the chip has been tampered with. Thus no looping constructs can be created by an attacker.
000014.1 DataSel Block
7336The DataSel block is designed to implement the selection between the MIU32Data and the immediate addressing mode for logical commands.
7337Immediate addressing relies on 3 bits of operand, plus an optional 8 bits at PC+1 to determine an 8-bit base value. Bits <b>0</b> to <b>1</b> determine whether the base value comes from the opcode byte itself, or from PC+1, as shown in Table 376.
7338<tables id="TABLE-US-00585" num="00585"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 376</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Selection for base value in immediate mode</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="84pt" align="center" /><colspec colname="2" colwidth="133pt" align="left" /><tbody valign="top"><row><entry>Cmd<sub>1−0</sub></entry><entry>Base value</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>00</entry><entry>00000000</entry></row><row><entry>01</entry><entry>00000001</entry></row><row><entry>10</entry><entry>From PC + 1 (i.e. MIUData<sub>31−24</sub>)</entry></row><row><entry>11</entry><entry>11111111</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7339The base value is computed by using CMD<sub>0 </sub>as bit <b>0</b>, and copying CMD<sub>1 </sub>into the upper 7 bits.
7340The 8-bit base value forms the lower 8 bits of output. These 8 bits are also ANDed with the sense of whether the data is replicated in the upper bits or not (i.e. CMD<sub>2</sub>). The resultant bits are copied in 3 times to form the upper 24 bits of the output.
7341<figref idref="DRAWINGS">FIG. 400</figref> shows a block diagram of the ALU's DataSel block:
000014.2 ROR Block
7342The ROR block implements the ROR and RIA functionality of the ALU.
7343A 1-bit register named RTMP is contained within the ROR unit. RTMP is cleared to 0 on a RstL, and set during the ROR RB and ROR XRB commands. The RTMP register allows implementation of Linear Feedback Shift Registers with any tap configuration.
7344<figref idref="DRAWINGS">FIG. 401</figref> shows a block diagram of the ALU's ROR block:
7345The ROR n, blocks are shown for clarity, but in fact would be hardwired into multiplexor MX<sub>3</sub>, since each block is simply a rewiring of the 32-bits, rotated right n bits.
7346Logic<sub>1 </sub>is used to provide the WriteEnable signal to RTMP. The RTMP register should only be written to during ROR RB and ROR XRB commands. The combinatorial logic block is:
7347<tables id="TABLE-US-00586" num="00586"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="154pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>Logic<sub>1</sub></entry><entry>Exec <img file="US7165824B2_D0890.tif" /> (Cmd<sub>7−4 </sub>= ROR) <img file="US7165824B2_D0891.tif" /> (Cmd<sub>3−1 </sub>= 000)</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7348Multiplexor MX<sub>1 </sub>performs the task of selecting the 6-bit value from Cn instead of bits <b>13</b>–<b>8</b> (6 bits) from Acc (the selection is based on the value of Logic<sub>2</sub>). Bit 5 is required to distinguish ROR from RIA.
7349<tables id="TABLE-US-00587" num="00587"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="98pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>Logic<sub>2</sub></entry><entry>Cmd<sub>5−2 </sub>= 0x10</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7350<tables id="TABLE-US-00588" num="00588"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 377</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Selection for multiplexor MX<sub>1</sub></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="91pt" align="left" /><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="98pt" align="center" /><tbody valign="top"><row><entry /><entry>Output</entry><entry>Logic<sub>2</sub></entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="28pt" align="left" /><colspec colname="3" colwidth="98pt" align="center" /><tbody valign="top"><row><entry /><entry>MX<sub>1</sub></entry><entry>Cn</entry><entry>1</entry></row><row><entry /><entry /><entry>Acc<sub>13−8</sub></entry><entry>0</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7351Multiplexor MX<sub>2 </sub>performs the task of selecting the 8-bit value from InByte instead of the lower 8 bits from the ANDed Acc based on the CMD.
7352<tables id="TABLE-US-00589" num="00589"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 378</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Selection for multiplexor MX<sub>2</sub></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="84pt" align="left" /><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="70pt" align="left" /><tbody valign="top"><row><entry /><entry>Output</entry><entry>Cmd<sub>4−0</sub></entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="63pt" align="left" /><colspec colname="3" colwidth="70pt" align="left" /><tbody valign="top"><row><entry /><entry>MX<sub>2</sub></entry><entry>InByte</entry><entry>0x110</entry></row><row><entry /><entry /><entry>Acc<sub>7−0</sub></entry><entry><img file="US7165824B2_D0892.tif" /> (0x110)</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7353Multiplexor MX<sub>3 </sub>does the final rotating of the 32-bit value. The bit patterns of the CMD operand are taken advantage of:
7354<tables id="TABLE-US-00590" num="00590"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 379</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Selection for multiplexor MX<sub>3</sub></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry>Output</entry><entry>Cmd<sub>3−0</sub></entry><entry>Comments</entry></row><row><entry /><entry namest="offset" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="5"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="42pt" align="left" /><colspec colname="3" colwidth="42pt" align="left" /><colspec colname="4" colwidth="91pt" align="left" /><tbody valign="top"><row><entry /><entry>MX<sub>3</sub></entry><entry>ROR 1</entry><entry>00xx</entry><entry>RB, XRB, WriteMask, 1</entry></row><row><entry /><entry /><entry>ROR 3</entry><entry>010x</entry><entry> 3</entry></row><row><entry /><entry /><entry>ROR 31</entry><entry>0110</entry><entry>31</entry></row><row><entry /><entry /><entry>ROR 24</entry><entry>0111</entry><entry>24</entry></row><row><entry /><entry /><entry>ROR 8</entry><entry>1xxx</entry><entry>RIA, InByte, 8,</entry></row><row><entry /><entry /><entry /><entry /><entry>OutByte, C1, C2, ID</entry></row><row><entry /><entry namest="offset" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 14.3 IO Block
7355The IO block within the ALU implements the logic for communicating with the IOU during instructions that involve the Accumulator. This includes generating appropriate control signals and for generating the correct data for sending during writes to the IOU's OutByte and LocalId registers.
7356<figref idref="DRAWINGS">FIG. 402</figref> shows a block diagram of the IO block:
7357Logic<sub>1 </sub>is used to provide the LocalIdWE signal to the IOU. The localId register should only be written to during the ROR ID command. Only the lower 7 bits of the Accumulator are written to the localId register.
7358Logic<sub>2 </sub>is used to provide the ALUOutByteWE signal to the IOU. The OutByte register should only be written to during the ROR OutByte command. Only the lower 8 bits of the Accumulator are written to the OutByte register.
7359In both cases we output the lower 8 bits of the Accumulator. The ALUIOData value is ANDed with the output of Logic<sub>2 </sub>to ensure that ALUIOData is only valid when it is safe to do so (thus the IOU logic never sees the key passing by in ALUIOData). The combinatorial logic blocks are:
7360<tables id="TABLE-US-00591" num="00591"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="133pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>Logic<sub>1</sub></entry><entry>Exec <img file="US7165824B2_D0893.tif" /> (Cmd<sub>7−0 </sub>= ROR ID)</entry></row><row><entry /><entry>Logic<sub>2</sub></entry><entry>Exec <img file="US7165824B2_D0894.tif" /> (Cmd<sub>7−0 </sub>= ROR OutByte)</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><ul id="ul1108" list-style="none"><li id="ul1108-0001" num="0000"><ul id="ul1109" list-style="none"><li id="ul1109-0001" num="7361">Logic<sub>3 </sub>is used to provide the ALUInByteUsed signal to the IOU. The InByte is only used during the ROR InByte command. The combinatorial logic is:</li></ul></li></ul>
7362<tables id="TABLE-US-00592" num="00592"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="126pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>Logic<sub>3</sub></entry><entry>Exec <img file="US7165824B2_D0895.tif" /> (Cmd<sub>7−0 </sub>= ROR InByte)</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 15 Program Counter Unit
7363The Program Counter Unit (PCU) includes the 12 bit PC (Program Counter), as well as logic for branching and subroutine control.
7364The PCU latches need to be parity-checked. In addition, the logic and registers contained in the PCU must be covered by both Tamper Detection Lines to ensure that the PC cannot be changed by an attacker.
7365The PC is implemented as a 12 entry by 12-bit PCA (PC Array), indexed by a 4-bit SP (Stack Pointer) register. The PC, PCRamSel and SP registers are all cleared to 0 on a RstL, and updated during the flow of program control according to the opcodes.
7366The current value for the PC is normally updated during the Execute cycle according to the command being executed. However it is also incremented by 1 during the Fetch cycle for two byte instructions such as JMP, JSR, DBR, TBR, and instructions that require an additional byte for immediate addressing. The mechanism for calculating the new PC value depends upon the opcode being processed.
7367<figref idref="DRAWINGS">FIG. 403</figref> shows a block diagram of the PCU:
7368The ADD block is a simple adder modulo 2<sup>12 </sup>with two inputs: an unsigned 12 bit number and an 8-bit signed number (high bit=sign). The signed input is either a constant of 0x01, or an 8-bit offset (the 8 bits from the MIU).
7369The “+1.” block takes a 4-bit input and increments it by 1 (modulo 12). The “−1.” block takes a 4-bit input and decrements it by 1 (modulo 12).
7370Table 380 lists the different forms of PC control:
7371<tables id="TABLE-US-00593" num="00593"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 381</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Different forms of PC control during the Exec cycle</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="35pt" align="left" /><colspec colname="2" colwidth="182pt" align="left" /><tbody valign="top"><row><entry>Command</entry><entry>Action</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>JMP</entry><entry>The PC is loaded with the current 12-bit value as</entry></row><row><entry /><entry>passed in from the MIU.</entry></row><row><entry>JPI</entry><entry>The PC is loaded with the current 12-bit value as</entry></row><row><entry /><entry>passed in from the Acc.</entry></row><row><entry /><entry>PCRamSel is loaded with the value from bit 15 of</entry></row><row><entry /><entry>the Acc.</entry></row><row><entry>JPZ</entry><entry>The PC is loaded with 0. PCRamSel is loaded with 0</entry></row><row><entry /><entry>(program in flash)</entry></row><row><entry>JSZ</entry><entry>Save old value of PC onto stack for later. The PC is</entry></row><row><entry /><entry>loaded with 0. PCRamSel is loaded with 0</entry></row><row><entry /><entry>(program in flash).</entry></row><row><entry>JSR, JSI</entry><entry>Save old value of PC onto stack for later. The PC is</entry></row><row><entry /><entry>loaded with the current 12-bit value as passed in</entry></row><row><entry /><entry>from either the MIU or the Acc. With JSI, PCRamSel</entry></row><row><entry /><entry>is loaded from the value in bit 15 of the Accumulator.</entry></row><row><entry>RTS</entry><entry>Pop old value of PC from stack and increment by 1</entry></row><row><entry /><entry>to get new PC.</entry></row><row><entry>TBR</entry><entry>If the Z flag matches the TBR test, add 8-bit signed</entry></row><row><entry /><entry>number (MIU8Data) to current PC. Otherwise increment</entry></row><row><entry /><entry>current PC by 1.</entry></row><row><entry>DBR</entry><entry>If the CZ flag is set, add 8-bit signed offset (MIU8Data)</entry></row><row><entry /><entry>to current PC. Otherwise increment current PC by 1.</entry></row><row><entry>All others</entry><entry>Increment current PC by 1</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7372The updating of PCRamSel only occurs during JPI, JSI, JPZ and JSZ instructions, detected via Logic<sub>0</sub>.
7373The same action for the Exec takes place for JMP, JSR, JPI, JSI, JPZ and JSZ, so we specifically detect that case in Logic<sub>1</sub>. In the same way, we test for the RTS case in Logic<sub>2</sub>.
7374<tables id="TABLE-US-00594" num="00594"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="112pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>Logic<sub>0</sub></entry><entry>Cmd<sub>7−1 </sub>= 011x001</entry></row><row><entry /><entry>Logic<sub>1</sub></entry><entry>(Cmd<sub>7−5 </sub>= 000) <img file="US7165824B2_D0896.tif" /> Logic<sub>0</sub></entry></row><row><entry /><entry>Logic<sub>2</sub></entry><entry>Cmd<sub>7−0 </sub>= RTS</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7375When updating the PC, we must decide if the PC is to be replaced by a completely new value (as in the case of the JMP, JSR, JPI, JSI, JPZ and JSZ instructions), or by the result of the adder (all other instructions). The output from Logic<sub>1 </sub>ANDed with Cycle can therefore be safely used by the multiplexor to obtain the new PC value (we need to always select PC+1 when Cycle is 0, even though we don't always write it to the PCA).
7376Note that the JPZ and JSZ instructions are implemented as 12 AND gates that cause the Accumulator value to be ignored, and the new PC to be set to 0. Likewise, the PCRamSel bit is cleared via these two instructions using the same AND mechanism.
7377The input to the 12-bit adder depends on whether we are incrementing by 1 (the usual case), or adding the offset as read from the MIU (when a branch is taken by the DBR and TBR instructions). Logic<sub>3 </sub>generates the test.
7378<tables id="TABLE-US-00595" num="00595"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="140pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>Logic<sub>3</sub></entry><entry>Cycle <img file="US7165824B2_D0897.tif" /> (((Cmd<sub>7−4 </sub>= DBR) <img file="US7165824B2_D0898.tif" /> <img file="US7165824B2_D0899.tif" /> CZ) <img file="US7165824B2_D0900.tif" /></entry></row><row><entry /><entry /><entry>((Cmd<sub>7−4 </sub>= TBR) <img file="US7165824B2_D0901.tif" /> (Cmd<sub>0 </sub>⊕ Z)))</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7379The actual offset to be added in the case of the DBR and TBR instructions is either the 8-bit value read from the MIU, or an 8-bit value generated by bits <b>3</b>–<b>1</b> of the opcode and treating bit <b>4</b> of the opcode as the sign (thereby making DBR immediate branching negative, and TBR immediate branching positive). The former is selected when bits <b>3</b>–<b>1</b> of the opcode is 0, as shown by Logic<sub>4</sub>.
7380<tables id="TABLE-US-00596" num="00596"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="189pt" align="left" /><thead><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>Logic<sub>4</sub></entry><entry>If (Cmd<sub>3−1 </sub>= 000) output MIU8Data</entry></row><row><entry /><entry>Else output Cmd<sub>4 </sub>| Cmd<sub>4 </sub>| Cmd<sub>4 </sub>| Cmd<sub>4 </sub>| Cmd<sub>4 </sub>| Cmd<sub>3−1</sub></entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7381Finally, the selection of which PC entry to use depends on the current value for SP. As we enter a subroutine, the SP index value must increment, and as we return from a subroutine, the SP index value must decrement. Logic<sub>1 </sub>tells us when a subroutine is being entered, and Logic<sub>2 </sub>tells us when the subroutine is being returned from. We use Logic<sub>2 </sub>to select the altered SP value, but only write to the SP register when Exec and Cmd<sub>4 </sub>are also set (to prevent JMP and JPZ from adjusting SP).
7382The two VAL units are validation units connected to the Tamper Prevention and Detection circuitry (described in Section 10.3.5 on page 962), each with an OK bit. The OK bit is set to 1 on PORstL, and ORed with the ChipOK values from both Tamper Detection Lines each cycle. The OK bit is ANDed with each data bit that passes through the unit. Both VAL units also parity-check the data bits to ensure that they are valid. If the parity-check fails, the Erase Tamper Detection Line is triggered.
7383In the case of VAL<sub>1</sub>, the effective output from the SP register will always be 0. If the chip has been tampered with. This prevents an attacker from executing any subroutines.
7384In the case of VAL<sub>2</sub>, the effective PC output will always be 0 if the chip has been tampered with. This prevents an attacker from executing any program code.
000016 Address Generator Unit
7385The Address Generator Unit (AGU) generates effective addresses for accessing the Memory Unit (MU). In Cycle 0, the PC is passed through to the MU in order to fetch the next opcode. The AGU interprets the returned opcode in order to generate the effective address for Cycle 1. In Cycle 1, the generated address is passed to the MU.
7386The logic and registers contained in the AGU must be covered by both Tamper Detection Lines. This is to ensure that an attacker cannot alter any generated address. The latches for the counters and calculated address should also be parity-checked.
7387If either of the Tamper Detection Lines is broken, the AGU will generate address 0 each cycle and all counters will be fixed at 0. This will only come into effect if an attacker has disabled the RESET and/or erase circuitry, since under normal circumstances, breaking a Tamper Detection Line will result in a RESET or the erasure of all Flash memory.
000016.1 Implementation
7388The block diagram for the AGU is shown in <figref idref="DRAWINGS">FIG. 404</figref>:
7389The accessMode and WriteMask registers must be cleared to 0 on reset to ensure that no access to memory occurs at startup of the CPU.
7390The Adr and accessMode registers are written to during the final cycle of cycle 0 (Fetch) and cycle 1 (Exec) with the address to use during the following cycle phase. For example, when cycle=1, the PC is selected so that it can be written to Adr during Exec. During cycle 0, while the PC is being output from Adr, the address to be used in the following cycle 1 is calculated (based on the fetched opcode seen as Cmd) and finally stored in Adr when Fetch is 1. The accessMode register is also updated in the same way.
7391It is important to distinguish between the value of Cmd during different values for Cycle: <ul id="ul1110" list-style="none"><li id="ul1110-0001" num="0000"><ul id="ul1111" list-style="none"><li id="ul1111-0001" num="7392">During Cycle 0, when Fetch is 1, the 8-bit input Cmd holds the instruction to be executed in the following Cycle 1. This 8-bit value is used to decode the effective address for the operand of the instruction.</li><li id="ul1111-0002" num="7393">During Cycle 1, when Exec is 1, Cmd holds the currently executing instruction.</li></ul></li></ul>
7394The WriteMask register is only ever written to during execution of an appropriate ROR instruction. Logic<sub>1 </sub>sets the WriteMask and MMR WriteEnables respectively based on this condition:
7395<tables id="TABLE-US-00597" num="00597"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="140pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>Logic<sub>1</sub></entry><entry>Exec <img file="US7165824B2_D0902.tif" /> (Cmd<sub>7−0 </sub>= ROR WriteMask)</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7396The data written to the WriteMask register is the lower 8 bits of the Accumulator.
7397The Address Register Unit is only updated by an RIA or LIA instruction, so the writeEnable is generated by Logic<sub>2 </sub>as follows:
7398<tables id="TABLE-US-00598" num="00598"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="112pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>Logic<sub>2</sub></entry><entry>Exec <img file="US7165824B2_D0903.tif" /> (Cmd<sub>6−3 </sub>= 1111)</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7399The Counter Unit (CU) generates counters C1, C2 and the selected N index. In addition, the CU outputs a CZ flag for use by the PCU. The CU is described in more detail below.
7400The VAL<sub>1 </sub>unit is a validation unit connected to the Tamper Prevention and Detection circuitry (described in Section 10.3.5 on page 962). It contains an OK bit that is set to 1 on PORstL, and ORed with the ChipOK values from both Tamper Detection Lines each cycle. The OK bit is ANDed with the 12 bits of Adr before they can be used. If the chip has been tampered with, the address output will be always 0, thereby preventing an attacker from accessing other parts of memory. The VAL<sub>1 </sub>unit also performs a parity check on the Adr Address bits to ensure it has not been tampered with. If the parity-check fails, the Erase Tamper Detection Line is triggered.
000016.1.1 Counter Unit
7401The Counter Unit (CU) generates counters C1 and C2 (used internally). In addition, the CU outputs Cn and flag CZ for use externally. The block diagram for the CU is shown in <figref idref="DRAWINGS">FIG. 405</figref>: Registers C1 and C2 are updated when they are the targets of a DBR, SC or ROR instruction. Logic<sub>1 </sub>generates the control signals for the write enables as shown in the following pseudocode.
7402<tables id="TABLE-US-00599" num="00599"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>isDbrSc = (Cmd<sub>7−4 </sub>= DBR) <img file="US7165824B2_D0904.tif" /> (Cmd<sub>7−4 </sub>= SC)</entry></row><row><entry /><entry>isRorCn = (Cmd<sub>7−4 </sub>= ROR) <img file="US7165824B2_D0905.tif" /> (Cmd<sub>3−2 </sub>= 10)</entry></row><row><entry /><entry>CnWE = Exec <img file="US7165824B2_D0906.tif" /> (isDbrSc <img file="US7165824B2_D0907.tif" /> isRorCn)</entry></row><row><entry /><entry>C1we = CnWE <img file="US7165824B2_D0908.tif" /> <img file="US7165824B2_D0909.tif" /> Cmd<sub>0</sub></entry></row><row><entry /><entry>C2we = CnWE <img file="US7165824B2_D0910.tif" /> Cmd<sub>0</sub></entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><ul id="ul1112" list-style="none"><li id="ul1112-0001" num="0000"><ul id="ul1113" list-style="none"><li id="ul1113-0001" num="7403">The single bit flag CZ is produced by the NOR of the appropriate C1 or C2 register for use during a DBR instruction. Thus CZ is 1 if the appropriate Cn value=0.</li></ul></li></ul>
7404The actual value written to C1 or C2 depends on whether the ROR, DBR or SC instruction is being executed. During a DBR instruction, the value of either C1 or C2 is decremented by 1 (with wrap). One multiplexor selects between the lower 6 bits of the Accumulator (for ROR instructions), and a 6-bit value for an SC instruction where the upper 3 bits=the low 3 bits from C2, and low 3 bits=low 3 bits from Cmd. Note that only the lowest 3 bits of the operand are written to C1.
7405The two VAL units are validation units connected to the Tamper Prevention and Detection circuitry (described in Section 10.3.5 on page 962), each with an OK bit. The OK bit is set to 1 on PORstL, and ORed with the ChipOK values from both Tamper Detection Lines each cycle. The OK bit is ANDed with each data bit that passes through the unit. All VAL units also parity check the data to ensure the counters have not been tampered with. If a parity check fails, the Erase Tamper Detection Line is triggered.
7406In the case of VAL<sub>1</sub>, the effective output from the counter C1 will always be 0 if the chip has been tampered with. This prevents an attacker from executing any looping constructs.
7407In the case of VAL<sub>2</sub>, the effective output from the counter C2 will always be 0 if the chip has been tampered with. This prevents an attacker from executing any looping constructs.
000016.1.2 Calculate Next Address
7408This unit generates the address of the operand for the next instruction to be executed. It makes use of the Address Register Unit and PC to obtain base addresses, and the counters from the Counter Unit to assist in generating offsets from the base address.
7409This unit consists of some simple combinatorial logic, including an adder that adds a 6-bit number to a 10-bit number. The logic is shown in the following pseudocode.
7410<tables id="TABLE-US-00600" num="00600"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>isErase = (Cmd<sub>7−0 </sub>= ERA)</entry></row><row><entry>isSt = (Cmd<sub>7−4 </sub>= ST)</entry></row><row><entry>isAccRead = (Cmd<sub>7−6 </sub>= 10)</entry></row><row><entry># First determine whether this is an immediate mode requiring PC+1</entry></row><row><entry>isJmpJsrDbrTbrImmed = (Cmd<sub>7−6 </sub>= 00) <img file="US7165824B2_D0911.tif" /> (<img file="US7165824B2_D0912.tif" /> Cmd<sub>5 </sub><img file="US7165824B2_D0913.tif" /> (Cmd<sub>5−1 </sub>= 1x000))</entry></row><row><entry>isLia = (Cmd<sub>7−3 </sub>= LIA)</entry></row><row><entry>isLogImmed = ((Cmd<sub>7−6 </sub>= 11) <img file="US7165824B2_D0914.tif" /> ((Cmd<sub>5 </sub><img file="US7165824B2_D0915.tif" /> Cmd<sub>4</sub>) <img file="US7165824B2_D0916.tif" /> (Cmd<sub>5−3 </sub>≠ 111))) <img file="US7165824B2_D0917.tif" /></entry></row><row><entry>(Cmd<sub>1−0 </sub>= 10)</entry></row><row><entry>pcSel = Cycle <img file="US7165824B2_D0918.tif" /> (<img file="US7165824B2_D0919.tif" /> Cycle <img file="US7165824B2_D0920.tif" /> (isJmpJsrDbrTbrImmed <img file="US7165824B2_D0921.tif" /> isLogImmed <img file="US7165824B2_D0922.tif" /> isLia))</entry></row><row><entry># Generate AnSel signal for the Address Register Unit</entry></row><row><entry>A0Sel = (isAccRead <img file="US7165824B2_D0923.tif" /> isSt) <img file="US7165824B2_D0924.tif" /> (<img file="US7165824B2_D0925.tif" /> Cmd<sub>3 </sub><img file="US7165824B2_D0926.tif" /> (Cmd<sub>5−3 </sub>= 001))</entry></row><row><entry>AnSel<sub>1−0 </sub>= <img file="US7165824B2_D0927.tif" /> A0Sel <img file="US7165824B2_D0928.tif" /> Cmd<sub>2−1</sub></entry></row><row><entry># The next address is either the new PC or must be generated</entry></row><row><entry># (we require the base address from Address Register Unit)</entry></row><row><entry>nextRAMSel = AnDataOut<sub>8 </sub><img file="US7165824B2_D0929.tif" /> <img file="US7165824B2_D0930.tif" /> isErase</entry></row><row><entry>If (nextRAMSel)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>baseAdr = 00 | AnDataOut<sub>7−0 </sub># ram addresses are already word</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>aligned</entry></row><row><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>baseAdr = AnDataOut<sub>7−0 </sub>| 00 # flash addresses are 4-byte aligned</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry># Base address is now word (4-byte) aligned</entry></row><row><entry># Now generate the offset amount to be added to the base address</entry></row><row><entry>selCn = (isAccRead <img file="US7165824B2_D0931.tif" /> isSt) <img file="US7165824B2_D0932.tif" /> (Cmd<sub>5 </sub><img file="US7165824B2_D0933.tif" /> Cmd<sub>4</sub>) <img file="US7165824B2_D0934.tif" /> Cmd<sub>3</sub></entry></row><row><entry>offset<sub>0 </sub>= (A0Sel <img file="US7165824B2_D0935.tif" /> Cmd<sub>0</sub>) <img file="US7165824B2_D0936.tif" /> (selCn <img file="US7165824B2_D0937.tif" /> Cn<sub>0</sub>)</entry></row><row><entry>offset<sub>1 </sub>= (A0Sel <img file="US7165824B2_D0938.tif" /> Cmd<sub>1</sub>) <img file="US7165824B2_D0939.tif" /> (selCn <img file="US7165824B2_D0940.tif" /> Cn<sub>1</sub>)</entry></row><row><entry>offset<sub>2 </sub>= (A0Sel <img file="US7165824B2_D0941.tif" /> Cmd<sub>2</sub>) <img file="US7165824B2_D0942.tif" /> (selCn <img file="US7165824B2_D0943.tif" /> Cn<sub>2</sub>)</entry></row><row><entry>offset<sub>5−3 </sub>= selCn <img file="US7165824B2_D0944.tif" /> Cn<sub>5−3</sub></entry></row><row><entry>If (isErase)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>nextEffAdr<sub>11−4 </sub>= Acc<sub>7−0</sub></entry></row><row><entry /><entry>nextEffAdr<sub>3−0 </sub>= don't care</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry># now we can simply add the offset to the base address to get</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>the effective adr</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>nextEffAdr<sub>11−2 </sub>= baseAdr + offset # 10 bit plus 6 bit, with wrap</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>= 10 bits out</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>nextEffAdr<sub>1−0 </sub>= 0 # word access, so lower bits of effadr are 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry># Now generate the various signals for use during Cycle=1</entry></row><row><entry># Note that these are only valid when pcSel is 0 (otherwise will</entry></row><row><entry>read PC)</entry></row><row><entry>nextAccessMode<sub>0 </sub>= 1 # want 32-bit access</entry></row><row><entry>nextAccessMode<sub>1 </sub>= nextRAMSel # ram or flash access (only valid if</entry></row><row><entry>rd/wr/erase set)</entry></row><row><entry>nextAccessMode<sub>2 </sub>= isAccRead # pcSel takes care of LIA instruction</entry></row><row><entry>nextAccessMode<sub>3 </sub>= isSt # write access</entry></row><row><entry>nextAccessMode<sub>4 </sub>= isErase # erase page access</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 16.1.3 Address Register Unit
7411This unit contains 4×9-bit registers that are optionally cleared to 0 on PORstL. The 2-bit input AnSel selects which of the 4 registers to output on DataOut. When the writeEnable is set, the AnSel selects which of the 4 registers is written to with the 9-bit DataIn.
000017 Program Mode Unit
7412The Program Mode Unit (PMU) is responsible for Program Mode and Trim Mode operations: <ul id="ul1114" list-style="none"><li id="ul1114-0001" num="0000"><ul id="ul1115" list-style="none"><li id="ul1115-0001" num="7413">Program Mode involves erasing the existing flash memory and loading the new program/data into the flash. The program that is loaded can be a bootstrap program if desired, and may contain additional program code to produce a digital signature of the final program to verify that the program was written correctly (e.g. by producing a SHA-1 signature of the entire flash memory).</li><li id="ul1115-0002" num="7414">Trim Mode involves counting the number of internal cycles that have elapsed between the entry of Trim Mode (at the falling edge of the ack) and the receipt of the next byte (at the falling edge of the last bit before the ack) from the Master. When the byte is received, the current count value divided by 2 is transmitted to the Master.</li></ul></li></ul>
7415The PMU relies on a fuse (implemented as the value of word 0 of the flash information block) to determine whether it is allowed to perform Program Mode operations. The purpose of this fuse is to prevent easy (or accidental) reprogramming of QA Chips once their purpose has been set. For example, an attacker may want to reuse chips from old consumables. If an attacker somehow bypasses the fuse check, the PMU will still erase all of flash before storing the desired program. Even if the attacker somehow disconnects the erasure logic, they will be unable to store a program in the flash due to the shadow nybbles.
7416The PMU contains an 8-bit buff register that is used to hold the byte being written to flash and a 12-bit adr register that is used to hold the byte address currently being written to.
7417The PMU is also used to load word 1 of the information block into a 32-bit register (combined from 8-bits of buff, 12-bits of adr, and a further 12-bit register) so it can be used to XOR all data to and from memory (both Flash and RAM) for future CPU accesses. This logic is activated only when the chip enters ActiveMode (so as not to access flash and possibly cause an erasure directly after manufacture since shadows will not be correct). The logic and 32-bit mask register is in the PMU to minimize chip area.
7418The PMU therefore has an asymmetric access to flash memory: <ul id="ul1116" list-style="none"><li id="ul1116-0001" num="0000"><ul id="ul1117" list-style="none"><li id="ul1117-0001" num="7419">writes are to main memory</li><li id="ul1117-0002" num="7420">reads are from information block memory</li></ul></li></ul>
7421The reads and writes are automatically directed appropriately in the MRU.
7422A block diagram of the PMU is shown in <figref idref="DRAWINGS">FIG. 406</figref>.
000017.1 Local Storage and Counters
7423The PMU keeps a 1-cycle delayed version of MRURdy, called prevMRURdy. It is used to generate PMNewTrans. Therefore each cycle the PMU performs the following task: <ul id="ul1118" list-style="none"><li id="ul1118-0001" num="0000"><ul id="ul1119" list-style="none"><li id="ul1119-0001" num="7424">prevMRURdy←MRURdy v (state=loadByte)</li></ul></li></ul>
7425The PMU also requires 1-bit maskLoaded, idlePending and idlePending registers, all of which are cleared to 0 on RstL. The 1-bit fuseBlown register is set to 1 on RstL for security.
000017.2 State Machine
0000<ul id="ul1120" list-style="none"><li id="ul1120-0001" num="0000"><ul id="ul1121" list-style="none"><li id="ul1121-0001" num="7426">The state machine for the PMU is shown in <figref idref="DRAWINGS">FIG. 407</figref>, with the pseudocode for the various states outlined below.</li></ul></li></ul>
7427<tables id="TABLE-US-00601" num="00601"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>rstl</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>prevMRURdy, maskLoaded, idlePending, adr <img file="US7165824B2_D0945.tif" /> 0 #clear most regs</entry></row><row><entry /><entry>fuseBlown <img file="US7165824B2_D0946.tif" /> 1 # for security sake assume the worst</entry></row><row><entry /><entry>state <img file="US7165824B2_D0947.tif" /> idle</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><ul id="ul1122" list-style="none"><li id="ul1122-0001" num="0000"><ul id="ul1123" list-style="none"><li id="ul1123-0001" num="7428">The idle state, entered after reset, simply waits for the IOMode to enter ProgramMode, ActiveMode, or TrimMode. Note that the reset value for fuseBlown means that ProgramMode and TrimMode cannot be entered until after a successful entry into ActiveMode that also clears the fuseBlown register. In state idle, PMEn=<img file="US7165824B2_D0948.tif" />maskLoaded, and in state wait4Mode PMEn=0. In all other states, PMEn=1.</li></ul></li></ul>
7429<tables id="TABLE-US-00602" num="00602"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>idle</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>idlePending <img file="US7165824B2_D0949.tif" /> 0</entry></row><row><entry /><entry>PMEn = <img file="US7165824B2_D0950.tif" /> imaskLoaded</entry></row><row><entry /><entry>PMNewTrans = 0</entry></row><row><entry /><entry>If ((IOMode = ActiveMode) <img file="US7165824B2_D0951.tif" /> MRURdy)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>If (maskLoaded)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0952.tif" /> wait4mode # no need to reload mask</entry></row><row><entry /><entry>once loaded</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>adr <img file="US7165824B2_D0953.tif" /> 0 # the location of the fuse is within</entry></row><row><entry /><entry>32-bit word</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0954.tif" /> loadFuse</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ElseIf ((IOMode = ProgramMode) <img file="US7165824B2_D0955.tif" /> MRURdy <img file="US7165824B2_D0956.tif" /> <img file="US7165824B2_D0957.tif" /> fuseBlown) #</entry></row><row><entry /><entry>wait 4 access 2 finish</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>maskLoaded <img file="US7165824B2_D0958.tif" /> 0 # the mask is now invalid</entry></row><row><entry /><entry>adr <img file="US7165824B2_D0959.tif" /> 0 # the location of the fuse is within 32-bit</entry></row><row><entry /><entry>word 0</entry></row><row><entry /><entry>state <img file="US7165824B2_D0960.tif" /> loadFuse</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ElseIf ((IOMode = TrimMode) <img file="US7165824B2_D0961.tif" /> MRURdy <img file="US7165824B2_D0962.tif" /> <img file="US7165824B2_D0963.tif" /> fuseBlown) #</entry></row><row><entry /><entry>wait 4 access 2 finish</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>maskLoaded <img file="US7165824B2_D0964.tif" /> 0 # the mask is now invalid</entry></row><row><entry /><entry>adr <img file="US7165824B2_D0965.tif" /> 0 # start the counter on entering TrimMode</entry></row><row><entry /><entry>state <img file="US7165824B2_D0966.tif" /> trim</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0967.tif" /> idle</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><ul id="ul1124" list-style="none"><li id="ul1124-0001" num="0000"><ul id="ul1125" list-style="none"><li id="ul1125-0001" num="7430">The wait4mode state simply waits until for the current mode to finish and returns to idle.</li></ul></li></ul>
7431<tables id="TABLE-US-00603" num="00603"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="63pt" align="left" /><colspec colname="1" colwidth="154pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>wait4mode</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="77pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>PMEn = 0</entry></row><row><entry /><entry>PMNewTrans = 0</entry></row><row><entry /><entry>If (IOMode = IdleMode)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="91pt" align="left" /><colspec colname="1" colwidth="126pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0968.tif" /> idle</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="77pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row><row><entry /><entry>state <img file="US7165824B2_D0969.tif" /> wait4mode</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="63pt" align="left" /><colspec colname="1" colwidth="154pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7432The trim state is where we count the number of cycles between the entry of the Trim Mode and the arrival of a byte from the Master. When the byte arrives from the Master, we send the resultant count:
7433<tables id="TABLE-US-00604" num="00604"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>trim</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry># We saturate the adder at all 1s to make external trim control</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>easier</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>lastOne = adr<sub>0 </sub><img file="US7165824B2_D0970.tif" /> adr<sub>1 </sub><img file="US7165824B2_D0971.tif" /> . . . adr<sub>11</sub></entry></row><row><entry /><entry>If (<img file="US7165824B2_D0972.tif" /> lastOne)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>adr = adr + 1 # 12 bit incrementor</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry># This logic simply causes the current adder value to be written</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>to the</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry># outByte when the inByte is received. The inByte is cleared</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>when received</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry># although it is not strictly necessary to do so</entry></row><row><entry /><entry>PMOutByteWE = InByteValid # 0 in all other states</entry></row><row><entry /><entry>PMInByteUsed = InByteValid # same as in loadByte state, 0 in all</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>other states</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>If (IOMode ≠ TrimMode)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0973.tif" /> idle</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ElseIf (InByteValid)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0974.tif" /> wait4mode</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0975.tif" /> trim</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7434The loadFuse state is called whenever there is an attempt to program the device or we are entering ActiveMode and the mask is invalid (i.e. after power up or after a ProgramMode or TrimMode command). We load the 32-bit fuse value from word 0 of information memory in flash and compare it against the FuseSig constant (0x5555AAAA) to obtain the fuse value. The next state depends on IOMode and the Fuse.
7435<tables id="TABLE-US-00605" num="00605"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>loadFuse</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>PMEn = 1</entry></row><row><entry /><entry>PMNewTrans = prevMRURdy</entry></row><row><entry /><entry>idlePending_in = idlePending <img file="US7165824B2_D0976.tif" /> (IOMode = IdleMode)</entry></row><row><entry /><entry>idlePending <img file="US7165824B2_D0977.tif" /> idlePending_in</entry></row><row><entry /><entry>If (MRURdy)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>If (idlePending_in)# don't change state until the memory</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>access is complete</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0978.tif" /> idle</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>fuseBlown_in = (MRUData<sub>31−0 </sub>= FuseSig)</entry></row><row><entry /><entry>fuseBlown <img file="US7165824B2_D0979.tif" /> fuseBlown_in</entry></row><row><entry /><entry>If (IOMode = ProgramMode)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>If (fuseBlown_in)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="84pt" align="left" /><colspec colname="1" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0980.tif" /> wait4mode # not allowed to</entry></row><row><entry /><entry>program anymore</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="84pt" align="left" /><colspec colname="1" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0981.tif" /> erase</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>Elsif (IOMode = ActiveMode)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>adr <img file="US7165824B2_D0982.tif" /> 4 # byte 4 is word 1 (the location of the</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>XORMask)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0983.tif" /> getMask</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0984.tif" /> idle</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0985.tif" /> loadFuse</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7436The erase state erases the flash memory and then leads into the main programming states:
7437<tables id="TABLE-US-00606" num="00606"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>erase</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>PMNewTrans = prevMRURdy</entry></row><row><entry /><entry>PMEraseDevice = 1 # is 0 in all other states</entry></row><row><entry /><entry>adr <img file="US7165824B2_D0986.tif" /> 0</entry></row><row><entry /><entry>idlePending_in = idlePending <img file="US7165824B2_D0987.tif" /> (IOMode ≠ ProgramMode)</entry></row><row><entry /><entry>idlePending <img file="US7165824B2_D0988.tif" /> idlePending_in</entry></row><row><entry /><entry>If (MRURdy)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>If (idlePending_in)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0989.tif" /> idle</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row><row><entry /><entry>state <img file="US7165824B2_D0990.tif" /> loadByte</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0991.tif" /> erase</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7438Program Mode involves loading a series of 8-bit data values into the Flash. The PMU reads bytes via the IOU's InByte and InByteValid, setting MUInByteUsed as it loads data. The Master must send data slightly slower than the speed it takes to write to Flash to ensure that data is not lost.
7439<tables id="TABLE-US-00607" num="00607"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="168pt" align="left" /><thead><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>loadByte</entry><entry># Load in 1 byte (1 word) from IO Unit</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>PMNewTrans = 0</entry></row><row><entry /><entry>PMInByteUsed = InByteValid # same as in TrimIn state, and 0 in</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>all other states</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>If (IOMode ≠ ProgramMode)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0992.tif" /> idle</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>If (InByteValid)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>buff <img file="US7165824B2_D0993.tif" /> InByte</entry></row><row><entry /><entry>state <img file="US7165824B2_D0994.tif" /> writeByte</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D0995.tif" /> loadByte</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>writeByte</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>PMNewTrans = prevMRURdy</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>PMRW = 0</entry><entry># write. In all other states, PMRW = 1 (read)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>PM32Out<sub>7−0 </sub>= buff # data (can be tied to this)</entry></row><row><entry /><entry>PM32Out<sub>19−8 </sub>= adr # can be tied to this</entry></row><row><entry /><entry>PM32Out<sub>31−20 </sub>= 12bitReg# is always this (is don't care during a</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>write)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>idlePending_in = idlePending <img file="US7165824B2_D0996.tif" /> (IOMode ≠ ProgramMode)</entry></row><row><entry /><entry>idlePending <img file="US7165824B2_D0997.tif" /> idlePending_in</entry></row><row><entry /><entry>If (MRURdy)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>lastOne = adr<sub>0 </sub><img file="US7165824B2_D0998.tif" /> adr<sub>1 </sub><img file="US7165824B2_D0999.tif" /> . . . adr<sub>11</sub></entry></row><row><entry /><entry>adr <img file="US7165824B2_D1000.tif" /> adr + 1 # 12 bit incrementor</entry></row><row><entry /><entry>If (idlePending_in)</entry></row><row><entry /><entry>state <img file="US7165824B2_D1001.tif" /> idle</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>ElseIf (lastOne)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D1002.tif" /> wait4Mode</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D1003.tif" /> loadByte</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D1004.tif" /> writeByte</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>EndIf</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7440The getMask state loads up word 1 of the flash information block (bytes <b>4</b>–<b>7</b>) into the 32-bit buffer so it can be used to XOR all data to and from memory (both Flash and RAM) for future CPU accesses.
7441<tables id="TABLE-US-00608" num="00608"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>getMask</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>PMNewTrans = prevMRURdy</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>PM32Out<sub>19−8 </sub>= adr</entry><entry># adr should = 4, i.e. word 1 which holds the</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>CPU's mask</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>PMRW = 1</entry><entry># read (MUST be 1 in this state)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>idlePending_in = idlePending <img file="US7165824B2_D1005.tif" /> (IOMode ≠ ActiveMode)</entry></row><row><entry /><entry>idlePending <img file="US7165824B2_D1006.tif" /> idlePending_in</entry></row><row><entry /><entry>If (MRURdy)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>buff <img file="US7165824B2_D1007.tif" /> MRUData<sub>7−0</sub></entry></row><row><entry /><entry>adr <img file="US7165824B2_D1008.tif" /> MRUData<sub>19−8</sub></entry></row><row><entry /><entry>12bitReg <img file="US7165824B2_D1009.tif" /> MRUData<sub>31−20</sub></entry></row><row><entry /><entry>maskLoaded <img file="US7165824B2_D1010.tif" /> 1</entry></row><row><entry /><entry>If (idlePending_in)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D1011.tif" /> idle</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D1012.tif" /> wait4mode</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D1013.tif" /> getMask</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 18 Memory Request Unit
7442The Memory Request Unit (MRU) provides arbitration between PMU memory requests and CPU-based memory requests.
7443The arbitration is straightforward: if the input PMEn is asserted, then PMU inputs are processed and CPU inputs are ignored. If PMEn is deasserted, the reverse is true.
7444A block diagram of the MRU is shown in <figref idref="DRAWINGS">FIG. 408</figref>.
000018.1 Arbitration Logic
7445The arbitration logic block provides arbitration between the accesses of the PM and the 8/32-bit accesses of the CPU via a simple multiplexing mechanism based on PMEn:
7446<tables id="TABLE-US-00609" num="00609"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>ReqDataOut<sub>31−8 </sub>= CPUDataOut<sub>31−8</sub></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>If (PMEn)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>NewTrans = PMNewTrans</entry></row><row><entry /><entry>AccessMode<sub>0 </sub>= PMRW # maps to 1 for reads (32 bits), 0 for</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>writes (8 bits)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>AccessMode<sub>1 </sub>= 0 # flash accesses only</entry></row><row><entry /><entry>AccessMode<sub>2 </sub>= PMRW <img file="US7165824B2_D1014.tif" /> <img file="US7165824B2_D1015.tif" /> PMEraseDevice # read has lower</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>priority than erase</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>AccessMode<sub>3 </sub>= <img file="US7165824B2_D1016.tif" /> PMRW <img file="US7165824B2_D1017.tif" /> <img file="US7165824B2_D1018.tif" /> PMEraseDevice # write has</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>lower priority than erase</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>AccessMode<sub>4 </sub>= 0 # pageErase</entry></row><row><entry /><entry>AccessMode<sub>5 </sub>= PMEraseDevice # erase everything (main &</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>info block)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>WriteMask = 0xFF</entry></row><row><entry /><entry>Adr = PM32Out<sub>19−8</sub></entry></row><row><entry /><entry>ReqDataOut<sub>7−0 </sub>= PM32Out<sub>7−0</sub></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>NewTrans = CPUNewTrans <img file="US7165824B2_D1019.tif" /> (CPUAccessMode<sub>4−2 </sub>≠ 000)</entry></row><row><entry /><entry>AccessMode<sub>4−0 </sub>= CPUAccessMode</entry></row><row><entry /><entry>AccessMode<sub>5 </sub>= 0 # cpu cannot ever erase entire chip</entry></row><row><entry /><entry>WriteMask = CPUWriteMask</entry></row><row><entry /><entry>Adr = CPUAdr</entry></row><row><entry /><entry>ReqDataOut<sub>7−0 </sub>= CPUDataOut<sub>7−0</sub></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 18.2 Memory Request Logic
7447The Memory Request Logic in the MRU implements the memory requests from the selected input. An individual request may involve outputting multiple sub-requests e.g. an 8-bit read consists of 2×4-bit reads (each flash byte contains a nybble plus its inverse). <ul id="ul1126" list-style="none"><li id="ul1126-0001" num="0000"><ul id="ul1127" list-style="none"><li id="ul1127-0001" num="7448">The input accessMode bits are interpreted as follows:</li></ul></li></ul>
7449<tables id="TABLE-US-00610" num="00610"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 382</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Interpretation of accessMode bits</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="35pt" align="center" /><colspec colname="2" colwidth="182pt" align="left" /><tbody valign="top"><row><entry>Bit</entry><entry>Description</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row><row><entry>0</entry><entry>0 = 8-bit access</entry></row><row><entry /><entry>1 = 32-bit access</entry></row><row><entry>1</entry><entry>0 = flash access</entry></row><row><entry /><entry>1 = RAM access</entry></row><row><entry /><entry>this bit is only valid if bit 2, 3 or 4 is set</entry></row><row><entry>2</entry><entry>1 = read access</entry></row><row><entry>3</entry><entry>1 = write access</entry></row><row><entry>4</entry><entry>1 = erase page access</entry></row><row><entry>5</entry><entry>1 = erase entire (info and main) flash (only used within the</entry></row><row><entry /><entry>MRU)</entry></row><row><entry namest="1" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7450The MRU contains the following registers for general purpose flow control:
7451<tables id="TABLE-US-00611" num="00611"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 383</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Description of register settings</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="56pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="140pt" align="left" /><tbody valign="top"><row><entry>name</entry><entry>#bits</entry><entry>Description</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>ActiveTrans</entry><entry>1</entry><entry>Is there a transaction still running? If so,</entry></row><row><entry /><entry /><entry>then extraTrans and</entry></row><row><entry /><entry /><entry>nextToXfer can be considered valid.</entry></row><row><entry>badUntilRestart</entry><entry>1</entry><entry>0 = memory (flash and ram) reads work</entry></row><row><entry /><entry /><entry>correctly</entry></row><row><entry /><entry /><entry>1 = memory (flash and ram) reads return 0</entry></row><row><entry /><entry /><entry>Gets set whenever illChip gets set, and</entry></row><row><entry /><entry /><entry>remains set until a soft restart occurs i.e.</entry></row><row><entry /><entry /><entry>IOMode passes through Idle.</entry></row><row><entry>extraTrans</entry><entry>1</entry><entry>Determines whether there is an additional sub-</entry></row><row><entry /><entry /><entry>transaction to perform, e.g. a 32 bit read from</entry></row><row><entry /><entry /><entry>flash involves 4 sub-transactions in the case of</entry></row><row><entry /><entry /><entry>8-bit accesses, and 8 sub-transactions in the</entry></row><row><entry /><entry /><entry>case of 4-bit accesses.</entry></row><row><entry>IllChip</entry><entry>1</entry><entry>0 = 15 consecutive bad reads have not</entry></row><row><entry /><entry /><entry>occurred</entry></row><row><entry /><entry /><entry>1 = 15 consecutive bad reads have occurred</entry></row><row><entry>nextToXfer</entry><entry>3</entry><entry>The next element (byte or nybble) number to</entry></row><row><entry /><entry /><entry>transfer to/from memory</entry></row><row><entry>restartPending</entry><entry>1</entry><entry>1 = IOMode passed through Idle while a</entry></row><row><entry /><entry /><entry>transaction was being processed</entry></row><row><entry /><entry /><entry>0 = The transaction completed without</entry></row><row><entry /><entry /><entry>IOMode passing through Idle</entry></row><row><entry>retryCount</entry><entry>4</entry><entry>Number of times that a byte has been read</entry></row><row><entry /><entry /><entry>badly from flash. When a byte has been read</entry></row><row><entry /><entry /><entry>badly 15 consecutive times illChip will be</entry></row><row><entry /><entry /><entry>set.</entry></row><row><entry>retryStarted</entry><entry>1</entry><entry>0 = no retries encountered yet for this</entry></row><row><entry /><entry /><entry>read</entry></row><row><entry /><entry /><entry>1 = retries have been encountered -</entry></row><row><entry /><entry /><entry>retryCount holds the number of retries</entry></row><row><entry /><entry /><entry>The retryStarted register is used to stop</entry></row><row><entry /><entry /><entry>retryCount being cleared on good reads -</entry></row><row><entry /><entry /><entry>thus keeping a record of the last number of</entry></row><row><entry /><entry /><entry>retries on a bad read.</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables>
7452Table 383 lists the registers specifically for testing flash. Although the complete set of flash test registers is in both the MRU and MAU (group 0 is in the MRU, groups 1 and 2 are in the MAU), all the decoding takes place from the MRU.
7453<tables id="TABLE-US-00612" num="00612"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="322pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 383</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Flash test registers settable from CPU when the RAM address is > 128<sup>7</sup></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="21pt" align="center" /><colspec colname="3" colwidth="56pt" align="left" /><colspec colname="4" colwidth="154pt" align="left" /><tbody valign="top"><row><entry>adrbitSuperscriptparanumonly</entry><entry>bits</entry><entry>name</entry><entry>description</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="21pt" align="char" char="." /><colspec colname="3" colwidth="56pt" align="left" /><colspec colname="4" colwidth="154pt" align="left" /><tbody valign="top"><row><entry>0</entry><entry>0</entry><entry>shadowsOff</entry><entry>0 = regular shadowing (nybble based access to</entry></row><row><entry /><entry /><entry /><entry>flash)</entry></row><row><entry /><entry /><entry /><entry>1 = shadowing disabled, 8-bit direct accesses to</entry></row><row><entry /><entry /><entry /><entry>flash.</entry></row><row><entry /><entry>1</entry><entry>hiFlashAdr</entry><entry>Only valid when shadowsOff = 1</entry></row><row><entry /><entry /><entry /><entry>0 = accesses are to lower 4 Kbytes of flash</entry></row><row><entry /><entry /><entry /><entry>1 = accesses are to upper 4 Kbytes of flash</entry></row><row><entry /><entry>2</entry></row><row><entry>1</entry><entry>3</entry><entry>enableFlashTest</entry><entry>0 = keep flash test register within the TSMC flash</entry></row><row><entry /><entry /><entry /><entry>IP in its reset state</entry></row><row><entry /><entry /><entry /><entry>1 = enable flash test register to take on non-reset</entry></row><row><entry /><entry /><entry /><entry>values.</entry></row><row><entry /><entry> 8–4</entry><entry>flashTest</entry><entry>Internal 5-bit flash test register within the TSMC</entry></row><row><entry /><entry /><entry /><entry>flash IP (SFC008_08B9_HE).</entry></row><row><entry /><entry /><entry /><entry>If this is written with 0x1E, then subsequent</entry></row><row><entry /><entry /><entry /><entry>writes will be according to the TSMC write test</entry></row><row><entry /><entry /><entry /><entry>mode. You must write a non-0x1E value or reset</entry></row><row><entry /><entry /><entry /><entry>the register to exit this mode.</entry></row><row><entry>2</entry><entry>28–9</entry><entry>flashTime</entry><entry>When timerSel is 1, this value is used for the</entry></row><row><entry /><entry /><entry /><entry>duration of the program cycle within a standard</entry></row><row><entry /><entry /><entry /><entry>flash write or erasure. 1 unit = 16 clock cycles</entry></row><row><entry /><entry /><entry /><entry>(16 × 100 ns typical).</entry></row><row><entry /><entry /><entry /><entry>Regardless of timerSel, this value is also used for</entry></row><row><entry /><entry /><entry /><entry>the timeout following power down detection</entry></row><row><entry /><entry /><entry /><entry>before the QA Chip resets itself. 1 unit = 1 clock</entry></row><row><entry /><entry /><entry /><entry>cycle (=100 ns typical).</entry></row><row><entry /><entry /><entry /><entry>Note that this means the programmer should set</entry></row><row><entry /><entry /><entry /><entry>this to an appropriate value (e.g. 5 μs), just as the</entry></row><row><entry /><entry /><entry /><entry>localId needs to be set.</entry></row><row><entry /><entry>29</entry><entry>timerSel</entry><entry>0 = use internal (default) timings for flash writes &</entry></row><row><entry /><entry /><entry /><entry>erasures</entry></row><row><entry /><entry /><entry /><entry>1 = use flashTime for flash writes and erasures</entry></row><row><entry namest="1" nameend="4" align="center" rowsep="1" /></row><row><entry namest="1" nameend="4" align="left" id="FOO-00121"><sup>7</sup>This is from the programmer's perspective. Addresses sent from the CPU are byte aligned, so the MRU needs to test bit n + 2. Similarly, checking DRAM address >128 means testing bit 7 of the address in the CPU, and bit 9 in the MRU.</entry></row></tbody></tgroup></table></tables><br /> 18.2.1 Reset <ul id="ul1128" list-style="none"><li id="ul1128-0001" num="0000"><ul id="ul1129" list-style="none"><li id="ul1129-0001" num="7454">Initialization on reset involves clearing all the flags:</li></ul></li></ul>
7455<tables id="TABLE-US-00613" num="00613"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>MRURdy = 0 # can't process anything at this point</entry></row><row><entry /><entry>activeTrans <img file="US7165824B2_D1020.tif" /> 0</entry></row><row><entry /><entry>extraTrans <img file="US7165824B2_D1021.tif" /> 0</entry></row><row><entry /><entry>illChip <img file="US7165824B2_D1022.tif" /> 0</entry></row><row><entry /><entry>badUntilRestart <img file="US7165824B2_D1023.tif" /> 0</entry></row><row><entry /><entry>restartPending <img file="US7165824B2_D1024.tif" /> 0</entry></row><row><entry /><entry>retryCount <img file="US7165824B2_D1025.tif" /> 0</entry></row><row><entry /><entry>retryStarted <img file="US7165824B2_D1026.tif" /> 0</entry></row><row><entry /><entry>nextToXfer <img file="US7165824B2_D1027.tif" /> 0 # don't care</entry></row><row><entry /><entry>shadowsOff <img file="US7165824B2_D1028.tif" /> 0</entry></row><row><entry /><entry>hiFlashAdr <img file="US7165824B2_D1029.tif" /> 0</entry></row><row><entry /><entry>infoBlockSel <img file="US7165824B2_D1030.tif" /> 0# used to generate MRUMode<sub>2</sub></entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 18.2.2 Main Logic <ul id="ul1130" list-style="none"><li id="ul1130-0001" num="0000"><ul id="ul1131" list-style="none"><li id="ul1131-0001" num="7456">The main logic consists of waiting for a new transaction, and starting an appropriate sub-transaction accordingly, as shown in the following pseudocode:</li></ul></li></ul>
7457<tables id="TABLE-US-00614" num="00614"><table frame="none" colsep="0" rowsep="0" pgwide="1"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry># Generate some basic signals for use in determining</entry></row><row><entry /><entry>accessPatterns</entry></row><row><entry /><entry>Is32Bit = AccessMode<sub>0</sub></entry></row><row><entry /><entry>Is8Bit = <img file="US7165824B2_D1031.tif" /> AccessMode<sub>0</sub></entry></row><row><entry /><entry>IsFlash = <img file="US7165824B2_D1032.tif" /> AccessMode<sub>1</sub></entry></row><row><entry /><entry>IsRAM = AccessMode<sub>1</sub></entry></row><row><entry /><entry>IsRead = AccessMode<sub>2</sub></entry></row><row><entry /><entry>IsWrite = AccessMode<sub>3</sub></entry></row><row><entry /><entry>noShadows = shadowsOff</entry></row><row><entry /><entry>doShadows = IsFlash <img file="US7165824B2_D1033.tif" /> <img file="US7165824B2_D1034.tif" /> noShadows</entry></row><row><entry /><entry>continueRequest = (IOMode ≠ IdleMode)</entry></row><row><entry /><entry>okForTrans = <img file="US7165824B2_D1035.tif" /> restartPending <img file="US7165824B2_D1036.tif" /> continueRequest</entry></row><row><entry /><entry>startOfSubTrans = (NewTrans <img file="US7165824B2_D1037.tif" /> extraTrans) <img file="US7165824B2_D1038.tif" /> okForTrans</entry></row><row><entry /><entry>doingTrans = startOfSubTrans <img file="US7165824B2_D1039.tif" /> (activeTrans <img file="US7165824B2_D1040.tif" /> <img file="US7165824B2_D1041.tif" /> extraTrans)</entry></row><row><entry /><entry>IsInvalidRAM = doingTrans <img file="US7165824B2_D1042.tif" /> IsRAM <img file="US7165824B2_D1043.tif" /> (Adr<sub>9 </sub><img file="US7165824B2_D1044.tif" /> (Adr<sub>8 </sub><img file="US7165824B2_D1045.tif" /> Adr<sub>7</sub>))</entry></row><row><entry /><entry>IsTestModeWE = doingTrans <img file="US7165824B2_D1046.tif" /> IsRAM <img file="US7165824B2_D1047.tif" /> IsWrite <img file="US7165824B2_D1048.tif" /> Adr<sub>9</sub></entry></row><row><entry /><entry>IsTestReg<sub>0 </sub>= IsTestModeWE <img file="US7165824B2_D1049.tif" /> Adr<sub>3</sub> #write to flash test register -</entry></row><row><entry /><entry>bit 1 of word adr</entry></row><row><entry /><entry>IsTestReg<sub>1 </sub>= IsTestModeWE <img file="US7165824B2_D1050.tif" /> Adr<sub>4 </sub>#write to flash test register -</entry></row><row><entry /><entry>bit 2 of word adr</entry></row><row><entry /><entry>MRUTestWE = IsTestReg<sub>0 </sub><img file="US7165824B2_D1051.tif" /> IsTestReg<sub>1</sub></entry></row><row><entry /><entry>IsPageErase = AccessMode<sub>4</sub></entry></row><row><entry /><entry>IsDeviceErase = AccessMode<sub>5 </sub><img file="US7165824B2_D1052.tif" /> (IsTestModeWE <img file="US7165824B2_D1053.tif" /> (Adr<sub>8−2 </sub>=</entry></row><row><entry /><entry>0001000)) #</entry></row><row><entry /><entry>bit 9 not req</entry></row><row><entry /><entry>IsErase = IsDeviceErase <img file="US7165824B2_D1054.tif" /> IsPageErase</entry></row><row><entry /><entry>MRURAMSel = IsRAM <img file="US7165824B2_D1055.tif" /> <img file="US7165824B2_D1056.tif" /> MRUTestWE <img file="US7165824B2_D1057.tif" /> <img file="US7165824B2_D1058.tif" /> IsDeviceErase</entry></row><row><entry /><entry>IsInfBlock = (PMEn <img file="US7165824B2_D1059.tif" /> (IsDeviceErase <img file="US7165824B2_D1060.tif" /> IsRead)) <img file="US7165824B2_D1061.tif" /></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>(<img file="US7165824B2_D1062.tif" /> PMEn <img file="US7165824B2_D1063.tif" /> infoBlockSel <img file="US7165824B2_D1064.tif" /></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>(IsDeviceErase <img file="US7165824B2_D1065.tif" /> (IsFlash <img file="US7165824B2_D1066.tif" /> (Adr<sub>11−7 </sub>= 0) <img file="US7165824B2_D1067.tif" /> <img file="US7165824B2_D1068.tif" /> (Adr<sub>6 </sub><img file="US7165824B2_D1069.tif" /></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>doShadows))))</entry></row><row><entry /><entry># Which element (byte or nybble) are we up to xferring?</entry></row><row><entry /><entry>If (NewTrans)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>toXfer = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>toXfer = nextToXfer</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry># Form the address that goes to the outside world</entry></row><row><entry /><entry>If (IsFlash <img file="US7165824B2_D1070.tif" /> noShadows)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>byteCount = toXfer<sub>1−0</sub></entry></row><row><entry /><entry>MRUAdr<sub>12 </sub>= hiFlashAdr # upper or lower block of 4Kbytes</entry></row><row><entry /><entry>of flash</entry></row><row><entry /><entry>MRUAdr<sub>11−2 </sub>= Adr<sub>11−2</sub> # word #</entry></row><row><entry /><entry>MRUAdr<sub>1−0 </sub>= (Adr<sub>1−0 </sub><img file="US7165824B2_D1071.tif" /> (<img file="US7165824B2_D1072.tif" /> Is32Bit|<img file="US7165824B2_D1073.tif" /> Is32Bit)) <img file="US7165824B2_D1074.tif" /> byteCount # byte</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>byteCount = toXfer<sub>2−1</sub></entry></row><row><entry /><entry>MRUAdr<sub>12−3 </sub>= Adr<sub>11−2</sub> # word #</entry></row><row><entry /><entry>MRUAdr<sub>2−1 </sub>= (Adr<sub>1−0 </sub><img file="US7165824B2_D1075.tif" /> (<img file="US7165824B2_D1076.tif" /> Is32Bit|<img file="US7165824B2_D1077.tif" /> Is32Bit)) <img file="US7165824B2_D1078.tif" /> byteCount # byte</entry></row><row><entry /><entry>MRUAdr<sub>0 </sub>= toXfer<sub>0 </sub>#nybble</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry># Assuming a write, are we allowed to write to this address?</entry></row><row><entry /><entry>writeEn = SelectBit [WriteMask, ( (MRUAdr<sub>2 </sub><img file="US7165824B2_D1079.tif" /> doShadows) |</entry></row><row><entry /><entry>MRUAdr<sub>1−0</sub>) ] #</entry></row><row><entry /><entry>mux: 1 from 8</entry></row><row><entry /><entry># Generate the 4-bit mask to be used for XORing during CPU</entry></row><row><entry /><entry>access</entry></row><row><entry /><entry>to flash</entry></row><row><entry /><entry>baseMask = SelectNybble (PM32Out, MRUAdr<sub>2−0</sub>) # mux selects 4</entry></row><row><entry /><entry>bits of 32</entry></row><row><entry /><entry>If (PMEn)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>theMask = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>theMask = baseMask # we only use mask for CPU accesses</entry></row><row><entry /><entry>to flash</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry># Select a byte (and nybble) from the data for writes</entry></row><row><entry /><entry>baseByte = SelectByte[ReqDataOut, byteCount] # mux:</entry></row><row><entry /><entry>8 bits from 32</entry></row><row><entry /><entry>baseNybble = SelectNybble [baseByte, toXfer<sub>0</sub>] # mux: 4 bits</entry></row><row><entry /><entry>from 8</entry></row><row><entry /><entry>outNybble = baseNybble ⊕ theMask # only used when nybble</entry></row><row><entry /><entry>writing</entry></row><row><entry /><entry># Generate the data on the output lines (doesn't matter for reads</entry></row><row><entry /><entry>or erasures)</entry></row><row><entry /><entry>MRUDataOut<sub>31−8 </sub>= ReqDataOut<sub>31−8 </sub># effectively don't care for flash</entry></row><row><entry /><entry>writes</entry></row><row><entry /><entry>If (doShadows)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>MRUDataOut<sub>7 </sub>= <img file="US7165824B2_D1080.tif" /> outNybble<sub>3</sub></entry></row><row><entry /><entry>MRUDataOut<sub>6 </sub>= outNybble<sub>3</sub></entry></row><row><entry /><entry>MRUDataOut<sub>5 </sub>= <img file="US7165824B2_D1081.tif" /> outNybble<sub>2</sub></entry></row><row><entry /><entry>MRUDataOut<sub>4 </sub>= outNybble<sub>2</sub></entry></row><row><entry /><entry>MRUDataOut<sub>3 </sub>= <img file="US7165824B2_D1082.tif" /> outNybble<sub>1</sub></entry></row><row><entry /><entry>MRUDataOut<sub>2 </sub>= outNybble<sub>1</sub></entry></row><row><entry /><entry>MRUDataOut<sub>1 </sub>= <img file="US7165824B2_D1083.tif" /> outNybble<sub>0</sub></entry></row><row><entry /><entry>MRUDataOut<sub>0 </sub>= outNybble<sub>0</sub></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>MRUDataOut<sub>7−0 </sub>= baseByte</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry># Setup MRUMode</entry></row><row><entry /><entry>allowTrans = IsRAM <img file="US7165824B2_D1084.tif" /> IsRead <img file="US7165824B2_D1085.tif" /> (IsWrite <img file="US7165824B2_D1086.tif" /> writeEn) <img file="US7165824B2_D1087.tif" /> IsErase</entry></row><row><entry /><entry>If (doingTrans)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>MRUMode<sub>2 </sub>= IsInfBlock</entry></row><row><entry /><entry>MRUMode<sub>1 </sub>= IsErase <img file="US7165824B2_D1088.tif" /> IsTestReg<sub>1</sub></entry></row><row><entry /><entry>MRUMode<sub>0 </sub>= IsDeviceErase <img file="US7165824B2_D1089.tif" /> (<img file="US7165824B2_D1090.tif" /> IsWrite <img file="US7165824B2_D1091.tif" /> <img file="US7165824B2_D1092.tif" /> IsPageErase) <img file="US7165824B2_D1093.tif" /></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>IsTestReg<sub>0</sub></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>MRUNewTrans = startOfSubTrans <img file="US7165824B2_D1094.tif" /> allowTrans <img file="US7165824B2_D1095.tif" /></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>(<img file="US7165824B2_D1096.tif" /> IsInvalidRAM <img file="US7165824B2_D1097.tif" /> MRUTestWE <img file="US7165824B2_D1098.tif" /> IsDeviceErase)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>MRUMode<sub>2−0 </sub>= 001 # read (safe)</entry></row><row><entry /><entry>MRUNewTrans = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry># Generate the effective nybble read from flash (this may not be</entry></row><row><entry /><entry>used).</entry></row><row><entry /><entry># When there is a shadowFault (non-erased memory and invalid</entry></row><row><entry /><entry>shadows) we consider</entry></row><row><entry /><entry># it a bad read when an 8-bit read, or when writeMask<sub>0 </sub>is 0.</entry></row><row><entry /><entry># Note: we always substitute the upper nybble of WriteMask for the</entry></row><row><entry /><entry>non-valid data,</entry></row><row><entry /><entry># but only flag a read error if WriteMask<sub>0 </sub>is also 1. When the</entry></row><row><entry /><entry>data is erased,</entry></row><row><entry /><entry># we return 0 regardless of WriteMask<sub>0</sub>.</entry></row><row><entry /><entry>finishedTrans = doingTrans <img file="US7165824B2_D1099.tif" /> MAURdy</entry></row><row><entry /><entry>finishedFlashSubTrans = finishedTrans <img file="US7165824B2_D1100.tif" /> IsFlash <img file="US7165824B2_D1101.tif" /> <img file="US7165824B2_D1102.tif" /> IsErase</entry></row><row><entry /><entry>isWrittenFlash = (FlashData<sub>7−0 </sub>≠ 11111111) # flash is erased to</entry></row><row><entry /><entry>all 1s</entry></row><row><entry /><entry>If (isWrittenFlash <img file="US7165824B2_D1103.tif" /> ((FlashData<sub>7,5,3,1 </sub>⊕ FlashData<sub>6,4,2,0</sub>) ≠ 1111))</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>inNybble<sub>3−0 </sub>= WriteMask<sub>7−4</sub></entry></row><row><entry /><entry>badRead = finishedFlashSubTrans <img file="US7165824B2_D1104.tif" /> IsRead <img file="US7165824B2_D1105.tif" /> (Is8Bit <img file="US7165824B2_D1106.tif" /></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry><img file="US7165824B2_D1107.tif" /> WriteMask<sub>0</sub>) <img file="US7165824B2_D1108.tif" /> doShadows</entry></row><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>inNybble<sub>3,2,1,0 </sub>= (theMask<sub>3,2,1,0 </sub>⊕ FlashData<sub>6,4,2,0</sub>) <img file="US7165824B2_D1109.tif" /></entry></row><row><entry /><entry>isWrittenFlash</entry></row><row><entry /><entry>badRead = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry># Present the resultant data to the outside world</entry></row><row><entry /><entry>MaskTheData = IsInvalidRAM <img file="US7165824B2_D1110.tif" /> badRead <img file="US7165824B2_D1111.tif" /> (badUntilRestart <img file="US7165824B2_D1112.tif" /> <img file="US7165824B2_D1113.tif" /> IsRAM)</entry></row><row><entry /><entry>NoData = IsErase <img file="US7165824B2_D1114.tif" /> IsWrite <img file="US7165824B2_D1115.tif" /> <img file="US7165824B2_D1116.tif" /> doingTrans</entry></row><row><entry /><entry>If (NoData <img file="US7165824B2_D1117.tif" /> MaskTheData)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>MRUData<sub>0 </sub>= IsInvalidRAM <img file="US7165824B2_D1118.tif" /> illChip</entry></row><row><entry /><entry>MRUData<sub>4−1 </sub>= retryCount <img file="US7165824B2_D1119.tif" /> (IsInvalidRAM <img file="US7165824B2_D1120.tif" /> Adr<sub>2</sub>) # mask</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="259pt" align="left" /><tbody valign="top"><row><entry>all 4 count bits</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>MRUData<sub>31−5 </sub>= 0 # also ensures a read that is bad returns 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>ElseIf (IsRAM)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>MRUData<sub>31−24 </sub>= SelectByte[RAMData, (Adr<sub>1−0 </sub><img file="US7165824B2_D1121.tif" /></entry></row><row><entry /><entry>Is32Bit|Is32Bit)] #</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>mux: 8 from 32</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>MRUData<sub>23−0 </sub>= RAMData<sub>23−0</sub> # lsbs remain unchanged</entry></row><row><entry /><entry>from RAM</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>ElseIf (doShadows)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>MRUData<sub>31−28 </sub>= inNybble</entry></row><row><entry /><entry>MRUData<sub>27−0 </sub>= buff<sub>27−0</sub></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>MRUData<sub>31−24 </sub>= FlashData</entry></row><row><entry /><entry>MRUData<sub>23−0 </sub>= buff<sub>27−4</sub></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry># Shift in the data for the good reads - either 4 or 8 bits</entry></row><row><entry /><entry>(writes = don't care)</entry></row><row><entry /><entry>If (finishedFlashSubTrans <img file="US7165824B2_D1122.tif" /> <img file="US7165824B2_D1123.tif" /> badRead)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>buff<sub>3−0 </sub><img file="US7165824B2_D1124.tif" /> buff<sub>7−4</sub> # shift right 4 bits</entry></row><row><entry /><entry>If (doShadows)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="126pt" align="left" /><tbody valign="top"><row><entry /><entry>buff<sub>23−4 </sub><img file="US7165824B2_D1125.tif" /> buff<sub>27−8</sub></entry><entry># shift right 4</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>bits</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>buff<sub>27−24 </sub><img file="US7165824B2_D1126.tif" /> inNybble</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>buff<sub>19−4 </sub><img file="US7165824B2_D1127.tif" /> buff<sub>27−12 </sub># shift right 8 bits, buff<sub>3−0 </sub>is</entry></row><row><entry /><entry>don't care</entry></row><row><entry /><entry>buff<sub>27−20 </sub><img file="US7165824B2_D1128.tif" /> FlashData</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry># Determine whether or not we need a new sub-transaction. We only</entry></row><row><entry /><entry>need one if:</entry></row><row><entry /><entry># * there hasn't been a transition to IdleMode during this</entry></row><row><entry /><entry>transaction</entry></row><row><entry /><entry># * we're doing 8 bit reads that are shadowed</entry></row><row><entry /><entry># * we're doing 32 bit reads and we've done less than 4 or 8 (sh</entry></row><row><entry /><entry>vs non-sh)</entry></row><row><entry /><entry># * we got a bad read from flash and we need to retry the read</entry></row><row><entry /><entry>(jic was a glitch)</entry></row><row><entry /><entry>moreAdrsToGo = (<img file="US7165824B2_D1129.tif" /> toXfer<sub>0 </sub><img file="US7165824B2_D1130.tif" /> ((Is8Bit <img file="US7165824B2_D1131.tif" /> doShadows) <img file="US7165824B2_D1132.tif" /> Is32Bit)) <img file="US7165824B2_D1133.tif" /></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>(<img file="US7165824B2_D1134.tif" /> toXfer<sub>1 </sub><img file="US7165824B2_D1135.tif" /> Is32Bit) <img file="US7165824B2_D1136.tif" /> (<img file="US7165824B2_D1137.tif" /> toXfer<sub>2 </sub><img file="US7165824B2_D1138.tif" /> Is32Bit <img file="US7165824B2_D1139.tif" /> doShadows)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>needToRetryRead = badRead <img file="US7165824B2_D1140.tif" /> (<img file="US7165824B2_D1141.tif" /> retryStarted <img file="US7165824B2_D1142.tif" /> (retryCount ≠ 1111))</entry></row><row><entry /><entry>extraTrans_in = finishedFlashSubTrans <img file="US7165824B2_D1143.tif" /> (moreAdrsToGo <img file="US7165824B2_D1144.tif" /></entry></row><row><entry /><entry>needToRetryRead)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry><img file="US7165824B2_D1145.tif" /> okForTrans</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>nextToXfer <img file="US7165824B2_D1146.tif" /> toXfer + (finishedFlashSubTrans <img file="US7165824B2_D1147.tif" /> (IsWrite <img file="US7165824B2_D1148.tif" /></entry></row><row><entry /><entry><img file="US7165824B2_D1149.tif" /> needToRetryRead))</entry></row><row><entry /><entry># generate our rdy signal and state values for next cycle</entry></row><row><entry /><entry>MRURdy = <img file="US7165824B2_D1150.tif" /> doingTrans <img file="US7165824B2_D1151.tif" /> (doingTrans <img file="US7165824B2_D1152.tif" /> MAURdy <img file="US7165824B2_D1153.tif" /> <img file="US7165824B2_D1154.tif" /> extraTrans_in)</entry></row><row><entry /><entry>extraTrans <img file="US7165824B2_D1155.tif" /> extraTrans_in</entry></row><row><entry /><entry>activeTrans <img file="US7165824B2_D1156.tif" /> <img file="US7165824B2_D1157.tif" /> MRURdy # all complete only when MRURdy is set</entry></row><row><entry /><entry># Take account of bad reads</entry></row><row><entry /><entry>triedEnough = badRead <img file="US7165824B2_D1158.tif" /> retryStarted <img file="US7165824B2_D1159.tif" /> (retryCount = 1111)</entry></row><row><entry /><entry>If (MAURdy)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>If (IsTestModeWE <img file="US7165824B2_D1160.tif" /> (Adr<sub>5−2 </sub>= 0000)) # capture writes to local</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>regs</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>illChip <img file="US7165824B2_D1161.tif" /> 0</entry></row><row><entry /><entry>retryCount <img file="US7165824B2_D1162.tif" /> 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>illChip <img file="US7165824B2_D1163.tif" /> illChip <img file="US7165824B2_D1164.tif" /> triedEnough</entry></row><row><entry /><entry>If (badRead)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>retryCount <img file="US7165824B2_D1165.tif" /> (retryCount <img file="US7165824B2_D1166.tif" /> retryStarted) + 1 #</entry></row><row><entry /><entry>AND all 4</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>bits</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>retryStarted <img file="US7165824B2_D1167.tif" /> 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>retryStarted <img file="US7165824B2_D1168.tif" /> 0# clear flag so will be ok for the next</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>read</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry># Ensure that we won't have problems restarting a program</entry></row><row><entry /><entry>If (MRURdy <img file="US7165824B2_D1169.tif" /> <img file="US7165824B2_D1170.tif" /> okForTrans) # note MRURdy (may not be</entry></row><row><entry /><entry>running a transaction!)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>shadowsOff, hiFlashAdr, infoBlockSel, restartPending,</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>badUntilRestart <img file="US7165824B2_D1171.tif" /> 0</entry></row><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>badUntilRestart <img file="US7165824B2_D1172.tif" /> badUntilRestart <img file="US7165824B2_D1173.tif" /> triedEnough</entry></row><row><entry /><entry>If (doingTrans <img file="US7165824B2_D1174.tif" /> <img file="US7165824B2_D1175.tif" /> continueRequest)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>restartPending <img file="US7165824B2_D1176.tif" /> 1 # record for later use</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>If (IsTestModeWE <img file="US7165824B2_D1177.tif" /> Adr<sub>2</sub>) # the other writes are taken care of by</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>the MAU</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry /><entry>shadowsOff <img file="US7165824B2_D1178.tif" /> ReqDataOut<sub>0</sub></entry></row><row><entry /><entry>hiFlashAdr <img file="US7165824B2_D1179.tif" /> ReqDataOut<sub>1</sub></entry></row><row><entry /><entry>infoBlockSel <img file="US7165824B2_D1180.tif" /> ReqDataOut<sub>2</sub></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="231pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="245pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 19 Memory Access Unit
7458The Memory Access Unit (MAU) takes memory access control signals and turns them into RAM accesses and flash access strobed signals with appropriate duration.
7459A new transaction is given by MRUNewTrans. The address to be read from or written to is on MRUAdr, which is a nybble-based address. The MRUAdr (13-bits) is used as-is for Flash addressing. When MRURAMSel=1, then the RAM address (RAMAdr) is taken from bits <b>9</b>–<b>3</b> of MRUAdr. The data to be written is on MRUData.
7460The return value MAURdy is set when the MAU is capable of receiving a new transaction the following cycle. Thus MAURdy will be 1 during the final cycle of a flash or ram access, and should be 1 when the MAU is idle. MAURdy should only be 0 during startup or when a transaction has yet to finish.
7461When MRURAMSel=1, the access is to RAM, and MRUMode has the following interpretation:
7462<tables id="TABLE-US-00615" num="00615"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 384</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Interpretation of MRUMode<sup>10 </sup>for RAM accesses</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="77pt" align="left" /><colspec colname="2" colwidth="84pt" align="left" /><tbody valign="top"><row><entry /><entry>bits</entry><entry>action</entry></row><row><entry /><entry>xx0</entry><entry>doWrite</entry></row><row><entry /><entry>xx1</entry><entry>doRead</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry namest="offset" nameend="2" align="left" id="FOO-00122"><sup>10</sup>MRUMode<sub>2-1 </sub>is ignored for RAM accesses</entry></row></tbody></tgroup></table></tables><ul id="ul1132" list-style="none"><li id="ul1132-0001" num="0000"><ul id="ul1133" list-style="none"><li id="ul1133-0001" num="7463">When MRURAMSel=0, the access is to flash. If MRUTesfWE=0, then the access is to regular flash memory, as given by MRUMode:</li></ul></li></ul>
7464<tables id="TABLE-US-00616" num="00616"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 385</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Interpretation of MRUMode for regular flash accesses<sup>11</sup></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="28pt" align="left" /><colspec colname="2" colwidth="98pt" align="left" /><colspec colname="3" colwidth="91pt" align="left" /><tbody valign="top"><row><entry>bits 1–0</entry><entry>action when MRUMode<sub>2 </sub>= 1</entry><entry>action when MRUMode<sub>2 </sub>= 1</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>00</entry><entry>doWrite (main memory)</entry><entry>doWrite (info block)</entry></row><row><entry>01</entry><entry>doRead (main memory)</entry><entry>doRead (info block)</entry></row><row><entry>10</entry><entry>doErasePage (main</entry><entry>doErasePage (info block)</entry></row><row><entry /><entry>memory)</entry></row><row><entry>11</entry><entry>doEraseDevice (main</entry><entry>doEraseDevice (both</entry></row><row><entry /><entry>memory)</entry><entry>blocks)</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry namest="1" nameend="3" align="left" id="FOO-00123"><sup>11</sup>MRUMode<sub>2 </sub>can be directly interpreted by the MAU as the IFREN signal required for embedded flash block SFC008_08B9_HE</entry></row></tbody></tgroup></table></tables><ul id="ul1134" list-style="none"><li id="ul1134-0001" num="0000"><ul id="ul1135" list-style="none"><li id="ul1135-0001" num="7465">If MRUTestWE is 1, then MRUMode<sub>2 </sub>will also be 0, and the access is to a flash test register, as given by MRUMode:</li></ul></li></ul>
7466<tables id="TABLE-US-00617" num="00617"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 386</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Interpretation of MRUMode for flash test register write accesses</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="21pt" align="left" /><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>bits<sup>12</sup></entry><entry>action</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry>xx1</entry><entry>If (MRUData<sub>3 </sub>= 0), tie the flash IP</entry></row><row><entry /><entry /><entry>test register to its reset state</entry></row><row><entry /><entry /><entry>If (MRUData<sub>3 </sub>= 1), take the flash IP</entry></row><row><entry /><entry /><entry>test register out of reset state, and</entry></row><row><entry /><entry /><entry>write MRUData<sub>8−4 </sub>to the 5-bit flash</entry></row><row><entry /><entry /><entry>test register within the flash IP</entry></row><row><entry /><entry /><entry>(SFC008_08B9_HE)</entry></row><row><entry /><entry>x1x</entry><entry>Write MRUData<sub>28−9 </sub>to the internal 20-</entry></row><row><entry /><entry /><entry>bit alternate-counter-source register</entry></row><row><entry /><entry /><entry>flashTime, and MRUData<sub>29 </sub>to the corres-</entry></row><row><entry /><entry /><entry>ponding 1-bit test register timerSel.</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row><row><entry /><entry namest="offset" nameend="2" align="left" id="FOO-00124"><sup>12</sup>MRUMode<sub>2 </sub>will always be 0 when MRUTestWE = 1.</entry></row></tbody></tgroup></table></tables><br /> 19.1 Implementation
7467The MAU consists of logic that calculates MAURdy, and additional logic that produces the various strobed signals according to the TSMC Flash memory SFC0008<sub>—</sub>08B9_HE; refer to this datasheet [4] for detailed timing diagrams. Both main memory and information blocks can be accessed in the Flash. The Flash test modes are also supported as described in [5] and general application information is given in [6].
7468The MAU can be considered to be a RAM control block and a flash control block, with appropriate action selected by MRURAMSel. For all modes except read, the Flash requires wait states (which are implemented with a single counter) during which it is possible to access the RAM. Only 1 transaction may be pending while waiting for the wait states to expire. Multiple bytes may be written to Flash without exiting the write mode.
7469The MAU ensures that only valid control sequences meeting the timing requirements of the Flash memory are provided. A write time-out is included which ensures the Flash cannot be left in write mode indefinitely; this is used when the Flash is programmed via the IO Unit to ensure the X address does not change while in write mode. Otherwise, other units should ensure that when writing bytes to Flash, the X address does not change. The X address is held constant by the MAU during write and page erase modes to protect the Flash. If an X address change is detected by the MAU during a Flash write sequence, it will exit write mode allowing the X address to change and re-enter write mode. Thus, the data will still be written to Flash but it will take longer.
7470When either the Flash or RAM is not being used, the MAU sets the control signals to put the particular memory type into standby to minimise power consumption.
7471The MAU assumes no new transactions can start while one is in progress and all inputs must remain constant until MAU is ready.
000019.2 Flash Test Mode
7472MAU also enables the Flash test mode register to be programmed which allows various production tests to be carried out. If MRUTestWE=1, transactions are directed towards the test mode register. Most of the tests use the same control sequences that are used for normal operation except that one time value needs to be changed. This is provided by the flashTime register that can be written to by the CPU allowing the timer to be set to a range of values up to more than 1 second. A special control sequence is generated when the test mode register is set to 0x1E and is initiated by writing to the Flash.
7473Note that on reset, timeSel and flashTime are both cleared to 0. The 5-bit flash test register within the TSMC flash IP is also reset by setting TMR=1. When MRUTestWE=1, any open write sequence is closed even if the write is not to the 5-bit flash test register within the TSMC flash IP.
000019.3 Flash Power Failure Protection
7474Power could fail at any time; the most serious consequence would be if this occurred during writing to the Flash and data became corrupted in another location to that being written to. The MAU will protect the Flash by switching off the charge pump (high voltage supply used for programming and erasing) as soon as the power starts to fail. After a time delay of about 5 μs (programmable), to allow the discharge of the charge pump, the QA chip will be reset whether or not the power supply recovers.
000019.4 Flash Access State Machine
000019.5 Interface
7475<tables id="TABLE-US-00618" num="00618"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 387</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>MAU interface description</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="21pt" align="left" /><colspec colname="3" colwidth="126pt" align="left" /><tbody valign="top"><row><entry>Signal name</entry><entry>I/O</entry><entry>Description</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>Clk</entry><entry>In</entry><entry>System clock.</entry></row><row><entry>RstL</entry><entry>In</entry><entry>System reset (active low).</entry></row><row><entry>MAURAMEn</entry><entry>In</entry><entry>Flag indicating whether the</entry></row><row><entry /><entry /><entry>external user needs access to</entry></row><row><entry /><entry /><entry>the RAM at a gross level (e.g.</entry></row><row><entry /><entry /><entry>the CPU is active and therefore</entry></row><row><entry /><entry /><entry>may want RAM access). 1 = wants</entry></row><row><entry /><entry /><entry>access available, 0 = don't want.</entry></row><row><entry>MRUNewTrans</entry><entry>In</entry><entry>Flag indicating MRU wishes to</entry></row><row><entry /><entry /><entry>start a new transaction. May only</entry></row><row><entry /><entry /><entry>be asserted (=1) when MAURdy = 1.</entry></row><row><entry /><entry /><entry>All inputs below must be held constant</entry></row><row><entry /><entry /><entry>until MAU is ready.</entry></row><row><entry>MRURAMSel</entry><entry>In</entry><entry>1 = RAM, 0 = Flash.</entry></row><row><entry>MRUMode2–0</entry><entry>In</entry><entry>Type of transaction to be performed.</entry></row><row><entry>MRUAdr12–0</entry><entry>In</entry><entry>Memory address from the MRU.</entry></row><row><entry>MRUDataOut31–0</entry><entry>In</entry><entry>Data used to control and set test</entry></row><row><entry /><entry /><entry>modes and timing.</entry></row><row><entry>MRUTestWE</entry><entry>In</entry><entry>Flag indicating test mode transactions.</entry></row><row><entry>PwrFailing</entry><entry>In</entry><entry>Flag indicating possible power failure</entry></row><row><entry /><entry /><entry>in progress.</entry></row><row><entry>MAURdy</entry><entry>Out</entry><entry>The MAU is ready when MAURdy = 1.</entry></row><row><entry /><entry /><entry>It is always set for RAM transactions</entry></row><row><entry /><entry /><entry>and held low during Flash wait states.</entry></row><row><entry>RAMOutEn</entry><entry>Out</entry><entry>0 = enable the RAM to read or write</entry></row><row><entry /><entry /><entry>this cycle (i.e. active low) 1 =</entry></row><row><entry /><entry /><entry>disable the RAM this cycle (saves</entry></row><row><entry /><entry /><entry>power, memory is intact)</entry></row><row><entry>RAMWE</entry><entry>Out</entry><entry>RAM write when RAMWE = 0 (Artisan</entry></row><row><entry /><entry /><entry>Synchronous SRAM).</entry></row><row><entry>MemClk</entry><entry>Out</entry><entry>Inverted system clock to the RAM</entry></row><row><entry /><entry /><entry>(required to meet timing).</entry></row><row><entry>FlashCtrl8–0</entry><entry>Out</entry><entry>Control signals to the Flash.</entry></row><row><entry /><entry /><entry>IFREN = information block enable,</entry></row><row><entry /><entry /><entry>not used always = 0</entry></row><row><entry /><entry /><entry>XE = X address enable</entry></row><row><entry /><entry /><entry>YE = Y address enable</entry></row><row><entry /><entry /><entry>SE = sense amplifier enable</entry></row><row><entry /><entry /><entry>(read only)</entry></row><row><entry /><entry /><entry>OE = output enable (read only),</entry></row><row><entry /><entry /><entry>hi-Z when OE = 0</entry></row><row><entry /><entry /><entry>PROG = program (write bytes)</entry></row><row><entry /><entry /><entry>NVSTR = enables all write and</entry></row><row><entry /><entry /><entry>erase modes</entry></row><row><entry /><entry /><entry>ERASE = page erase mode</entry></row><row><entry /><entry /><entry>MAS1 = mass erase mode</entry></row><row><entry>TMR</entry><entry>Out</entry><entry>TMR = Register reset for test</entry></row><row><entry /><entry /><entry>mode</entry></row><row><entry>RAMAdr6–0</entry><entry>Out</entry><entry>RAM address in the range 0 to 95.</entry></row><row><entry>FlashAdr12–0</entry><entry>Out</entry><entry>Flash address, full range.</entry></row><row><entry>MAURstOutL</entry><entry>Out</entry><entry>Activates the global reset, RstL.</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 19.6 Calculation of Timer Values
7476Set and calculate timer initialisation values based on Flash data sheet values, clock period and clock range.
7477<tables id="TABLE-US-00619" num="00619"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry># Note: Flash data sheet gives minimum timings</entry></row><row><entry># Delays greater than 1 clock cycle</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><colspec colname="3" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>clock_per</entry><entry>= 100</entry><entry># ns</entry></row><row><entry>Flash_Tnvs</entry><entry>= 7500</entry><entry># ns</entry></row><row><entry>Flash_Tnvh</entry><entry>= 7500</entry><entry># ns</entry></row><row><entry>Flash_Tnvh1</entry><entry>= 150</entry><entry># us</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="91pt" align="left" /><colspec colname="3" colwidth="56pt" align="left" /><tbody valign="top"><row><entry>Flash_Tpgs</entry><entry>= 15</entry><entry># us</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><colspec colname="3" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>Flash_Tpgh</entry><entry>= 100</entry><entry># ns</entry></row><row><entry>Flash_Tprog</entry><entry>= 30</entry><entry># us</entry></row><row><entry>Flash_Tads</entry><entry>= 100</entry><entry># ns</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><colspec colname="3" colwidth="42pt" align="left" /><colspec colname="4" colwidth="70pt" align="left" /><tbody valign="top"><row><entry>Flash_Tadh</entry><entry>= 30</entry><entry># us</entry><entry># Byte write timeout</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><colspec colname="3" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>Flash_Trcv</entry><entry>= 1500</entry><entry># ns</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="4"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><colspec colname="3" colwidth="42pt" align="left" /><colspec colname="4" colwidth="70pt" align="left" /><tbody valign="top"><row><entry>Flash_Thv</entry><entry>= 6</entry><entry># ms</entry><entry># Not currently used</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><colspec colname="3" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>Flash_Terase</entry><entry>= 30</entry><entry># ms</entry></row><row><entry>Flash_Tme</entry><entry>= 300</entry><entry># ms</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry># Derive maximum counts (−1 since state machine is synchronous)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>FLASH_NVS</entry><entry>= Flash_Tnvs/clock_per − 1</entry></row><row><entry>FLASH_NVH</entry><entry>= Flash_Tnvh/clock_per − 1</entry></row><row><entry>FLASH_NVH1</entry><entry>= Flash_Tnvh1*1000/clock_per − 1</entry></row><row><entry>FLASH_PGS</entry><entry>= Flash_Tpgs*1000/clock_per − 1</entry></row><row><entry>FLASH_PGH</entry><entry>= Flash_Tpgh/clock_per − 1</entry></row><row><entry>FLASH_PROG</entry><entry>= Flash_Tprog*1000/clock_per − 1</entry></row><row><entry>FLASH_ADS</entry><entry>= Flash_Tads/clock_per − 1</entry></row><row><entry>FLASH_ADH</entry><entry>= Flash_Tadh*1000/clock_per − 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>FLASH_ADH_AND_WRITE_PGH =</entry></row><row><entry>FLASH_ADH + FLASH_PGH + 1 # note is +1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="147pt" align="left" /><tbody valign="top"><row><entry>FLASH_RCV</entry><entry>= Flash_Trcv/clock_per − 1</entry></row><row><entry>FLASH_HV</entry><entry>= Flash_Thv*1000000/clock_per − 1</entry></row><row><entry>FLASH_ERASE</entry><entry>= Flash_Terase*1000000/clock_per − 1</entry></row><row><entry>FLASH_ME</entry><entry>= Flash_Tme*1000000/clock_per − 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="70pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><colspec colname="3" colwidth="112pt" align="left" /><tbody valign="top"><row><entry>count_size</entry><entry>= 24</entry><entry># Number of bits in timer counter</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="105pt" align="left" /><colspec colname="1" colwidth="112pt" align="left" /><tbody valign="top"><row><entry /><entry>(newCount)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>determined by Tme</entry></row><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 19.7 Defaults <ul id="ul1136" list-style="none"><li id="ul1136-0001" num="0000"><ul id="ul1137" list-style="none"><li id="ul1137-0001" num="7478">Defaults to use when no action is specified.</li></ul></li></ul>
7479<tables id="TABLE-US-00620" num="00620"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>FlashTransPendingSet = 0</entry></row><row><entry /><entry>FlashTransPendingReset = 0</entry></row><row><entry /><entry>TMRSet = 0</entry></row><row><entry /><entry>TMRRst = 0</entry></row><row><entry /><entry>STLESet = 0</entry></row><row><entry /><entry>STLERst = 0</entry></row><row><entry /><entry>TestTimeEn = 0</entry></row><row><entry /><entry>IFREN = FlashXadr<sub>7</sub></entry></row><row><entry /><entry>XE = 0</entry></row><row><entry /><entry>YE = 0</entry></row><row><entry /><entry>SE = 0</entry></row><row><entry /><entry>OE = 0</entry></row><row><entry /><entry>PROG = 0</entry></row><row><entry /><entry>NVSTR = 0</entry></row><row><entry /><entry>ERASE = 0</entry></row><row><entry /><entry>MAS1 = 0</entry></row><row><entry /><entry>MAURstOutL = 1</entry></row><row><entry /><entry>If (accessCount ≠ 0)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>newCount =accessCount − 1</entry></row><row><entry /><entry># decrement unless instructed</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>otherwise</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>newCount = 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 19.8 Reset <ul id="ul1138" list-style="none"><li id="ul1138-0001" num="0000"><ul id="ul1139" list-style="none"><li id="ul1139-0001" num="7480">Initialise state and counter registers</li></ul></li></ul>
7481<tables id="TABLE-US-00621" num="00621"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry># asynchronous reset (active low)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>state <img file="US7165824B2_D1181.tif" /> idle</entry></row><row><entry /><entry>accessCount <img file="US7165824B2_D1182.tif" /> 1</entry></row><row><entry /><entry>countZ <img file="US7165824B2_D1183.tif" /> 0</entry></row><row><entry /><entry>XadrReg <img file="US7165824B2_D1184.tif" /> 0</entry></row><row><entry /><entry>FlashTransPending <img file="US7165824B2_D1185.tif" /> 0</entry></row><row><entry /><entry>TestTime <img file="US7165824B2_D1186.tif" /> 0</entry></row><row><entry /><entry>TMR <img file="US7165824B2_D1187.tif" /> 1</entry></row><row><entry /><entry>STLEFlag <img file="US7165824B2_D1188.tif" /> 0</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 19.9 State Machine
7482The state machine generates sequences of timed waveforms to control the operation of the Flash memory.
7483<tables id="TABLE-US-00622" num="00622"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>idle</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>FlashTransPendingReset = 1</entry></row><row><entry /><entry>If (somethingToDo) # Flash starting conditions</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>If (MRUTestWE)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>nextState = TM0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>Switch (MRUModeint)</entry></row><row><entry /><entry>Case doWrite:</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="84pt" align="left" /><colspec colname="1" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>nextState = writeNVS</entry></row><row><entry /><entry>newCount = FLASH_NVS</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>Case doRead:</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="84pt" align="left" /><colspec colname="1" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>YE = 1</entry></row><row><entry /><entry>SE = 1</entry></row><row><entry /><entry>OE = 1</entry></row><row><entry /><entry>XE = 1</entry></row><row><entry /><entry>nextState = idle</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>Case doErasePage:</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="84pt" align="left" /><colspec colname="1" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>nextState = pageErase</entry></row><row><entry /><entry>newCount = FLASH_NVS</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>Case doEraseDevice:</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="84pt" align="left" /><colspec colname="1" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>nextState = massErase</entry></row><row><entry /><entry>newCount = FLASH_NVS</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>EndSwitch</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 19.9.1 Flash Page Erase <ul id="ul1140" list-style="none"><li id="ul1140-0001" num="0000"><ul id="ul1141" list-style="none"><li id="ul1141-0001" num="7484">The following pseducocode illustrates the Flash page erase sequence.</li></ul></li></ul>
7485<tables id="TABLE-US-00623" num="00623"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>pageErase</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>ERASE = 1</entry></row><row><entry /><entry>XE = 1</entry></row><row><entry /><entry>If (<img file="US7165824B2_D1189.tif" /> PwrFailing)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>If (countZ)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="84pt" align="left" /><colspec colname="1" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>newCount = FLASH_ERASE</entry></row><row><entry /><entry>nextState = pageEraseERASE</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>newCount = TestTime<sub>19−0</sub></entry></row><row><entry /><entry>nextState = Help1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>pageEraseERASE</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>ERASE = 1</entry></row><row><entry /><entry>NVSTR = 1</entry></row><row><entry /><entry>XE = 1</entry></row><row><entry /><entry>If (<img file="US7165824B2_D1190.tif" /> PwrFailing)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>If (countZ)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="84pt" align="left" /><colspec colname="1" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>newCount = FLASH_NVH</entry></row><row><entry /><entry>nextState = pageEraseNVH</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>newCount = TestTime<sub>19−0</sub></entry></row><row><entry /><entry>nextState = Help1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>pageEraseNVH</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>NVSTR = 1</entry></row><row><entry /><entry>XE = 1</entry></row><row><entry /><entry>If (<img file="US7165824B2_D1191.tif" /> PwrFailing)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>If (countZ)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="84pt" align="left" /><colspec colname="1" colwidth="133pt" align="left" /><tbody valign="top"><row><entry /><entry>newCount = FLASH_RCV</entry></row><row><entry /><entry>nextState = RCVPM</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>newCount = TestTime<sub>19−0</sub></entry></row><row><entry /><entry>nextState = Help1</entry></row><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>RCVPM</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>If (countZ)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>nextState = idle # exit</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 19.9.2 Flash Mass Erase <ul id="ul1142" list-style="none"><li id="ul1142-0001" num="0000"><ul id="ul1143" list-style="none"><li id="ul1143-0001" num="7486">The following pseducocode illustrates the Flash mass erase sequence.</li></ul></li></ul>
7487<tables id="TABLE-US-00624" num="00624"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>massErase</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>MAS1 = 1</entry></row><row><entry /><entry>ERASE = 1</entry></row><row><entry /><entry>XE = 1</entry></row><row><entry /><entry>If (countZ)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="63pt" align="left" /><colspec colname="1" colwidth="154pt" align="left" /><tbody valign="top"><row><entry /><entry>If (<img file="US7165824B2_D1192.tif" /> TestTime<sub>20</sub>)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="77pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>newCount = FLASH_ME</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="63pt" align="left" /><colspec colname="1" colwidth="154pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="77pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>newCount = TestTime<sub>19−0 </sub>| 0000</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="63pt" align="left" /><colspec colname="1" colwidth="154pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>nextState = massEraseME</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>massEraseME</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>MAS1 = 1</entry></row><row><entry /><entry>ERASE = 1</entry></row><row><entry /><entry>NVSTR = 1</entry></row><row><entry /><entry>XE = 1</entry></row><row><entry /><entry>If (countZ)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="63pt" align="left" /><colspec colname="1" colwidth="154pt" align="left" /><tbody valign="top"><row><entry /><entry>newCount = FLASH_NVH1</entry></row><row><entry /><entry>nextState = massEraseNVH1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="35pt" align="left" /><colspec colname="1" colwidth="182pt" align="left" /><tbody valign="top"><row><entry /><entry>massEraseNVH1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>MAS1 = 1</entry></row><row><entry /><entry>NVSTR = 1</entry></row><row><entry /><entry>XE = 1</entry></row><row><entry /><entry>If (countZ)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="63pt" align="left" /><colspec colname="1" colwidth="154pt" align="left" /><tbody valign="top"><row><entry /><entry>newCount = FLASH_RCV</entry></row><row><entry /><entry>nextState = RCVPM</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><ul id="ul1144" list-style="none"><li id="ul1144-0001" num="0000"><ul id="ul1145" list-style="none"><li id="ul1145-0001" num="7488">The following pseducocode illustrates the Flash byte write sequence.</li></ul></li></ul>
7489<tables id="TABLE-US-00625" num="00625"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>writeNVS</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>PROG = 1</entry></row><row><entry /><entry>XE = 1</entry></row><row><entry /><entry>If (<img file="US7165824B2_D1193.tif" /> PwrFailing)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>If (countZ)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>If (<img file="US7165824B2_D1194.tif" /> STLEFlag)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>newCount = FLASH_PGS</entry></row><row><entry /><entry>nextState = writePGS</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>newCount = TestTime<sub>19−0 </sub>| 0000</entry></row><row><entry /><entry>nextState = STLE0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>newCount = TestTime<sub>19−0</sub></entry></row><row><entry /><entry>nextState = Help1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>writePGS</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>PROG = 1</entry></row><row><entry /><entry>NVSTR = 1</entry></row><row><entry /><entry>XE = 1</entry></row><row><entry /><entry>If (<img file="US7165824B2_D1195.tif" /> PwrFailing)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>If (countZ)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>newCount = FLASH_ADS</entry></row><row><entry /><entry>nextState = writeADS</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>newCount = TestTime<sub>19−0</sub></entry></row><row><entry /><entry>nextState = Help1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>writeADS # Add Tads to Tpgs</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>PROG = 1</entry></row><row><entry /><entry>NVSTR = 1</entry></row><row><entry /><entry>XE = 1</entry></row><row><entry /><entry>FlashTransPendingReset = 1</entry></row><row><entry /><entry>If (<img file="US7165824B2_D1196.tif" /> PwrFailing)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>If (countZ)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>If (<img file="US7165824B2_D1197.tif" /> TestTime<sub>20</sub>)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>newCount = FLASH_PROG</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>newCount = TestTime<sub>19−0 </sub>| 0000</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>nextState = writePROG</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>newCount = TestTime<sub>19−0</sub></entry></row><row><entry /><entry>nextState = Help1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>writePROG</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>PROG = 1</entry></row><row><entry /><entry>NVSTR = 1</entry></row><row><entry /><entry>YE = 1</entry></row><row><entry /><entry>XE = 1</entry></row><row><entry /><entry>If (<img file="US7165824B2_D1198.tif" /> PwrFailing)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>If (countZ)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>newCount = FLASH_ADH_AND_WRITE_PGH</entry></row><row><entry /><entry>nextState = writeADH</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>newCount = TestTime<sub>19−0</sub></entry></row><row><entry /><entry>nextState = Help2</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>writeADH</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>PROG = 1</entry></row><row><entry /><entry>NVSTR = 1</entry></row><row><entry /><entry>XE = 1</entry></row><row><entry /><entry>FlashTransPendingSet = somethingToDo</entry></row><row><entry /><entry>If (<img file="US7165824B2_D1199.tif" /> PwrFailing)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>If (<img file="US7165824B2_D1200.tif" /> FlashNewTrans)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>If (countZ) -- Gracefull exit after timeout</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>newCount = FLASH_NVH</entry></row><row><entry /><entry>nextState = writeNVH</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>Else # -- Do something as there is a new transaction</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>If ((MRUModeint = doWrite) <img file="US7165824B2_D1201.tif" /> (<img file="US7165824B2_D1202.tif" /> XadrCh))</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>newCount = FLASH_ADS -- Write another byte</entry></row><row><entry /><entry>nextState = writeADS</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>newCount = FLASH_NVH -- Exit as new</entry></row><row><entry /><entry>trans is not Flash</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>write</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>nextState = writeNVH</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>newCount = TestTime<sub>19−0</sub></entry></row><row><entry /><entry>nextState = Help1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>writeNVH</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>NVSTR = 1</entry></row><row><entry /><entry>XE = 1</entry></row><row><entry /><entry>FlashTransPendingSet = somethingToDo</entry></row><row><entry /><entry>If (<img file="US7165824B2_D1203.tif" /> PwrFailing)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>If (countZ)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>newCount = FLASH_RCV</entry></row><row><entry /><entry>nextState = RCV</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>newCount = TestTime<sub>19−0</sub></entry></row><row><entry /><entry>nextState = Help1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="1" colwidth="35pt" align="left" /><colspec colname="2" colwidth="182pt" align="left" /><tbody valign="top"><row><entry>RCV</entry><entry># wait til we're allowed to do another transaction</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>FlashTransPendingSet = somethingToDo</entry></row><row><entry /><entry>If (countZ)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>nextState = idle</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 19.9.4 Test Mode Sequence <ul id="ul1146" list-style="none"><li id="ul1146-0001" num="0000"><ul id="ul1147" list-style="none"><li id="ul1147-0001" num="7490">The following pseducocode illustrates the test mode sequence.</li></ul></li></ul>
7491<tables id="TABLE-US-00626" num="00626"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>TM0 # Needed this due to delay on TMR</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>IFREN = 0</entry></row><row><entry /><entry>nextState = idle # default</entry></row><row><entry /><entry>If ( MRUModeint<sub>1</sub>)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>TestTimeEn = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>If (MRUModeint<sub>0</sub>)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>If (<img file="US7165824B2_D1204.tif" /> MRUDataOut<sub>3</sub>)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>TMRSet = 1</entry></row><row><entry /><entry>STLERst = 1 # Reset flag as leaving test mode</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>If (MRUDataOut<sub>8−4 </sub>= 11110)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>STLESet = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="70pt" align="left" /><colspec colname="1" colwidth="147pt" align="left" /><tbody valign="top"><row><entry /><entry>STLERst = 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="56pt" align="left" /><colspec colname="1" colwidth="161pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>TMRRst = 1</entry></row><row><entry /><entry>nextState = TM1 # Will get priority</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>TM1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>IFREN = 0</entry></row><row><entry /><entry>nextState = TM2</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>TM2</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>NVSTR = 1</entry></row><row><entry /><entry>SE = 1</entry></row><row><entry /><entry>IFREN = 0</entry></row><row><entry /><entry>nextState = TM3</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>TM3</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>NVSTR = 1</entry></row><row><entry /><entry>SE = 1</entry></row><row><entry /><entry>MAS1 = MRUDataOut<sub>4</sub></entry></row><row><entry /><entry>IFREN = MRUDataOut<sub>5</sub></entry></row><row><entry /><entry>XE = MRUDataOut<sub>6</sub></entry></row><row><entry /><entry>YE = MRUDataOut<sub>7</sub></entry></row><row><entry /><entry>ERASE = MRUDataOut<sub>8</sub></entry></row><row><entry /><entry>TMRSet = 1</entry></row><row><entry /><entry>nextState = TM4</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>TM4</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>NVSTR = 1</entry></row><row><entry /><entry>SE = 1</entry></row><row><entry /><entry>MAS1 = MRUDataOut<sub>4</sub></entry></row><row><entry /><entry>IFREN = MRUDataOut<sub>5</sub></entry></row><row><entry /><entry>XE = MRUDataOut<sub>6</sub></entry></row><row><entry /><entry>YE = MRUDataOut<sub>7</sub></entry></row><row><entry /><entry>ERASE = MRUDataOut<sub>8</sub></entry></row><row><entry /><entry>TMRRst = 1</entry></row><row><entry /><entry>nextState = TM5</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>TM5</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>NVSTR = 1</entry></row><row><entry /><entry>SE = 1</entry></row><row><entry /><entry>MAS1 = MRUDataOut<sub>4</sub></entry></row><row><entry /><entry>IFREN = MRUDataOut<sub>5</sub></entry></row><row><entry /><entry>XE = MRUDataOut<sub>6</sub></entry></row><row><entry /><entry>YE = MRUDataOut<sub>7</sub></entry></row><row><entry /><entry>ERASE = MRUDataOut<sub>8</sub></entry></row><row><entry /><entry>nextState = TM6</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>TM6</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>NVSTR = 1</entry></row><row><entry /><entry>SE = 1</entry></row><row><entry /><entry>nextState = idle</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 19.9.5 Reverse Tunneling and Thin Oxide Leak Test <ul id="ul1148" list-style="none"><li id="ul1148-0001" num="0000"><ul id="ul1149" list-style="none"><li id="ul1149-0001" num="7492">The following pseducocode shows the reverse tunneling and thin oxide leak test sequence.</li></ul></li></ul>
7493<tables id="TABLE-US-00627" num="00627"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>STLE0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="63pt" align="left" /><colspec colname="1" colwidth="154pt" align="left" /><tbody valign="top"><row><entry /><entry>XE = 1</entry></row><row><entry /><entry>PROG = 1</entry></row><row><entry /><entry>NVSTR = 1</entry></row><row><entry /><entry>If (countZ)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="77pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>newCount = FLASH_NVH</entry></row><row><entry /><entry>nextState = STLE1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="63pt" align="left" /><colspec colname="1" colwidth="154pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>STLE1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="63pt" align="left" /><colspec colname="1" colwidth="154pt" align="left" /><tbody valign="top"><row><entry /><entry>XE = 1</entry></row><row><entry /><entry>NVSTR = 1</entry></row><row><entry /><entry>If (countZ)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="77pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>newCount = FLASH_RCV</entry></row><row><entry /><entry>nextState = STLE2</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="63pt" align="left" /><colspec colname="1" colwidth="154pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="49pt" align="left" /><colspec colname="1" colwidth="168pt" align="left" /><tbody valign="top"><row><entry /><entry>STLE2</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="63pt" align="left" /><colspec colname="1" colwidth="154pt" align="left" /><tbody valign="top"><row><entry /><entry>If (countZ)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="77pt" align="left" /><colspec colname="1" colwidth="140pt" align="left" /><tbody valign="top"><row><entry /><entry>nextState = idle</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="63pt" align="left" /><colspec colname="1" colwidth="154pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 19.9.6 Emergency Instructions <ul id="ul1150" list-style="none"><li id="ul1150-0001" num="0000"><ul id="ul1151" list-style="none"><li id="ul1151-0001" num="7494">The following pseducocode shows the states used for emergency situations such as when power is failing.</li></ul></li></ul>
7495<tables id="TABLE-US-00628" num="00628"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><thead><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry>Help1 # MAURdy −> 0 to hold MAU inputs constant, if not too late</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>XE = 1</entry></row><row><entry /><entry>If (countZ)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>nextState = Goodbye</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Help2 # MAURdy −> 0 to hold MAU inputs constant, if not too late</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>XE = 1</entry></row><row><entry /><entry>YE = 1</entry></row><row><entry /><entry>If (countZ)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>nextState = Goodbye</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>Goodbye</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>XE = 1 # Prevents Flash timing violation</entry></row><row><entry /><entry>MAURstOutL = 0 # Reset whole chip whether power fails</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry># nothing else to do or recovers</entry></row><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 19.10 Concurrent Logic
7496<tables id="TABLE-US-00629" num="00629"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><thead><row><entry /><entry namest="offset" nameend="1" align="center" rowsep="1" /></row></thead><tbody valign="top"><row><entry /><entry>accessCount <img file="US7165824B2_D1205.tif" /> newCount # update accessCount every cycle</entry></row><row><entry /><entry>countZ <img file="US7165824B2_D1206.tif" /> (newCount = 0)</entry></row><row><entry /><entry>XadrReg <img file="US7165824B2_D1207.tif" /> FlashXAdr # store the previous X address</entry></row><row><entry /><entry>state <img file="US7165824B2_D1208.tif" /> nextState</entry></row><row><entry /><entry>If (FlashTransPendingReset)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>FlashTransPending <img file="US7165824B2_D1209.tif" /> 0 # Reset flag (has priority)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>If (FlashTransPendingSet)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>FlashTransPending <img file="US7165824B2_D1210.tif" /> 1 # Set flag</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>If (TestTimeEn)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>TestTime <img file="US7165824B2_D1211.tif" /> MRUDataOut<sub>29−9</sub></entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>If (TMRSet) -- SRFF for TMR</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>TMR <img file="US7165824B2_D1212.tif" /> 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>If (TMRRst)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>TMR <img file="US7165824B2_D1213.tif" /> 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>If (STLERst) -- SRFF for STLE tests</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>STLEFlag <img file="US7165824B2_D1214.tif" /> 0</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>If (STLESet)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="42pt" align="left" /><colspec colname="1" colwidth="175pt" align="left" /><tbody valign="top"><row><entry /><entry>STLEFlag <img file="US7165824B2_D1215.tif" /> 1</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>FlashNewTrans = MRUNewTrans <img file="US7165824B2_D1216.tif" /> (<img file="US7165824B2_D1217.tif" /> MRURAMSel)</entry></row><row><entry /><entry>RAMNewTrans = MRUNewTrans <img file="US7165824B2_D1218.tif" /> MRURAMSel</entry></row><row><entry /><entry>somethingToDo = FlashTransPending <img file="US7165824B2_D1219.tif" /> FlashNewTrans</entry></row><row><entry /><entry>quickCmd = (MRUModeint = doRead) <img file="US7165824B2_D1220.tif" /> <img file="US7165824B2_D1221.tif" /> MRUTestWE</entry></row><row><entry /><entry>FlashRdy = ((state = idle) <img file="US7165824B2_D1222.tif" /> (<img file="US7165824B2_D1223.tif" /> somethingToDo <img file="US7165824B2_D1224.tif" /> quickCmd))</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry><img file="US7165824B2_D1225.tif" /> (((state = writeADH)</entry></row><row><entry /><entry><img file="US7165824B2_D1226.tif" /> (state = writeNVH)</entry></row><row><entry /><entry><img file="US7165824B2_D1227.tif" /> (state = writeRCV)) <img file="US7165824B2_D1228.tif" /> (<img file="US7165824B2_D1229.tif" /> FlashTransPendingSet))</entry></row><row><entry /><entry><img file="US7165824B2_D1230.tif" /> ((state = TM0) <img file="US7165824B2_D1231.tif" /> (nextState = idle))</entry></row><row><entry /><entry><img file="US7165824B2_D1232.tif" /> (state = TM6)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>If (MRURamSel)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>MAURdy = 1 # Always ready for RAM</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>Else</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="28pt" align="left" /><colspec colname="1" colwidth="189pt" align="left" /><tbody valign="top"><row><entry /><entry>MAURdy = FlashRdy</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>EndIf</entry></row><row><entry /><entry>IandX = MRUMode<sub>2 </sub>| MRUAdr<sub>12−6</sub></entry></row><row><entry /><entry>FlashXAdr = IandX When ((<img file="US7165824B2_D1233.tif" /> XE) <img file="US7165824B2_D1234.tif" /> (SE <img file="US7165824B2_D1235.tif" /> OE)) Else XadrReg</entry></row><row><entry /><entry>FlashAdr = FlashXAdr | MRUAdr<sub>5−0 </sub># Merge X and Y addresses</entry></row><row><entry /><entry>XadrCh = 1 When ((XadrReg /= IandX)</entry></row><row><entry /><entry><img file="US7165824B2_D1236.tif" /> XE <img file="US7165824B2_D1237.tif" /> (<img file="US7165824B2_D1238.tif" /> SE) <img file="US7165824B2_D1239.tif" /> (<img file="US7165824B2_D1240.tif" /> OE)</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry><img file="US7165824B2_D1241.tif" /> FlashNewTrans) Else 0</entry></row><row><entry># Xadr change</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>MRUModeint = MRUMode<sub>1−0 </sub># Backwards compatability</entry></row><row><entry /><entry>RAMAdr = MRUAdr<sub>9−3</sub> # maximum address = 95,</entry></row><row><entry /><entry>responsibility of</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="left" /><tbody valign="top"><row><entry>MRU for valid adr</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="2"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="203pt" align="left" /><tbody valign="top"><row><entry /><entry>RAMWE = MRUModeint<sub>0</sub></entry></row><row><entry /><entry>RAMOutEn = <img file="US7165824B2_D1242.tif" /> RAMNewTrans # turn off RAM if not using it</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="91pt" align="left" /><colspec colname="2" colwidth="112pt" align="left" /><tbody valign="top"><row><entry /><entry>FlashCtrl(0)</entry><entry>= IFREN</entry></row><row><entry /><entry>FlashCtrl(1)</entry><entry>= XE</entry></row><row><entry /><entry>FlashCtrl(2)</entry><entry>= YE</entry></row><row><entry /><entry>FlashCtrl(3)</entry><entry>= SE</entry></row><row><entry /><entry>FlashCtrl(4)</entry><entry>= OE</entry></row><row><entry /><entry>FlashCtrl(5)</entry><entry>= PROG</entry></row><row><entry /><entry>FlashCtrl(6)</entry><entry>= NVSTR</entry></row><row><entry /><entry>FlashCtrl(7)</entry><entry>= ERASE</entry></row><row><entry /><entry>FlashCtrl(8)</entry><entry>= MAS1</entry></row><row><entry /><entry>MemClk</entry><entry>= <img file="US7165824B2_D1243.tif" /> Clk # Memory clock</entry></row><row><entry /><entry namest="offset" nameend="2" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 20 Analogue Unit
7497This section specifies the mandatory blocks of Section 11.1 on page 965 in a way which allows some freedom in the detailed implementation.
7498Circuits need to operate over the temperature range −40° C. to +125° C.
7499The unit provides power on reset, protection of the Flash memory against erroneous writes during power down (in conjunction with the MAU) and the system clock SysClk.
000020.1 Voltage Budget
7500The table below shows the key thresholds for V<sub>DD </sub>which define the requirements for power on reset and normal operation.
7501<tables id="TABLE-US-00630" num="00630"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 388</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>V<sub>DD </sub>limits</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="3"><colspec colname="1" colwidth="63pt" align="left" /><colspec colname="2" colwidth="126pt" align="left" /><colspec colname="3" colwidth="28pt" align="left" /><tbody valign="top"><row><entry>VDD parameter</entry><entry>Description</entry><entry>Voltage</entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry>VDDFTmax</entry><entry>Flash test maximum</entry><entry>3.6<sup>13</sup></entry></row><row><entry>VDDFTtyp</entry><entry>Flash test typical</entry><entry>3.3</entry></row><row><entry>VDDFTmin</entry><entry>Flash test minimum</entry><entry>3.0</entry></row><row><entry>VDDmax</entry><entry>Normal operation maximum (typ + 10%)</entry><entry>2.75<sup>14</sup></entry></row><row><entry>VDDtyp</entry><entry>Normal operation typical</entry><entry>2.5</entry></row><row><entry>VDDmin</entry><entry>Normal operation minimum (typ − 5%)</entry><entry>2.375</entry></row><row><entry>VDDPORmax</entry><entry>Power on reset maximum</entry><entry>2.0<sup>15</sup></entry></row><row><entry namest="1" nameend="3" align="center" rowsep="1" /></row><row><entry namest="1" nameend="3" align="left" id="FOO-00125"><sup>13</sup>The voltage VDDFT may only be applied for the times specified in the TSMC Flash memory test document.</entry></row><row><entry namest="1" nameend="3" align="left" id="FOO-00126"><sup>14</sup>Voltage regulators used to derive VDD will typically have symmetric tolerance limits</entry></row><row><entry namest="1" nameend="3" align="left" id="FOO-00127"><sup>15</sup>The minimum allowable voltage for Flash memory operation.</entry></row></tbody></tgroup></table></tables><br /> 20.2 Voltage Reference
7502This circuit generates a stable voltage that is approximately independent of PVT (process, voltage, temperature) and will typically be implemented as a bandgap. Usually, a startup circuit is required to avoid the stable V<sub>bg</sub>=0 condition. The design should aim to minimise the additional voltage above V<sub>bg </sub>required for the circuit to operate. An additional output, BGOn, will be provided and asserted when the bandgap has started and indicates to other blocks that the output voltage is stable and may be used.
7503<tables id="TABLE-US-00631" num="00631"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 389</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Bandgap target performance</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><colspec colname="3" colwidth="35pt" align="center" /><colspec colname="4" colwidth="21pt" align="center" /><colspec colname="5" colwidth="35pt" align="center" /><colspec colname="6" colwidth="42pt" align="left" /><tbody valign="top"><row><entry>Parameter</entry><entry>Conditions</entry><entry>Min</entry><entry>Typ</entry><entry>Max</entry><entry>Units</entry></row><row><entry namest="1" nameend="6" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><colspec colname="3" colwidth="35pt" align="center" /><colspec colname="4" colwidth="21pt" align="char" char="." /><colspec colname="5" colwidth="35pt" align="char" char="." /><colspec colname="6" colwidth="42pt" align="left" /><tbody valign="top"><row><entry>Vbg<sup>16</sup></entry><entry>typical</entry><entry>1.2</entry><entry>1.23</entry><entry>1.26</entry><entry>V</entry></row><row><entry>IDD</entry><entry>typical</entry><entry /><entry>50</entry><entry /><entry>μA</entry></row><row><entry>Vstart</entry><entry>worst case</entry><entry>1.6</entry><entry /><entry /><entry>V</entry></row><row><entry>Iout</entry><entry /><entry /><entry /><entry>10</entry><entry>nA</entry></row><row><entry>Vtemp</entry><entry /><entry /><entry>+0.1</entry><entry /><entry>mV/o C.</entry></row><row><entry namest="1" nameend="6" align="center" rowsep="1" /></row><row><entry namest="1" nameend="6" align="left" id="FOO-00128"><sup>16</sup>Over PVT, not including offsets</entry></row></tbody></tgroup></table></tables><br /> 20.3 Power Detection Unit
7504Only under voltage detection will be described and is required to provide two outputs: <ul id="ul1152" list-style="none"><li id="ul1152-0001" num="0000"><ul id="ul1153" list-style="none"><li id="ul1153-0001" num="7505">underL controls the power on reset; and</li><li id="ul1153-0002" num="7506">PwrFailing indicates possible failure of the power supply.</li></ul></li></ul>
7507Both signals are derived by comparing scaled versions of V<sub>DD </sub>against the reference voltage V<sub>bg</sub>.
000020.3.1 V<sub>DD </sub>Monotonicity
7508The rising and falling edges of V<sub>DD </sub>(from the external power supply) shall be monotonic in order to guarantee correct operation of power on reset and power failing detection. Random noise may be present but should have a peak to peak amplitude of less than the hysteresis of the comparators used for detection in the PDU.
000020.3.2 Under Voltage Detection Unit
7509The underL signal generates the global reset to the logic which should be de-asserted when the supply voltage is high enough for the logic and analogue circuits to operate. Since the logic reset is asynchronous, it is not necessary to ensure the clock is active before releasing the reset or to include any delay.
7510The QA chip logic will start immediately the power on reset is released so this should only be done when the conditions of supply voltage and clock frequency are within limits for the correct operation of the logic.
7511The power on reset signal shall not be triggered by narrow spikes (<100 ns) on the power supply. Some immunity should be provided to power supply glitches although since the QA chip may be under attack, any reset delay should be kept short. The unit should not be triggered by logic dynamic current spikes resulting in short voltage spikes due to bond wire and package inductance. On the rising edge of V<sub>DD</sub>, the maximum threshold for de-asserting the signal shall be when V<sub>DD</sub>>V<sub>DDmin</sub>. On the falling edge of V<sub>DD</sub>, the minimum threshold for asserting the signal shall be V<sub>DD</sub><V<sub>DDPORmax</sub>.
7512The reset signal must be held low long enough (T<sub>pwmin</sub>) to ensure all flip-flops are reset. The standard cell data sheet [7] gives a figure of 0.73 ns for the minimum width of the reset pulse for all flip-flop types.
75132 bits of trimming (trim<sub>1-0</sub>) will be provided to take up all of the error in the bandgap voltage. This will only affect the assertion of the reset during power down since the power on default setting must be used during power up.
7514Although the reference voltage cannot be directly measured, it is compared against V<sub>DD </sub>in the PDU. The state of the power on reset signal can be inferred by trying to communicate through the serial bus with the chip. By polling the chip and slowly increasing V<sub>DD</sub>, a point will be reached where the power on reset is released allowing the serial bus to operate; this voltage should be recorded. As V<sub>DD </sub>is lowered, it will cross the threshold which asserts the reset signal. The power on default is set to the lowest voltage that can be trimmed (which gives the maximum hysterisis). This voltage should be recorded (or it may be sufficient to estimate it from the reset release voltage recorded above). V<sub>DD </sub>is then increased above the reset release threshold and the PDU trim adjusted to the setting the closest to V<sub>DDPORmax</sub>. V<sub>DD </sub>should then be lowered and the threshold at which the reset is re-asserted confirmed.
7515<tables id="TABLE-US-00632" num="00632"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 390</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Power on reset target performance</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="7"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="42pt" align="center" /><colspec colname="3" colwidth="35pt" align="center" /><colspec colname="4" colwidth="21pt" align="center" /><colspec colname="5" colwidth="35pt" align="center" /><colspec colname="6" colwidth="28pt" align="left" /><tbody valign="top"><row><entry /><entry>Parameter</entry><entry>Conditions</entry><entry>Min</entry><entry>Typ</entry><entry>Max</entry><entry>Units</entry></row><row><entry /><entry namest="offset" nameend="6" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="7"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="42pt" align="center" /><colspec colname="3" colwidth="35pt" align="char" char="." /><colspec colname="4" colwidth="21pt" align="char" char="." /><colspec colname="5" colwidth="35pt" align="char" char="." /><colspec colname="6" colwidth="28pt" align="left" /><tbody valign="top"><row><entry /><entry>Vthrup</entry><entry>T = 27o C.</entry><entry>2.0</entry><entry /><entry>2.375</entry><entry>V</entry></row><row><entry /><entry>Vthrdn</entry><entry>T = 27o C.</entry><entry>2.0</entry><entry /><entry>2.1</entry><entry>V</entry></row><row><entry /><entry>Vhystmin</entry><entry /><entry /><entry>16</entry><entry /><entry>mV</entry></row><row><entry /><entry>IDD</entry><entry /><entry /><entry>5</entry><entry /><entry>μA</entry></row><row><entry /><entry>Tspike</entry><entry /><entry /><entry>100</entry><entry /><entry>ns</entry></row><row><entry /><entry>Vminr</entry><entry /><entry /><entry>0.5</entry><entry /><entry>V</entry></row><row><entry /><entry>Tpwmin</entry><entry /><entry>1</entry><entry /><entry /><entry>ns</entry></row><row><entry /><entry namest="offset" nameend="6" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> Power on Reset Behaviour
7516The signal PwrFailing will be used to protect the Flash memory by turning off the charge pump during a write or page erase if the supply voltage drops below a certain threshold. The charge pump is expected to take about 5 us to discharge. The PwrFailing signal shall be protected against narrow spikes (<100 ns) on the power supply.
7517The nominal threshold for asserting the signal needs to be in the range V<sub>PORmax</sub><V<sub>DDPFtyp</sub><V<sub>DDmin </sub>so is chosen to be asserted when V<sub>DD</sub><V<sub>DDPFtyp</sub>=V<sub>DDPORmax</sub>+200 mV. This infers a V<sub>DD </sub>slew rate limitation which must be <200 mV/5 us to ensure enough time to detect that power is failing before the supply drops too low and the reset is activated. This requirement must be met in the application by provision of adequate supply decoupling or other means to control the rate of descent of V<sub>DD</sub>.
7518<tables id="TABLE-US-00633" num="00633"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 391</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Power failing detection target performance</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="7"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="42pt" align="center" /><colspec colname="3" colwidth="35pt" align="center" /><colspec colname="4" colwidth="21pt" align="center" /><colspec colname="5" colwidth="35pt" align="center" /><colspec colname="6" colwidth="28pt" align="left" /><tbody valign="top"><row><entry /><entry>Parameter</entry><entry>Conditions</entry><entry>Min</entry><entry>Typ</entry><entry>Max</entry><entry>Units</entry></row><row><entry /><entry namest="offset" nameend="6" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="7"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="42pt" align="center" /><colspec colname="3" colwidth="35pt" align="char" char="." /><colspec colname="4" colwidth="21pt" align="char" char="." /><colspec colname="5" colwidth="35pt" align="char" char="." /><colspec colname="6" colwidth="28pt" align="left" /><tbody valign="top"><row><entry /><entry>Vthr</entry><entry>T = 27o C.</entry><entry>2.1</entry><entry>2.2</entry><entry>2.3</entry><entry>V<sup>17</sup></entry></row><row><entry /><entry>Vhyst</entry><entry /><entry /><entry>16</entry><entry /><entry>mV</entry></row><row><entry /><entry>IDD</entry><entry /><entry /><entry>5</entry><entry /><entry>μA</entry></row><row><entry /><entry>Tspike</entry><entry /><entry /><entry>100</entry><entry /><entry>ns</entry></row><row><entry /><entry>Vminr</entry><entry /><entry /><entry>0.5</entry><entry /><entry>V</entry></row><row><entry /><entry namest="offset" nameend="6" align="center" rowsep="1" /></row><row><entry /><entry namest="offset" nameend="6" align="left" id="FOO-00129"><sup>17</sup>These limits are after trimming and include an allowance for VDD ramping.</entry></row></tbody></tgroup></table></tables>
75192 bits of trimming (trim<sub>1-0</sub>) will be provided to take up all of the error in the bandgap voltage.
000020.4 Ring Oscillator
7520SysClk is required to be in the range 7–14 MHz throughout the lifetime of the circuit provided V<sub>DD </sub>is maintained within the range V<sub>DDMIN</sub><V<sub>DD</sub><V<sub>DDMAX</sub>. The 2:1 range is derived from the programming time requirements of the TSMC Flash memory. If this range is exceeded, the useful lifetime of the Flash may be reduced.
7521The first version of the QA chip, without physical protection, does not require the addition of random jitter to the clock. However, it is recommended that the ring oscillator be designed in such a way as to allow for the addition of jitter later on with minimal modification. In this way, the un-trimmed centre frequency would not be expected to change.
7522The initial frequency error must be reduced to remain within the range 10 MHz/1.41 to 10 MHz×1.41 allowing for variation in: <ul id="ul1154" list-style="none"><li id="ul1154-0001" num="0000"><ul id="ul1155" list-style="none"><li id="ul1155-0001" num="7523">voltage</li><li id="ul1155-0002" num="7524">temperature</li><li id="ul1155-0003" num="7525">ageing</li><li id="ul1155-0004" num="7526">added jitter</li><li id="ul1155-0005" num="7527">errors in frequency measurement and setting accuracy</li></ul></li></ul>
7528The range budget must be partitioned between these variables.
7529FIG. <b>411</b>._Ring oscillator block diagram
7530The above arrangement allows the oscillator centre frequency to be trimmed since the bias current of the ring oscillator is controlled by the DAC. SysClk is derived by dividing the oscillator frequency by 5 which makes the oscillator smaller and allows the duty cycle of the clock to be better controlled.
000020.4.1 DAC (Programmable Current Source)
7531Using V<sub>bg</sub>, this block sources a current that can be programmed by the Trim signal. 6 of the available 8 trim bits will be used (trim<sub>7-2</sub>) giving a clock adjustment resolution of about 250 kHz. The range of current should be such that the ring oscillator frequency can be adjusted over a 4 to 1 range.
7532<tables id="TABLE-US-00634" num="00634"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 392</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Programmable current source target performance</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="1" colwidth="35pt" align="left" /><colspec colname="2" colwidth="70pt" align="center" /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="35pt" align="center" /><colspec colname="5" colwidth="28pt" align="left" /><colspec colname="6" colwidth="28pt" align="left" /><tbody valign="top"><row><entry>Parameter</entry><entry>Conditions</entry><entry>Min</entry><entry>Typ</entry><entry>Max</entry><entry>Units</entry></row><row><entry namest="1" nameend="6" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="1" colwidth="35pt" align="left" /><colspec colname="2" colwidth="70pt" align="center" /><colspec colname="3" colwidth="21pt" align="center" /><colspec colname="4" colwidth="35pt" align="char" char="." /><colspec colname="5" colwidth="28pt" align="left" /><colspec colname="6" colwidth="28pt" align="left" /><tbody valign="top"><row><entry>Iout</entry><entry>Trim7-2 = 0 </entry><entry /><entry>5</entry><entry /><entry>μA</entry></row><row><entry /><entry>Trim7-2 = 32</entry><entry /><entry>12.5</entry></row><row><entry /><entry>Trim7-2 = 63</entry><entry /><entry>20</entry></row><row><entry>Vrefin</entry><entry /><entry /><entry>1.23</entry><entry /><entry>V</entry></row><row><entry>Rout</entry><entry>Trim7-2 = 63</entry><entry>2.5</entry><entry /><entry /><entry>MΩ</entry></row><row><entry namest="1" nameend="6" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 20.4.2 Ring Oscillator Circuit
7533<tables id="TABLE-US-00635" num="00635"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 393</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Ring oscillator target performance</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><colspec colname="3" colwidth="35pt" align="center" /><colspec colname="4" colwidth="21pt" align="center" /><colspec colname="5" colwidth="35pt" align="center" /><colspec colname="6" colwidth="42pt" align="left" /><tbody valign="top"><row><entry>Parameter</entry><entry>Conditions</entry><entry>Min</entry><entry>Typ</entry><entry>Max</entry><entry>Units</entry></row><row><entry namest="1" nameend="6" align="center" rowsep="1" /></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="6"><colspec colname="1" colwidth="49pt" align="left" /><colspec colname="2" colwidth="35pt" align="left" /><colspec colname="3" colwidth="35pt" align="char" char="." /><colspec colname="4" colwidth="21pt" align="char" char="." /><colspec colname="5" colwidth="35pt" align="center" /><colspec colname="6" colwidth="42pt" align="left" /><tbody valign="top"><row><entry>Fosc<sup>18</sup></entry><entry /><entry>7</entry><entry>10</entry><entry>14</entry><entry>MHz</entry></row><row><entry>IDD</entry><entry /><entry /><entry>10</entry><entry /><entry>μA</entry></row><row><entry>KI</entry><entry /><entry /><entry>1</entry><entry /><entry>MHz/μA</entry></row><row><entry>KVDD</entry><entry /><entry /><entry>+200</entry><entry /><entry>KHz/V</entry></row><row><entry>KT</entry><entry /><entry /><entry>+30</entry><entry /><entry>KHz/o C.</entry></row><row><entry>Vstart</entry><entry /><entry>1.5</entry><entry /><entry /><entry>V</entry></row><row><entry namest="1" nameend="6" align="center" rowsep="1" /></row><row><entry namest="1" nameend="6" align="left" id="FOO-00130">K<sub>I </sub>= control sensitivity,</entry></row><row><entry namest="1" nameend="6" align="left" id="FOO-00131">K<sub>VDD </sub>= V<sub>DD </sub>sensitivity,</entry></row><row><entry namest="1" nameend="6" align="left" id="FOO-00132">K<sub>T </sub>= temperature sensitivity</entry></row><row><entry namest="1" nameend="6" align="left" id="FOO-00133">With the figures above, K<sub>VDD </sub>will give rise to a maximum variation of ±50 kHz and K<sub>T </sub>to ±1.8 MHz over the specified range of V<sub>DD </sub>and temperature.</entry></row><row><entry namest="1" nameend="6" align="left" id="FOO-00134"><sup>18</sup>Accounting for division by 5</entry></row></tbody></tgroup></table></tables><br /> 20.4.3 Div5
7534The ring oscillator will be prescaled by 5 to obtain the nominal 10 MHz clock. An asynchronous design may be used to save power. Several divided clock duty cycles are obtainable, eg 4:1, 3:2 etc. To ease timing requirements for the standard cell logic block, the following clock will be generated; most flip-flops will operate on the rising edge of the clock allowing negative edge clocking to meet memory timing.
7535<tables id="TABLE-US-00636" num="00636"><table frame="none" colsep="0" rowsep="0"><tgroup align="left" colsep="0" rowsep="0" cols="1"><colspec colname="1" colwidth="217pt" align="center" /><thead><row><entry namest="1" nameend="1" rowsep="1">TABLE 394</entry></row></thead><tbody valign="top"><row><entry namest="1" nameend="1" align="center" rowsep="1" /></row><row><entry>Div5 target performance</entry></row></tbody></tgroup><tgroup align="left" colsep="0" rowsep="0" cols="7"><colspec colname="offset" colwidth="14pt" align="left" /><colspec colname="1" colwidth="42pt" align="left" /><colspec colname="2" colwidth="42pt" align="center" /><colspec colname="3" colwidth="35pt" align="center" /><colspec colname="4" colwidth="21pt" align="center" /><colspec colname="5" colwidth="35pt" align="center" /><colspec colname="6" colwidth="28pt" align="left" /><tbody valign="top"><row><entry /><entry>Parameter</entry><entry>Conditions</entry><entry>Min</entry><entry>Typ</entry><entry>Max</entry><entry>Units</entry></row><row><entry /><entry namest="offset" nameend="6" align="center" rowsep="1" /></row><row><entry /><entry>Fmax</entry><entry>Vdd = 1.5 V</entry><entry>100</entry><entry /><entry /><entry>MHz</entry></row><row><entry /><entry>IDD</entry><entry /><entry /><entry>10</entry><entry /><entry>μA</entry></row><row><entry /><entry namest="offset" nameend="6" align="center" rowsep="1" /></row></tbody></tgroup></table></tables><br /> 20.5 Power on Reset
7536This block combines the overL (omitted from the current version), underL and MAURstOutL signals to provide the global reset. MAURstOutL is delayed by one clock cycle to ensure a reset generated when this signal is asserted has at least this duration since the reset deasserts the signal itself. It should be noted that the register, with active low reset RN, is the only one in the QA chip not connected to RstL. <ul id="ul1156" list-style="none"><li id="ul1156-0001" num="7537">[4] TSMC, Oct. 1, 2000, SFC0008<sub>—</sub>08B9_HE, 8K×8 Embedded Flash Memory Specification, Rev 0.1.</li><li id="ul1156-0002" num="7538">[5] TSMC (design service division), Sep. 10, 2001, 0.25 <i>um Embedded Flash Test Mode User Guide</i>, V0.3.</li><li id="ul1156-0003" num="7539">[6] TSMC (EmbFlash product marketing), Oct. 19, 2001, 0.25 <i>um Application Note</i>, V2.2.</li><li id="ul1156-0004" num="7540">[7] Artisan Components, January 1999, Process Perfect Library Databook 2.5-Volt Standard Cells, Rev1.0. <br /> Other Applcations for Protocols and QA Chips <br /> 1 Introduction </li></ul>
7541In its preferred form, the QA chip [1] is a programmable 32 bit microprocessor with security features (8,000 gates, 3 k bits of RAM and 8 kbytes of flash memory for program and non-volatile data storage). It is manufactured in a 0.25 um CMOS process.
7542Physically, the chip is mounted in a 5 pin SOT23 plastic package and communicates with external circuitry via a two pin serial bus.
7543The QA chip was designed to for authenticating consumable usage and performance upgrades in printers and associated hardware.
7544Because of its core functionality and programmability the QA chip can also be used in applications that differ significantly from its original one. This document seeks to identify some of those areas.
00003 Applications Overview
7545Applications include: <ul id="ul1157" list-style="none"><li id="ul1157-0001" num="0000"><ul id="ul1158" list-style="none"><li id="ul1158-0001" num="7546">Regular EEPROM</li><li id="ul1158-0002" num="7547">Secure EEPROM</li><li id="ul1158-0003" num="7548">General purpose MPU with security features</li><li id="ul1158-0004" num="7549">Security coprocessor for microprocessor system</li><li id="ul1158-0005" num="7550">Security coprocessor for PC (with optional USB connection)</li><li id="ul1158-0006" num="7551">Resource dispenser—secure, web based transfer of a variable quantity from “source” to “sink”</li><li id="ul1158-0007" num="7552">IDtag</li><li id="ul1158-0008" num="7553">Security pass inside offices</li><li id="ul1158-0009" num="7554">Set top box security</li><li id="ul1158-0010" num="7555">Car key</li><li id="ul1158-0011" num="7556">Car Petrol</li><li id="ul1158-0012" num="7557">Car manufacturer “genuine parts” detection, where the car requires genuine (or authorised) parts to function.</li><li id="ul1158-0013" num="7558">Aeroplane control on motor-control servos to allow secure external control on an aircraft in a hijack situation.</li><li id="ul1158-0014" num="7559">Security device for controlling access to and copying of audio, video, and data (eg, preventing unauthorized downloading of music to a device). <br /> 4 Exemplary Application Descriptions <br /> 4.1 Car Petrol </li></ul></li></ul>
7560Using mechanisms and protocols similar to those described in relation to ink refills, refilling of petrol can be controlled. An example of a commercial relationship this allows is selling a car at a discounted rate, but requiring that the car be refilled at designated service stations. Similarly, prevention of unauthorized servicing can be achieved.
00004.2 Car Keys
00004.2.1 Basic Advantages Over Physical Keys
0000<ul id="ul1159" list-style="none"><li id="ul1159-0001" num="0000"><ul id="ul1160" list-style="none"><li id="ul1160-0001" num="7561">Keys and locks can be easily programmed & configured for use</li><li id="ul1160-0002" num="7562">Can only be duplicated/reprogrammed by an authorised individual</li><li id="ul1160-0003" num="7563">The same key can be used for physical entry/exit and remote (radio-based) entry/exit</li><li id="ul1160-0004" num="7564">Inbuilt security features <br /> 4.2.2 Single Key for Multiple Vehicles </li></ul></li></ul>
7565Useful when a family has more than one car. <ul id="ul1161" list-style="none"><li id="ul1161-0001" num="0000"><ul id="ul1162" list-style="none"><li id="ul1162-0001" num="7566">Can be programmed so any keys fits any car.</li><li id="ul1162-0002" num="7567">Fewer number of duplicate keys.</li><li id="ul1162-0003" num="7568">Misplacing a key for a particular car—any key for any other car can be used as oppose to duplicate of the same key. <br /> 4.2.3 Multiple Keys for a Single Vehicle <br /> 4.2.3.1 Same Company Car Being Driven by Multiple Drivers </li><li id="ul1162-0004" num="7569">Mileage can be logged per driver e.g. for accounting purposes.</li><li id="ul1162-0005" num="7570">Key permissions can be different per driver (e.g. boot/trunk access may be disabled) <br /> 4.2.3.2 Same Family Car Being Driven by Children and Parents </li><li id="ul1162-0006" num="7571">Time/date restrictions can be applied to (e.g. children's) keys</li><li id="ul1162-0007" num="7572">Speeds above a specified limit (and duration of that speed) can be logged for auditing purposes (may be less dangerous than actually enforcing a speed limit) <br /> 4.2.4 No Problem if Key Lost </li></ul></li></ul>
7573Can easily: <ul id="ul1163" list-style="none"><li id="ul1163-0001" num="0000"><ul id="ul1164" list-style="none"><li id="ul1164-0001" num="7574">make a new key the same as lost one (existing copies of key will still function)</li><li id="ul1164-0002" num="7575">reprogram the locks on car (and reprogram all non-lost keys to match) so the lost key will no longer function <br /> 4.2.5 No Problem if Key Left in Car </li><li id="ul1164-0003" num="7576">Easy to create a one-time-use open-door-only key via roadside assistance based on secret password information, driver's license etc (prevents having to break into the car) <br /> 4.2.6 Car Rentals </li><li id="ul1164-0004" num="7577">Key can have an expiration date (e.g. some period past the rental end-date) <br /> 4.2.7 Single Physical Key for All Locks in Car </li></ul></li></ul>
7578A single physical key can open all locks (door, immobiliser, boot/trunk, glovebox etc.).
0000The Following Documents are Incorporated by Cross-reference[
0000<ul id="ul1165" list-style="none"><li id="ul1165-0001" num="7579">[1] IBM Cu-11 Databook: Macros, Mar. 21, 2002.</li><li id="ul1165-0002" num="7580">[2] Universal Serial Bus (USB) Specification Rev 1.1, Compaq Computer Corporation, Intel Corporation, Microsoft Corporation, NEC Corporation, Sep. 28, 1998.</li><li id="ul1165-0003" num="7581">[3] Synopsys DesignWare USB 1.1 OHCI Host Controller with AHB/PVCI Databook Version 2.6, February 2003.</li><li id="ul1165-0004" num="7582">[4] Open Host Controller Interface Specification (OpenHCI) for USB Rev1.0a, Compaq, Microsoft, National Semiconductor, Sep. 14, 1999.</li><li id="ul1165-0005" num="7583">[5] inSilicon TymeWare USB 1.1 Device Controller (UDCVCI) Core User Manual Version 1.1, inSilicon Corporation, November 2000.</li><li id="ul1165-0006" num="7584">[6] Amphion, 2001<i>, CS</i>6150 <i>Motion JPEG Decoder Databook</i>, Amphion Semiconductor Ltd.</li><li id="ul1165-0007" num="7585">[7] ANSI/EIA 538–1988<i>, Facsimile Coding Schemes and Coding Control Functions for Group </i>4 <i>Facsismile Equipment</i>, August 1988</li><li id="ul1165-0008" num="7586">[8] Bender, W., P. Chesnais, S. Elo, A. Shaw, and M. Shaw, <i>Enriching communities: Harbingers of news in the future</i>, IBM Systems Journal, Vol.35, Nos.3&4, 1996, pp. 369–380</li><li id="ul1165-0009" num="7587">[9] CCIR Rec. 601–2<i>, Encoding Parameters of Digital Television for Studios</i>, Recommendations of the CCIR, 1990, Vol XI-Part 1, Broadcasting Service (Television), pp. 95–104.</li><li id="ul1165-0010" num="7588">[10] Farrell, J., <i>How to Allocate Bits to Optimize Photographic Image Quality</i>, Proceedings of IS&T International Conference on Digital Printing Technologies, 1998, pp. 572–576</li><li id="ul1165-0011" num="7589">[11] Humphreys, G. W., and V. Bruce, <i>Visual Cognition</i>, Lawrence Erlbaum Associates, 1989, p. 15</li><li id="ul1165-0012" num="7590">[12] ISO/IEC 19018-1:1994<i>, Information technology—Digital compression and coding of continuous</i>-<i>tone still images: Requirements and guidelines, </i>1994</li><li id="ul1165-0013" num="7591">[13]Lyppens, H., <i>Reed</i>-<i>Solomon Error Correction, Dr. Dobb's Journal </i>Vol.22, No.1, January 1997</li><li id="ul1165-0014" num="7592">[14] Olsen, J. <i>Smoothing Enlarged Monochrome Images</i>, in Glassner, A. S. (ed.), Graphics Gems, AP Professional, 1990</li><li id="ul1165-0015" num="7593">[15] Rorabaugh, C, <i>Error Coding Cookbook</i>, McGraw-Hill 1996</li><li id="ul1165-0016" num="7594">[16] Thompson, H. S., <i>Multilingual Corpus </i>1 CD-ROM, European Corpus Initiative</li><li id="ul1165-0017" num="7595">[17] Urban, S. J., <i>Review of standards for electronic imaging for facsimile systems</i>, Journal of Electronic Imaging, Vol.1(1), January 1992, pp. 5–21</li><li id="ul1165-0018" num="7596">[18] Wallace, G. K., <i>The JPEG Still Picture Compression Standard</i>, Communications of the ACM, Vol.34, No.4, April 1991, pp. 30–44</li><li id="ul1165-0019" num="7597">[19] Wicker, S., and Bhargava, V., <i>Reed</i>-<i>Solomon Codes and their Applications</i>, IEEE Press 1994</li><li id="ul1165-0020" num="7598">[20] Yasuda, Y., <i>Overview of Digital Facsimile Coding Techniques in Japan</i>, Proceedings of the IEEE, Vol. 68(7), July 1980, pp. 830–845</li><li id="ul1165-0021" num="7599">[21] SPARC International, <i>SPARC Architecture Manual, Version</i>8, Revision SAV080SI9308</li><li id="ul1165-0022" num="7600">[22] Gaisler Research, <i>The LEON</i>-2 <i>Processor User's Manual, Version </i>1.0.7, September 2002</li><li id="ul1165-0023" num="7601">[23] ARM Limited, <i>AMBA Specification</i>, Rev2.0, May 1999</li><li id="ul1165-0024" num="7602">[24] ITU-T, Reccomendation T30, Procedures for document facsimile transmission in the general switched telephone network, 07/2003.</li><li id="ul1165-0025" num="7603">[25] Anderson, R, and Kuhn, M., 1997<i>, Low Cost Attacks on Tamper Resistant Devices</i>, Security Protocols, Proceedings 1997, LNCS 1361, B. Christianson, B. Crispo, M. Lomas, M. Roe, Eds., Springer-Verlag, pp. 125–136.</li><li id="ul1165-0026" num="7604">[26] Anderson, R., and Needham, R. M., <i>Programming Satan's Computer</i>, Computer Science Today, LNCS 1000, pp. 426–441.</li><li id="ul1165-0027" num="7605">[27] Atkins, D., Graff, M., Lenstra, A. K., and Leyland, P. C., 1995<i>, The Magic Words Are Squeamish Ossifrage</i>, Advances in Cryptology—ASIACRYPT '94 Proceedings, Springer-Verlag, pp. 263–277.</li><li id="ul1165-0028" num="7606">[28]Bains, S., 1997<i>, Optical schemes tried out in IC test—IBM and Lucent teams take passive and active paths, respectively, to imaging</i>. EETimes, Dec. 22, 1997.</li><li id="ul1165-0029" num="7607">[29] Bao, F., Deng, R. H., Yan, Y, Jeng, A., Narasimhalu, A. D., Ngair, T., 1997<i>, Breaking Public Key Cryptosystems on Tamper Resistant Devices in the Presence of Transient Faults</i>, Security Protocols, Proceedings 1997, LNCS 1361, B. Christianson, B. Crispo, M. Lomas, M. Roe, Eds., Springer-Verlag, pp. 115–124.</li><li id="ul1165-0030" num="7608">[30] Bellare, M., Canetti, R., and Krawczyk. H., 1996<i>, Keying Hash Functions For Message Authentication</i>, Advances in Cryptology, Proceedings Crypto'96, LNCS 1109, N. Koblitz, Ed., Springer-Verlag, 1996, pp. 1–15. Full version: http://www.research.ibm.com/security/keyed-md5.html</li><li id="ul1165-0031" num="7609">[31] Bellare, M., Canetti, R., and Krawczyk, H., 1996<i>, The HMAC Construction</i>, RSA Laboratories CryptoBytes, Vol. 2, No 1, 1996, pp. 12–15.</li><li id="ul1165-0032" num="7610">[32] Bellare, M., Guérin, R., and Rogaway, P., 1995<i>, XOR MA Cs: New Methods For Message Authentication Using Finite Pseudorandom Functions</i>, Advances in Cryptology, Proceedings Crypto'95, LNCS 963, D Coppersmith, Ed., Springer-Verlag, 1995, pp. 15–28.</li><li id="ul1165-0033" num="7611">[33] Blaze, M., Diffie, W., Rivest, R., Schneier, B., Shimomura, T., Thompson, E., Wiener, M., 1996<i>, Minimal Key Lengths For Symmetric Ciphers To Provide Adequate Commercial Security</i>, A Report By an Ad Hoc Group of Cryptographers and Computer Scientists, Published on the internet: http://www.livelinks.com/livelinks/bsa/cryptographers.html</li><li id="ul1165-0034" num="7612">[34] Blum, L., Blum, M., and Shub, M., <i>A Simple Unpredictable Pseudo</i>-<i>random Number Generator</i>, SIAM Journal of Computing, vol 15, no 2, May 1986, pp 364–383.</li><li id="ul1165-0035" num="7613">[35] Bosselaers, A., and Preneel, B., editors, 1995<i>, Integrity Primitives for Secure Information Systems: Final Report of RACE Integrity Primitives Evaluation RIPE</i>-<i>RACE </i>1040, LNCS 1007, Springer-Verlag, New York.</li><li id="ul1165-0036" num="7614">[36] Brassard, G., 1988<i>, Modern Cryptography</i>, a Tutorial, LNCS 325, Springer-Verlag.</li><li id="ul1165-0037" num="7615">[37] Canetti, R., 1997<i>, Towards Realizing Random Oracles: Hash Functions That Hide All Partial Information, Advances in Cryptology</i>, Proceedings Crypto'97, LNCS 1294, B. Kaliski, Ed., Springer-Verlag, pp. 455–469.</li><li id="ul1165-0038" num="7616">[38] Cheng, P., and Glenn, R., 1997<i>, Test Cases for HMAC</i>-<i>MD</i>5 <i>and HMAC</i>-<i>SHA</i>-1, Network Working Group RFC 2202, http://reference.ncrs.usda.gov/ietf/rfc/2300/rfc2202.htm</li><li id="ul1165-0039" num="7617">[39] Diffie, W., and Hellman, M. E., 1976<i>, Multiuser Cryptographic Techniques</i>, AFIPS national Computer Conference, Proceedings '76, pp. 109–112.</li><li id="ul1165-0040" num="7618">[40] Diffie, W., and Hellman, M. E., 1976<i>, New Directions in Cryptography</i>, IEEE Transactions on Information Theory, Volume IT-22, No 6 (November 1976), pp. 644–654.</li><li id="ul1165-0041" num="7619">[41] Diffie, W., and Hellman, M. E., 1977<i>, Exhaustive Cryptanalysis of the NBS Data Encryption Standard</i>, Computer, Volume 10, No 6, (June 1977), pp. 74–84.</li><li id="ul1165-0042" num="7620">[42]Dobbertin, H., 1995<i>, Alf Swindles Ann</i>, RSA Laboratories CryptoBytes, Volume 1, No 3, p. 5.</li><li id="ul1165-0043" num="7621">[43] Dobbertin, H, 1996<i>, Cryptanalysis of MD</i>4, Fast Software Encryption—Cambridge Workshop, LNCS 1039, Springer-Verlag, 1996, pp 53–69.</li><li id="ul1165-0044" num="7622">[44] Dobbertin, H, 1996<i>, The Status of MD</i>5 <i>After a Recent Attack, RSA Laboratories CryptoBytes, Volume </i>2, No 2, pp. 1, 3–6.</li><li id="ul1165-0045" num="7623">[45] Dreifus, H., and Monk, J. T., 1988<i>, Smart Cards—A Guide to Building and Managing Smart Card Applications</i>, John Wiley and Sons.</li><li id="ul1165-0046" num="7624">[46] EIGamal, T., 1985<i>, A Public</i>-<i>Key Cryptosystem and a Signature Scheme Based on Discrete Logarithms</i>, Advances in Cryptography, Proceedings Crypto'84, LNCS 196, Springer-Verlag, pp. 10–18.</li><li id="ul1165-0047" num="7625">[47] EIGamal, T., 1985<i>, A Public</i>-<i>Key Cryptosystem and a Signature Scheme Based on Discrete Logarithms</i>, IEEE Transactions on Information Theory, Volume 31, No 4, pp. 469–472</li><li id="ul1165-0048" num="7626">[48] Feige, U., Fiat, A, and Sharnir, A., 1988<i>, Zero Knowledge Proofs of Identity</i>, J Cryptography, Volume 1, pp. 77–904.</li><li id="ul1165-0049" num="7627">[49] Feigenbaum, J., 1992<i>, Overview of Interactive Proof Systems and Zero</i>-<i>Knowledge</i>, Contemporary Cryptology—The Science of Information Integrity, G Simmons, Ed., IEEE Press, New York.</li><li id="ul1165-0050" num="7628">[50] FIPS 46–1, 1977<i>, Data Encryption Standard</i>, NIST, US Department of Commerce, Washington D.C., January 1977.</li><li id="ul1165-0051" num="7629">[51] FIPS 180, 1993<i>, Secure Hash Standard, NIST, US Department of Commerce</i>, Washington D.C., May 1993.</li><li id="ul1165-0052" num="7630">[52] FIPS 180–1, 1995<i>, Secure Hash Standard</i>, NIST, US Department of Commerce, Washington D.C., April 1995.</li><li id="ul1165-0053" num="7631">[53] FIPS 186, 1994<i>, Digital Signature Standard</i>, NIST, US Department of Commerce, Washington D.C., 1994.</li><li id="ul1165-0054" num="7632">[54] Gardner, M., 1977<i>, A New Kind of Cipher That Would Take Millions of Years to Break</i>, Scientific American, Vol. 237, No. 8, pp. 120–124.</li><li id="ul1165-0055" num="7633">[55]Girard, P., Roche, F. M., Pistoulet, B., 1986<i>, Electron Beam Effects on VLSI MOS Conditions for Testing and Reconfiguration</i>, Wafer-Scale Integration, G. Saucier and J. Trihle, Eds., Amsterdam</li><li id="ul1165-0056" num="7634">[56] Girard, P., Pistoulet, B., Valenza, M., and Lorival, R., 1987<i>, Electron Beam Switching of Floating Gate MOS Transistors</i>, IFIP International Workshop on Wafer Scale International, Brunel University, Sep. 23–25, 1987.</li><li id="ul1165-0057" num="7635">[57] Goldberg, I., and Wagner, D., 1996<i>, Randomness and the Netscape Browser</i>, Dr. Dobb's Journal, January 1996.</li><li id="ul1165-0058" num="7636">[58] Guilou, L. G., Ugon, M., and Quisquater, J., 1992<i>, The Smart Card, Contemporary Cryptology—The Science of Information Integrity</i>, G Simmons, Ed., IEEE Press, New York.</li><li id="ul1165-0059" num="7637">[59] Gutman, P., 1996<i>, Secure Deletion ofData From Magnetic and Solid</i>-<i>State Memory</i>, Sixth USENIX Security Symposium Proceedings (July 1996), pp. 77–89.</li><li id="ul1165-0060" num="7638">[60] Hendry, M., 1997<i>, Smart Card Security and Applications</i>, Artech House, Norwood Mass.</li><li id="ul1165-0061" num="7639">[61]Holgate, S. A., 1998<i>, Sensing is Believing</i>, New Scientist, 15 Aug. 1998, p 20.</li><li id="ul1165-0062" num="7640">[62] Johansson, T., 1997<i>, Bucket Hashing with a Small Key Size</i>, Advances in Cryptology, Proceedings Eurocrypt'97, LNCS 1233, W. Fumy, Ed., Springer-Verlag, pp. 149–162.</li><li id="ul1165-0063" num="7641">[63] Kahn, D., 1967<i>, The Codebreakers: The Story of Secret Writing</i>, New York: Macmillan Publishing Co.</li><li id="ul1165-0064" num="7642">[64] Kaliski, B., 1991<i>, Letter to NIST regarding DSS, </i>4 Nov. 1991.</li><li id="ul1165-0065" num="7643">[65] Kaliski, B., 1998<i>, New Threat Discovered and Fixed</i>, RSA Laboratories Web site http://www.rsa.com/rsalabs/pkcs1</li><li id="ul1165-0066" num="7644">[66] Kaliski, B., and Robshaw, M, 1995<i>, Message Authentication With MD</i>5, RSA Laboratories Crypto-Bytes, Volume 1, No 1, pp. 5–8.</li><li id="ul1165-0067" num="7645">[67] Kaliski, B., and Yin, Y. L., 1995<i>, On Differential and Linear Cryptanalysis of the RC</i>5 <i>Encryption Algorithm, Advances in Cryptology, Proceedings Crypto '</i>95, LNCS 963, D. Coppersrnith, Ed., Springer-Verlag, pp. 171–184.</li><li id="ul1165-0068" num="7646">[68] Klapper, A., and Goresky, M., 1994, 2-<i>Adic Shift Registers</i>, Fast Software Encryption: Proceedings Cambridge Security Workshop '93, LNCS 809, R. Anderson, Ed., Springer-Verlag, pp. 174–178.</li><li id="ul1165-0069" num="7647">[69] Klapper, A., 1996<i>, On the Existence of Secure Feedback Registers</i>, Advances in Cryptology, Proceedings Eurocrypt'96, LNCS 1070, U. Maurer, Ed., Springer-Verlag, pp. 256–267.</li><li id="ul1165-0070" num="7648">[70] Kleiner, K., 1998<i>, Cashing in on the not so smart cards</i>, New Scientist, 20 Jun. 1998, p 12.</li><li id="ul1165-0071" num="7649">[71] Knudsen, L. R., and Lai, X., <i>Improved Differential Attacks on RC</i>5, Advances in Cryptology, Proceedings Crypto'96, LNCS 1109, N. Koblitz, Ed., Springer-Verlag, 1996, pp. 216–228</li><li id="ul1165-0072" num="7650">[72] Knuth, D. E., 1998<i>, The Art of Computer Programing—Volume </i>2<i>/Seminumerical Algorithms, </i>3rd edition, Addison-Wesley.</li><li id="ul1165-0073" num="7651">[73] Krawczyk, H., 1995<i>, New Hash Functions for Message Authentication</i>, Advances in Cryptology, Proceedings Eurocrypt'95, LNCS 921, L Guillou, J Quisquater, (editors), Springer-Verlag, pp. 301-310.</li><li id="ul1165-0074" num="7652">[74] Krawczyk, H., 199x, <i>Network Encryption—History and Patents</i>, internet publication: http://www.cygnus.com/˜gnu/netcrypt.html</li><li id="ul1165-0075" num="7653">[75]Krawczyk, H., Bellare, M, Canetti, R., 1997<i>, HMAC: Keyed Hashing for message Authentication</i>, Network Working Group RFC 2104, http:reference.ncrs.usda.gov/ietf/rfc/2200/rfc2104.htm</li><li id="ul1165-0076" num="7654">[76] Lai, X., 1992<i>, On the Design and Security of Block Ciphers</i>, ETH Series in Information Processing, J. L. Massey (editor), Volume 1, Konstanz: hartung-Gorre Verlag (Zurich).</li><li id="ul1165-0077" num="7655">[77] Lai, X, and Massey, 1991, J. L, <i>A Proposal for a New Block Encryption Standard</i>, Advances in Cryptology, Proceedings Eurocrypt'90, LNCS 473, Springer-Verlag, pp. 389–404.</li><li id="ul1165-0078" num="7656">[78] Massey, J. L., 1969<i>, Shift Register Sequences and BCH Decoding</i>, IEEE Transactions on Information Theory, IT-15, pp. 122–127.</li><li id="ul1165-0079" num="7657">[79] Mende, B., Noll, L., and Sisodiya, S., 1997<i>, How Lavarand Works</i>, Silicon Graphics Incorporated, published on Internet: http://lavarand.sgi.com (also reported in Scientific American, November 1997 p. 18, and New Scientist, 8 Nov. 1997).</li><li id="ul1165-0080" num="7658">[80] Menezes, A. J., van Oorschot, P. C., Vanstone, S. A., 1997<i>, Handbook of Applied Cryptography</i>, CRC Press.</li><li id="ul1165-0081" num="7659">[81]Merkle, R. C., 1978<i>, Secure Communication Over Insecure Channels</i>, Communications of the ACM, Volume 21, No 4, pp. 294–299.</li><li id="ul1165-0082" num="7660">[82] Montgomery, P. L., 1985<i>, Modular Multiplication Without Trial Division</i>, Mathematics of Computation, Volume 44, Number 170, pp. 519–521.</li><li id="ul1165-0083" num="7661">[83] Moreau, T., <i>A Practical “Perfect” Pseudo</i>-<i>Random Number Generator</i>, paper submitted to Computers in Physics on Feb. 27, 1996, Internet version: http://www.connotech.com/BBS.HTM</li><li id="ul1165-0084" num="7662">[84] Moreau, T., 1997<i>, Pseudo</i>-<i>Random Generators, a High</i>-<i>Level Survey</i>-<i>in</i>-<i>Progress</i>, Published on the internet: http://www.cabano.com/connotech/RNG.HTM</li><li id="ul1165-0085" num="7663">[85] NIST, 1994<i>, Digital Signature Standard</i>, NIST ISL Bulletin, online version at http://csrc.ncsl.nist.gov/nistbul/cs194-11.txt</li><li id="ul1165-0086" num="7664">[86] Oehler, M., Glenn, R., 1997<i>, HMAC</i>-<i>MD</i>5 <i>IP Authentication with Replay Prevention</i>, Network Working Group RFC 2085, http://reference.ncrs.usda.gov/ietf/rfc/2100/rfc2085.txt</li><li id="ul1165-0087" num="7665">[87] Oppliger, R., 1996<i>, Authentication Systems For Secure Networks</i>, Artech House, Norwood Mass.</li><li id="ul1165-0088" num="7666">[88]Preneel, B., van Oorschot, P. C., 1996<i>, MDx</i>-<i>MAC And Building Fast MACs From Hash Functions</i>, Advances in Cryptology, Proceedings Crypto'95, LNCS 963, D. Coppersmith, Ed., Springer-Verlag, pp. 1–14.</li><li id="ul1165-0089" num="7667">[89] Preneel, B., van Oorschot, P. C., 1996<i>, On the Security of Two MAC Algorithms</i>, Advances in Cryptology, Proceedings Eurocrypt'96, LNCS 1070, U. Maurer, Ed., Springer-Verlag, 1996, pp. 19-32.</li><li id="ul1165-0090" num="7668">[90] Preneel, B., Bosselaers, A., Dobbertin, H., 1997<i>, The Cryptographic Hash Function RIPEMD</i>-160, CryptoBytes, Volume 3, No 2, 1997, pp. 9–14.</li><li id="ul1165-0091" num="7669">[91] Rankl, W., and Effing, W., 1997<i>, Smart Card Handbook</i>, John Wiley and Sons (first published as Handbuch der Chipkarten, Carl Hanser Verlag, Munich, 1995).</li><li id="ul1165-0092" num="7670">[92] Ritter, T., 1991<i>, The Efficient Generation of Cryptographic Confusion Sequences</i>, Cryptologia, Volume 15, No 2, pp. 81–139.</li><li id="ul1165-0093" num="7671">[93] Rivest, R. L, 1993<i>, Dr. Ron Rivest on the Difficulties of Factoring</i>, Ciphertext: The RSA Newsletter, Vol 1, No 1, pp. 6, 8.</li><li id="ul1165-0094" num="7672">[94] Rivest, R. L., 1991<i>, The MD</i>4 <i>Message</i>-<i>Digest Algorithm, Advances in Cryptology, Proceedings Crypto'</i>90, LNCS 537, S. Vanstone, Ed., Springer-Verlag, pp. 301–311.</li><li id="ul1165-0095" num="7673">[95] Rivest, R. L., 1992<i>, The RC</i>4 <i>Encryption Algorithm</i>, RSA Data Security Inc. (This document has not been made public).</li><li id="ul1165-0096" num="7674">[96] Rivest, R. L., 1992<i>, The MD</i>4 <i>Message</i>-<i>Digest Algorithm</i>, Request for Comments (RFC) 1320, Internet Activities Board, Internet Privacy Task Force, April 1992.</li><li id="ul1165-0097" num="7675">[97] Rivest, R. L., 1992<i>, The MD</i>5 <i>Message</i>-<i>Digest Algorithm</i>, Request for Comments (RFC) 1321, Internet Activities Board, Internet privacy Task Force.</li><li id="ul1165-0098" num="7676">[98] Rivest, R. L., 1995<i>, The RC</i>5 <i>Encryption Algorithm, Fast Software Encryption, LNCS </i>1008, Springer-Verlag, pp. 86–96.</li><li id="ul1165-0099" num="7677">[99] Rivest, R. L., Shamir, A., and Adleman, L. M., 1978<i>, A Method For Obtaining Digital Signatures and Public</i>-<i>Key Cryptosystems</i>, Communications of the ACM, Volume 21, No 2, pp. 120–126.</li><li id="ul1165-0100" num="7678">[100] Schneier, S., 1994<i>, Description of a New Variable</i>-<i>Length Key, </i>64-<i>Bit Block Cipher </i>(Blowfish), Fast Software Encryption (December 1993), LNCS 809, Springer-Verlag, pp. 191–204.</li><li id="ul1165-0101" num="7679">[101] Schneier, S., 1995<i>, The Blowfish Encryption Algorithm—One Year Later</i>, Dr Dobb's Journal, September 1995.</li><li id="ul1165-0102" num="7680">[102] Schneier, S., 1996<i>, Applied Cryptography</i>, Wiley Press.</li><li id="ul1165-0103" num="7681">[103] Schneier, S., 1998<i>, The Blowfish Encryption Algorithm</i>, revision date Feb. 25, 1998, http://www.counterpane.com/blowfish.html</li><li id="ul1165-0104" num="7682">[104] Schneier, S., 1998<i>, The Crypto Bomb is Ticking</i>, Byte Magazine, May 1998, pp. 97–102.</li><li id="ul1165-0105" num="7683">[105] Schnorr, C. P., 1990<i>, Efficient Identification and Signatures for Smart Cards</i>, Advances in Cryptology, Proceedings Eurocrypt'89, LNCS 435, Springer-Verlag, pp. 239–252.</li><li id="ul1165-0106" num="7684">[106] Shamir, A., and Fiat, A., Method, <i>Apparatus and Article For Identification and Signature</i>, U.S. Pat. No. 4,748,668, 31 May 1988.</li><li id="ul1165-0107" num="7685">[107] Shor, W., 1994<i>, Algorithms for Quantum Computation: Discrete Logarithms and Factoring</i>, Proc. 35th Symposium. Foundations of Computer Science (FOCS), IEEE Computer Society, Los Alamitos, Calif., 1994.</li><li id="ul1165-0108" num="7686">[108] Simmons, G. J., 1992<i>, A Survey of Information Authentication</i>, Contemporary Cryptology—The Science of Information Integrity, G Simmons, Ed., IEEE Press, New York.</li><li id="ul1165-0109" num="7687">[109] Tewksbury, S. K., 1998<i>, Architectural Fault Tolerance, Integrated Circuit Manufacturability</i>, Pineda de Gyvez, J., and Pradhan, D. K., Eds., IEEE Press, New York.</li><li id="ul1165-0110" num="7688">[110] TSMC, 2000, SFC0008<sub>—</sub>08B9_HE, 8K×8 Embedded Flash Memory Specification, Rev 0.1.</li><li id="ul1165-0111" num="7689">[111] Tsudik, G., 1992<i>, Message Authentication With One</i>-<i>way Hash Functions</i>, Proceedings of Infocom '92 (Also in Access Control and Policy Enforcement in Internetworks, Ph.D. Dissertation, Computer Science Department, University of Southern California, April 1991).</li><li id="ul1165-0112" num="7690">[112] Vallett. D., Kash, J., and Tsang, J., <i>Watching Chips Work</i>, IBM MicroNews, Vol 4, No 1, 1998.</li><li id="ul1165-0113" num="7691">[113] Vazirani, U. V., and Vazirani, V. V., 1984<i>, Efficient and Secure Random Number Generation, </i>25th Symposium. Foundations of Computer Science (FOCS), IEEE Computer Society, 1984, pp. 458–463.</li><li id="ul1165-0114" num="7692">[114] Wagner, D., Goldberg, I., and Briceno, M., 1998<i>, GSM Cloning</i>, ISAAC Research Group, University of California, http://www.isaac.cs.berkeley.edu/isaac/gsm-faq.html</li><li id="ul1165-0115" num="7693">[115] Wiener, M. J., 1997<i>, Efficient DES Key Search—An Update</i>, RSA Laboratories CryptoBytes, Volume 3, No 2, pp. 6–8.</li><li id="ul1165-0116" num="7694">[116] Zoreda, J. L., and Otón, J. M., 1994<i>, Smart Cards</i>, Artech House, Norwood Mass.</li><li id="ul1165-0117" num="7695">[117] Authentication Protocols v0<sub>—</sub>2 29 Nov. 2002. Silverbrook Research.</li><li id="ul1165-0118" num="7696">[118] H. Krawczyk IBM, M. Bellare UCSD, R. Canetti IBM, RFC 2104, February 1997, http://www.ietf.org/rfc/rfc2104.txt</li><li id="ul1165-0119" num="7697">[119] 4-3-1-2-QAChipSpec v4<sub>—</sub>09 17 Apr. 2003, Silverbrook Research</li><li id="ul1165-0120" num="7698">[120] 4-4-9-4 SoPEC_hardware_design_v3<sub>—</sub>1 28 Jan. 2003</li><li id="ul1165-0121" num="7699">[121] Silverbrook Research, 2002, 4-3-1-8 <i>QID Requirements Specification. </i></li><li id="ul1165-0122" num="7700">[122] TSMC, Oct. 1, 2000, SFC008<sub>—</sub>08B9_HE, 8K×8 Embedded Flash Memory Specification, Rev 0.1.</li><li id="ul1165-0123" num="7701">[123] TSMC (design service division), Sep. 10, 2001, 0.25 <i>um Embedded Flash Test Mode User Guide, V</i>0.3.</li><li id="ul1165-0124" num="7702">[124] TSMC (EmbFlash product marketing), Oct. 19, 2001, 0.25 <i>um Application Note, V</i>2.2.</li><li id="ul1165-0125" num="7703">[125] Artisan Components, Jan 99, Process Perfect Library Databook 2.5-Volt Standard Cells, Rev1.0.</li><li id="ul1165-0126" num="7704">[126] “4-3-1-2 QA Chip Technical Reference v 4.06”, Silverbrook Research.</li><li id="ul1165-0127" num="7705">[127] National Institute of Standards and Technology—Federal Information Processing Standardshttp://csrc.nist.gov/publications/fips/</li><li id="ul1165-0128" num="7706">[128] U.S. patent application Ser. No. 09/575,108, filed May 23, 2000, Silverbrook Research Pty Ltd</li><li id="ul1165-0129" num="7707">[129] U.S. patent application Ser. No. 09/575,109, filed May 23, 2000, Silverbrook Research Pty Ltd</li><li id="ul1165-0130" num="7708">[130] U.S. patent application Ser. No. 09/575,100, filed May 23, 2000, Silverbrook Research Pty Ltd</li><li id="ul1165-0131" num="7709">[131] U.S. patent application Ser. No. 09/607,985, filed May 23, 2000, Silverbrook Research Pty Ltd</li><li id="ul1165-0132" num="7710">[132] U.S. Pat. No. 6,398,332, filed Jun. 30, 2000, Silverbrook Research Pty</li><li id="ul1165-0133" num="7711">[133] U.S. Pat. No. 6,394,573, filed Jun. 30, 2000, Silverbrook Research Pty Ltd</li><li id="ul1165-0134" num="7712">[134] U.S. Pat. No. 6,622,923, filed Jun. 30, 2000, Silverbrook Research Pty Ltd</li><li id="ul1165-0135" num="7713">[135] U.S. patent application Ser. No. 09/517,539, filed Mar. 2, 2000, Silverbrook Research Pty Ltd</li><li id="ul1165-0136" num="7714">[136] U.S. Pat. No. 6,566,858, filed Jul. 10, 1998, Silverbrook Research Pty Ltd</li><li id="ul1165-0137" num="7715">[137] U.S. Pat. No. 6,331,946, filed Jul. 10, 1998, Silverbrook Research Pty Ltd</li><li id="ul1165-0138" num="7716">[138] U.S. Pat. No. 6,246,970, filed Jul. 10, 1998, Silverbrook Research Pty Ltd</li><li id="ul1165-0139" num="7717">[139] U.S. Pat. No. 6,442,525, filed Jul. 10, 1998, Silverbrook Research Pty Ltd</li><li id="ul1165-0140" num="7718">[140] U.S. patent application Ser. No. 09/517,384, filed Mar. 2, 2000, Silverbrook Research Pty Ltd</li><li id="ul1165-0141" num="7719">[141] U.S. patent application Ser. No. 09/505,951, filed Feb. 21, 2001, Silverbrook Research Pty Ltd</li><li id="ul1165-0142" num="7720">[142] U.S. Pat. No. 6,374,354, filed Mar. 2, 2000, Silverbrook Research Pty Ltd</li><li id="ul1165-0143" num="7721">[143] U.S. patent application Ser. No. 09/517,608, filed Mar. 2, 2000, Silverbrook Research Pty Ltd</li><li id="ul1165-0144" num="7722">[144] U.S. Pat. No. 6,334,190, filed Mar. 2, 2000, Silverbrook Research Pty Ltd</li><li id="ul1165-0145" num="7723">[145] U.S. patent application Ser. No. 09/517,541, filed Mar. 2, 2000, Silverbrook Research Pty Ltd</li></ul>
Contents38
358 sheets
Sheet 1 Sheet 2 Sheet 3 Sheet 4 Sheet 5 Sheet 6 Sheet 7 Sheet 8 Sheet 9 Sheet 10 Sheet 11 Sheet 12 Sheet 13 Sheet 14 Sheet 15 Sheet 16 Sheet 17 Sheet 18 Sheet 19 Sheet 20 Sheet 21 Sheet 22 Sheet 23 Sheet 24 Sheet 25 Sheet 26 Sheet 27 Sheet 28 Sheet 29 Sheet 30 Sheet 31 Sheet 32 Sheet 33 Sheet 34 Sheet 35 Sheet 36 Sheet 37 Sheet 38 Sheet 39 Sheet 40 Sheet 41 Sheet 42 Sheet 43 Sheet 44 Sheet 45 Sheet 46 Sheet 47 Sheet 48 Sheet 49 Sheet 50 Sheet 51 Sheet 52 Sheet 53 Sheet 54 Sheet 55 Sheet 56 Sheet 57 Sheet 58 Sheet 59 Sheet 60 Sheet 61 Sheet 62 Sheet 63 Sheet 64 Sheet 65 Sheet 66 Sheet 67 Sheet 68 Sheet 69 Sheet 70 Sheet 71 Sheet 72 Sheet 73 Sheet 74 Sheet 75 Sheet 76 Sheet 77 Sheet 78 Sheet 79 Sheet 80 Sheet 81 Sheet 82 Sheet 83 Sheet 84 Sheet 85 Sheet 86 Sheet 87 Sheet 88 Sheet 89 Sheet 90 Sheet 91 Sheet 92 Sheet 93 Sheet 94 Sheet 95 Sheet 96 Sheet 97 Sheet 98 Sheet 99 Sheet 100 Sheet 101 Sheet 102 Sheet 103 Sheet 104 Sheet 105 Sheet 106 Sheet 107 Sheet 108 Sheet 109 Sheet 110 Sheet 111 Sheet 112 Sheet 113 Sheet 114 Sheet 115 Sheet 116 Sheet 117 Sheet 118 Sheet 119 Sheet 120 Sheet 121 Sheet 122 Sheet 123 Sheet 124 Sheet 125 Sheet 126 Sheet 127 Sheet 128 Sheet 129 Sheet 130 Sheet 131 Sheet 132 Sheet 133 Sheet 134 Sheet 135 Sheet 136 Sheet 137 Sheet 138 Sheet 139 Sheet 140 Sheet 141 Sheet 142 Sheet 143 Sheet 144 Sheet 145 Sheet 146 Sheet 147 Sheet 148 Sheet 149 Sheet 150 Sheet 151 Sheet 152 Sheet 153 Sheet 154 Sheet 155 Sheet 156 Sheet 157 Sheet 158 Sheet 159 Sheet 160 Sheet 161 Sheet 162 Sheet 163 Sheet 164 Sheet 165 Sheet 166 Sheet 167 Sheet 168 Sheet 169 Sheet 170 Sheet 171 Sheet 172 Sheet 173 Sheet 174 Sheet 175 Sheet 176 Sheet 177 Sheet 178 Sheet 179 Sheet 180 Sheet 181 Sheet 182 Sheet 183 Sheet 184 Sheet 185 Sheet 186 Sheet 187 Sheet 188 Sheet 189 Sheet 190 Sheet 191 Sheet 192 Sheet 193 Sheet 194 Sheet 195 Sheet 196 Sheet 197 Sheet 198 Sheet 199 Sheet 200 Sheet 201 Sheet 202 Sheet 203 Sheet 204 Sheet 205 Sheet 206 Sheet 207 Sheet 208 Sheet 209 Sheet 210 Sheet 211 Sheet 212 Sheet 213 Sheet 214 Sheet 215 Sheet 216 Sheet 217 Sheet 218 Sheet 219 Sheet 220 Sheet 221 Sheet 222 Sheet 223 Sheet 224 Sheet 225 Sheet 226 Sheet 227 Sheet 228 Sheet 229 Sheet 230 Sheet 231 Sheet 232 Sheet 233 Sheet 234 Sheet 235 Sheet 236 Sheet 237 Sheet 238 Sheet 239 Sheet 240 Sheet 241 Sheet 242 Sheet 243 Sheet 244 Sheet 245 Sheet 246 Sheet 247 Sheet 248 Sheet 249 Sheet 250 Sheet 251 Sheet 252 Sheet 253 Sheet 254 Sheet 255 Sheet 256 Sheet 257 Sheet 258 Sheet 259 Sheet 260 Sheet 261 Sheet 262 Sheet 263 Sheet 264 Sheet 265 Sheet 266 Sheet 267 Sheet 268 Sheet 269 Sheet 270 Sheet 271 Sheet 272 Sheet 273 Sheet 274 Sheet 275 Sheet 276 Sheet 277 Sheet 278 Sheet 279 Sheet 280 Sheet 281 Sheet 282 Sheet 283 Sheet 284 Sheet 285 Sheet 286 Sheet 287 Sheet 288 Sheet 289 Sheet 290 Sheet 291 Sheet 292 Sheet 293 Sheet 294 Sheet 295 Sheet 296 Sheet 297 Sheet 298 Sheet 299 Sheet 300 Sheet 301 Sheet 302 Sheet 303 Sheet 304 Sheet 305 Sheet 306 Sheet 307 Sheet 308 Sheet 309 Sheet 310 Sheet 311 Sheet 312 Sheet 313 Sheet 314 Sheet 315 Sheet 316 Sheet 317 Sheet 318 Sheet 319 Sheet 320 Sheet 321 Sheet 322 Sheet 323 Sheet 324 Sheet 325 Sheet 326 Sheet 327 Sheet 328 Sheet 329 Sheet 330 Sheet 331 Sheet 332 Sheet 333 Sheet 334 Sheet 335 Sheet 336 Sheet 337 Sheet 338 Sheet 339 Sheet 340 Sheet 341 Sheet 342 Sheet 343 Sheet 344 Sheet 345 Sheet 346 Sheet 347 Sheet 348 Sheet 349 Sheet 350 Sheet 351 Sheet 352 Sheet 353 Sheet 354 Sheet 355 Sheet 356 Sheet 357 Sheet 358
Every citation, both ways
| Document | Relation | Office | Cited during |
|---|---|---|---|
| US2008150997A1 | Cited by | United States of America | Pre-grant |
| US2009150720A1 | Cited by | United States of America | Pre-grant |
| US9764561B2 | Cited by | United States of America | Applicant |
| US7738137B2 | Cited by | United States of America | Search report |
| US2006285164A1 | Cited by | United States of America | Pre-grant |
| US7741659B2 | Cited by | United States of America | Applicant |
| US8065678B2 | Cited by | United States of America | Applicant |
| US11930126B2 | Cited by | United States of America | Applicant |
| US9767284B2 | Cited by | United States of America | Applicant |
| US8605346B2 | Cited by | United States of America | Search report |
| US11124002B2 | Cited by | United States of America | Applicant |
| US2009319802A1 | Cited by | United States of America | Pre-grant |
| US2007057060A1 | Cited by | United States of America | Pre-grant |
| US2012257263A1 | Cited by | United States of America | Pre-grant |
| US2009108348A1 | Cited by | United States of America | Pre-grant |
| US9215075B1 | Cited by | United States of America | Applicant |
| US8041945B2 | Cited by | United States of America | Search report |
| US2010245454A1 | Cited by | United States of America | Pre-grant |
| US2009271795A1 | Cited by | United States of America | Pre-grant |
| WO2018236396A1 | Cited by | World Intellectual Property Organization (WIPO) | International search |
| US2010033778A1 | Cited by | United States of America | Pre-grant |
| US7360131B2 | Cited by | United States of America | Search report |
| US2006242496A1 | Cited by | United States of America | Pre-grant |
| US12225141B2 | Cited by | United States of America | Applicant |
| US2010223453A1 | Cited by | United States of America | Pre-grant |
| US8417943B2 | Cited by | United States of America | Search report |
| US2010238213A1 | Cited by | United States of America | Pre-grant |
| US8786871B2 | Cited by | United States of America | Search report |
| US8162433B2 | Cited by | United States of America | Applicant |
| US10305695B1 | Cited by | United States of America | Applicant |
| US2009058903A1 | Cited by | United States of America | Pre-grant |
| US2012079564A1 | Cited by | United States of America | Pre-grant |
| US10841104B2 | Cited by | United States of America | Applicant |
| US9942051B1 | Cited by | United States of America | Applicant |
| US2013182276A1 | Cited by | United States of America | Pre-grant |
| US2009287925A1 | Cited by | United States of America | Pre-grant |
| US2005212831A1 | Cited by | United States of America | Pre-grant |
| US11588650B2 | Cited by | United States of America | Applicant |
| US7809980B2 | Cited by | United States of America | Applicant |
| CN110770029A | Cited by | China | Search report |
| EP0863004A2 | Cites | European Patent Office (EPO) | Applicant |
| EP0974467A1 | Cites | European Patent Office (EPO) | Applicant |
| EP0983855A2 | Cites | European Patent Office (EPO) | Applicant |
| EP1157840A2 | Cites | European Patent Office (EPO) | Applicant |
| US2002060707A1 | Cites | United States of America | Applicant |
| US4932232A | Cites | United States of America | Search report |
| US6283572B1 | Cites | United States of America | Search report |
| US6354689B1 | Cites | United States of America | Applicant |
| WO9840222A1 | Cites | World Intellectual Property Organization (WIPO) | Applicant |
| WO9908875A1 | Cites | World Intellectual Property Organization (WIPO) | Applicant |
| EP 0 983 855 A2□□Eckard, Bruce Michael Dec. 8, 1999. | Non-patent | – | Search report |
| EP 0 983 855 A2□□Eckard, Bruce Michael Dec. 8, 1999. | Non-patent | – | Search report |
113 members in 8 offices
Priority claims10
| Document | Office | Kind | Date |
|---|---|---|---|
| 2002953134 | Australia | A | |
| 2002953134 | Australia | A | |
| 2002953134 | Australia | – | |
| 2002953135 | Australia | A | |
| 2002953135 | Australia | A | |
| 2002953135 | Australia | – | |
| 2002953134 | – | – | – |
| 2002953135 | – | – | – |
| AU20020953134 | – | – | – |
| AU20020953135 | – | – | – |
Members113
| Document | Office | Kind | |
|---|---|---|---|
| CA2508141A1 | Canada | A1 | |
| WO2004050369A1 | World Intellectual Property Organization (WIPO) | A1 | |
| AU2003302611A1 | Australia | A1 | |
| US2004143710A1 | United States of America | A1 | |
| US2004174570A1 | United States of America | A1 | |
| US2004181303A1 | United States of America | A1 | |
| US2004183843A1 | United States of America | A1 | |
| US2004189355A1 | United States of America | A1 | |
| US2004189731A1 | United States of America | A1 | |
| US2004193880A1 | United States of America | A1 | |
| US2004196320A1 | United States of America | A1 | |
| US2004199786A1 | United States of America | A1 | |
| US2004201647A1 | United States of America | A1 | |
| US2004201939A1 | United States of America | A1 | |
| US2004221287A1 | United States of America | A1 | |
| US2004223010A1 | United States of America | A1 | |
| US2004225881A1 | United States of America | A1 | |
| US2004227205A1 | United States of America | A1 | |
| US2004243978A1 | United States of America | A1 | |
| US2004249757A1 | United States of America | A1 | |
| WO2004050369A9 | World Intellectual Property Organization (WIPO) | A9 | |
| US2005152596A1 | United States of America | A1 | |
| US2005160316A1 | United States of America | A1 | |
| US2005166040A1 | United States of America | A1 | |
| US2005177633A1 | United States of America | A1 | |
| US2005182985A1 | United States of America | A1 | |
| US2005188218A1 | United States of America | A1 | |
| US2005197159A1 | United States of America | A1 | |
| EP1572463A1 | European Patent Office (EPO) | A1 | |
| US2005200688A1 | United States of America | A1 | |
| US2005206944A1 | United States of America | A1 | |
| US2005210179A1 | United States of America | A1 | |
| US2005213761A1 | United States of America | A1 | |
| US2006052962A1 | United States of America | A1 | |
| US2006071951A1 | United States of America | A1 | |
| US2006071981A1 | United States of America | A1 | |
| US2006082609A1 | United States of America | A1 | |
| US7096137B2 | United States of America | B2 | |
| US2006214977A1 | United States of America | A1 | |
| US7121639B2 | United States of America | B2 | |
| US2006242496A1 | United States of America | A1 | |
| US2006259258A1 | United States of America | A1 | |
| US2006259706A1 | United States of America | A1 | |
| US7152942B2 | United States of America | B2 | |
| US2007006150A9 | United States of America | A9 | |
| US7165824B2This record | United States of America | B2 | |
| US7171323B2 | United States of America | B2 | |
| US7181572B2 | United States of America | B2 | |
| US7188282B2 | United States of America | B2 | |
| AU2003302611B2 | Australia | B2 | |
| US2007211285A1 | United States of America | A1 | |
| US7278034B2 | United States of America | B2 | |
| US7278697B2 | United States of America | B2 | |
| US7302592B2 | United States of America | B2 | |
| US7328115B2 | United States of America | B2 | |
| US2008086655A1 | United States of America | A1 | |
| US7360131B2 | United States of America | B2 | |
| US2008117243A1 | United States of America | A1 | |
| US7377608B2 | United States of America | B2 | |
| US2008150997A1 | United States of America | A1 | |
| EP1572463A4 | European Patent Office (EPO) | A4 | |
| US2008155826A1 | United States of America | A1 | |
| US7399043B2 | United States of America | B2 | |
| US2008170093A1 | United States of America | A1 | |
| US7404616B2 | United States of America | B2 | |
| US2008259711A1 | United States of America | A1 | |
| US7465005B2 | United States of America | B2 | |
| US7467839B2 | United States of America | B2 | |
| US2009058903A1 | United States of America | A1 | |
| US2009073196A1 | United States of America | A1 | |
| US7519772B2 | United States of America | B2 | |
| US7523111B2 | United States of America | B2 | |
| US2009125720A1 | United States of America | A1 | |
| US7540579B2 | United States of America | B2 | |
| US2009198894A1 | United States of America | A1 | |
| US7573301B2 | United States of America | B2 | |
| US7592829B2 | United States of America | B2 | |
| US2009251502A1 | United States of America | A1 | |
| US7610163B2 | United States of America | B2 | |
| CA2508141C | Canada | C | |
| US7611215B2 | United States of America | B2 | |
| US2009273389A1 | United States of America | A1 | |
| US2009284279A1 | United States of America | A1 | |
| US2009319802A1 | United States of America | A1 | |
| US2010010767A1 | United States of America | A1 | |
| US7660998B2 | United States of America | B2 | |
| US2010039467A1 | United States of America | A1 | |
| US7707621B2 | United States of America | B2 | |
| US7722146B2 | United States of America | B2 | |
| US2010134541A1 | United States of America | A1 | |
| US7740347B2 | United States of America | B2 | |
| US7747646B2 | United States of America | B2 | |
| US7747887B2 | United States of America | B2 | |
| US7770008B2 | United States of America | B2 | |
| US7783886B2 | United States of America | B2 | |
| US2010223453A1 | United States of America | A1 | |
| US7800410B2 | United States of America | B2 | |
| US2010238213A1 | United States of America | A1 | |
| US7805626B2 | United States of America | B2 | |
| US2010245505A1 | United States of America | A1 |
39 transactions on the USPTO file
Allowed after 1 non-final rejection.
- Non-final rejections
- 1
- Final rejections
- 0
- RCEs
- 0
- Appeals
- 0
Over time
Point at a mark for the transactionTransactions
| Event | Code | |
|---|---|---|
| Payment of Maintenance Fee, 12th Year, Large EntityM1553 | M1553 | |
| Correspondence Address ChangeC.ADB | C.ADB | |
| Change in Power of Attorney (May Include Associate POA)PA.. | PA.. | |
| Correspondence Address ChangeC.AD | C.AD | |
| Correspondence Address ChangeC.AD | C.AD | |
| Recordation of Patent Grant MailedPGM/ | PGM/ | |
| Patent Issue Date Used in PTA CalculationAllowedPTAC | PTAC | |
| Issue Notification MailedAllowedWPIR | WPIR | |
| Dispatch to FDCD1935 | D1935 | |
| Application Is Considered Ready for IssuePILS | PILS | |
| Issue Fee Payment VerifiedN084 | N084 | |
| Issue Fee Payment ReceivedIFEE | IFEE | |
| Mail Notice of AllowanceAllowedMN/=. | MN/=. | |
| Mail Examiner's AmendmentMEX.A | MEX.A | |
| Notice of Allowance Data Verification CompletedAllowedN/=. | N/=. | |
| Examiner's Amendment CommunicationEX.A | EX.A | |
| Date Forwarded to ExaminerFWDX | FWDX | |
| Response after Non-Final ActionA... | A... | |
| Request for Foreign Priority (Priority Papers May Be Included)RQPR | RQPR | |
| Mail Non-Final RejectionNon-final rejectionMCTNF | MCTNF | |
| Non-Final RejectionNon-final rejectionCTNF | CTNF | |
| Case Docketed to Examiner in GAUDOCK | DOCK | |
| Information Disclosure Statement consideredIDSC | IDSC | |
| Reference capture on IDSRCAP | RCAP | |
| Information Disclosure Statement (IDS) FiledM844 | M844 | |
| Information Disclosure Statement (IDS) FiledWIDS | WIDS | |
| IFW TSS Processing by Tech Center CompleteTSSCOMP | TSSCOMP | |
| Case Docketed to Examiner in GAUDOCK | DOCK | |
| Application Return from OIPEWROIPE | WROIPE | |
| Application Return TO OIPEROIPE | ROIPE | |
| Application Dispatched from OIPEOIPE | OIPE | |
| Application Is Now CompleteCOMP | COMP | |
| Preliminary AmendmentA.PE | A.PE | |
| Additional Application Filing FeesADDFLFEE | ADDFLFEE | |
| Ommited Drawings. Applicant has Petitioned that the Filing Date not be changed and the Petition hasODRWNFD | ODRWNFD | |
| Notice of Omitted ItemsOMIT | OMIT | |
| Cleared by OIPE CSRL194 | L194 | |
| IFW Scan & PACR Auto Security ReviewSCAN | SCAN | |
| Initial Exam Team nnIEXX | IEXX |
7 legal events, as the office reported them to INPADOC
Over the term
Point at a mark for the eventEvents
| Event | Code | |
|---|---|---|
| Maintenance fee paymentMAFP | MAFP | |
| Fee paymentFPAY | FPAY | |
| AssignmentAS | AS | |
| AssignmentAS | AS | |
| Fee paymentFPAY | FPAY | |
| Information on status: patent grantGrantedPATENTED CASESTCF | STCF | |
| AssignmentAS | AS |
Numbers
- Publication
- 07165824
- Publication, DOCDB
- 7165824
- Publication, EPODOC
- US7165824
- Application
- 10727233
- Application, DOCDB
- 72723303
- Application, EPODOC
- US20030727233
Titles
- English
- Dead nozzle compensation
Patent term adjustment
- A delay
- +480 daysthe office missed an examination deadline
- Net adjustment
- 480 days
Classification
- CPC, 23
- G06F21/73
- B41J2/04505
- B41J2/04508
- B41J2/0451
- B41J2/04528
- B41J2/04541
- B41J2/04543
- B41J2/04563
- B41J2/04573
- B41J2/04586
- B41J2202/20
- G06F21/554
- G06F21/57
- G06F21/575
- G06F21/64
- G06F21/71
- G06F21/74
- G06F21/78
- H03K5/1252
- H04N1/405
- Y10T29/49401
- Y10S707/99933
- Y10S707/99939
- IPC, 7
- B41J29 393
- G06K15 00
- H04N1 46
- B41J2 05
- G06F21 00
- H04L9 00
- H04N1 405
- USPC, 5
- 347019000
- 358001900
- 358002990
- 358502000
- 358504000