Coding for Reuse Course - Module 2 Review

We covered a lot of topics and created a lot of code in module 2. Now let's see what you learned.

Module 2 introduction discussed the operation and encoding of the major architectural blocks, the differences between ours and the classical architectures, and how they could affect our design. We outlined our register arrangement and placement. Finally, we indicated that our processor is "BIG ENDIAN" format (i.e. the least significant byte of multi-byte data occupies the lowermost address).

In lesson 1 we discussed the register file and the source and destination muxes. We demonstrated two different mux architectures and how to use them to reduce logic levels. We also learned some Boolean math principles that allow us to simplify subsequent processing; as well as using a combination of UDP's and muxes to implement these principles during source selection. Finally, we studied flags and sign extension.

Partitioning and some implementation of the ALU took place in lesson 2. We talked about the role of the incrementor in applying Boolean principles to the ALU logic. We saw how to use UPD's and muxes to enable or disable the increment function. We outlined the major architectural blocks that the ALU requires, although we did not code them all. We added more UDP's to implement the logic block, and extensively studied carry, and avoiding pitfalls when it is used as a borrow indication. We learned to leverage the incrementor carry to help generate carry. Finally, we encoded the flag generation logic.

Lesson 3 introduced state machines and how to diagram and implement them. We discussed how to use bits in the state machine to directly control signals, fields in the state machine to facilitate decode, differentiating seemingly identical states, and using asynchronous events to either clock or control a state machine. We then studied the various processor bus cycles, including the effect of the ready and hold signals on those cycles. Finally, we encoded a preliminary bus state machine to try to implement those bus cycles.

Lesson 4 began with a discussion of using "iterative compilation" to remove basic errors early on in the coding process (I don't know about you, but I admit to sometimes making a typo). We showed how to use parameters and dummy blocks to source or sink signals that we have not yet coded. We then studied the serial output port and the "HALT" instruction and the implications to our architecture, especially during the early encoding phase. We then partitioned the "Instruction decode and sequencing" block and learned about microcode, transparent latches, and microcode expansion. We also talked about a flag mask decoder, that enables/disables flags on a per instruction basis. The concept of a "coded state machine", which uses fields, was expounded upon, as was the use of differentiator bits. We also discussed the use of alternative interpretation of fields to minimize the state machine width.

Lesson 5 expounded upon the microcode state machine and microcode expander to allow our processor to begin to execute instructions. We begin with a discussion of priority encoders, although they aren't used yet, which are extremely important in the future. We then delve into the microcode organization. We then get into specific sequences, such as instruction fetch, that allow the processor to execute instructions. Finally, we encode a large subset of single cycle instructions and simulated our skeleton.

In lesson 6 we completely rewrote the bus state machine to add extra states and to improve DMA handling. We also modified the destination mux to allow 16-bit adder addends and encoded the shifter block, eliminating the ase and sce signals in the process. We also removed some of the deltas between the 8085A, 8085B, 8085C and 8085D architectures, simplifying the parameter file and the microcode state machine. We filled in the remaining "left for you to code" instructions and then introduced the multi-cycle instructions. We began the discussion of multi-cycle instructions with simple two-cycle instructions. We demonstrated state sharing to simplify the microcode state machine and different methods of preventing multiple executions. We then revealed the encoding of the more complex multi-cycle instructions which require three or more bus cycles. At the conclusion of this lesson we had completed more than 80% of our microprocessor.

  1. In a state machine, what are the differentiator bits used for?

  2. What is the 'multiple execution pitfall'? What are the different methods to avoid it?

  3. In two's complement math, what happens when we negate a number and then perform the one's complement of the result?

  4. What is a 'transparent latch'? Why do we want to avoid combinatorial logic when we need one? How do you code a transparent latch and not use combinatorial logic?

  5. What are the uses for the incrementor block in the ALU?

  6. What is a priority encoder? Is it always a good thing that you intentionally encode?

  7. Describe two different types of muxes and how they are used.

  8. Draw the state transition diagram for the instruction fetch cycle in the improved version of the bus state machine. Include the effect of READY and HOLD.