Hardware Design Patterns
The purpose of this document is to detail a set of "best practices"
solutions to common hardware/software interface design problems.
Systems designed by hardware engineers that do not appreciate the
subtleties of interface implementation can impact software development
in ways that range cause from anoyances to complete project failures.
Many of the common mistakes impact the ability to write reusable
- Register grouping
- Mixed functions
- Forced mutexes
- Forced polling
- Loss of synchronization between HW and SW
ystems that involve custom hardware with software interfaces
The advent of the micro-processor allows digital hardware designers
to avoid a great deal of design effort by plopping down a processor and
leaving the problem to the software guys.
The result is inevitably that the
A system development should recognize the needs of both hardware and
software aspects systems.
To summarize: get involved with the system design.
The State Change Pattern Interrupt
Pattern. describes a best practice for implementing the interface
for a set of state change indications.
- Group contiguously in memory map by low level function rather
than by register type.
- Think modular. E.g. today I may only have one foo-bar, but in a
future design I may have ten foo-bars. Can I just add the ten
foo-bars to the memory map, or must I change the register contents or
locations in ways that cause the software to be changed, other than
simply creating another instance of the driver?
- Separate control and status (e.g. avoid read-clear registers).
- Separate functions:
- E.g. UART
- Modem Control
- Flow Control
- Avoid read-modify-write requirements if a register contains bits
related to more than one low level function. Otherwise, software must
take steps to ensure mutually exclusive access to the register by the
drivers. These avoidable unnecessary software constraints affect not
only the design of the software, but can be a source of latent software
anomalies. Requiring software to provide the mutual exclusion causes
the software to be written such that it is either dependent upon system
services for mutexes that vary from system to system adversely
affecting the reusability and reliability of the software across
processors and operating systems. In addition, the overhead required
for the mutual exclusion enforcement has adverse affects on performance
characteristics such as interrupt latencies and processor throughput.
- Writes are typically more efficient than reads on the processor
bus. For example Posted Writes vs Delayed Reads on a PCI bus.
- Polling sucks. Polling is a waste of processor bandwidth, but tt
also has a negative impact on system scalability.
- Do not mix bit fields with different semantics in the same
- Hitel example of control and interrupt clear.
- Analyze Register Types
- Interrupt per source
- Symmetry (Interrupt on All state changes, not Hitel
- Strive for symmetry. Symmetry is beauty.
- Contiguous memories. Simplify exception cases for buffer
- Consistent access rule memory spaces. E.g. External PCI bus
masters access all program memory spaces (e.g. All RAM, ROM).
Otherwise, software must make special provisions for buffer space, and
will need to perform otherwise unneccessary copy operations that
negatively affect processor throughput and utilization.