Wiring the Stages ################# .. include:: /header.inc .. vim:filetype=rst spell: There is a simple pattern that you will use to wire up the internal structure of each stage. It looks like this: .. code-block:: c++ w1.attach_driven(inv1.get_out_pin("OUT")); w1.attach_drives(inv2.get_in_pin("IN")); Basically, you need to study the stage diagram, identify all the wires in that stage, and make the connections needed. .. note:: In the old days, I use to print out the diagram, and use a marker to highlight each connection I made until the circuit was actually constructed. I still have my original diagrams from the very first computer I designed from scratch back in 1978. Rather than build each stage completely, we will use test-driven-development to put together our machine. We will use a top-down approach, beginning with a top-level class that encapsulates the entire machine. We will call that class the ``AVRsim``. The constructor for this class will put together the entire machine (actually, it will just create stage classess, each of which is responsible for wiring up the needed internal structure). Since we will want to run our machine either in a command line mode, or in a graphics mode, we will use pass the ``guienabled`` flag into this class through a ``run`` method. Here is the class header file: .. literalinclude:: code/avrsim/ex01/include/AVRsim.h :linenos: :caption: include/AVRsim.h And, here is our traditional first test case for this clas: .. literalinclude:: code/avrsim/ex01/tests/test_avrsim.cpp :linenos: :caption: tests/test_avsim.cpp Here is enough of an implementation to get started: .. literalinclude:: code/avrsim/ex01/lib/AVRsim.cpp :linenos: :caption: lib/AVRsim.cpp Wiring the Stages ***************** We can create simple classes that encapsulate the functions of each stage. These should inherit from our standard ``Component`` class. Here is an example, for the ``Fetch Unit``: .. literalinclude:: code/avrsim/ex02/include/Fetch.h :linenos: :caption: include/Fetch.h Program Counter Updating ======================== The Program Counter is the key part of the ``Fetch`` stage. We will pass the value used to fetch an instruction through to the decode stage where it will be updated depending on the size f the current instruction. After that, the PC will flow into the other stages, eventually ending up back at the entry point to the Fetch Stage, where it will be used for the next instruction fetch. We can wire up our entire machine using a simple pattern, and verify that we get a new PC when we get back to another fetch. Here is the Fetch Unit implementation we need for this test: .. literalinclude:: code/avrsim/ex02/lib/Fetch.cpp :linenos: :caption: lib/Fetch.cpp All other stages are identical for now, except we will add one to the PC as it passes through the decoder for this next test. Each of these classes will contain an internal ``build`` method, where the internal structure of the stage will be wired. We will ge to that soon enough. For now, we want to focus on the top level structure of our simulator, so we have something running. Testing a Machine Cycle ======================= Obviously, we need to wire up all four stages to be able to run the next test. Here are the additions we need to do that: .. literalinclude:: code/avrsim/ex02/include/AVRsim.h :linenos: :caption: include/AVRsim.h .. literalinclude:: code/avrsim/ex02/lib/AVRsim.cpp :linenos: :caption: lib/AVRsim.cpp The test we will run runs through a full four step cycle, and verifies that the program counter has been incremented .. literalinclude:: code/avrsim/ex02/tests/test_avrsim.cpp :linenos: :caption: tests/test_avrsim.cpp .. note:: This is a bad test. Normally, you work hard to create tests that will survive untouched as the project eolves. In our real machine, there will be times when the program counter will increment by two, and this test will fail! It will also fail if we run a branch instruction, since then the value of the PC will be defined by that branch instruction. We have enough of the top-level done now. We want to study how to integrate this machine into our graphics system next.