Am2901 Completion and Integration with Am9080a A. Objectives Written By Kurt English This laboratory assignment is an introduction to the Verilog Hardware Description Language, which will be used to complete an AMD Am2901 microprocessor slice. Students are expected to complete the Q- Register, ALU, ALU input and output routing, RAM shift, and Q shift sections of the Am2901, while the memory of the Am2901 is already provided. The Am2901 will then be implemented into a provided Am9080a Verilog code and execute full Intel 8080 compatible instructions. The Verilog code will be run on a Cyclone II FPGA through Altera Quartus II software. B. Preparatory Reading and Other References 1. Am2901 Datasheet. Provided in lab assignment. 2. Am9080a Datasheet. Provided in lab assignment. C. General Description of Am2901 Microprocessor Slice The Am2901 contains a 4-bit ALU, 16x2x4bit memory, and a Q-register for output shift operations. It has a 9-bit opcode. ALU o 4-bit o The ALU can read in data from its internal memory, external connections, or the Q- register. o 3-bit Opcode from overall 9-bit opcode to Am2901 o Can perform addition, subtraction, or, and, xor, and xnor operations. Memory o 16 addresses o 2 4-bit divisions, A and B o 2 output ports, A and B o Can read from A or B sections of memory independently o Write address for B is used for both A and B write address
o Memory is read and written to every clock cycle. Writes occur on the positive clock edge, and reads on the negative clock edge. Q-Register o 4-bit o Can shift left or right by 1 bit each clock cycle o Leftmost and rightmost bits have external bidirectional connections outside the Am2901 o Can receive input from itself or ALU output
Am2901 Block Diagram
Am2901 Internal Operation
Am2901 Op-Codes D. Am2901 Relation to Am9080a The Am2901 serves as the ALU and register file for the Am9080a. The Am9080a register file is stored within the Am2901 internal memory. Four AM2901 microprocessor slices are used to conduct math operations up to 16 bits. E. Differences Between Lab Implementation and Literal Am2901 The Am2901 used in the provided Am9080a code is expanded to 8-bits. This reduces the complexity of the Am9080a design while adding little to the complexity of the Am2901. In the current implementation of the Am9080a and Am2901, the C n+4 signal is omitted, which causes some 8080 instructions to fail. Extra credit will be awarded to students who implement the C n+4 signal and properly wire it into the Am9080a.
F. Verilog Basics Assignment Asynchronous Asynchronous signal assignment is done with the assign operator. Assign will connect two wires together. Assign can be used to connect multiple wires if a wire is already connected to another wire: wire A; wire B; wire C; assign B = A; assign C = B; // connects wires A and B together // connects wire C to wire B, which is also connected to wire A The above will connect wires A, B, and C together. Assign can also set outputs to high impedance, logic high, or logic low. assign C = 1 bz; // high impedance assign B = 1 b0 // logic low assign A = 1 b1 // logic high Assign can also be used to make decisions on what the output should be, instead of a simple assignment: assign B = (A)? 1 b1 : 1 bz; The above will set wire B to logic high if wire A is logic high. If wire A is logic low, wire B will be set to high impedance. This is very useful for making buses. Synchronous Synchronous signal assignment is done with the always operator. Always will conduct logic when a certain condition is met, such as a clock pulse transitioning to logic high. Output signals set in an always block must be registers, not wires. reg S; wire B; wire C; always @ (posedge clock) begin S = B + C; end The above will add B and C and set the result to register S whenever a positive transition occurs on clock.
Math Mathmatical operations are very simple in Verilog, for example, the following code will add signals A and B together for sum S. Addition can be done on multi-bit signals: assign S = A+B; OR is done in the following code snipet. The signal ored will be the result of the OR operation between A and B. You can place any signal name in place of ored, A, or B : assign ored = A B; Other operations are very similar to OR: assign result = A&B; // A AND B assign result = A^B; // A XOR B assign result = A~^B; // A XNOR B Modules All Verilog code must be within a module. A module will have inputs and outputs linking it to other modules. A Verilog HDL file can contain just one, or multiple modules. module example_module ( A, B, C ); input A; output B; inout C; // input to module // output from module // bidirectional // code here end
Below demonstrates how to link modules: // code in calling module wire D; wire E; wire F; example_module example_module_name { D, // first pin on module is connected to wire D E, // second pin on module is connected to wire E F // third pin on module is connected to wire F }; // more code in calling module An alternative syntax is below: // code in calling module wire D; wire E; wire F; example_module example_module_name {.A(D), // module pin A on child module is connected to wire D of parent module.b(e), // module pin B on child module is connected to wire E of parent module.c(f) // module pin C on child module is connected to wire F of parent module }; // more code in calling module
G. Testing on Am9080a When just beginning the lab, your AM2901 implementation will not be complete enough to produce meaningful output for the rest of the CPU. Therefore, to begin testing you should set the E2901_8.v file to be the Top-Level Entity. This will cause all files above the Am2901 to be ignored, letting you see the direct inputs and outputs to the Am2901 to debug operation. You will then need to create a new.vwf file to test the Am2901 directly.
When your Am2901 is nearing completion and you want to test if it produces the exact output required by the Am9080a, then switch the top level back to the combined.bdf file. 8080_TEST.vwf is already configured with many debug signals to test operation. Multiple test files are included to run full 8080 instructions. The way a test is run is by changing the system memory initialization file. The system memory is separate from the Am9080a. You can either change the memory settings within the default initialization file, which is sysinit3.txt, or you can make a new memory initialization file and change sysmem.v to load that file instead. When using the 8080_TEST.vwf file, it is difficult to find what registers were set to after an Am2901 operation. Some operations only write to the registers within the Am2901, resulting in no output from the Am2901. An easy way to find a result of an operation is to run an STA instruction, which will output the accumulator register. This will send the accumulator to memory, requiring it to be sent out from the Am2901 and allowing the result to be read. The opcode for an 8080 store instruction is 0x32, with 2 additional bytes for the memory destination.
When STA is run, the system memory will latch onto Am9080a data output on the falling edge of DB1 (a control signal for MEMW), so whatever is being sent out of ALU_2_Y (the high-byte Am2901) will be sent to memory, and was the data stored within the accumulator. In green you can see the 0x11 result after subtracting 0xAA from 0xBB, and in red you can see the 0x88, which is the result after rotating right once.
H. RTL Viewer Quartus II contains a highly useful debugging feature known as the RTL Viewer, which will generate visual blocks of each module and display connections. You can double click on each module to view the internal features of that module, single click on a wire to view all connection points for that wire, and zoom out to see the big picture. To use the RTL Viewer, compile your code and click Tools -> Netlist Viewers -> RTL Viewer.
I. Routed Am9080a Verilog is highly portable code that can be used by many programs in addition to Quartus II. Below Synopsys software is used to compile structural Verilog code describing point-to-point connections on an IBM 90nm process, then Cadence Encounter is used to route this structural Verilog as a microprocessor ready for production. High ALU refers to the high 8-bit Am2901, and LOW ALU refers to the low 8-bit AM2901. Other file types such as Altera Quartus II.bdf files are specific to Quartus II only, and cannot be used by other programs for other applications.