Updating CamEntry to use commands.
[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) \
13 for x in range(cam_size))
14 encoder_input = Signal(cam_size)
15
16 # Input
17 self.write = Signal(1) # Denotes read (0) or write (1)
18 self.address = Signal(max=cam_size) # address of the CAM to be written
19 self.key = Signal(key_size) # The key to search for or to be written
20 self.data_in = Signal(key_size) # The data to be written
21
22 # Output
23 self.data_hit = Signal(1) # Denotes a key data pair was stored at key_in
24 self.data_out = Signal(data_size) # The data mapped to by key_in
25
26 def elaborate(self, platform):
27 m = Module()
28
29 m.d.submodules.encoder = encoder = Encoder(cam_size)
30
31 # Set the key value for every CamEntry
32 for index in range(cam_size):
33 m.d.sync += [
34 If(self.write == 0,
35 entry_array[index].write.eq(self.write),
36 entry_array[index].key_in.eq(self.key),
37 entry_array[index].data_in.eq(self.data_in),
38 encoder_input[index].eq(entry_array[index].match)
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