From: Daniel Benusovich Date: Sat, 23 Feb 2019 18:13:54 +0000 (-0800) Subject: Renaming Cam X-Git-Tag: div_pipeline~2388 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4b8df1c8be611091d099dae927d623ace3b16cb6;p=soc.git Renaming Cam --- diff --git a/TLB/CAM.py b/TLB/CAM.py index 694925b2..a5ce0c66 100644 --- a/TLB/CAM.py +++ b/TLB/CAM.py @@ -1,61 +1,83 @@ from nmigen import Array, Module, Signal from nmigen.lib.coding import Encoder -from nmigen.cli import main - -from math import log from CamEntry import CamEntry -class CAM(): +# Content Addressable Memory (CAM) +# The purpose of this module is to quickly look up whether an entry exists +# given a certain key and return the mapped data. +# This module when given a key will search for the given key +# in all internal entries and output whether a match was found or not. +# If an entry is found the data will be returned and data_hit is HIGH, +# if it is not LOW is asserted on data_hit. When given a write +# command it will write the given key and data into the given cam entry index. +# Entry managment should be performed one level above this block as lookup is +# performed within. +class Cam(): + + # Arguments: + # key_size: (bit count) The size of the key + # data_size: (bit count) The size of the data + # cam_size: (entry count) The number of entries int he CAM def __init__(self, key_size, data_size, cam_size): # Internal - entry_array = Array(CamEntry(key_size, data_size) \ + self.cam_size = cam_size + self.entry_array = Array(CamEntry(key_size, data_size) \ for x in range(cam_size)) - encoder_input = Signal(cam_size) + self.encoder_input = Signal(cam_size) # Input - self.write = Signal(1) # Denotes read (0) or write (1) - self.address = Signal(max=cam_size) # address of the CAM to be written - self.key = Signal(key_size) # The key to search for or to be written + self.command = Signal(2) # 00 => NA 01 => Read 10 => Write 11 => Search + self.address = Signal(max=cam_size) # address of CAM Entry to write/read + self.key_in = Signal(key_size) # The key to search for or to be written self.data_in = Signal(key_size) # The data to be written # Output self.data_hit = Signal(1) # Denotes a key data pair was stored at key_in self.data_out = Signal(data_size) # The data mapped to by key_in - def elaborate(self, platform): - m = Module() - - m.d.submodules.encoder = encoder = Encoder(cam_size) + def get_fragment(self, platform=None): + m = Module() + + m.d.submodules.encoder = encoder = Encoder(self.cam_size) - # Set the key value for every CamEntry - for index in range(cam_size): + # Set the key value for every CamEntry + for index in range(self.cam_size): + with m.If(self.command == 3): m.d.sync += [ - If(self.write == 0, - entry_array[index].write.eq(self.write), - entry_array[index].key_in.eq(self.key), - entry_array[index].data_in.eq(self.data_in), - encoder_input[index].eq(entry_array[index].match) - ) + self.entry_array[index].write.eq(0), + self.entry_array[index].key_in.eq(self.key_in), + self.entry_array[index].data_in.eq(self.data_in), + self.encoder_input[index].eq(self.entry_array[index].match) ] - - m.d.sync += [ - encoder.i.eq(encoder_input), - # 1. Read request - # 2. Write request - If(self.write == 0, - # 0 denotes a mapping was found - If(encoder.n == 0, - self.data_hit.eq(0), - self.data_out.eq(entry_array[encoder.o].data) - ).Else( - self.data_hit.eq(1) - ) - ).Else( - entry_array[self.address].key_in.eq(self.key_in), - entry_array[self.address].data.eq(self.data_in) - ) - - ] - - return m + + with m.Switch(self.command): + # Read + with m.Case("01"): + m.d.sync += [ + self.data_hit.eq(0), + self.data_out.eq(self.entry_array[self.address].data) + ] + # Write + with m.Case("10"): + m.d.sync += [ + self.data_hit.eq(0), + self.entry_array[self.address].write.eq(1), + self.entry_array[self.address].key_in.eq(self.key_in), + self.entry_array[self.address].data.eq(self.data_in) + ] + # Search + with m.Case("11"): + m.d.sync += encoder.i.eq(self.encoder_input) + with m.If(encoder.n == 0): + m.d.sync += [ + self.data_hit.eq(0), + self.data_out.eq(self.entry_array[encoder.o].data) + ] + with m.Else(): + m.d.sync += self.data_hit.eq(1) + # NA + with m.Case(): + self.data_hit.eq(0) + + return m