hwtLib.amba.axi_comp.cache package

# AXI4 caches This module contains an implementation of various caces for AXI interfaces.

Submodules

hwtLib.amba.axi_comp.cache.addrTypeConfig module

class hwtLib.amba.axi_comp.cache.addrTypeConfig.CacheAddrTypeConfig(hdl_name_override: Optional[str] = None)[source]

Bases: hwt.synthesizer.unit.Unit

A container of address type configuration and address parsing utils.

Variables
  • ADDR_WIDTH – the total width of the address in bits

  • CACHE_LINE_SIZE – cache line width in bytes

  • CACHE_LINE_CNT – total number of cache lines available in this cache (sum in all sets/”ways” together).

Address is composed of several parts as shown in table bellow:

tag

index

offset

  • offset is an offset in cacheline

  • index is an index of set where the cacheline could be stored in cache

  • tag is a rest of address used to check if the calenine stored on index in cache is the cacheline of the requested address

_compupte_tag_index_offset_widths()[source]
addr_in_data_array(way: hwt.synthesizer.rtlLevel.rtlSignal.RtlSignal, index: hwt.synthesizer.rtlLevel.rtlSignal.RtlSignal)[source]
deparse_addr(tag, index, offset) Tuple[hwt.synthesizer.rtlLevel.rtlSignal.RtlSignal, hwt.synthesizer.rtlLevel.rtlSignal.RtlSignal, hwt.synthesizer.rtlLevel.rtlSignal.RtlSignal][source]
parse_addr(addr) Tuple[hwt.synthesizer.rtlLevel.rtlSignal.RtlSignal, hwt.synthesizer.rtlLevel.rtlSignal.RtlSignal, hwt.synthesizer.rtlLevel.rtlSignal.RtlSignal][source]
parse_addr_int(addr: int) Tuple[int, int, int][source]

hwtLib.amba.axi_comp.cache.cacheWriteAllocWawOnlyWritePropagating module

class hwtLib.amba.axi_comp.cache.cacheWriteAllocWawOnlyWritePropagating.AxiCacheWriteAllocWawOnlyWritePropagating(hdl_name_override: Optional[str] = None)[source]

Bases: hwtLib.amba.axi_comp.cache.addrTypeConfig.CacheAddrTypeConfig

Non-blocking pipelined Set Associative cache for AXI interfaces which is designed to work with an LSU which solves only WAW (write-after-write) conflicts.

_images/AxiCacheWriteAllocWawOnlyWritePropagating.png
  • The tag_array contains tags and cache line status flags for cache lines.

  • The lsu_array contains the data for data for pseudo LRU (Last Recently Used) cache replacement policy. It is stored in a separate array due to high requirements for concurrent access which results in increased memory consumption.

  • The data_array is a RAM where data for cache lines is stored.

The memories are separated because they have a different memory port requirements and we want to keep the number of memory ports and the size of the memory minimal as resource requirements grow exponentially with increasing number of memory ports.

HDL params
  • ADDR_WIDTH - default value 32 of type int

  • DATA_WIDTH - default value 16 of type intdata width of interfaces

  • ID_WIDTH - default value 6 of type int

  • ADDR_USER_WIDTH - default value 0 of type int

  • WAY_CNT - default value 2 of type intnumber of places where one cache line can be stored

  • MAX_BLOCK_DATA_WIDTH - default value 8 of type int

  • CACHE_LINE_SIZE - default value 2 of type int

  • CACHE_LINE_CNT - default value 16 of type int

HDL IO
HDL components
schematic
_impl()[source]

Read operation:

  • Use index to lookup in tag memory

  • if tag matches return cacheline else dispatch read request (the transaction is dispatched with original id, upon data receive the transaction is passed to master without any synchronization with the cache )

Write operation:

  • Use index to lookup in tag memory

  • If tag matches and the cacheline is not being replaced update the data in data array.

  • If tag is not found in corresponding set select a victim and read it from data array, flush it and write back cacheline to array and update tag

axiAddrDefaults(a: hwtLib.amba.axi4.Axi4_addr)[source]
connect_tag_lookup()[source]
flush_handler(flush_data: hwtLib.mem.ramTransactional_io.TransRamHsW, axi_m_aw: hwtLib.amba.axi4.Axi4_addr, axi_m_w: hwtLib.amba.axi4.Axi4_w, axi_m_b: hwtLib.amba.axi4.Axi4_b)[source]
incr_lru_on_hit(lru_incr: hwtLib.amba.axi_comp.cache.lru_array.IndexWayHs, tag_res: hwtLib.amba.axi_comp.cache.tag_array.AxiCacheTagArrayLookupResIntf)[source]
read_handler(ar_tagRes: hwtLib.amba.axi_comp.cache.tag_array.AxiCacheTagArrayLookupResIntf, axi_s_r: hwtLib.amba.axi4.Axi4_r, ar_lru_incr: hwtLib.amba.axi_comp.cache.lru_array.IndexWayHs, da_r: hwtLib.mem.ramTransactional_io.TransRamHsR, axi_m_ar: hwtLib.amba.axi4.Axi4_addr, axi_m_r: hwtLib.amba.axi4.Axi4_r)[source]
Parameters
  • ar_tagRes – Read request including information from tag_array for given tag.

  • axi_s_r – Read data requested by ar_tagRes.

  • ar_lru_incr – Incrementing LRU for given address when tag is found.

  • da_r – Read interface of data_array used when tag is found.

  • axi_m_ar – Read address request interface to memory when tag is not found.

  • axi_m_r – Read data requested by axi_m_ar from memory when tag is not found.

