Difference between revisions of "Single Core Cache Controller"

From NaplesPU Documentation
Jump to: navigation, search
(Sequential section)
Line 61: Line 61:
 
  ~
 
  ~
  
There is some information such as thread ID that it sent a request or address of LOAD request or type of request.  
+
There is some information such as thread ID that it sent a request or address of LOAD request or type of request. If there is at least one request, then CC move into SEND REQ state.
 
 
Type of request is READ and WRITE. Load/store and instruction misses are READ request because they have to read from the cache; flush, replacement, dinv(?) are WRITE request because they have to write into the cache.
 
 
 
 
 
If there is at least one request, then CC move into SEND REQ state.
 
  
 
In the SEND REQ state, there is a logic that allows CC to send a request to the memory. If the request is executable and the memory is available, then CC can send the request by writing the address and kind (READ or WRITE) of request.  If kind of request is READ, then CC need to waits for a response, else if kind of request is WRITE, CC computes a DINV request and it comes back in the IDLE state. Else if the request isn't executable, then CC comes back in the IDLE state.  
 
In the SEND REQ state, there is a logic that allows CC to send a request to the memory. If the request is executable and the memory is available, then CC can send the request by writing the address and kind (READ or WRITE) of request.  If kind of request is READ, then CC need to waits for a response, else if kind of request is WRITE, CC computes a DINV request and it comes back in the IDLE state. Else if the request isn't executable, then CC comes back in the IDLE state.  

Revision as of 15:49, 23 April 2019

This page describes the L1 cache controller (CC) allocated in the nu+ core and directly connected to the LDST unit. The main task is to handle requests from the core (load/store miss, instruction miss, flush, evict) and to serialize them. The requests are scheduled with a fixed priority.

TODO: magari un disegno di tutti i componenti collegati al CC

In a single core architecture, there is no need for Miss Status Holding Register (MSHR).

Interface

This section shows the interface of the cache controller to/from all other linked units.

To/from Core interface

Core interface (CI) is a component that buffers all request to/from LDST unit. Regards to this component, it can be possible to decouple a service speed of CC and a service speed of LDST units. In fact, the cache controller can execute one request at a time but there are more than one LDST units so they can send more than one request at a time. Core interface receives a request from the LDST unit (all the event concerned to the memory: instruction miss, load/store miss, flush, evict) and put it in one of four queues. Once elaboration of CC terminated, it sends a dequeue signal to CI for delete request in queues.

Following lines of code define interface to/from core interface:

output logic                                       cc_dequeue_store_request,
~
input  logic                                       ci_store_request_valid,
input  thread_id_t                                 ci_store_request_thread_id,
input  dcache_address_t                            ci_store_request_address,
input  logic                                       ci_store_request_coherent,
~

To/from LDST

TODO

To/from IO Map

TODO

To/from Memory controller

TODO

To/from Instruction cache

TODO

To/from Thread controller

TODO

Implementation

In this section is described how to is implemented CC.

FSM

The behaviour is implemented by a finite state machine (FSM). There are three states:

  • idle
  • send request
  • wait response

Below is represented the graph of FSM of CC.

Fsm cc.png

The FSM is implemented dividing sequential and combinatorial output.

Sequential section

In the IDLE state, there is a preparation of request. Preparation depends on the type of request. Below there is an example of LOAD request:

~
if (grants[LOAD]) begin
 granted_read          <= 1'b1;
 granted_write         <= 1'b0;
 granted_need_snoop    <= 1'b1;
 granted_need_hit_miss <= 1'b0;
 granted_wakeup        <= 1'b1;
 granted_thread_id     <= ci_load_request_thread_id;
 granted_address       <= ci_load_request_address;
~

There is some information such as thread ID that it sent a request or address of LOAD request or type of request. If there is at least one request, then CC move into SEND REQ state.

In the SEND REQ state, there is a logic that allows CC to send a request to the memory. If the request is executable and the memory is available, then CC can send the request by writing the address and kind (READ or WRITE) of request. If kind of request is READ, then CC need to waits for a response, else if kind of request is WRITE, CC computes a DINV request and it comes back in the IDLE state. Else if the request isn't executable, then CC comes back in the IDLE state.

In the WAIT RESP state, CC waits for a response from the memory. If memory response is available, then CC comes back in the IDLE state. If kind of request is INSTR, then CC return to Thread Controller (TC) the contents of memory. Else if kind of request is READ or WRITE, then CC performs a request by below lines of code:

~
end else if (grants_reg[LOAD] | grants_reg[STORE]) begin
 cc_update_ldst_valid       <= 1'b1;
 cc_update_ldst_way         <= counter_way[granted_address.index];
 cc_update_ldst_address     <= granted_address;
 cc_update_ldst_privileges  <= dcache_privileges_t'(2'b11);
 cc_update_ldst_store_value <= m2n_response_data_swap;
 cc_update_ldst_command     <= ways_full ? CC_REPLACEMENT : CC_UPDATE_INFO_DATA;
~

CC returns to LDST the way where a request has to execute, READ and WRITE privileges, data from memory that has to write if the type of request is STORE.

Combinatorial section

TODO

IO, Instruction and Core Interface requests buffering

Every request is stored in a vector (TODO: chiedere se il segnale valid è un id della richiesta; TODO: chiedere meglio questa parte). Regards to this vector, it can be possible to schedule a request. There is a component (described [here]) that allow rounding robin schedule.

TODO: gestione istruzioni "speciali"

Snoop managing

snoop + way TODO: chiedere meglio questa parte

Memory swap

This portion of code is used to transform a vector of data from xxx-endian into xxx-endian (TODO: chiedere a francesco cosa siamo noi e in cosa trasforma). For each vector of date there is a flag ENDSWAP: if it is asserted then is need to transform the format of data.