Main

ECE 576 - Homework Assignment 1

Due TBD via D2L

THIS ASSIGNMENT IS UNDER CONSTRUCTION. PLEASE CHECK BACK LATER FOR FINAL DETAILS


Announcements and Clarifications:

Q: Does the MEMORY_RTL implementation need separate states for read and write operations?

A: No. The memory does not need to be implemented as a state machine as there no "states" in the memory beyond the storage. Instead, you are modeling the memory as a synchronous process that on each clock cycle will check in incoming commands signals to determine and carry out the desired operations. In template provided for the MEMORY_RTL component, the rtl() function (i.e. SC_METHOD) will be executed on each rising clock edge. Thus, the implementation of this function will simply interface with the inputs to the component and assign the outputs.

Q: How do you connect the MEMORY_RTL component to the simple_if interface?

A: A instance of the MEMORY_RTL component will need to be instantiated within the Memory component, where the memory component still implements the simple_if interface. Unlike like the untimed model, the implementation of the interface will directly interface with the inputs and outputs of the MEMORY_RTL component. In order to do so, you will need to use sc_signals to connected to the inputs/outputs of the MEMORY_RTL instance along with adding a special thread for generating the clock signal. Within the implementation of the simple_if interface, the implementation can directly assign values to the signals and wait for the appropriate response, before returning the required data and Boolean flag for success of the operation.

Q: What is meant by requiring that a usage statement be provided if an argument is incorrect.

A: A short usage statement should be printed in the user does not specify the correct number of commandline arguments, displaying a message such as:

"usage: sad memfile"

Q: In the simple interface definition given for homework 1, it says that it should return true if the specified location in the memory is valid or false otherwise. I am not sure I understand what exactly needs to be done for this. The SAD pseudo-code clearly shows that the memory location addresses will always be between 0 and MEM_SIZE.

A: The memory should not be modeled to only work for the SAD example, but instead should be modeled properly as a memory. It is possible that the address provided could exceed the defined size of the memory. For example, you could test that this functionality is working by selecting a MEM_SIZE smaller than the BLOCK_SIZE. Similarly, you need to implement the Write() transaction even though the SAD component does not write to the memory. Be sure to test this functionality as well.

Q: What exactly needs to be done by the model in case the read function returns a false and under what case would a false be returned by the interface?

A: The simplest option is to report a descriptive error.


Un-timed TLM Model for SAD (25 points)

Using SystemC and transaction-level modeling, implement an un-timed system model of a sum of absolute differences (SAD) computation composed of an SAD component directly connected to a memory. As shown if the diagram to the right, the system consists of a SAD master directly connected to a memory component using a simple interface, simple_mem_if.


SAD Component

The SAD will compute the sum of absolute differences between two blocks of data stores within the memory. This computation should be customizable using #define's for BLOCK_SIZE, BLOCK1_ADDR, and BLOCK2_ADDR. The final result of the SAD component should be printed along with the current simulation time.

The following pseudocode provides a overview of the intended SAD component's functionality that should be customizable using a set of #define's with the resulting SystemC implementation.

#define BLOCK_SIZE 64
#define BLOCK1_ADDR 0
#define BLOCK2_ADDR 64

int i, v;
int sad;

for (i=0; i<BLOCK_SIZE; i++)
{
   v = MEM[BLOCK1_ADDR+i] - MEM[BLOCK2_ADDR+i];
   if( v < 0 ) v = -v;
   sad += v;
}

Simple Interface

A single interface named simple_mem_if will be used to specify two possible transactions between the SAD and memory components. The simple_mem_if is defined as:

class simple_mem_if : virtual public sc_interface
{
  public:
    virtual bool Write(unsigned int addr, unsigned int data) = 0;
    virtual bool Read(unsigned int addr, unsigned int& data) = 0;
};

The return value for each transaction will report the success of the operation, returning true is the specified location in the memory is valid, and false' otherwise.