_images/AxiCacheWriteAllocWawOnlyWritePropagating_read_handler.png
resolve_victim(st0_o_tag_found: hwt.synthesizer.rtlLevel.rtlSignal.RtlSignal, st0_o_found_way: hwt.synthesizer.rtlLevel.rtlSignal.RtlSignal, st0_o_tags: List[hwt.interfaces.structIntf.StructIntf], victim_way: hwt.interfaces.std.Handshaked)[source]
write_handler(aw_tagRes: hwtLib.amba.axi_comp.cache.tag_array.AxiCacheTagArrayLookupResIntf, axi_s_b: hwtLib.amba.axi4.Axi4_b, aw_lru_incr: hwtLib.amba.axi_comp.cache.lru_array.IndexWayHs, victim_way_req: hwtLib.common_nonstd_interfaces.addr_hs.AddrHs, victim_way_resp: hwt.interfaces.std.Handshaked, da_w: hwtLib.mem.ramTransactional_io.TransRamHsW, tag_update: hwtLib.amba.axi_comp.cache.tag_array.AxiCacheTagArrayUpdateIntf)[source]
Parameters
  • aw_tagRes – Write request including in information from tag_array for given tag.

  • axi_s_b – Response requested by aw_tagRes

  • aw_lru_incr – Incrementing LRU for given address when tag is found.

  • victim_way_req – Request victim from LRU array for a specified index, when cache is full.

  • victim_way_resp – Victim address requested by victim_way_req

  • da_w – Write interface of data_array to write and initiate flush when cache is full.

  • tag_update – Tag update interface for newly written data.

_images/AxiCacheWriteAllocWawOnlyWritePropagating_write_handler.png
hwtLib.amba.axi_comp.cache.cacheWriteAllocWawOnlyWritePropagating._example_AxiCacheWriteAllocWawOnlyWritePropagating()[source]

hwtLib.amba.axi_comp.cache.lru_array module

class hwtLib.amba.axi_comp.cache.lru_array.AxiCacheLruArray(hdl_name_override: Optional[str] = None)[source]

Bases: hwtLib.amba.axi_comp.cache.addrTypeConfig.CacheAddrTypeConfig

A memory storing Tree-PLRU records with multiple ports. The access using various ports is merged together. The victim_req port also marks the way as lastly used. The set port dissables all discards all pending updates and it is ment to be used for an intialization of the array/cache.

_images/AxiCacheLruArray.png
HDL params
  • ADDR_WIDTH - default value 32 of type int

  • CACHE_LINE_SIZE - default value 64 of type int

  • CACHE_LINE_CNT - default value 4096 of type int

  • INCR_PORT_CNT - default value 2 of type int

  • WAY_CNT - default value 4 of type int

HDL IO
HDL components
schematic
_compute_constants()[source]
merge_successor_writes_into_incr_one_hot(succ_writes, incr_val_oh)[source]
class hwtLib.amba.axi_comp.cache.lru_array.IndexWayHs(masterDir=DIRECTION.OUT, hdl_name: Optional[Union[str, Dict[str, str]]] = None, loadConfig=True)[source]

Bases: hwt.interfaces.std.HandshakeSync

hwtLib.amba.axi_comp.cache.pseudo_lru module

class hwtLib.amba.axi_comp.cache.pseudo_lru.PseudoLru(lru_reg: hwt.synthesizer.rtlLevel.rtlSignal.RtlSignal)[source]

Bases: object

Tree-PLRU, Pseudo Last Recently Used (LRU) algorithm * Often used to select least used value in caches etc.

Example for four-way set associative cache (three bits)

