Memory Interface

Memory is organized as follows

                      |------------  N  -------------|
 -                    --------------------------------
 |    addr = 0        B bits |B bits |B bits |B bits |
 |                    --------------------------------
 |    addr = 1        B bits |B bits |B bits |B bits |
1<<SZ                 -------------------------------
 |    addr = 2        B bits |B bits |B bits |B bits |
 |                    --------------------------------
 |    addr = 3        B bits |B bits |B bits |B bits |
 |                    --------------------------------
 - 


Brief summary:
There are two aggregate types in the memory interface - the mem_req type and the mem_resp type. You issue requests using the mem_req type and receive responses using the mem_resp type. For issuing a request, set the address, mask, data, wr and id signals in the request. For receiving a response, check the id and read the data lines from the response.

Interface Details:

For ISSUING READ or WRITE requests to the memory, check the following fields of the mem_req type:
    i) CHECK that req_ready is 1 in order to send a request
    ii) SET req_valid as 1
    iii) SET the addr and mask. Mask is bvec<N>, which selects the B-bit sized chucks to be read/written. Address is A bits, and there are 1<<A lines (A=SZ). 
    iv) SET the id. Each request is accompanied with a unique req_id. Since requests are satisfied out of order, the id is used for matching responses to requests.
    v) SET wr=1 for write requests. 
    vi) SET the data field for write requests. 

For RECEIVING responses, check the following fields of the mem_resp type:
    i) CHECK that resp_valid and resp_ready are 1.
    ii) CHECK the resp_id value and match it against the request you had sent.
    iii) CHECK the data fields for read requests
 

Implementation details:

There is a variable latency associated with requests. You can't issue requests if the mem unit is busy (req_ready would be 0), and response can take a variable number of cycles . There are two sources of randomness. The resp_ready and req_ready signals are derived from random numbers (set by Lfsr), and the response time is also dervied from a random number (controlled by the variable T). Adjust these parameters to get your desired latency behaviour.


Notes:
Instead of the run function, a separate run_with_mem function is included, which needs to be used. 

