From: Daniel Benusovich Date: Sat, 23 Feb 2019 18:14:54 +0000 (-0800) Subject: moving Cam to src X-Git-Tag: div_pipeline~2386 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=34b0aa8c94bdad48b66bb68d8cac368b47856cb1;p=soc.git moving Cam to src --- diff --git a/TLB/Cam.py b/TLB/Cam.py deleted file mode 100644 index a5ce0c66..00000000 --- a/TLB/Cam.py +++ /dev/null @@ -1,83 +0,0 @@ -from nmigen import Array, Module, Signal -from nmigen.lib.coding import Encoder - -from CamEntry import CamEntry - -# 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 - self.cam_size = cam_size - self.entry_array = Array(CamEntry(key_size, data_size) \ - for x in range(cam_size)) - self.encoder_input = Signal(cam_size) - - # Input - 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 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(self.cam_size): - with m.If(self.command == 3): - m.d.sync += [ - 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) - ] - - 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 diff --git a/TLB/src/Cam.py b/TLB/src/Cam.py new file mode 100644 index 00000000..a5ce0c66 --- /dev/null +++ b/TLB/src/Cam.py @@ -0,0 +1,83 @@ +from nmigen import Array, Module, Signal +from nmigen.lib.coding import Encoder + +from CamEntry import CamEntry + +# 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 + self.cam_size = cam_size + self.entry_array = Array(CamEntry(key_size, data_size) \ + for x in range(cam_size)) + self.encoder_input = Signal(cam_size) + + # Input + 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 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(self.cam_size): + with m.If(self.command == 3): + m.d.sync += [ + 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) + ] + + 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