each bit represents one branch point in a binary decision tree; let 1 represent that the left side has been referenced more recently than the right side, and 0 vice-versa

           are all 4 lines valid?
                /                             yes        no, use an invalid line
               |
               |
               |
          bit_0 == 0?            state | replace      ref to | next state
           /       \             ------+--------      -------+-----------
          y         n             00x  |  line_0      line_0 |    11_
         /           \            01x  |  line_1      line_1 |    10_
  bit_1 == 0?    bit_2 == 0?      1x0  |  line_2      line_2 |    0_1
    /    \          /    \        1x1  |  line_3      line_3 |    0_0
   y      n        y      n
  /        \      /        \        ('x' means       ('_' means unchanged)
line_0  line_1  line_2  line_3      don't care)
Note

that there is a 6-bit encoding for true LRU for four-way set associative bit 0: bank[1] more recently used than bank[0] bit 1: bank[2] more recently used than bank[0] bit 2: bank[2] more recently used than bank[1] bit 3: bank[3] more recently used than bank[0] bit 4: bank[3] more recently used than bank[1] bit 5: bank[3] more recently used than bank[2]

Note

this is not a component in order to make this alg independent on lru reg storage type

Variables

lru_reg – register with bits which represents binary tree used in pseudo LRU. It uses a common binary tree in array node representation index of left is 2x parent index; index of right is 2x parent index + 1

__init__(lru_reg: hwt.synthesizer.rtlLevel.rtlSignal.RtlSignal)[source]
_build_node_paths(node_paths: Dict[int, List[hwt.synthesizer.rtlLevel.rtlSignal.RtlSignal]], i: int, prefix: List[hwt.synthesizer.rtlLevel.rtlSignal.RtlSignal])[source]

Collect in tree paths for items.

get_lru()[source]

To find LRU, we can perform a depth-first-search starting from root, and traverse nodes in lower levels. If the node is 0, then we traverse the left sub-tree; otherwise, we traverse the right sub-tree. In the diagram above, the LRU is set 3.

static lru_reg_items(width)[source]
static lru_reg_width(items)[source]
mark_use_many(used_item_mask)[source]

Mark values as used just now

node_selected_mask(lru_tree, node_i)[source]
Variables
  • lru_tree – array with lru binary tree, nodes are lru registers, leafs are select flags

  • node_i – index of node which we are checking

hwtLib.amba.axi_comp.cache.pseudo_lru.parity(bit_vector)[source]

hwtLib.amba.axi_comp.cache.tag_array module

class hwtLib.amba.axi_comp.cache.tag_array.AxiCacheTagArray(hdl_name_override: Optional[str] = None)[source]

Bases: hwtLib.amba.axi_comp.cache.addrTypeConfig.CacheAddrTypeConfig

Storage of cache tags, cache line state bits (valid/shared/dirty…), pseudo-LRU bits

_images/AxiCacheTagArray.png
HDL params
  • PORT_CNT - default value 2 of type int

  • UPDATE_PORT_CNT - default value 1 of type intnumber of ports used for record update

  • ID_WIDTH - default value 4 of type int

  • WAY_CNT - default value 4 of type int

  • ADDR_WIDTH - default value 32 of type int

  • CACHE_LINE_SIZE - default value 64 of type intsize of cacheline [B]

  • CACHE_LINE_CNT - default value 4096 of type inta total number of cachelines in this array

  • MAX_BLOCK_DATA_WIDTH - default value 8 of type int

HDL IO
HDL components
schematic
connect_lookup_port(lookup: hwtLib.common_nonstd_interfaces.addr_hs.AddrHs, tag_mem_port_r: hwt.interfaces.std.BramPort_withoutClk, lookupRes: hwtLib.amba.axi_comp.cache.tag_array.AxiCacheTagArrayLookupResIntf, update_tmp: hwt.interfaces.structIntf.StructIntf)[source]
connect_update_port(update: hwtLib.amba.axi_comp.cache.tag_array.AxiCacheTagArrayUpdateIntf, tag_mem_port_w: hwt.interfaces.std.BramPort_withoutClk)[source]
define_tag_record_t()[source]
class hwtLib.amba.axi_comp.cache.tag_array.AxiCacheTagArrayLookupResIntf(masterDir=DIRECTION.OUT, hdl_name: Optional[Union[str, Dict[str, str]]] = None, loadConfig=True)[source]

Bases: hwt.interfaces.std.HandshakeSync

Interface used for r/w logic of cache to return result of search in cache

HDL params
  • ID_WIDTH - default value 4 of type int

  • WAY_CNT - default value 4 of type int

  • ADDR_WIDTH - default value 32 of type int

  • TAG_T - default value None of type None

HDL IO
class hwtLib.amba.axi_comp.cache.tag_array.AxiCacheTagArrayUpdateIntf(masterDir=DIRECTION.OUT, hdl_name: Optional[Union[str, Dict[str, str]]] = None, loadConfig=True)[source]

Bases: hwt.interfaces.std.VldSynced

Interface used to insert or delete records in tag array.

HDL params
  • WAY_CNT - default value 4 of type int

  • ADDR_WIDTH - default value 32 of type int

HDL IO
hwtLib.amba.axi_comp.cache.tag_array._example_AxiCacheTagArray()[source]

hwtLib.amba.axi_comp.cache.utils module

class hwtLib.amba.axi_comp.cache.utils.CamWithReadPort(hdl_name_override: Optional[str] = None)[source]

Bases: hwtLib.mem.cam.CamMultiPort

Content addressable memory with a read port which can be used to read cam array by index

HDL params
  • KEY_WIDTH - default value 15 of type int

  • ITEMS - default value 32 of type int

  • USE_VLD_BIT - default value False of type bool

  • MATCH_PORT_CNT - default value None of type None

HDL IO
schematic
hwtLib.amba.axi_comp.cache.utils.apply_write_with_mask(current_data, new_data, write_mask)[source]
hwtLib.amba.axi_comp.cache.utils.expand_byte_mask_to_bit_mask(m)[source]
hwtLib.amba.axi_comp.cache.utils.extend_to_width_multiple_of_8(sig)[source]

make width of signal modulo 8 equal to 0