Lecture 21: More Sequential logic (by Trek Palmer) ================================================ Timing diagrams ---------------- Because sequential circuits are dependent upon state, they can be said to have a notion of time. Therefore diagrams that explicitly chart the behavior of sequential circuits as time unfolds are useful. These are called, unsurprisingly, timing diagrams. Because we're dealing with synchronous logic, there is a global clock that all the circuitry is driven off of, so most timing diagrams are done in terms of clock ticks rather than nanoseconds. So, if we look at the simple 2-bit non-saturating counter, we can construct the following timing diagram: >| |<-one clock pulse CLK: ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |__ X: _____________________________________ ____________________________| y1: ____ _____ _____ _____ _____ _____ _____ _____ ___| |___| |___| |___| |___| |___| |___| |___| |___ y2: _________ _____________ _________ ________ ______| |_______| |_______| |_______| z _____ _____ _____ _____ __________| |___________| |___________| |___________| |___ You can see from this diagram, that in addition to being a two-bit counter, the circuit also acts as a clock divider. Note that for a constant value of X, y1 pulses at half the frequency of CLK, and y2 at a quarter. Timing diagrams are often used to illustrate periodic causal relationships separated in time. For a simple circuit like this, it might seem a touch overkill, but for busses timing diagrams are one of the better ways of expressing data transfer protocols. Now let's look at the timing diagram for the saturating counter: >| |<-one clock pulse CLK: ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |__ X: _____________________________________ ____________________________| y1: ____ _____________________ _____ ___| |___| |___| |__________________________ y2: _____________________________ ______| |______________________________ z _____________________ __________| |_________________________________ Not so clear now, eh. This is where timing diagrams start to show their usefulness. Here you can see more clearly the direct relationship between z and y1 and y2. Buses, at a low-level ---------------------- We briefly discussed buses at the beginning of the semester, but now that we have learned much more about the low-level hardware in the computer we can re-examine buses in a much more informed way. So a bus is, in essence, a collection of wires. These wires are used to transmit data, but are shared between many components. This is the tricky bit, because multiple devices may want to use the bus at the same time. Most of what distinguishes buses from one another is how they deal with these issues of contention and sharing. Bus wires perform three main tasks: data transfer, address selection, and control. Some buses have seperate wire groups for all three, some have wires that perform multiple tasks. The address lines on a bus serve the same purpose as addresses in a memory system. Each device connected to a bus has an address (or address range) assigned to it to distinguish it from all the others. Command/control wires are used to implement the protocol of the bus itself. They tell devices what the state of the bus is, let devices make requests of the bus controller, let devices talk to one another, etc. It's where all the out-of-band stuff goes that actually makes the bus work. Data is data. Usually, the bulk of the wires are dedicated to this. When people say things like 32-bit PCI what they usually mean is that the bus is capable of transferring data in 32-bit chunks. Bus control ------------ There are several ways of controlling a bus. One way is to have a centralized controller (often known as the bus master) who must be solicited for time on the bus. This is a fairly simple system, but it has its drawbacks, namely that it doesn't scale all to well. Also, there's the issue that if all data transfers have to be routed through the master, then that can slow down communication between devices (DMA can help solve this though). Another notion is to let all devices have control of the bus, and then construct a bus arbitration system that will let them argue and decide which device gets to be bus master next. This is a more complicated issue, and there's the problem that you can saturate the bus with arbitration traffic if you're not careful. This system eliminates the centralized master bottleneck, though. Centralized Control -------------------- In this organization, a bus controller decides who goes next. Consider the following example: Bus Controller--------+ -------+ ---------+ | |BG0 |BG1 |BG2 +--------------+----------+--------------+----------~BBSY +--------------+----------+--------------+----------~BR | | | Dev0 Dev1 Dev2 The control in this case consists of three signals, Bus request (BR), bus busy (BBSY) and Bus grant (BG). If a device wants to use the bus, it asserts BR. The bus controller then has to process this and decide whether or not to let the device use the bus. When the controller decides to grant the bus to the requesting device, it will assert the appropriate BG line. The device will then wait for the bus to become free (BBSY goes low) and will then assume control of the bus. Here's a transaction represented as a timing diagram: ~BR -----------+ +-------------------------------------- |__________|Dev0 requests the bus BG0 +-----------+The controller grants control _______________________| |__________________________ ~BBSY +---------------+Dev0 gets the bus _______________________________________| |_______ The advantage to centralized control is that the devices themselves can be relatively stupid in terms of how they use the bus. All the selection and arbitration logic can be placed in a single chip. The disadvantage is that the controller has to be part of any bus transaction, and it serves as a single point of failure. Decentralized Control --------------------- Decentralized control is trickier. All devices have to implement the arbitration protocol. There are positively oodles of distributed arbitration protocols, and they each have their own advantages and disadvantages. Often what happens is that when multiple devices contend, some mathematical operation is performed on the contending addresses to generate a final address which indicates who won this particular round. The losing devices will usually have to recontend when the bus becomes free again. DMA ----- Direct memory access (or DMA) is a way around the bottleneck problem in a centralized system. With DMA controllers, it is possible for a device to dump it's data direct to memory without having to pass through the CPU. This has several advantages: 1) While the bus is occupied with moving bits from a device into memory, the CPU can execute other code 2) Data transfers to and from memory are considerably faster Here's an archetypal DMA transaction: 1) Some code executing on the CPU wants to make a data transfer from some I/O device 2) The processor asks for the bus, and when it gets it sends a request to the DMA controller 3) The request, which is of the form (base address, number of words) goes out to the DMA controller 4) The CPU releases control of the bus 5) The DMA controller gets the bus, and starts pushing bytes around 6) Meanwhile, the CPU suspends the program waiting for the DMA request and does something else (this is usually a function of the OS) 7) The DMA finishes (and usually sets off an interrupt to let the CPU know) 8) The CPU resumes execution of the suspended program, and voila' the data is now in memory! Now that you've seen clocked circuits, you can understand the two main categories of buses. A Synchronous bus is one that has a global clock that all devices sync to, while an asynchronous bus is one that has no such clock and the devices need to jump through extra hoops to acquire the bus. Synchronous buses ----------------- In a synchronous bus, everything is oriented around the clock signal. All the logic in the attached devices runs off of the global clock, which simplifies the detection of bus signals. Here's an example of a data transfer on a synchronous bus: Clock +-------------------------+ +-------- ___| |__________________________| __ ____________________________________________________ ________ Addr/ \/ \/ Cmd __/\____________________________________________________/\________ Data ___________________________ ____________________________/ \_________ \___________________________/ With synchronous buses, the clock pulse must be long enough to allow for signals to propagate to the farthest devices on the bus, and to allow them time to decode and react to control signals. In this case, the data is sent over the bus sometime after the master asserts the address and command lines because there's a delay between when the master sends the signal and when the slave recieves and interprets the signal. Getting the timing of the clock correct is perhaps the biggest headache in synchronous bus design. Asynchronous Buses ------------------- In an asynchronous bus, there is no centralized clock. This means that the bus designers can be much more relaxed about the clock signal, but it means that the bus protocol becomes much more complicated. Like in networking, devices now have to "handshake" in order to communicate to one another. A handshake is an exchange between two devices to establish a communication channel. In a bus it boils down to two questions: Master: "Are you ready? Cause I'm ready." and the response, Slave: "Now I'm ready. Let's get started." In a timing diagram: __ ____________________________________ __________________________ Addr/ \/ \/ Cmd __/\____________________________________/\__________________________ Master _______________________ Ready ____________| |________________________________ Slave ______________________________ Ready _____________________________| |________ ____________________________ Data _____________________________/ \________ \____________________________/ So here, the master asserts its ready signal until the slave is ready, and then it waits for the transfer. In general, asynchronous buses operate by the master signalling that it's ready, the slave signalling that its ready and lowering the ready signal when this particular transaction is complete.