X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=TLB%2Fsrc%2FCam.py;h=3606234b1180c96324480bb71d13ca73150d6b41;hb=2a7a2246b3ce4bb44f30b9be6401ae2fa7bd2206;hp=92464103b775faa7892ee5fdc2497c319d2e84e4;hpb=f8e0131810dbe3b9f201e2b8ebceada941a8d596;p=soc.git diff --git a/TLB/src/Cam.py b/TLB/src/Cam.py index 92464103..3606234b 100644 --- a/TLB/src/Cam.py +++ b/TLB/src/Cam.py @@ -1,8 +1,10 @@ from nmigen import Array, Module, Signal -from nmigen.lib.coding import Decoder, Encoder, PriorityEncoder +from nmigen.lib.coding import Decoder from nmigen.cli import main #, verilog from CamEntry import CamEntry +from AddressEncoder import AddressEncoder +from VectorAssembler import VectorAssembler class Cam(): """ Content Addressable Memory (CAM) @@ -32,11 +34,11 @@ class Cam(): # Internal self.cam_size = cam_size - self.encoder = Encoder(cam_size) - self.p_encoder = PriorityEncoder(cam_size) + self.encoder = AddressEncoder(cam_size) self.decoder = Decoder(cam_size) self.entry_array = Array(CamEntry(data_size) \ for x in range(cam_size)) + self.vector_assembler = VectorAssembler(cam_size) # Input self.enable = Signal(1) @@ -54,14 +56,13 @@ class Cam(): def elaborate(self, platform=None): m = Module() # Encoder checks for multiple matches - m.submodules += self.encoder - # Priority Encoder is used to select output address - m.submodules += self.p_encoder + m.submodules.AddressEncoder = self.encoder # Decoder is used to select which entry will be written to - m.submodules += self.decoder + m.submodules.Decoder = self.decoder # Don't forget to add all entries to the submodule list entry_array = self.entry_array m.submodules += entry_array + m.submodules.VectorAssembler = self.vector_assembler # Decoder logic m.d.comb += [ @@ -73,48 +74,30 @@ class Cam(): # Set the key value for every CamEntry for index in range(self.cam_size): - # Read Operation - with m.If(~self.write_enable): - m.d.comb += entry_array[index].command.eq(1) - # Write Operation - with m.Else(): + with m.If(self.write_enable): with m.If(self.decoder.o[index]): m.d.comb += entry_array[index].command.eq(2) with m.Else(): - m.d.comb += entry_array[index].command.eq(0) + m.d.comb += entry_array[index].command.eq(0) + + # Read Operation + with m.Else(): + m.d.comb += entry_array[index].command.eq(1) # Send data input to all entries m.d.comb += entry_array[index].data_in.eq(self.data_in) - #Send all entry matches to encoder - m.d.comb += self.encoder.i[index].eq(entry_array[index].match) - # Send all entry matches to the priority encoder - m.d.comb += self.p_encoder.i[index].eq(entry_array[index].match) - - # If the priority encoder recieves an input of 0 - with m.If(self.p_encoder.n): - m.d.comb += [ - self.read_warning.eq(0), - self.single_match.eq(0), - self.multiple_match.eq(0), - self.match_address.eq(0) - ] - # If the priority encoder recieves an input > 0 - with m.Else(): - # Multiple Match if encoder n is invalid - with m.If(self.encoder.n): - m.d.comb += [ - self.single_match.eq(0), - self.multiple_match.eq(1) - ] - # Single Match if encoder n is valid - with m.Else(): - m.d.comb += [ - self.single_match.eq(1), - self.multiple_match.eq(0) - ] - # Always set output based on priority encoder output - m.d.comb += self.match_address.eq(self.p_encoder.o) + # Send all entry matches to encoder + ematch = entry_array[index].match + m.d.comb += self.vector_assembler.i[index].eq(ematch) + + # Give input to and accept output from encoder module + m.d.comb += [ + self.encoder.i.eq(self.vector_assembler.o), + self.single_match.eq(self.encoder.single_match), + self.multiple_match.eq(self.encoder.multiple_match), + self.match_address.eq(self.encoder.o) + ] # If the CAM is not enabled set all outputs to 0 with m.Else():