Changed CAM to accept write address. Pushed back and LRU logic to a higher block.
[soc.git] / TLB / CAM.py
1 from nmigen import Array, Module, Signal
2 from nmigen.lib.coding import Encoder
3 from nmigen.cli import main
4
5 from math import log
6
7 from CamEntry import CamEntry
8
9 class CAM():
10 def __init__(self, key_size, data_size, cam_size):
11 # Internal
12 entry_array = Array(CamEntry(key_size, data_size) for x in range(cam_size))
13 encoder_input = Signal(cam_size)
14
15 # Input
16 self.write = Signal(1) # Denotes read (0) or write (1)
17 self.address = Signal(max=cam_size) # The address of the CAM to be written
18 self.key = Signal(key_size) # The key to search for or to be written
19 self.data_in = Signal(key_size) # The data to be written
20
21 # Output
22 self.data_hit = Signal(1) # Denotes a key data pair was stored at key_in
23 self.data_out = Signal(data_size) # The data mapped to by key_in
24
25 def elaborate(self, platform):
26 m = Module()
27
28 m.d.submodules.encoder = encoder = Encoder(cam_size)
29
30 # Set the key value for every CamEntry
31 for index in range(cam_size):
32 m.d.sync += [
33 If(self.write == 0,
34 entry_array[index].write.eq(self.write),
35 entry_array[index].key_in.eq(self.key),
36 entry_array[index].data_in.eq(self.data_in),
37 encoder_input[index].eq(entry_array[index].match)
38 )
39 ]
40
41
42 m.d.sync += [
43 encoder.i.eq(encoder_input),
44 # 1. Read request
45 # 2. Write request
46 If(self.write == 0,
47 # 0 denotes a mapping was found
48 If(encoder.n == 0,
49 self.data_hit.eq(0),
50 self.data_out.eq(entry_array[encoder.o].data)
51 ).Else(
52 self.data_hit.eq(1)
53 )
54 ).Else(
55 entry_array[self.address].key_in.eq(self.key_in),
56 entry_array[self.address].data.eq(self.data_in)
57 )
58
59 ]
60
61 return m
62