Memory Component

The memory component should be modeled as 32-bit wide memory, where the size of the memory should be customizable using a #define MEM_SIZE. The memory should be initialized by reading in the initial values from an input file provided as a commandline argument, where the file contains whitespace separated integer values. This initialization should be implemented within the constructor for the memory. If the provided memory file does not enough values to initialize the entire memory, the remaining entries should be initialized to 0.

Commandline Arguments

Your program must be capable of utilizing a commandline argument to specify the location of the memory initialize file. The following provides an example of the acceptable commandline arguments:

sad memfile

Your program must also ensure the user has correctly provided the required commandline options and display a usage statement if the provided arguments are incorrect.

Mixed Cycle-Accurate and Approximate-Timed Model for SAD (25 points)

Create a revised implementation of the SAD system in which approximate timing information is incorporated within the SAD component to model the computational performance and implement the memory as a cycle accurate implementation using the following specifications.

Approximate-Timed SAD Model

Assuming all individual operations, e.g. additions, multiplication, comparisons, etc., require a 10 ns delay, incorporate wati() statements within the SAD component to model the appropriate delays. Using C/C++ comments within the code itself, provide a detailed annotation of the approximate time delays utilized.

Cycle-Accurate Memory Model

As shown if the diagram above, implement a cycle-accurate RTL memory component named MEMORY_RTL and integrate this model within the original memory component to maintain compatibility with existing simple_mem_if interface. The RTL memory implementation should use one of the the following SystemC templates:

SC_MODULE(MEMORY_RTL)
{
   sc_in<sc_logic> Clk;
   sc_in<sc_logic> Ren, Wen;
   sc_in<unsigned int> Addr;
   sc_in<unsigned int> DataIn;
   sc_out<unsigned int> DataOut;
   sc_out<sc_logic> Ack;

   unsigned int memory_data[MEM_SIZE];

   SC_CTOR(MEMORY_RTL)
   {
      SC_METHOD(rtl);
      sensitive << Clk.pos();
   }

   void rtl() {
   }
};
class MEMORY_RTL : public sc_module
{
public:
   sc_in<sc_logic> Clk;
   sc_in<sc_logic> Ren, Wen;
   sc_in<unsigned int> Addr;
   sc_in<unsigned int> DataIn;
   sc_out<unsigned int> DataOut;
   sc_out<sc_logic> Ack;

public:
   unsigned int memData[MEM_SIZE];

   SC_HAS_PROCESS(MEMORY_RTL);

   MEMORY_RTL(sc_module_name name) : sc_module(name)
   {           
      SC_METHOD(rtl);
      sensitive << Clk.pos();
   }

public:
   void rtl() {
   }
};

The MEMORY_RTL component should provide a cycle-accurate model of a synchronous memory with the following behavior:

  • If the Ren input is asserted, the memory will output the data within the location specified by the input Addr on the output DataOut', if the provided location is valid.
  • If the Wen input is asserted, the memory will write the data provided by the input DataIn to the location specified by the input 'Addr, if the provided location is valid.
  • If the specified location is a valid location within the memory, the Ack output should asserted, otherwise the Ack should remain 0.

The MEMORY_RTL component should be instantiated within the original memory component using sc_signal's to interface to the IOs of the component. Within the implementation of the simple_mem_if, these signals should be used to interface to the MEMORY_RTL component.

Assuming a 100 MHz operation, the clock for the memory can be implemented as an 'SC_THREA'D as follows:

void oscillator()
{
   while(true) {
      clk.write(SC_LOGIC_0);
      wait(5, SC_NS);
      clk.write(SC_LOGIC_1);
      wait(5, SC_NS);
   }
}

Submission Requirements:

You must submit both SystemC implementations along with a brief README via D2L as a single ZIP or TAR/GZIPPED archive. Note: Do not submit executables, Makefiles, or Visual Studio project files.