HW6 Task 3 - Cycle Errors

Supplement to the hw6 main assignment.

Introduction

As you build your machine, you might encounter an error that looks like this (but with a different component name):
This can come about in two ways:
  1. The stall output of the DCache component is processed through one or more other components and used to feed the DCache's W input port.
  2. You add new input ports to the ICache to support the flush instruction. The instruction produced by the ICache is processed through some other components and then feeds the new flush support input ports.

The first problem has a simple fix. The second requires some changes to originally distributed set of source files, and an upgrade to SMOK V7.1.9.

DCache to DCache Cycle

This happens because the Stall output of the DCache is used to compute the W input to the DCache. The solution is to not use the DCache's Stall output when deciding whether or not to assert the W input -- use just the ICache's Stall (plus the usual computation of whether a store to memory is happening). (The DCache can read its own input during clock up and figure out (in C++ code) that it has to stall, so there's no need to run its own output back into it.)

ICache to ICache Cycle for flush

To implement flush, you have to add two new input ports to the ICache component, one giving the flush address and the other a bit indicating whether or not to flush. These inputs necessarily depend on an output of the ICache -- the current instruction. Thus, a cycle of combinational components is formed, leading to a message box like the one above.

The solution to this is to tag the two new input ports as being needed only at clock down. (I'll explain how in a moment.) Having done that, SMOK knows not to read them during clock up, and so doesn't encounter a cycle. At clock down it's guaranteed everything has settled, so when the ports are read there's still no cycle (to worry about).

Fixing the Original Distribution

You have to do a few, simple things to the original setup.
  1. You must use SMOK V7.1.9. This has been installed in the lab machines in O:\nt\courses\cse378\smok\SMOK719\, and is available for download for other machines.

  2. You must add a line to DLLInterface.h (at around line 38). Here's the code once you have added the line:
    typedef struct {
    	INPORTTYPE	type;
    	const char*	name;
    	int		width;
    	int		isClockdownInput;
    } INPORTDESC;
    
    The isClockdownInput is new.

  3. You must add a parameter to each input port created in ICache.cpp and DCache.cpp. Here is the snippet from ICache.cpp once corrected:
    	INPORTDESC	ICache::INPORT_DESCRIPTION[] = {
    		{MEM_INPORT, "Mem", 32, 0},	   // see comments for ExampleMAXComponent::INPORT_DESCRIPTION
    		{STD_INPORT, "PC", 32, 0},
    		{NO_INPORT, "", 0, 0}              // this ends the list.  It is REQUIRED!!!
    	};
    
    Note the fourth parameter on each line (it's zero in all these cases).

  4. Add a fourth parameter of zero to all the input ports originally created in DCache.cpp as well.

  5. Finally, when you create your new ports for flushing in the ICache, make the fourth parameter 1 (to indicate "read only at clock down"). For example:
            {STD_INPORT, "FE", 1, 1},
    
    creates the "flush enable" port.

  6. The inputs to the ports that have been marked "clock down inputs" (by setting their fourth parameter to 1) are available only during clock down. That means they are not available during the invocation of the ComputeOutputs() method. They are available during the invocation of LatchInputs().

  7. Note that you do NOT want to make the W port on the DCache a clock-down-only input port. You have to read that port during clock up to determine whether or not a line will be written, because you have to assert Stall during clock up if the write is going to miss (or otherwise require stalling). In fact, I think the only ports that should require clock-down-only status are the two new ones on the ICache.
Note that the un-fixed set of C++ source files is not compatible with SMOK V7.1.9 and the new (fixed) source code is not compatible with SMOK V7.1.8. Mixing the two versions is likely to lead to mis-behavior (including possible crashing).