From 528ac927eb8066f26ee288d9cbf7f308cae9a173 Mon Sep 17 00:00:00 2001 From: usman1515 Date: Wed, 22 Feb 2023 22:40:29 +0500 Subject: [PATCH 01/41] created py script andGate with class andGate --- compiler/src/andGate.py | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 compiler/src/andGate.py diff --git a/compiler/src/andGate.py b/compiler/src/andGate.py new file mode 100644 index 0000000..77087b6 --- /dev/null +++ b/compiler/src/andGate.py @@ -0,0 +1,5 @@ +from migen import * +from migen.fhdl.verilog import convert + +class andGate(Module): + pass \ No newline at end of file From 52e502e12653e809f6606dd2d1f09e32ca284756 Mon Sep 17 00:00:00 2001 From: usman1515 Date: Wed, 22 Feb 2023 22:51:01 +0500 Subject: [PATCH 02/41] created constructor for py class andGate --- compiler/src/andGate.py | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/compiler/src/andGate.py b/compiler/src/andGate.py index 77087b6..5d66976 100644 --- a/compiler/src/andGate.py +++ b/compiler/src/andGate.py @@ -1,5 +1,34 @@ +""" +List of all pip packages imported +""" + from migen import * from migen.fhdl.verilog import convert +# =========================================================================================== +# ======================================= Begin Class ======================================= +# =========================================================================================== + class andGate(Module): - pass \ No newline at end of file + """ + _summary_ + + """ + + # * ----------------------------------------------------------------- Variables + # Constructor: setup IO ports and logic here + def __init__(self, ports, dataWidth) -> None: + """ + _summary_ + + :param _type_ ports: _description_ + :param _type_ dataWidth: _description_ + """ + self.numInputs = ports + self.numInputWidth = dataWidth + self.verilogCode = "" + + +# =========================================================================================== +# ======================================== End Class ======================================== +# =========================================================================================== From 534bb4f90a8b165908a465fb93bc7b14cee6d9e6 Mon Sep 17 00:00:00 2001 From: usman1515 Date: Wed, 22 Feb 2023 23:05:08 +0500 Subject: [PATCH 03/41] created func ioPorts in py class andGate --- compiler/src/andGate.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/compiler/src/andGate.py b/compiler/src/andGate.py index 5d66976..2a6e717 100644 --- a/compiler/src/andGate.py +++ b/compiler/src/andGate.py @@ -2,6 +2,7 @@ List of all pip packages imported """ +import logging from migen import * from migen.fhdl.verilog import convert @@ -23,11 +24,28 @@ def __init__(self, ports, dataWidth) -> None: :param _type_ ports: _description_ :param _type_ dataWidth: _description_ + :return _type_ verilogCode: _description_ """ self.numInputs = ports self.numInputWidth = dataWidth self.verilogCode = "" + def ioPorts(self, inputs, dataWidth): + """ + _summary_ + + :param _type_ inputs: _description_ + :param _type_ dataWidth: _description_ + """ + self.inputs = [] + for inputs in range(inputs): + tempPort = Signal(dataWidth, name_override='in_data{}'.format(inputs)) + self.inputs.append(tempPort) + logging.info('Created AND gate input port: {:>s}{:d}'.format('in_data', inputs)) + self.outputs = Signal(dataWidth, name_override='out_data') + logging.info('Created AND gate output port: {:>s}{:d}'.format('in_data', inputs)) + + # =========================================================================================== # ======================================== End Class ======================================== From 538f0c8266dfdca1964c240ac1ecdaedf6d86a21 Mon Sep 17 00:00:00 2001 From: usman1515 Date: Wed, 22 Feb 2023 23:10:40 +0500 Subject: [PATCH 04/41] created func logicBlock in py class andGate --- compiler/src/andGate.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/compiler/src/andGate.py b/compiler/src/andGate.py index 2a6e717..c12cdb2 100644 --- a/compiler/src/andGate.py +++ b/compiler/src/andGate.py @@ -30,9 +30,14 @@ def __init__(self, ports, dataWidth) -> None: self.numInputWidth = dataWidth self.verilogCode = "" + # * setup IO ports + self.ioPorts(self, self.numInputs, self.numInputWidth) + # * generate module RTL + self.logicBlock(self) + def ioPorts(self, inputs, dataWidth): """ - _summary_ + declare all the input output ports here :param _type_ inputs: _description_ :param _type_ dataWidth: _description_ @@ -45,6 +50,14 @@ def ioPorts(self, inputs, dataWidth): self.outputs = Signal(dataWidth, name_override='out_data') logging.info('Created AND gate output port: {:>s}{:d}'.format('in_data', inputs)) + def logicBlock(self): + """ + Example of using reduce() to create an AND gate + """ + self.comb += self.outputs.eq(reduce(lambda x, y: x & y, self.inputs)) + logging.info('Generated AND gate logic') + + # =========================================================================================== From 55a80e1bd139eabcca86e8a6b82041c1350536e8 Mon Sep 17 00:00:00 2001 From: usman1515 Date: Thu, 23 Feb 2023 00:24:32 +0500 Subject: [PATCH 05/41] created func genVerilogAndGate, updated func ioPorts in py class andGate --- compiler/src/andGate.py | 53 +++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/compiler/src/andGate.py b/compiler/src/andGate.py index c12cdb2..023e4e3 100644 --- a/compiler/src/andGate.py +++ b/compiler/src/andGate.py @@ -31,11 +31,11 @@ def __init__(self, ports, dataWidth) -> None: self.verilogCode = "" # * setup IO ports - self.ioPorts(self, self.numInputs, self.numInputWidth) - # * generate module RTL - self.logicBlock(self) + self.ioPorts() + # * generate block RTL + self.logicBlock() - def ioPorts(self, inputs, dataWidth): + def ioPorts(self): """ declare all the input output ports here @@ -43,12 +43,12 @@ def ioPorts(self, inputs, dataWidth): :param _type_ dataWidth: _description_ """ self.inputs = [] - for inputs in range(inputs): - tempPort = Signal(dataWidth, name_override='in_data{}'.format(inputs)) + for port in range(self.numInputs): + tempPort = Signal(self.numInputWidth, name_override='in_data{}'.format(port)) self.inputs.append(tempPort) - logging.info('Created AND gate input port: {:>s}{:d}'.format('in_data', inputs)) - self.outputs = Signal(dataWidth, name_override='out_data') - logging.info('Created AND gate output port: {:>s}{:d}'.format('in_data', inputs)) + logging.info('Created AND gate input port: {:>s}{:d}'.format('in_data', port)) + self.outputs = Signal(self.numInputWidth, name_override='out_data') + logging.info('Created AND gate output port: {:>s}{:d}'.format('out_data', port)) def logicBlock(self): """ @@ -57,9 +57,38 @@ def logicBlock(self): self.comb += self.outputs.eq(reduce(lambda x, y: x & y, self.inputs)) logging.info('Generated AND gate logic') - - - # =========================================================================================== # ======================================== End Class ======================================== # =========================================================================================== + +def genVerilogAndGate(ports, dataWidth, filePath): + """ + _summary_ + + :param _type_ ports: _description_ + :param _type_ dataWidth: _description_ + :param _type_ filePath: _description_ + :return _type_: _description_ + """ + # * instantiate the module + gate = andGate(ports=ports, dataWidth=dataWidth) + + # * ----- setup the IO ports for the verilog module definition + # * input port set + myinputs = {gate.inputs[i] for i in range(ports)} + # * output port set + myoutputs = {gate.outputs} + # * combine input and output sets + myports = myinputs.union(myoutputs) + logging.info('Generated AND gate verilog module definition') + + # * generate the verilog code + gate.verilogCode = convert(gate, name='andGate', ios=myports) + logging.info('Generated AND gate verilog module RTL') + + # * write verilog code to a file + with open(filePath, 'w', encoding='utf-8') as rtl: + rtl.write(str(gate.verilogCode)) + logging.info('Created rtl file {:s}'.format(filePath)) + + return str(gate.verilogCode) From 5df408ee483b88a3e1dd097a0491061a01fd5538 Mon Sep 17 00:00:00 2001 From: usman1515 Date: Thu, 23 Feb 2023 00:58:56 +0500 Subject: [PATCH 06/41] added docstrings for funcs in py class andGate --- compiler/src/andGate.py | 45 ++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/compiler/src/andGate.py b/compiler/src/andGate.py index 023e4e3..ad1e85e 100644 --- a/compiler/src/andGate.py +++ b/compiler/src/andGate.py @@ -12,19 +12,19 @@ class andGate(Module): """ - _summary_ - + Generates the verilog code for an AND gate with N inputs each input M bits wide. + The output is M bits wide. """ # * ----------------------------------------------------------------- Variables - # Constructor: setup IO ports and logic here - def __init__(self, ports, dataWidth) -> None: + def __init__(self, ports, dataWidth): """ - _summary_ + Constructor: call IO ports and logic here - :param _type_ ports: _description_ - :param _type_ dataWidth: _description_ - :return _type_ verilogCode: _description_ + **Public Variables:** + :param int ports: number of input ports. + :param int dataWidth: width of input ports. + :return str verilogCode: store RTL code of the gate. """ self.numInputs = ports self.numInputWidth = dataWidth @@ -37,10 +37,7 @@ def __init__(self, ports, dataWidth) -> None: def ioPorts(self): """ - declare all the input output ports here - - :param _type_ inputs: _description_ - :param _type_ dataWidth: _description_ + Create a list of Signal objects for N input ports each of width M. Create a Signal object for an output port of width M. """ self.inputs = [] for port in range(self.numInputs): @@ -52,7 +49,7 @@ def ioPorts(self): def logicBlock(self): """ - Example of using reduce() to create an AND gate + Setup the combinatorial logic for creating an AND gate using migen. Using the reduce() function to combine all input signals into a single output signal. """ self.comb += self.outputs.eq(reduce(lambda x, y: x & y, self.inputs)) logging.info('Generated AND gate logic') @@ -63,27 +60,29 @@ def logicBlock(self): def genVerilogAndGate(ports, dataWidth, filePath): """ - _summary_ - - :param _type_ ports: _description_ - :param _type_ dataWidth: _description_ - :param _type_ filePath: _description_ - :return _type_: _description_ + Main user function for class andGate. + Creates the IO ports for the verilog RTL module definition. + Generates the verilog code for an AND gate with N inputs each input M bits wide. The output is M bits wide. + + :param int ports: number of input ports. + :param int dataWidth: width of input ports. + :param str filePath: absolute path for the verilog file. + :return str: RTL code of the gate. """ # * instantiate the module gate = andGate(ports=ports, dataWidth=dataWidth) # * ----- setup the IO ports for the verilog module definition # * input port set - myinputs = {gate.inputs[i] for i in range(ports)} + inPortsSet = {gate.inputs[i] for i in range(ports)} # * output port set - myoutputs = {gate.outputs} + outPortsSet = {gate.outputs} # * combine input and output sets - myports = myinputs.union(myoutputs) + moduleIOs = inPortsSet.union(outPortsSet) logging.info('Generated AND gate verilog module definition') # * generate the verilog code - gate.verilogCode = convert(gate, name='andGate', ios=myports) + gate.verilogCode = convert(gate, name='andGate', ios=moduleIOs) logging.info('Generated AND gate verilog module RTL') # * write verilog code to a file From e64bbfe6e39dcd823ce64a330d45668f87817738 Mon Sep 17 00:00:00 2001 From: usman1515 Date: Thu, 23 Feb 2023 01:10:03 +0500 Subject: [PATCH 07/41] created py script priorityEncoder with class priorityEncoder --- compiler/src/priorityEncoder.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 compiler/src/priorityEncoder.py diff --git a/compiler/src/priorityEncoder.py b/compiler/src/priorityEncoder.py new file mode 100644 index 0000000..50392bf --- /dev/null +++ b/compiler/src/priorityEncoder.py @@ -0,0 +1,24 @@ +""" +List of all pip packages imported +""" + +import logging +from migen import * +from migen.fhdl.verilog import convert + +# =========================================================================================== +# ======================================= Begin Class ======================================= +# =========================================================================================== + +class priorityEncoder(Module): + """ + _summary_ + + :param _type_ Module: _description_ + :return _type_: _description_ + """ + pass + +# =========================================================================================== +# ======================================== End Class ======================================== +# =========================================================================================== From 62d4901e67a00869b179e4623cf2e6f251311252 Mon Sep 17 00:00:00 2001 From: usman1515 Date: Thu, 23 Feb 2023 01:19:42 +0500 Subject: [PATCH 08/41] created constructor for py class priorityEncoder --- compiler/src/priorityEncoder.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/compiler/src/priorityEncoder.py b/compiler/src/priorityEncoder.py index 50392bf..e457ad2 100644 --- a/compiler/src/priorityEncoder.py +++ b/compiler/src/priorityEncoder.py @@ -17,7 +17,16 @@ class priorityEncoder(Module): :param _type_ Module: _description_ :return _type_: _description_ """ - pass + # * ----------------------------------------------------------------- Variables + def __init__(self, ports): + self.numInputs = ports + self.verilogCode = '' + + # * setup IO ports + # self.ioPorts() + # * generate block RTL + # self.logicBlock() + # =========================================================================================== # ======================================== End Class ======================================== From b90fb264f0dde3049d8b2954afa33cb8d965f7d4 Mon Sep 17 00:00:00 2001 From: usman1515 Date: Thu, 23 Feb 2023 12:34:48 +0500 Subject: [PATCH 09/41] created func ioPorts in py class priorityEncoder --- compiler/src/priorityEncoder.py | 36 ++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/compiler/src/priorityEncoder.py b/compiler/src/priorityEncoder.py index e457ad2..ccc2dd4 100644 --- a/compiler/src/priorityEncoder.py +++ b/compiler/src/priorityEncoder.py @@ -3,6 +3,8 @@ """ import logging +import math +import sys from migen import * from migen.fhdl.verilog import convert @@ -17,15 +19,43 @@ class priorityEncoder(Module): :param _type_ Module: _description_ :return _type_: _description_ """ - # * ----------------------------------------------------------------- Variables + # * ----------------------------------------------------------------- Functions def __init__(self, ports): - self.numInputs = ports + """ + _summary_ + + :param _type_ ports: _description_ + """ + self.inputWidth = ports + self.outputWidth = 0 self.verilogCode = '' # * setup IO ports - # self.ioPorts() + self.ioPorts() # * generate block RTL # self.logicBlock() + + def ioPorts(self): + """ + _summary_ + """ + # * check if input port width is of 2^N + if math.floor(math.log2(self.inputWidth)) == math.ceil(math.log2(self.inputWidth)): + logging.info('"VALID": prioirty encoder input width {:d} is of 2^N'.format(self.inputWidth)) + # * set output port width of log2(N) + self.outputWidth = int(math.log2(self.inputWidth)) + logging.info('prioirty encoder output width: {:d}'.format(self.outputWidth)) + # * create IO port objects + self.inputs = Signal(self.inputWidth, name_override='in_data') + logging.info('Created prioirty encoder input port: {:>s}'.format('in_data')) + self.outputs = Signal(self.outputWidth, name_override='out_data') + logging.info('Created prioirty encoder output port: {:>s}'.format('out_data')) + print(self.inputs) + print(self.outputs) + else: + print('num isnt 2^N', type(self.inputWidth)) + logging.error('"INVALID": prioirty Encoder input width {:d} isnt of 2^N'.format(self.inputWidth)) + sys.exit('"INVALID": prioirty encoder input width {:d} isnt of 2^N'.format(self.inputWidth)) # =========================================================================================== From bbd4bd9ffedf98fe9706c309f941c1151ecb3a1b Mon Sep 17 00:00:00 2001 From: usman1515 Date: Thu, 23 Feb 2023 23:14:08 +0500 Subject: [PATCH 10/41] created func logicBlock in py class priorityEncoder --- compiler/src/priorityEncoder.py | 37 ++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/compiler/src/priorityEncoder.py b/compiler/src/priorityEncoder.py index ccc2dd4..62bd63e 100644 --- a/compiler/src/priorityEncoder.py +++ b/compiler/src/priorityEncoder.py @@ -25,7 +25,7 @@ def __init__(self, ports): _summary_ :param _type_ ports: _description_ - """ + """ self.inputWidth = ports self.outputWidth = 0 self.verilogCode = '' @@ -33,30 +33,43 @@ def __init__(self, ports): # * setup IO ports self.ioPorts() # * generate block RTL - # self.logicBlock() - + self.logicBlock() + def ioPorts(self): """ _summary_ - """ + """ # * check if input port width is of 2^N if math.floor(math.log2(self.inputWidth)) == math.ceil(math.log2(self.inputWidth)): - logging.info('"VALID": prioirty encoder input width {:d} is of 2^N'.format(self.inputWidth)) + logging.info('"VALID": priority encoder input width {:d} is of 2^N'.format(self.inputWidth)) # * set output port width of log2(N) self.outputWidth = int(math.log2(self.inputWidth)) - logging.info('prioirty encoder output width: {:d}'.format(self.outputWidth)) + logging.info('priority encoder output width: {:d}'.format(self.outputWidth)) # * create IO port objects self.inputs = Signal(self.inputWidth, name_override='in_data') - logging.info('Created prioirty encoder input port: {:>s}'.format('in_data')) + logging.info('Created priority encoder input port: {:>s}'.format('in_data')) self.outputs = Signal(self.outputWidth, name_override='out_data') - logging.info('Created prioirty encoder output port: {:>s}'.format('out_data')) - print(self.inputs) - print(self.outputs) + logging.info('Created priority encoder output port: {:>s}'.format('out_data')) else: print('num isnt 2^N', type(self.inputWidth)) - logging.error('"INVALID": prioirty Encoder input width {:d} isnt of 2^N'.format(self.inputWidth)) - sys.exit('"INVALID": prioirty encoder input width {:d} isnt of 2^N'.format(self.inputWidth)) + logging.error('"INVALID": priority encoder input width {:d} isnt of 2^N'.format(self.inputWidth)) + sys.exit('"INVALID": priority encoder input width {:d} isnt of 2^N'.format(self.inputWidth)) + def logicBlock(self): + """ + _summary_ + """ + # * dict to store priority cases + priorityCases = {} + # * create N priority cases + for i in reversed(range(self.inputWidth)): + # * generate one hot encoding + oneHotEncode = bin(pow(2,i)) + # * add ith priority case + priorityCases[oneHotEncode] = self.outputs.eq(i) + logging.info('Created priority case for {:3d} input bit'.format(i)) + # * concat using case + self.comb += Case(self.inputs, priorityCases) # =========================================================================================== # ======================================== End Class ======================================== From 3553c0b0b5924283fa67d0e1bc18e25c1f9e9920 Mon Sep 17 00:00:00 2001 From: usman1515 Date: Thu, 23 Feb 2023 23:18:05 +0500 Subject: [PATCH 11/41] created func genVerilogPriorityEncoder in py class priorityEncoder --- compiler/src/priorityEncoder.py | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/compiler/src/priorityEncoder.py b/compiler/src/priorityEncoder.py index 62bd63e..32c5df8 100644 --- a/compiler/src/priorityEncoder.py +++ b/compiler/src/priorityEncoder.py @@ -66,7 +66,7 @@ def logicBlock(self): # * generate one hot encoding oneHotEncode = bin(pow(2,i)) # * add ith priority case - priorityCases[oneHotEncode] = self.outputs.eq(i) + priorityCases[int(oneHotEncode, 2)] = self.outputs.eq(i) logging.info('Created priority case for {:3d} input bit'.format(i)) # * concat using case self.comb += Case(self.inputs, priorityCases) @@ -74,3 +74,34 @@ def logicBlock(self): # =========================================================================================== # ======================================== End Class ======================================== # =========================================================================================== + +def genVerilogPriorityEncoder(ports, filePath): + """ + _summary_ + + :param _type_ ports: _description_ + :param _type_ filePath: _description_ + :return _type_: _description_ + """ + # * instantiate the module + encoder = priorityEncoder(ports=ports) + + # * ----- setup the IO ports for the verilog module definition + # * input port set + inPortsSet = {encoder.inputs} + # * output port set + outPortsSet = {encoder.outputs} + # * combine input and output sets + moduleIOs = inPortsSet.union(outPortsSet) + logging.info('Generated Priority Encoder verilog module definition') + + # * generate the verilog code + encoder.verilogCode = convert(encoder, name='priorityEncoder', ios=moduleIOs) + logging.info('Generated Priority Encoder verilog module RTL') + + # * write verilog code to a file + with open(filePath, 'w', encoding='utf-8') as rtl: + rtl.write(str(encoder.verilogCode)) + logging.info('Created rtl file {:s}'.format(filePath)) + + return str(encoder.verilogCode) From c5247ae1a41582d9654c08c3220e1a93a6ea4d71 Mon Sep 17 00:00:00 2001 From: usman1515 Date: Thu, 23 Feb 2023 23:28:16 +0500 Subject: [PATCH 12/41] added docstrings for funcs in py class priorityEncoder --- compiler/src/priorityEncoder.py | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/compiler/src/priorityEncoder.py b/compiler/src/priorityEncoder.py index 32c5df8..0ba0b44 100644 --- a/compiler/src/priorityEncoder.py +++ b/compiler/src/priorityEncoder.py @@ -14,17 +14,17 @@ class priorityEncoder(Module): """ - _summary_ - - :param _type_ Module: _description_ - :return _type_: _description_ + Generates the verilog code for a Priority Encoder with N-bit input and log2(N) bit output. """ + # * ----------------------------------------------------------------- Functions def __init__(self, ports): """ - _summary_ + Constructor: call IO ports and logic here - :param _type_ ports: _description_ + **Public Variables:** + :param int ports: number of input ports. + :return str verilogCode: store RTL code of the encoder. """ self.inputWidth = ports self.outputWidth = 0 @@ -37,7 +37,7 @@ def __init__(self, ports): def ioPorts(self): """ - _summary_ + Create a Signal object for an input port of width N bits and an output port of width log2(N) bits. """ # * check if input port width is of 2^N if math.floor(math.log2(self.inputWidth)) == math.ceil(math.log2(self.inputWidth)): @@ -57,7 +57,7 @@ def ioPorts(self): def logicBlock(self): """ - _summary_ + Setup the sequential logic for creating a priority encoder using migen. """ # * dict to store priority cases priorityCases = {} @@ -77,11 +77,13 @@ def logicBlock(self): def genVerilogPriorityEncoder(ports, filePath): """ - _summary_ + Main user function for class priorityEncoder. + Creates the IO ports for the verilog RTL module definition. + Generates the verilog code for a Priority Encoder with N-bit input and log2(N) bit output. - :param _type_ ports: _description_ - :param _type_ filePath: _description_ - :return _type_: _description_ + :param int ports: number of input ports. + :param str filePath: absolute path for the verilog file. + :return str: RTL code of the encoder. """ # * instantiate the module encoder = priorityEncoder(ports=ports) From d81235309e3ded52bb58300a26011c7b8be32db0 Mon Sep 17 00:00:00 2001 From: usman1515 Date: Thu, 23 Feb 2023 23:30:14 +0500 Subject: [PATCH 13/41] added migen in requirements --- requirements.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 05f4bc9..f81528c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -64,4 +64,8 @@ coverage==6.5.0 # pdoc - API documentation for python Pygments==2.13.0 -pdoc==12.3.0 \ No newline at end of file +pdoc==12.3.0 + +# migen - toolbox for building complex digital hardware +colorama==0.4.6 +migen==0.9.2 \ No newline at end of file From ae3bd68cc92ef08381bde8ea96020a05ce34a7d4 Mon Sep 17 00:00:00 2001 From: usman1515 Date: Fri, 24 Feb 2023 00:13:34 +0500 Subject: [PATCH 14/41] created py script tcamMemory7x64 with class tcamMemory7x64 --- compiler/src/tcamMemory7x64.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 compiler/src/tcamMemory7x64.py diff --git a/compiler/src/tcamMemory7x64.py b/compiler/src/tcamMemory7x64.py new file mode 100644 index 0000000..e27ac3e --- /dev/null +++ b/compiler/src/tcamMemory7x64.py @@ -0,0 +1,22 @@ +""" +List of all pip packages imported +""" + +import logging +from migen import * +from migen.fhdl.verilog import convert + +# =========================================================================================== +# ======================================= Begin Class ======================================= +# =========================================================================================== + +class tcamMemory7x64(Module): + """ + _summary_ + + :param _type_ Module: _description_ + """ + + # * ----------------------------------------------------------------- Variables + def __init__(self): + pass \ No newline at end of file From 55f659e709e5190141a8544e98d3d2a57a361d61 Mon Sep 17 00:00:00 2001 From: usman1515 Date: Mon, 27 Feb 2023 16:44:26 +0500 Subject: [PATCH 15/41] created func ioPorts in py class tcamMemory7x64 --- compiler/src/andGate.py | 4 ++-- compiler/src/priorityEncoder.py | 4 ++-- compiler/src/tcamMemory7x64.py | 39 ++++++++++++++++++++++++++++++++- 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/compiler/src/andGate.py b/compiler/src/andGate.py index ad1e85e..2025ea1 100644 --- a/compiler/src/andGate.py +++ b/compiler/src/andGate.py @@ -43,9 +43,9 @@ def ioPorts(self): for port in range(self.numInputs): tempPort = Signal(self.numInputWidth, name_override='in_data{}'.format(port)) self.inputs.append(tempPort) - logging.info('Created AND gate input port: {:>s}{:d}'.format('in_data', port)) + logging.info('Created AND gate input port: {:>s}{:d}[{:d}:0]'.format('in_data', port, self.numInputWidth-1)) self.outputs = Signal(self.numInputWidth, name_override='out_data') - logging.info('Created AND gate output port: {:>s}{:d}'.format('out_data', port)) + logging.info('Created AND gate output port: {:>s}[{:d}:0]'.format('out_data', self.numInputWidth-1)) def logicBlock(self): """ diff --git a/compiler/src/priorityEncoder.py b/compiler/src/priorityEncoder.py index 0ba0b44..35540c2 100644 --- a/compiler/src/priorityEncoder.py +++ b/compiler/src/priorityEncoder.py @@ -47,9 +47,9 @@ def ioPorts(self): logging.info('priority encoder output width: {:d}'.format(self.outputWidth)) # * create IO port objects self.inputs = Signal(self.inputWidth, name_override='in_data') - logging.info('Created priority encoder input port: {:>s}'.format('in_data')) + logging.info('Created priority encoder input port: {:>s}[{:d}:0]'.format('in_data', self.inputWidth-1)) self.outputs = Signal(self.outputWidth, name_override='out_data') - logging.info('Created priority encoder output port: {:>s}'.format('out_data')) + logging.info('Created priority encoder output port: {:>s}[{:d}:0]'.format('out_data', self.outputWidth-1)) else: print('num isnt 2^N', type(self.inputWidth)) logging.error('"INVALID": priority encoder input width {:d} isnt of 2^N'.format(self.inputWidth)) diff --git a/compiler/src/tcamMemory7x64.py b/compiler/src/tcamMemory7x64.py index e27ac3e..5ecd04e 100644 --- a/compiler/src/tcamMemory7x64.py +++ b/compiler/src/tcamMemory7x64.py @@ -19,4 +19,41 @@ class tcamMemory7x64(Module): # * ----------------------------------------------------------------- Variables def __init__(self): - pass \ No newline at end of file + """ + _summary_ + """ + # * variables + self.__sramModule = 'sky130_sram_1kbyte_1rw1r_32x256_8' + + # * setup IO ports + self.ioPorts() + # * generate block RTL + self.logicBlock() + + def ioPorts(self): + """ + _summary_ + """ + self.inputs = [] + # * setup input ports + self.inClk = Signal(1, name_override='in_clk') + logging.info('Created tcamMemory7x64 input port: {:>s}'.format(self.inClk.name_override)) + self.inCsb = Signal(1, name_override='in_csb') + logging.info('Created tcamMemory7x64 input port: {:>s}'.format(self.inCsb.name_override)) + self.inWeb = Signal(1, name_override='in_web') + logging.info('Created tcamMemory7x64 input port: {:>s}'.format(self.inWeb.name_override)) + self.inWmask = Signal(4, name_override='in_wmask') + logging.info('Created tcamMemory7x64 input port: {:>s}[{:d}:0]'.format(self.inWmask.name_override, 4)) + self.inAddr = Signal(8, name_override='in_addr') + logging.info('Created tcamMemory7x64 input port: {:>s}[{:d}:0]'.format(self.inAddr.name_override, 8)) + self.inWdata = Signal(32, name_override='in_wdata') + logging.info('Created tcamMemory7x64 input port: {:>s}[{:d}:0]'.format(self.inWdata.name_override, 32)) + # * add all input ports to an input list + self.inputs = [self.inClk, self.inCsb, self.inWeb, self.inWmask, self.inAddr, self.inWdata] + logging.info('Created list of all input ports') + # * setup output ports + self.outRdata = Signal(64, name_override='out_rdata') + logging.info('Created tcamMemory7x64 output port: {:>s}[{:d}:0]'.format(self.outRdata.name_override, 64)) + # * add all output ports to an output list + self.outputs = self.outRdata + logging.info('Created list of all output ports') From 3bb7f4fcd7b48c9683a1e7e449820eba5b3fda7e Mon Sep 17 00:00:00 2001 From: usman1515 Date: Mon, 27 Feb 2023 16:48:20 +0500 Subject: [PATCH 16/41] created func logicBlock in py class tcamMemory7x64 --- compiler/src/tcamMemory7x64.py | 49 ++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/compiler/src/tcamMemory7x64.py b/compiler/src/tcamMemory7x64.py index 5ecd04e..e35d4aa 100644 --- a/compiler/src/tcamMemory7x64.py +++ b/compiler/src/tcamMemory7x64.py @@ -57,3 +57,52 @@ def ioPorts(self): # * add all output ports to an output list self.outputs = self.outRdata logging.info('Created list of all output ports') + + def logicBlock(self): + """ + _summary_ + """ + # * ----- setup write address logic + awAddr = Signal(8, name_override='aw_addr') + self.comb += awAddr.eq(Cat(Replicate(~self.inWeb, 8)) & self.inAddr) + logging.info('Created write address logic') + + # * ----- setup Read/Search address + arAddr1 = Signal(8, name_override='ar_addr1') + arAddr2 = Signal(8, name_override='ar_addr2') + # * always read/search lower 128 rows + self.comb += arAddr1.eq(Cat(self.inAddr[0:6], 0)) + # * always read/search upper 128 rows + self.comb += arAddr2.eq(Cat(self.inAddr[0:6], 1) & Cat(Replicate(self.inWeb, 8))) + logging.info('Created read/search address logic') + + # * ----- PMA + rdataLower = Signal(32, name_override='rdata_lower') + rdataUpper = Signal(32, name_override='rdata_upper') + rdata = Signal(64, name_override='rdata') + + self.comb += rdata.eq(Cat(rdataLower, rdataUpper)) + self.comb += self.outputs.eq(rdata) + logging.info('Created upper and lower potential matcha address logic') + + # * ----- instantiate the sky130 1KB RAM module as submodule + self.specials += Instance( + of=self.__sramModule, # module name + name='dut_vtb', # instance name + i_clk0=self.inClk, # input port (use i_) + i_csb0=self.inCsb, # input port (use i_) + i_web0=self.inWeb, # input port (use i_) + i_wmask0=self.inWmask, # input port (use i_) + i_addr0=Mux(self.inWeb, arAddr1, awAddr), # input port (use i_) + i_din0=self.inWdata, # input port (use i_) + o_dout0=rdataLower, # input port (use i_) + i_clk1=self.inClk, # input port (use i_) + i_csb1=self.inCsb, # input port (use i_) + i_addr1=arAddr2, # input port (use i_) + o_dout1=rdataUpper # output port (use o_) + ) + logging.info('Instantiated {:s} module'.format(self.__sramModule)) + +# =========================================================================================== +# ======================================== End Class ======================================== +# =========================================================================================== From 905faac26bbee795f6a2e8303fe3d75d80964f75 Mon Sep 17 00:00:00 2001 From: usman1515 Date: Mon, 27 Feb 2023 17:10:28 +0500 Subject: [PATCH 17/41] created func genVerilogTcamMemory7x64 in py class tcamMemory7x64 --- compiler/src/tcamMemory7x64.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/compiler/src/tcamMemory7x64.py b/compiler/src/tcamMemory7x64.py index e35d4aa..2f844e1 100644 --- a/compiler/src/tcamMemory7x64.py +++ b/compiler/src/tcamMemory7x64.py @@ -89,13 +89,15 @@ def logicBlock(self): self.specials += Instance( of=self.__sramModule, # module name name='dut_vtb', # instance name + # Port 0: RW i_clk0=self.inClk, # input port (use i_) i_csb0=self.inCsb, # input port (use i_) i_web0=self.inWeb, # input port (use i_) i_wmask0=self.inWmask, # input port (use i_) i_addr0=Mux(self.inWeb, arAddr1, awAddr), # input port (use i_) i_din0=self.inWdata, # input port (use i_) - o_dout0=rdataLower, # input port (use i_) + o_dout0=rdataLower, # output port (use o_) + # Port 1: R i_clk1=self.inClk, # input port (use i_) i_csb1=self.inCsb, # input port (use i_) i_addr1=arAddr2, # input port (use i_) @@ -106,3 +108,18 @@ def logicBlock(self): # =========================================================================================== # ======================================== End Class ======================================== # =========================================================================================== + +def genVerilogTcamMemory7x64(filePath): + # * instantiate the module + tcamMem = tcamMemory7x64() + + # * generate the verilog code + tcamMem.verilogCode = convert(tcamMem, name='tcamMemory7x64') + logging.info('Generated TCAM Memory 7x64 verilog module RTL') + + # * write verilog code to a file + with open(filePath, 'w', encoding='utf-8') as rtl: + rtl.write(str(tcamMem.verilogCode)) + logging.info('Created rtl file {:s}'.format(filePath)) + + return str(tcamMem.verilogCode) \ No newline at end of file From 7df4acfca515ea68cec0dd83f6406fa8e2ec01b0 Mon Sep 17 00:00:00 2001 From: usman1515 Date: Mon, 27 Feb 2023 17:24:13 +0500 Subject: [PATCH 18/41] added docstrings for funcs in py class tcamMemory7x64 --- compiler/src/tcamMemory7x64.py | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/compiler/src/tcamMemory7x64.py b/compiler/src/tcamMemory7x64.py index 2f844e1..c2fbcdb 100644 --- a/compiler/src/tcamMemory7x64.py +++ b/compiler/src/tcamMemory7x64.py @@ -12,18 +12,21 @@ class tcamMemory7x64(Module): """ - _summary_ - - :param _type_ Module: _description_ + Generates the verilog code for a TCAM 7x64 memory block. """ # * ----------------------------------------------------------------- Variables def __init__(self): """ - _summary_ + Constructor: call IO ports and logic here + + **Variables:** + :param str __sramModule: module definition name of the SRAM block. + :return str verilogCode: store RTL code of the encoder. """ # * variables self.__sramModule = 'sky130_sram_1kbyte_1rw1r_32x256_8' + self.verilogCode = '' # * setup IO ports self.ioPorts() @@ -32,7 +35,7 @@ def __init__(self): def ioPorts(self): """ - _summary_ + Create Signal objects for all the input ports of various widths and output ports of various widths. """ self.inputs = [] # * setup input ports @@ -60,7 +63,7 @@ def ioPorts(self): def logicBlock(self): """ - _summary_ + Setup the sequential logic for creating a TCAM 7x64 memory block using migen. """ # * ----- setup write address logic awAddr = Signal(8, name_override='aw_addr') @@ -110,6 +113,14 @@ def logicBlock(self): # =========================================================================================== def genVerilogTcamMemory7x64(filePath): + """ + Main user function for class tcamMemory7x64. + Creates the IO ports for the verilog RTL module definition. + Generates the verilog code for a TCAM 7x64 memory block. + + :param str filePath: absolute path for the verilog file. + :return str: RTL code of the TCAM 7x64 memory. + """ # * instantiate the module tcamMem = tcamMemory7x64() From 745383de7739e369b934c9e7ec3c1cc052191851 Mon Sep 17 00:00:00 2001 From: usman1515 Date: Mon, 27 Feb 2023 17:32:07 +0500 Subject: [PATCH 19/41] renamed py classs and file tcamMemory7x64 to tcamMemBlock7x64 --- ...{tcamMemory7x64.py => tcamMemBlock7x64.py} | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) rename compiler/src/{tcamMemory7x64.py => tcamMemBlock7x64.py} (84%) diff --git a/compiler/src/tcamMemory7x64.py b/compiler/src/tcamMemBlock7x64.py similarity index 84% rename from compiler/src/tcamMemory7x64.py rename to compiler/src/tcamMemBlock7x64.py index c2fbcdb..36ef7f3 100644 --- a/compiler/src/tcamMemory7x64.py +++ b/compiler/src/tcamMemBlock7x64.py @@ -10,7 +10,7 @@ # ======================================= Begin Class ======================================= # =========================================================================================== -class tcamMemory7x64(Module): +class tcamMemBlock7x64(Module): """ Generates the verilog code for a TCAM 7x64 memory block. """ @@ -40,23 +40,23 @@ def ioPorts(self): self.inputs = [] # * setup input ports self.inClk = Signal(1, name_override='in_clk') - logging.info('Created tcamMemory7x64 input port: {:>s}'.format(self.inClk.name_override)) + logging.info('Created tcamMemBlock7x64 input port: {:>s}'.format(self.inClk.name_override)) self.inCsb = Signal(1, name_override='in_csb') - logging.info('Created tcamMemory7x64 input port: {:>s}'.format(self.inCsb.name_override)) + logging.info('Created tcamMemBlock7x64 input port: {:>s}'.format(self.inCsb.name_override)) self.inWeb = Signal(1, name_override='in_web') - logging.info('Created tcamMemory7x64 input port: {:>s}'.format(self.inWeb.name_override)) + logging.info('Created tcamMemBlock7x64 input port: {:>s}'.format(self.inWeb.name_override)) self.inWmask = Signal(4, name_override='in_wmask') - logging.info('Created tcamMemory7x64 input port: {:>s}[{:d}:0]'.format(self.inWmask.name_override, 4)) + logging.info('Created tcamMemBlock7x64 input port: {:>s}[{:d}:0]'.format(self.inWmask.name_override, 4)) self.inAddr = Signal(8, name_override='in_addr') - logging.info('Created tcamMemory7x64 input port: {:>s}[{:d}:0]'.format(self.inAddr.name_override, 8)) + logging.info('Created tcamMemBlock7x64 input port: {:>s}[{:d}:0]'.format(self.inAddr.name_override, 8)) self.inWdata = Signal(32, name_override='in_wdata') - logging.info('Created tcamMemory7x64 input port: {:>s}[{:d}:0]'.format(self.inWdata.name_override, 32)) + logging.info('Created tcamMemBlock7x64 input port: {:>s}[{:d}:0]'.format(self.inWdata.name_override, 32)) # * add all input ports to an input list self.inputs = [self.inClk, self.inCsb, self.inWeb, self.inWmask, self.inAddr, self.inWdata] logging.info('Created list of all input ports') # * setup output ports self.outRdata = Signal(64, name_override='out_rdata') - logging.info('Created tcamMemory7x64 output port: {:>s}[{:d}:0]'.format(self.outRdata.name_override, 64)) + logging.info('Created tcamMemBlock7x64 output port: {:>s}[{:d}:0]'.format(self.outRdata.name_override, 64)) # * add all output ports to an output list self.outputs = self.outRdata logging.info('Created list of all output ports') @@ -112,9 +112,9 @@ def logicBlock(self): # ======================================== End Class ======================================== # =========================================================================================== -def genVerilogTcamMemory7x64(filePath): +def genVerilogtcamMemBlock7x64(filePath): """ - Main user function for class tcamMemory7x64. + Main user function for class tcamMemBlock7x64. Creates the IO ports for the verilog RTL module definition. Generates the verilog code for a TCAM 7x64 memory block. @@ -122,10 +122,10 @@ def genVerilogTcamMemory7x64(filePath): :return str: RTL code of the TCAM 7x64 memory. """ # * instantiate the module - tcamMem = tcamMemory7x64() + tcamMem = tcamMemBlock7x64() # * generate the verilog code - tcamMem.verilogCode = convert(tcamMem, name='tcamMemory7x64') + tcamMem.verilogCode = convert(tcamMem, name='tcamMemBlock7x64') logging.info('Generated TCAM Memory 7x64 verilog module RTL') # * write verilog code to a file From 23e9c175970a954f9c1609fa8948329d127e245d Mon Sep 17 00:00:00 2001 From: usman1515 Date: Mon, 27 Feb 2023 17:36:36 +0500 Subject: [PATCH 20/41] created py script tcamMemTopwrapper with class tcamMemTopwrapper --- compiler/src/tcamMemTopWrapper.py | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 compiler/src/tcamMemTopWrapper.py diff --git a/compiler/src/tcamMemTopWrapper.py b/compiler/src/tcamMemTopWrapper.py new file mode 100644 index 0000000..2081ea6 --- /dev/null +++ b/compiler/src/tcamMemTopWrapper.py @@ -0,0 +1,5 @@ +from migen import * +from migen.fhdl.verilog import convert + +class tcamMemTopwrapper(Module): + pass \ No newline at end of file From deee0f334a078896c0089fbb1671e0e6d65fc1d2 Mon Sep 17 00:00:00 2001 From: usman1515 Date: Mon, 27 Feb 2023 18:00:16 +0500 Subject: [PATCH 21/41] created constructor for py class tcamMemTopWrapper --- compiler/src/tcamMemTopWrapper.py | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/compiler/src/tcamMemTopWrapper.py b/compiler/src/tcamMemTopWrapper.py index 2081ea6..e954004 100644 --- a/compiler/src/tcamMemTopWrapper.py +++ b/compiler/src/tcamMemTopWrapper.py @@ -1,5 +1,29 @@ +""" +List of all pip packages imported +""" + from migen import * from migen.fhdl.verilog import convert +# =========================================================================================== +# ======================================= Begin Class ======================================= +# =========================================================================================== + class tcamMemTopwrapper(Module): - pass \ No newline at end of file + """ + _summary_ + + :param _type_ Module: _description_ + """ + + # * ----------------------------------------------------------------- Variables + def __init__(self): + """ + _summary_ + """ + # * variables + + # * setup IO ports + self.ioPorts() + # * generate block RTL + # self.logicBlock() From 510c8386e0f6b3cf53397a97d8fe260564adfb57 Mon Sep 17 00:00:00 2001 From: usman1515 Date: Mon, 27 Feb 2023 19:14:30 +0500 Subject: [PATCH 22/41] created func ioPorts in py class tcamMemTopWrapper --- compiler/src/tcamMemTopWrapper.py | 37 ++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/compiler/src/tcamMemTopWrapper.py b/compiler/src/tcamMemTopWrapper.py index e954004..9cfc3e5 100644 --- a/compiler/src/tcamMemTopWrapper.py +++ b/compiler/src/tcamMemTopWrapper.py @@ -2,6 +2,7 @@ List of all pip packages imported """ +import logging from migen import * from migen.fhdl.verilog import convert @@ -9,7 +10,7 @@ # ======================================= Begin Class ======================================= # =========================================================================================== -class tcamMemTopwrapper(Module): +class tcamMemTopWrapper(Module): """ _summary_ @@ -17,13 +18,43 @@ class tcamMemTopwrapper(Module): """ # * ----------------------------------------------------------------- Variables - def __init__(self): + def __init__(self, memBlocks): """ _summary_ """ # * variables - + self.memBlocks = memBlocks # 4 + self.__inAddrWidth = 0 # * setup IO ports self.ioPorts() # * generate block RTL # self.logicBlock() + + def ioPorts(self): + """ + _summary_ + """ + self.inputs = [] + # * setup input ports + self.inClk = Signal(1, name_override='in_clk') + logging.info('Created tcamMemTopWrapper input port: {:>s}'.format(self.inClk.name_override)) + self.inCsb = Signal(1, name_override='in_csb') + logging.info('Created tcamMemTopWrapper input port: {:>s}'.format(self.inCsb.name_override)) + self.inWeb = Signal(1, name_override='in_web') + logging.info('Created tcamMemTopWrapper input port: {:>s}'.format(self.inWeb.name_override)) + self.inWmask = Signal(4, name_override='in_wmask') + logging.info('Created tcamMemTopWrapper input port: {:>s}[{:d}:0]'.format(self.inWmask.name_override, 3)) + self.__inAddrWidth = self.memBlocks * 7 + self.inAddr = Signal(self.__inAddrWidth, name_override='in_addr') + logging.info('Created tcamMemTopWrapper input port: {:>s}[{:d}:0]'.format(self.inAddr.name_override, self.__inAddrWidth-1)) + self.inWdata = Signal(32, name_override='in_wdata') + logging.info('Created tcamMemTopWrapper input port: {:>s}[{:d}:0]'.format(self.inWdata.name_override, 31)) + # * add all input ports to an input list + self.inputs = [self.inClk, self.inCsb, self.inWeb, self.inWmask, self.inAddr, self.inWdata] + logging.info('Created list of all input ports') + # * setup output ports + self.outPma = Signal(6, name_override='out_pma') + logging.info('Created tcamMemTopWrapper output port: {:>s}[{:d}:0]'.format(self.outPma.name_override, 5)) + # * add all output ports to an output list + self.outputs = self.outPma + logging.info('Created list of all output ports') From 932c14c98569588c9e8083485891b78bea023a89 Mon Sep 17 00:00:00 2001 From: usman1515 Date: Mon, 27 Feb 2023 19:17:42 +0500 Subject: [PATCH 23/41] created func genVerilogTcamMemTopWrapper in py class tcamMemTopWrapper --- compiler/src/tcamMemTopWrapper.py | 32 +++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/compiler/src/tcamMemTopWrapper.py b/compiler/src/tcamMemTopWrapper.py index 9cfc3e5..cb781d4 100644 --- a/compiler/src/tcamMemTopWrapper.py +++ b/compiler/src/tcamMemTopWrapper.py @@ -25,6 +25,8 @@ def __init__(self, memBlocks): # * variables self.memBlocks = memBlocks # 4 self.__inAddrWidth = 0 + self.verilogCode = '' + # * setup IO ports self.ioPorts() # * generate block RTL @@ -58,3 +60,33 @@ def ioPorts(self): # * add all output ports to an output list self.outputs = self.outPma logging.info('Created list of all output ports') + + + + + + +# =========================================================================================== +# ======================================== End Class ======================================== +# =========================================================================================== + +def genVerilogTcamMemTopWrapper(memBlocks, filePath): + """ + _summary_ + + :param _type_ filePath: _description_ + :return _type_: _description_ + """ + # * instantiate the module + tcamMemTop = tcamMemTopWrapper(memBlocks) + + # * generate the verilog code + tcamMemTop.verilogCode = convert(tcamMemTop, name='tcamMemBlock7x64') + logging.info('Generated TCAM Memory Top Wrapper verilog module RTL') + + # * write verilog code to a file + with open(filePath, 'w', encoding='utf-8') as rtl: + rtl.write(str(tcamMemTop.verilogCode)) + logging.info('Created rtl file {:s}'.format(filePath)) + + return str(tcamMemTop.verilogCode) \ No newline at end of file From 5995d83b4c8e744a86dd62c0fa68c4aefd0f4dee Mon Sep 17 00:00:00 2001 From: usman1515 Date: Tue, 28 Feb 2023 18:59:49 +0500 Subject: [PATCH 24/41] created func logicBlock in py class tcamMemTopWrapper --- compiler/src/tcamMemTopWrapper.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/compiler/src/tcamMemTopWrapper.py b/compiler/src/tcamMemTopWrapper.py index cb781d4..6ca5fd8 100644 --- a/compiler/src/tcamMemTopWrapper.py +++ b/compiler/src/tcamMemTopWrapper.py @@ -3,6 +3,7 @@ """ import logging +import math from migen import * from migen.fhdl.verilog import convert @@ -30,7 +31,7 @@ def __init__(self, memBlocks): # * setup IO ports self.ioPorts() # * generate block RTL - # self.logicBlock() + self.logicBlock() def ioPorts(self): """ @@ -61,7 +62,8 @@ def ioPorts(self): self.outputs = self.outPma logging.info('Created list of all output ports') - + def logicBlock(self): + pass From 8bbbd8544092808632885c5d9aa25f1e66ee8cf6 Mon Sep 17 00:00:00 2001 From: usman1515 Date: Tue, 28 Feb 2023 19:00:59 +0500 Subject: [PATCH 25/41] added mem block selection logic in func logicBlock in py class tcamMemTopWrapper --- compiler/src/tcamMemTopWrapper.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/compiler/src/tcamMemTopWrapper.py b/compiler/src/tcamMemTopWrapper.py index 6ca5fd8..019db0f 100644 --- a/compiler/src/tcamMemTopWrapper.py +++ b/compiler/src/tcamMemTopWrapper.py @@ -63,7 +63,16 @@ def ioPorts(self): logging.info('Created list of all output ports') def logicBlock(self): - pass + # * ----- memory block selection for write logic + # * setup wire + blockSel = Signal(self.memBlocks, name_override='block_sel') + # * calculate width for inAddr slice + inAddrWidth = int(math.ceil(math.log2(self.memBlocks))) + 8 + # * combinational logic for block sel + for i in range(self.memBlocks): + self.comb += blockSel[i].eq(self.inAddr[8:inAddrWidth] == i) + + From 93975b2e251f388ceb71145245210b5b1cea6fe7 Mon Sep 17 00:00:00 2001 From: usman1515 Date: Tue, 28 Feb 2023 19:01:37 +0500 Subject: [PATCH 26/41] added write amsk logic in func logicBlock in py class tcamMemTopWrapper --- compiler/src/tcamMemTopWrapper.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/compiler/src/tcamMemTopWrapper.py b/compiler/src/tcamMemTopWrapper.py index 019db0f..a8b73fe 100644 --- a/compiler/src/tcamMemTopWrapper.py +++ b/compiler/src/tcamMemTopWrapper.py @@ -71,7 +71,15 @@ def logicBlock(self): # * combinational logic for block sel for i in range(self.memBlocks): self.comb += blockSel[i].eq(self.inAddr[8:inAddrWidth] == i) - + + # * ----- generating logic for write mask + wMaskList = [] + for i in range(self.memBlocks): + # * setup wire + tempWire = Signal(4, name_override='wmask{:d}'.format(i)) + wMaskList.append(tempWire) + # * combinational logic for write mask + self.comb += wMaskList[i].eq(Replicate(blockSel[i], 4) & self.inWmask) From 8a8575c54f45e2942d8e6d7e1a6c8c91b6ef40a2 Mon Sep 17 00:00:00 2001 From: usman1515 Date: Tue, 28 Feb 2023 19:02:10 +0500 Subject: [PATCH 27/41] added write addr logic in func logicBlock in py class tcamMemTopWrapper --- compiler/src/tcamMemTopWrapper.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/compiler/src/tcamMemTopWrapper.py b/compiler/src/tcamMemTopWrapper.py index a8b73fe..fb76239 100644 --- a/compiler/src/tcamMemTopWrapper.py +++ b/compiler/src/tcamMemTopWrapper.py @@ -81,6 +81,15 @@ def logicBlock(self): # * combinational logic for write mask self.comb += wMaskList[i].eq(Replicate(blockSel[i], 4) & self.inWmask) + # * ----- generating logic for write addresses + awAddrList = [] + for i in range(self.memBlocks): + # * setup wire + tempWire = Signal(8, name_override='aw_addr{:d}'.format(i)) + awAddrList.append(tempWire) + # * combinational logic for write addresses + self.comb += awAddrList[i].eq(Replicate(blockSel[i], 8) & self.inAddr[0:8]) + From ecbcbc13762dd1731719ec0f48672afc1d4acf10 Mon Sep 17 00:00:00 2001 From: usman1515 Date: Tue, 28 Feb 2023 19:02:48 +0500 Subject: [PATCH 28/41] added addr mux generation logic in func logicBlock in py class tcamMemTopWrapper --- compiler/src/tcamMemTopWrapper.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/compiler/src/tcamMemTopWrapper.py b/compiler/src/tcamMemTopWrapper.py index fb76239..57384d9 100644 --- a/compiler/src/tcamMemTopWrapper.py +++ b/compiler/src/tcamMemTopWrapper.py @@ -90,7 +90,18 @@ def logicBlock(self): # * combinational logic for write addresses self.comb += awAddrList[i].eq(Replicate(blockSel[i], 8) & self.inAddr[0:8]) - + # * ----- generating address mux for all N blocks (selects between read or write addresses) + vtbAddrList = [] + for i in range(self.memBlocks): + # * setup wire + tempWire = Signal(7, name_override='vtb_addr{:d}'.format(i)) + vtbAddrList.append(tempWire) + # * combinational logic for address mux + self.comb += If(self.inWeb, + vtbAddrList[i].eq(Cat(self.inAddr[i*7 : (i*7)+7], 0b0)), + ).Else( + vtbAddrList[i].eq(awAddrList[i]) + ) From 63f5a1e125cfbf617e19a43f18439dcaf928b732 Mon Sep 17 00:00:00 2001 From: usman1515 Date: Tue, 28 Feb 2023 19:03:40 +0500 Subject: [PATCH 29/41] added TCAM mem block instances logic in func logicBlock in py class tcamMemTopWrapper --- compiler/src/tcamMemTopWrapper.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/compiler/src/tcamMemTopWrapper.py b/compiler/src/tcamMemTopWrapper.py index 57384d9..911a5ca 100644 --- a/compiler/src/tcamMemTopWrapper.py +++ b/compiler/src/tcamMemTopWrapper.py @@ -103,6 +103,26 @@ def logicBlock(self): vtbAddrList[i].eq(awAddrList[i]) ) + # * ----- adding TCAM memory block instances + # * setup rdata output signals + outRdataList = [] + for i in range(self.memBlocks): + tempWire = Signal(64, name_override='out_rdata{:d}'.format(i)) + outRdataList.append(tempWire) + + # * tcam memory block 7x64 instantiations + self.specials += Instance( + of='tcamMemBlock7x64', + name='tcam_mem_7x64_dut{:d}'.format(i), + i_in_clk=self.inClk, + i_in_csb=self.inCsb, + i_in_web=self.inWeb, + i_in_wmask=self.inWmask, + i_in_addr=vtbAddrList[i], + i_in_wdata=self.inWdata, + o_out_rdata=outRdataList[i] + ) + # =========================================================================================== From deafffd0269ba3f0c0d4fc7d5dbd79ce2a835c3c Mon Sep 17 00:00:00 2001 From: usman1515 Date: Tue, 28 Feb 2023 19:04:04 +0500 Subject: [PATCH 30/41] added AND gate instances logic in func logicBlock in py class tcamMemTopWrapper --- compiler/src/tcamMemTopWrapper.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/compiler/src/tcamMemTopWrapper.py b/compiler/src/tcamMemTopWrapper.py index 911a5ca..38c6e94 100644 --- a/compiler/src/tcamMemTopWrapper.py +++ b/compiler/src/tcamMemTopWrapper.py @@ -123,7 +123,28 @@ def logicBlock(self): o_out_rdata=outRdataList[i] ) - + # * ------ AND gate instantiations + outAndGateList = [] + for i in range(self.memBlocks-1): + # * setup AND gate output signals + tempWire = Signal(64, name_override='out_gate{:d}'.format(i)) + outAndGateList.append(tempWire) + if i == 0: + self.specials += Instance( + of='and_gate', + name='and_gate_dut{:d}'.format(i), + i_in_dataA=outRdataList[i], # out_rdata0 + i_in_dataB=outRdataList[i+1], # out_rdata1 + o_out_data=outAndGateList[i] # out_gate0 + ) + else: + self.specials += Instance( + of='and_gate', + name='and_gate_dut{:d}'.format(i), + i_in_dataA=outRdataList[i+1], # out_rdata2 + i_in_dataB=outAndGateList[i-1], # out_gate0 + o_out_gate=outAndGateList[i] # out_gate1 + ) # =========================================================================================== # ======================================== End Class ======================================== From b4c29a9db445b863cfadd7cdac97fc28f32fba37 Mon Sep 17 00:00:00 2001 From: usman1515 Date: Tue, 28 Feb 2023 19:04:39 +0500 Subject: [PATCH 31/41] added priority encoder instance logic in func logicBlock in py class tcamMemTopWrapper --- compiler/src/tcamMemTopWrapper.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/compiler/src/tcamMemTopWrapper.py b/compiler/src/tcamMemTopWrapper.py index 38c6e94..2e1be16 100644 --- a/compiler/src/tcamMemTopWrapper.py +++ b/compiler/src/tcamMemTopWrapper.py @@ -146,6 +146,14 @@ def logicBlock(self): o_out_gate=outAndGateList[i] # out_gate1 ) + # * ------ Priority encoder instantiations + self.specials += Instance( + of='priority_encoder', + name='priority_encoder_dut0', + i_in_data=outAndGateList[-1], + o_out_data=self.outputs + ) + # =========================================================================================== # ======================================== End Class ======================================== # =========================================================================================== From 94edbf789389c742906d746b424a7bc5b15e8058 Mon Sep 17 00:00:00 2001 From: usman1515 Date: Wed, 1 Mar 2023 17:55:16 +0500 Subject: [PATCH 32/41] added docstrings and logging for funcs in py class tcamMemTopWrapper --- compiler/src/tcamMemTopWrapper.py | 118 +++++++++++++++++++----------- 1 file changed, 77 insertions(+), 41 deletions(-) diff --git a/compiler/src/tcamMemTopWrapper.py b/compiler/src/tcamMemTopWrapper.py index 2e1be16..c3223a4 100644 --- a/compiler/src/tcamMemTopWrapper.py +++ b/compiler/src/tcamMemTopWrapper.py @@ -13,21 +13,40 @@ class tcamMemTopWrapper(Module): """ - _summary_ - - :param _type_ Module: _description_ + Generates the verilog code for a TCAM memory block N*64 Wrapper. """ # * ----------------------------------------------------------------- Variables def __init__(self, memBlocks): """ - _summary_ + Constructor: call IO ports and logic here + + **Signals:** + :param Signal __blockSel: signals object for block_sel + :param list __wMaskList: list to store signal objects for wmaskN + :param list __awAddrList: list to store signal objects for aw_addrN + :param list __vtbAddrList: list to store signal objects for vtb_addrN + :param list __outRdataList: list to store signal objects for out_rdataN + :param list __outAndGateList: list to store signal objects for out_andgateN + + **Variables:** + :param int memBlocks: instantiate N instances of module tcamMemBlock7x64 + :param int __inAddrWidth: store bit width of signal in_addr + :return str verilogCode: store RTL code of the encoder. """ # * variables self.memBlocks = memBlocks # 4 self.__inAddrWidth = 0 self.verilogCode = '' + # * signals + self.__blockSel = Signal() + self.__wMaskList = [] + self.__awAddrList = [] + self.__vtbAddrList = [] + self.__outRdataList = [] + self.__outAndGateList = [] + # * setup IO ports self.ioPorts() # * generate block RTL @@ -35,7 +54,7 @@ def __init__(self, memBlocks): def ioPorts(self): """ - _summary_ + Create Signal objects for all the input ports of various widths and output ports of various widths. """ self.inputs = [] # * setup input ports @@ -63,96 +82,110 @@ def ioPorts(self): logging.info('Created list of all output ports') def logicBlock(self): + """ + Setup the logic for creating a TCAM Mx64 wrapper consisting of M/7 TCAM 7x64 memory block using migen. + """ # * ----- memory block selection for write logic # * setup wire - blockSel = Signal(self.memBlocks, name_override='block_sel') + self.__blockSel = Signal(self.memBlocks, name_override='block_sel') + logging.info('Created wire {:s}[{:d}:0]'.format(self.__blockSel.name_override, self.__blockSel.nbits-1)) # * calculate width for inAddr slice inAddrWidth = int(math.ceil(math.log2(self.memBlocks))) + 8 + logging.info('Calculated bit slice for signal in_addr[{:2d}:{:2d}]'.format(inAddrWidth, 8)) # * combinational logic for block sel for i in range(self.memBlocks): - self.comb += blockSel[i].eq(self.inAddr[8:inAddrWidth] == i) + self.comb += self.__blockSel[i].eq(self.inAddr[8:inAddrWidth] == i) + logging.info('Created logic for signal {:s}[{:d}]'.format(self.__blockSel.name_override, i)) # * ----- generating logic for write mask - wMaskList = [] for i in range(self.memBlocks): # * setup wire - tempWire = Signal(4, name_override='wmask{:d}'.format(i)) - wMaskList.append(tempWire) + tempWmask = Signal(4, name_override='wmask{:d}'.format(i)) + self.__wMaskList.append(tempWmask) + logging.info('Created wire {:s}[{:d}:0]'.format(self.__wMaskList[i].name_override, self.__wMaskList[i].nbits-1)) # * combinational logic for write mask - self.comb += wMaskList[i].eq(Replicate(blockSel[i], 4) & self.inWmask) + self.comb += self.__wMaskList[i].eq(Replicate(self.__blockSel[i], 4) & self.inWmask) + logging.info('Created logic for signal {:s}'.format(self.__wMaskList[i].name_override)) # * ----- generating logic for write addresses - awAddrList = [] for i in range(self.memBlocks): # * setup wire - tempWire = Signal(8, name_override='aw_addr{:d}'.format(i)) - awAddrList.append(tempWire) + tempAwAddr = Signal(8, name_override='aw_addr{:d}'.format(i)) + self.__awAddrList.append(tempAwAddr) + logging.info('Created wire {:s}[{:d}:0]'.format(self.__awAddrList[i].name_override, self.__awAddrList[i].nbits-1)) # * combinational logic for write addresses - self.comb += awAddrList[i].eq(Replicate(blockSel[i], 8) & self.inAddr[0:8]) + self.comb += self.__awAddrList[i].eq(Replicate(self.__blockSel[i], 8) & self.inAddr[0:8]) + logging.info('Created logic for signal {:s}'.format(self.__awAddrList[i].name_override)) # * ----- generating address mux for all N blocks (selects between read or write addresses) - vtbAddrList = [] for i in range(self.memBlocks): # * setup wire - tempWire = Signal(7, name_override='vtb_addr{:d}'.format(i)) - vtbAddrList.append(tempWire) + tempVtbAddr = Signal(7, name_override='vtb_addr{:d}'.format(i)) + self.__vtbAddrList.append(tempVtbAddr) + logging.info('Created wire {:s}[{:d}:0]'.format(self.__vtbAddrList[i].name_override, self.__vtbAddrList[i].nbits-1)) # * combinational logic for address mux self.comb += If(self.inWeb, - vtbAddrList[i].eq(Cat(self.inAddr[i*7 : (i*7)+7], 0b0)), + self.__vtbAddrList[i].eq(Cat(self.inAddr[i*7 : (i*7)+7], 0b0)), ).Else( - vtbAddrList[i].eq(awAddrList[i]) + self.__vtbAddrList[i].eq(self.__awAddrList[i]) ) + logging.info('Created logic for signal {:s}'.format(self.__vtbAddrList[i].name_override)) # * ----- adding TCAM memory block instances # * setup rdata output signals - outRdataList = [] for i in range(self.memBlocks): - tempWire = Signal(64, name_override='out_rdata{:d}'.format(i)) - outRdataList.append(tempWire) + tempRdata = Signal(64, name_override='out_rdata{:d}'.format(i)) + self.__outRdataList.append(tempRdata) + logging.info('Created wire {:s}[{:d}:0]'.format(self.__outRdataList[i].name_override, self.__outRdataList[i].nbits-1)) # * tcam memory block 7x64 instantiations + dutName = 'tcam_mem_7x64_dut{:d}'.format(i) self.specials += Instance( of='tcamMemBlock7x64', - name='tcam_mem_7x64_dut{:d}'.format(i), + name=dutName, i_in_clk=self.inClk, i_in_csb=self.inCsb, i_in_web=self.inWeb, i_in_wmask=self.inWmask, - i_in_addr=vtbAddrList[i], + i_in_addr=self.__vtbAddrList[i], i_in_wdata=self.inWdata, - o_out_rdata=outRdataList[i] + o_out_rdata=self.__outRdataList[i] ) + logging.info('Created instance "{:s}" of module "tcamMemBlock7x64"'.format(dutName)) # * ------ AND gate instantiations - outAndGateList = [] for i in range(self.memBlocks-1): # * setup AND gate output signals - tempWire = Signal(64, name_override='out_gate{:d}'.format(i)) - outAndGateList.append(tempWire) + tempOutAndGate = Signal(64, name_override='out_andgate{:d}'.format(i)) + self.__outAndGateList.append(tempOutAndGate) + logging.info('Created wire {:s}[{:d}:0]'.format(self.__outAndGateList[i].name_override, self.__outAndGateList[i].nbits-1)) + dutName = 'and_gate_dut{:d}'.format(i) if i == 0: self.specials += Instance( of='and_gate', - name='and_gate_dut{:d}'.format(i), - i_in_dataA=outRdataList[i], # out_rdata0 - i_in_dataB=outRdataList[i+1], # out_rdata1 - o_out_data=outAndGateList[i] # out_gate0 + name=dutName, + i_in_dataA=self.__outRdataList[i], # out_rdata0 + i_in_dataB=self.__outRdataList[i+1], # out_rdata1 + o_out_data=self.__outAndGateList[i] # out_gate0 ) else: self.specials += Instance( of='and_gate', - name='and_gate_dut{:d}'.format(i), - i_in_dataA=outRdataList[i+1], # out_rdata2 - i_in_dataB=outAndGateList[i-1], # out_gate0 - o_out_gate=outAndGateList[i] # out_gate1 + name=dutName, + i_in_dataA=self.__outRdataList[i+1], # out_rdata2 + i_in_dataB=self.__outAndGateList[i-1], # out_gate0 + o_out_gate=self.__outAndGateList[i] # out_gate1 ) + logging.info('Created instance "{:s}" of module "tcamMemBlock7x64"'.format(dutName)) # * ------ Priority encoder instantiations self.specials += Instance( of='priority_encoder', name='priority_encoder_dut0', - i_in_data=outAndGateList[-1], + i_in_data=self.__outAndGateList[-1], o_out_data=self.outputs ) + logging.info('Created instance "priority_encoder_dut0" of module "priority_encoder"') # =========================================================================================== # ======================================== End Class ======================================== @@ -160,10 +193,13 @@ def logicBlock(self): def genVerilogTcamMemTopWrapper(memBlocks, filePath): """ - _summary_ + Main user function for class tcamMemTopWrapper. + Creates the IO ports for the verilog RTL module definition. + Generates the verilog code for a TCAM Mx64 memory block wrapper. - :param _type_ filePath: _description_ - :return _type_: _description_ + :param int memBlocks: instantiate N instances of module tcamMemBlock7x64 + :param str filePath: absolute path for the verilog file. + :return str: RTL code of the TCAM 7x64 memory. """ # * instantiate the module tcamMemTop = tcamMemTopWrapper(memBlocks) From 50c4d9b771b7e729f8b0bdbfe8eb3ae23362486d Mon Sep 17 00:00:00 2001 From: usman1515 Date: Wed, 1 Mar 2023 19:29:20 +0500 Subject: [PATCH 33/41] added module definition ports for TCAM mem block and wrapper --- compiler/src/andGate.py | 8 +++++++- compiler/src/priorityEncoder.py | 7 +++++++ compiler/src/tcamMemBlock7x64.py | 25 +++++++++++++++++++------ compiler/src/tcamMemTopWrapper.py | 20 ++++++++++++++++---- 4 files changed, 49 insertions(+), 11 deletions(-) diff --git a/compiler/src/andGate.py b/compiler/src/andGate.py index 2025ea1..b79aa4b 100644 --- a/compiler/src/andGate.py +++ b/compiler/src/andGate.py @@ -22,14 +22,21 @@ def __init__(self, ports, dataWidth): Constructor: call IO ports and logic here **Public Variables:** + :param list inputs list containing objects for all input ports. + :param list outputs list containing objects for all output ports. :param int ports: number of input ports. :param int dataWidth: width of input ports. :return str verilogCode: store RTL code of the gate. """ + # * variables self.numInputs = ports self.numInputWidth = dataWidth self.verilogCode = "" + # * signals + self.inputs = [] + self.outputs = [] + # * setup IO ports self.ioPorts() # * generate block RTL @@ -39,7 +46,6 @@ def ioPorts(self): """ Create a list of Signal objects for N input ports each of width M. Create a Signal object for an output port of width M. """ - self.inputs = [] for port in range(self.numInputs): tempPort = Signal(self.numInputWidth, name_override='in_data{}'.format(port)) self.inputs.append(tempPort) diff --git a/compiler/src/priorityEncoder.py b/compiler/src/priorityEncoder.py index 35540c2..85f46a7 100644 --- a/compiler/src/priorityEncoder.py +++ b/compiler/src/priorityEncoder.py @@ -23,13 +23,20 @@ def __init__(self, ports): Constructor: call IO ports and logic here **Public Variables:** + :param list inputs list containing objects for all input ports. + :param list outputs list containing objects for all output ports. :param int ports: number of input ports. :return str verilogCode: store RTL code of the encoder. """ + # * variables self.inputWidth = ports self.outputWidth = 0 self.verilogCode = '' + # * signals + self.inputs = [] + self.outputs = [] + # * setup IO ports self.ioPorts() # * generate block RTL diff --git a/compiler/src/tcamMemBlock7x64.py b/compiler/src/tcamMemBlock7x64.py index 36ef7f3..988a24f 100644 --- a/compiler/src/tcamMemBlock7x64.py +++ b/compiler/src/tcamMemBlock7x64.py @@ -21,6 +21,8 @@ def __init__(self): Constructor: call IO ports and logic here **Variables:** + :param list inputs list containing objects for all input ports. + :param list outputs list containing objects for all output ports. :param str __sramModule: module definition name of the SRAM block. :return str verilogCode: store RTL code of the encoder. """ @@ -28,6 +30,10 @@ def __init__(self): self.__sramModule = 'sky130_sram_1kbyte_1rw1r_32x256_8' self.verilogCode = '' + # * signals + self.inputs = [] + self.outputs = [] + # * setup IO ports self.ioPorts() # * generate block RTL @@ -37,7 +43,6 @@ def ioPorts(self): """ Create Signal objects for all the input ports of various widths and output ports of various widths. """ - self.inputs = [] # * setup input ports self.inClk = Signal(1, name_override='in_clk') logging.info('Created tcamMemBlock7x64 input port: {:>s}'.format(self.inClk.name_override)) @@ -58,7 +63,7 @@ def ioPorts(self): self.outRdata = Signal(64, name_override='out_rdata') logging.info('Created tcamMemBlock7x64 output port: {:>s}[{:d}:0]'.format(self.outRdata.name_override, 64)) # * add all output ports to an output list - self.outputs = self.outRdata + self.outputs = [self.outRdata] logging.info('Created list of all output ports') def logicBlock(self): @@ -74,9 +79,9 @@ def logicBlock(self): arAddr1 = Signal(8, name_override='ar_addr1') arAddr2 = Signal(8, name_override='ar_addr2') # * always read/search lower 128 rows - self.comb += arAddr1.eq(Cat(self.inAddr[0:6], 0)) + self.comb += arAddr1.eq(Cat(self.inAddr[0:7], 0b0)) # * always read/search upper 128 rows - self.comb += arAddr2.eq(Cat(self.inAddr[0:6], 1) & Cat(Replicate(self.inWeb, 8))) + self.comb += arAddr2.eq(Cat(self.inAddr[0:7], 0b1) & Cat(Replicate(self.inWeb, 8))) logging.info('Created read/search address logic') # * ----- PMA @@ -85,7 +90,7 @@ def logicBlock(self): rdata = Signal(64, name_override='rdata') self.comb += rdata.eq(Cat(rdataLower, rdataUpper)) - self.comb += self.outputs.eq(rdata) + self.comb += self.outRdata.eq(rdata) logging.info('Created upper and lower potential matcha address logic') # * ----- instantiate the sky130 1KB RAM module as submodule @@ -124,8 +129,16 @@ def genVerilogtcamMemBlock7x64(filePath): # * instantiate the module tcamMem = tcamMemBlock7x64() + # * ----- setup the IO ports for the verilog module definition + # * input port set + inPortsSet = set(tcamMem.inputs) + # * output port set + outPortsSet = set(tcamMem.outputs) + # * combine input and output sets + moduleIOs = inPortsSet.union(outPortsSet) + # * generate the verilog code - tcamMem.verilogCode = convert(tcamMem, name='tcamMemBlock7x64') + tcamMem.verilogCode = convert(tcamMem, name='tcamMemBlock7x64', ios=moduleIOs) logging.info('Generated TCAM Memory 7x64 verilog module RTL') # * write verilog code to a file diff --git a/compiler/src/tcamMemTopWrapper.py b/compiler/src/tcamMemTopWrapper.py index c3223a4..27c059f 100644 --- a/compiler/src/tcamMemTopWrapper.py +++ b/compiler/src/tcamMemTopWrapper.py @@ -22,6 +22,8 @@ def __init__(self, memBlocks): Constructor: call IO ports and logic here **Signals:** + :param list inputs list containing objects for all input ports. + :param list outputs list containing objects for all output ports. :param Signal __blockSel: signals object for block_sel :param list __wMaskList: list to store signal objects for wmaskN :param list __awAddrList: list to store signal objects for aw_addrN @@ -46,6 +48,8 @@ def __init__(self, memBlocks): self.__vtbAddrList = [] self.__outRdataList = [] self.__outAndGateList = [] + self.inputs = [] + self.outputs = [] # * setup IO ports self.ioPorts() @@ -56,7 +60,7 @@ def ioPorts(self): """ Create Signal objects for all the input ports of various widths and output ports of various widths. """ - self.inputs = [] + self.inputs = {} # * setup input ports self.inClk = Signal(1, name_override='in_clk') logging.info('Created tcamMemTopWrapper input port: {:>s}'.format(self.inClk.name_override)) @@ -78,7 +82,7 @@ def ioPorts(self): self.outPma = Signal(6, name_override='out_pma') logging.info('Created tcamMemTopWrapper output port: {:>s}[{:d}:0]'.format(self.outPma.name_override, 5)) # * add all output ports to an output list - self.outputs = self.outPma + self.outputs = [self.outPma] logging.info('Created list of all output ports') def logicBlock(self): @@ -183,7 +187,7 @@ def logicBlock(self): of='priority_encoder', name='priority_encoder_dut0', i_in_data=self.__outAndGateList[-1], - o_out_data=self.outputs + o_out_data=self.outputs[0] ) logging.info('Created instance "priority_encoder_dut0" of module "priority_encoder"') @@ -204,8 +208,16 @@ def genVerilogTcamMemTopWrapper(memBlocks, filePath): # * instantiate the module tcamMemTop = tcamMemTopWrapper(memBlocks) + # * ----- setup the IO ports for the verilog module definition + # * input port set + inPortsSet = set(tcamMemTop.inputs) + # * output port set + outPortsSet = set(tcamMemTop.outputs) + # * combine input and output sets + moduleIOs = inPortsSet.union(outPortsSet) + # * generate the verilog code - tcamMemTop.verilogCode = convert(tcamMemTop, name='tcamMemBlock7x64') + tcamMemTop.verilogCode = convert(tcamMemTop, name='tcamMemBlock7x64', ios=moduleIOs) logging.info('Generated TCAM Memory Top Wrapper verilog module RTL') # * write verilog code to a file From 5f8870b89d0e5160045f7a313e223de1d30e1a95 Mon Sep 17 00:00:00 2001 From: usman1515 Date: Sat, 4 Mar 2023 16:38:28 +0500 Subject: [PATCH 34/41] created py file mainTcamMemTopWrapper --- compiler/src/mainTcamMemTopWrapper.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 compiler/src/mainTcamMemTopWrapper.py diff --git a/compiler/src/mainTcamMemTopWrapper.py b/compiler/src/mainTcamMemTopWrapper.py new file mode 100644 index 0000000..143ab60 --- /dev/null +++ b/compiler/src/mainTcamMemTopWrapper.py @@ -0,0 +1,19 @@ +""" +List of all pip packages imported +""" +from andGate import * +from priorityEncoder import * +from tcamMemBlock7x64 import * +from tcamMemTopWrapper import * +import os +import logging +import argparse +os.system('clear') + + +def main(): + pass + + +if __name__ == '__main__': + main() \ No newline at end of file From 39a4eeae8c0ede5aaf9a1649e68eb4be7b4da802 Mon Sep 17 00:00:00 2001 From: usman1515 Date: Sat, 4 Mar 2023 23:07:15 +0500 Subject: [PATCH 35/41] updated main func in py file mainTcamMemTopWrapper --- compiler/src/mainTcamMemTopWrapper.py | 97 ++++++++++++++++++++++++++- 1 file changed, 96 insertions(+), 1 deletion(-) diff --git a/compiler/src/mainTcamMemTopWrapper.py b/compiler/src/mainTcamMemTopWrapper.py index 143ab60..cce54cb 100644 --- a/compiler/src/mainTcamMemTopWrapper.py +++ b/compiler/src/mainTcamMemTopWrapper.py @@ -6,13 +6,108 @@ from tcamMemBlock7x64 import * from tcamMemTopWrapper import * import os +import sys +import shutil import logging import argparse os.system('clear') def main(): - pass + """ + _summary_ + """ + + # * ----- variables + pwd = os.getcwd() + logsDirPath = '' + tcamRtlDirPath = '' + tcamRtlConfigDirPath = '' + rtlFilePath = '' + memLength = 0 + memWidth = 0 + pathSram1kb = 'compiler/lib/tcam_block_rtl/sky130_sram_1kbyte_1rw1r_32x256_8.sv' + + # create logs dir if it doesn't exist + logsDirPath = os.path.join(pwd, "logs") + if os.path.exists(logsDirPath) is False: + os.makedirs("logs") + # create rtl dir if it doesn't exist + tcamRtlDirPath = os.path.join(pwd, 'tcam_mem_rtl') + if os.path.exists(tcamRtlDirPath) is False: + os.makedirs('tcam_mem_rtl') + # logging config + logging.basicConfig( + level=logging.DEBUG, + filename="./logs/tcamMemoryWrapper.log", + format="%(asctime)s | %(filename)s | %(funcName)s | %(levelname)s | %(lineno)d | %(message)s", + ) + + # set arguments for OpenTCAM RTL memory generator + parser = argparse.ArgumentParser( + prog="OpenTCAM ", + usage="%(prog)s [options] path", + description="TCAM memory generator", + epilog="Python framework for generating configurable SRAM based TCAM memories", + ) + # list of all possible args for OpenTCAM + parser.add_argument('-conf','--tcamConfig', + type=str,default='tcam_64x28',metavar='',required=True,nargs='?',help='name of specific TCAM mem wrapper config') + parser.add_argument('-d','--debug', + type=int,default=0,metavar='',required=False,nargs='?',help='print debugging mode') + parser.add_argument('-v','--verbose', + type=int,default=0,metavar='',required=False,nargs='?',help='print verbose mode') + arg = parser.parse_args() + + # ====================================================== code main body + + # * calculate how many tcam block are required + if arg.tcamConfig: + memLength=int(arg.tcamConfig[5:7]) + memWidth=int(arg.tcamConfig[8:10]) + print(memLength, memWidth, memWidth%7, memWidth/7) + if (memLength == 64) and (memWidth%7 == 0): + print('"VALID" TCAM memory wrapper config. tcam_[64]x[7*N] == {:s}'.format(arg.tcamConfig)) + logging.info('"VALID" TCAM memory wrapper config. tcam_[64]x[7*N] == {:s}'.format(arg.tcamConfig)) + logging.info('Total TCAM memory 64x7 blocks required: {:d}'.format(int(memWidth/7))) + # * create rtl dir for specific tcam mem wrap config + tcamRtlConfigDirPath = os.path.join(tcamRtlDirPath, arg.tcamConfig) + if os.path.exists(tcamRtlConfigDirPath): + shutil.rmtree(tcamRtlConfigDirPath) + os.makedirs(tcamRtlConfigDirPath) + logging.info('Created TCAM memory RTL dir: {:s}'.format(tcamRtlConfigDirPath)) + # * copy sky130 block to required config dir + shutil.copy(pathSram1kb, tcamRtlConfigDirPath) + logging.info('Copied file "{:s}" to dir "{:s}"'.format(pathSram1kb, tcamRtlConfigDirPath)) + print('Copied rtl file "{:s}" to dir "{:s}"'.format(os.path.basename(pathSram1kb), tcamRtlConfigDirPath)) + # * generate verilog for TCAM memory MxN top wrapper + fileName = 'top_tcam_mem_' + str(memLength) + 'x' + str(memWidth) + '.sv' + rtlFilePath = os.path.join(tcamRtlConfigDirPath, fileName) + codeTcamMemTopWrapper = genVerilogTcamMemTopWrapper(memBlocks=int(memWidth/7), filePath=rtlFilePath) + print('Created rtl file: "{:s}"'.format(rtlFilePath)) + if arg.debug: + print(codeTcamMemTopWrapper) + # * generate verilog for TCAM memory block 7x64 + rtlFilePath = os.path.join(tcamRtlConfigDirPath, 'tcam_mem_7x64.sv') + codeTcamMemBlock7x64 = genVerilogTcamMemBlock7x64(filePath=rtlFilePath) + print('Created rtl file: "{:s}"'.format(rtlFilePath)) + if arg.debug: + print(codeTcamMemBlock7x64) + # * generate verilog for andgate + rtlFilePath = os.path.join(tcamRtlConfigDirPath, 'and_gate.sv') + codeAndGate = genVerilogAndGate(inputPorts=2, dataWidth=64, filePath=rtlFilePath) + print('Created rtl file: "{:s}"'.format(rtlFilePath)) + if arg.debug: + print(codeAndGate) + # * generate verilog for priority encoder + rtlFilePath = os.path.join(tcamRtlConfigDirPath, 'priority_encoder_64x6.sv') + codePriorityEncoder = genVerilogPriorityEncoder(inDataWidth=64, filePath=rtlFilePath) + print('Created rtl file: "{:s}"'.format(rtlFilePath)) + if arg.debug: + print(codePriorityEncoder) + else: + logging.info('"INVALID" TCAM memory wrapper config. tcam_[64]x[7*N] != {:s}'.format(arg.tcamConfig)) + sys.exit('"INVALID" TCAM memory wrapper config. tcam_[64]x[7*N] != {:s}'.format(arg.tcamConfig)) if __name__ == '__main__': From d08aaa91f0b4e79ab24c0a88252dd31a4750ff7a Mon Sep 17 00:00:00 2001 From: usman1515 Date: Sun, 5 Mar 2023 00:17:45 +0500 Subject: [PATCH 36/41] updated py rtl gen scripts --- compiler/src/andGate.py | 20 +++++++++++--------- compiler/src/mainTcamMemTopWrapper.py | 3 +-- compiler/src/priorityEncoder.py | 14 ++++++++------ compiler/src/tcamMemBlock7x64.py | 8 +++++--- compiler/src/tcamMemTopWrapper.py | 24 +++++++++++++----------- 5 files changed, 38 insertions(+), 31 deletions(-) diff --git a/compiler/src/andGate.py b/compiler/src/andGate.py index b79aa4b..63f134e 100644 --- a/compiler/src/andGate.py +++ b/compiler/src/andGate.py @@ -3,6 +3,7 @@ """ import logging +import os from migen import * from migen.fhdl.verilog import convert @@ -17,19 +18,19 @@ class andGate(Module): """ # * ----------------------------------------------------------------- Variables - def __init__(self, ports, dataWidth): + def __init__(self, inputPorts, dataWidth): """ Constructor: call IO ports and logic here **Public Variables:** :param list inputs list containing objects for all input ports. :param list outputs list containing objects for all output ports. - :param int ports: number of input ports. + :param int inputPorts: number of input ports. :param int dataWidth: width of input ports. :return str verilogCode: store RTL code of the gate. """ # * variables - self.numInputs = ports + self.numInputs = inputPorts self.numInputWidth = dataWidth self.verilogCode = "" @@ -64,23 +65,23 @@ def logicBlock(self): # ======================================== End Class ======================================== # =========================================================================================== -def genVerilogAndGate(ports, dataWidth, filePath): +def genVerilogAndGate(inputPorts, dataWidth, filePath): """ Main user function for class andGate. Creates the IO ports for the verilog RTL module definition. Generates the verilog code for an AND gate with N inputs each input M bits wide. The output is M bits wide. - :param int ports: number of input ports. + :param int inputPorts: number of input ports. :param int dataWidth: width of input ports. :param str filePath: absolute path for the verilog file. :return str: RTL code of the gate. """ # * instantiate the module - gate = andGate(ports=ports, dataWidth=dataWidth) + gate = andGate(inputPorts=inputPorts, dataWidth=dataWidth) # * ----- setup the IO ports for the verilog module definition # * input port set - inPortsSet = {gate.inputs[i] for i in range(ports)} + inPortsSet = {gate.inputs[i] for i in range(inputPorts)} # * output port set outPortsSet = {gate.outputs} # * combine input and output sets @@ -88,12 +89,13 @@ def genVerilogAndGate(ports, dataWidth, filePath): logging.info('Generated AND gate verilog module definition') # * generate the verilog code - gate.verilogCode = convert(gate, name='andGate', ios=moduleIOs) + moduleName = os.path.basename(filePath).replace('.sv', '') + gate.verilogCode = convert(gate, name=moduleName, ios=moduleIOs) logging.info('Generated AND gate verilog module RTL') # * write verilog code to a file with open(filePath, 'w', encoding='utf-8') as rtl: rtl.write(str(gate.verilogCode)) - logging.info('Created rtl file {:s}'.format(filePath)) + logging.info('Created rtl file "{:s}"'.format(filePath)) return str(gate.verilogCode) diff --git a/compiler/src/mainTcamMemTopWrapper.py b/compiler/src/mainTcamMemTopWrapper.py index cce54cb..bfdbbe4 100644 --- a/compiler/src/mainTcamMemTopWrapper.py +++ b/compiler/src/mainTcamMemTopWrapper.py @@ -65,9 +65,8 @@ def main(): if arg.tcamConfig: memLength=int(arg.tcamConfig[5:7]) memWidth=int(arg.tcamConfig[8:10]) - print(memLength, memWidth, memWidth%7, memWidth/7) if (memLength == 64) and (memWidth%7 == 0): - print('"VALID" TCAM memory wrapper config. tcam_[64]x[7*N] == {:s}'.format(arg.tcamConfig)) + print('"VALID" TCAM memory wrapper config. tcam_[64]x[7*N] == {:s}\n'.format(arg.tcamConfig)) logging.info('"VALID" TCAM memory wrapper config. tcam_[64]x[7*N] == {:s}'.format(arg.tcamConfig)) logging.info('Total TCAM memory 64x7 blocks required: {:d}'.format(int(memWidth/7))) # * create rtl dir for specific tcam mem wrap config diff --git a/compiler/src/priorityEncoder.py b/compiler/src/priorityEncoder.py index 85f46a7..623f431 100644 --- a/compiler/src/priorityEncoder.py +++ b/compiler/src/priorityEncoder.py @@ -5,6 +5,7 @@ import logging import math import sys +import os from migen import * from migen.fhdl.verilog import convert @@ -18,7 +19,7 @@ class priorityEncoder(Module): """ # * ----------------------------------------------------------------- Functions - def __init__(self, ports): + def __init__(self, inDataWidth): """ Constructor: call IO ports and logic here @@ -29,7 +30,7 @@ def __init__(self, ports): :return str verilogCode: store RTL code of the encoder. """ # * variables - self.inputWidth = ports + self.inputWidth = inDataWidth self.outputWidth = 0 self.verilogCode = '' @@ -82,7 +83,7 @@ def logicBlock(self): # ======================================== End Class ======================================== # =========================================================================================== -def genVerilogPriorityEncoder(ports, filePath): +def genVerilogPriorityEncoder(inDataWidth, filePath): """ Main user function for class priorityEncoder. Creates the IO ports for the verilog RTL module definition. @@ -93,7 +94,7 @@ def genVerilogPriorityEncoder(ports, filePath): :return str: RTL code of the encoder. """ # * instantiate the module - encoder = priorityEncoder(ports=ports) + encoder = priorityEncoder(inDataWidth=inDataWidth) # * ----- setup the IO ports for the verilog module definition # * input port set @@ -105,12 +106,13 @@ def genVerilogPriorityEncoder(ports, filePath): logging.info('Generated Priority Encoder verilog module definition') # * generate the verilog code - encoder.verilogCode = convert(encoder, name='priorityEncoder', ios=moduleIOs) + moduleName = os.path.basename(filePath).replace('.sv', '') + encoder.verilogCode = convert(encoder, name=moduleName, ios=moduleIOs) logging.info('Generated Priority Encoder verilog module RTL') # * write verilog code to a file with open(filePath, 'w', encoding='utf-8') as rtl: rtl.write(str(encoder.verilogCode)) - logging.info('Created rtl file {:s}'.format(filePath)) + logging.info('Created rtl file "{:s}"'.format(filePath)) return str(encoder.verilogCode) diff --git a/compiler/src/tcamMemBlock7x64.py b/compiler/src/tcamMemBlock7x64.py index 988a24f..f16b66e 100644 --- a/compiler/src/tcamMemBlock7x64.py +++ b/compiler/src/tcamMemBlock7x64.py @@ -3,6 +3,7 @@ """ import logging +import os from migen import * from migen.fhdl.verilog import convert @@ -117,7 +118,7 @@ def logicBlock(self): # ======================================== End Class ======================================== # =========================================================================================== -def genVerilogtcamMemBlock7x64(filePath): +def genVerilogTcamMemBlock7x64(filePath): """ Main user function for class tcamMemBlock7x64. Creates the IO ports for the verilog RTL module definition. @@ -138,12 +139,13 @@ def genVerilogtcamMemBlock7x64(filePath): moduleIOs = inPortsSet.union(outPortsSet) # * generate the verilog code - tcamMem.verilogCode = convert(tcamMem, name='tcamMemBlock7x64', ios=moduleIOs) + moduleName = os.path.basename(filePath).replace('.sv', '') + tcamMem.verilogCode = convert(tcamMem, name=moduleName, ios=moduleIOs) logging.info('Generated TCAM Memory 7x64 verilog module RTL') # * write verilog code to a file with open(filePath, 'w', encoding='utf-8') as rtl: rtl.write(str(tcamMem.verilogCode)) - logging.info('Created rtl file {:s}'.format(filePath)) + logging.info('Created rtl file "{:s}"'.format(filePath)) return str(tcamMem.verilogCode) \ No newline at end of file diff --git a/compiler/src/tcamMemTopWrapper.py b/compiler/src/tcamMemTopWrapper.py index 27c059f..b931f9d 100644 --- a/compiler/src/tcamMemTopWrapper.py +++ b/compiler/src/tcamMemTopWrapper.py @@ -4,6 +4,7 @@ import logging import math +import os from migen import * from migen.fhdl.verilog import convert @@ -124,7 +125,7 @@ def logicBlock(self): # * ----- generating address mux for all N blocks (selects between read or write addresses) for i in range(self.memBlocks): # * setup wire - tempVtbAddr = Signal(7, name_override='vtb_addr{:d}'.format(i)) + tempVtbAddr = Signal(8, name_override='vtb_addr{:d}'.format(i)) self.__vtbAddrList.append(tempVtbAddr) logging.info('Created wire {:s}[{:d}:0]'.format(self.__vtbAddrList[i].name_override, self.__vtbAddrList[i].nbits-1)) # * combinational logic for address mux @@ -145,7 +146,7 @@ def logicBlock(self): # * tcam memory block 7x64 instantiations dutName = 'tcam_mem_7x64_dut{:d}'.format(i) self.specials += Instance( - of='tcamMemBlock7x64', + of='tcam_mem_7x64', name=dutName, i_in_clk=self.inClk, i_in_csb=self.inCsb, @@ -168,23 +169,23 @@ def logicBlock(self): self.specials += Instance( of='and_gate', name=dutName, - i_in_dataA=self.__outRdataList[i], # out_rdata0 - i_in_dataB=self.__outRdataList[i+1], # out_rdata1 - o_out_data=self.__outAndGateList[i] # out_gate0 + i_in_data0=self.__outRdataList[i], + i_in_data1=self.__outRdataList[i+1], + o_out_data=self.__outAndGateList[i] ) else: self.specials += Instance( of='and_gate', name=dutName, - i_in_dataA=self.__outRdataList[i+1], # out_rdata2 - i_in_dataB=self.__outAndGateList[i-1], # out_gate0 - o_out_gate=self.__outAndGateList[i] # out_gate1 + i_in_data0=self.__outRdataList[i+1], + i_in_data1=self.__outAndGateList[i-1], + o_out_data=self.__outAndGateList[i] ) logging.info('Created instance "{:s}" of module "tcamMemBlock7x64"'.format(dutName)) # * ------ Priority encoder instantiations self.specials += Instance( - of='priority_encoder', + of='priority_encoder_64x6', name='priority_encoder_dut0', i_in_data=self.__outAndGateList[-1], o_out_data=self.outputs[0] @@ -217,12 +218,13 @@ def genVerilogTcamMemTopWrapper(memBlocks, filePath): moduleIOs = inPortsSet.union(outPortsSet) # * generate the verilog code - tcamMemTop.verilogCode = convert(tcamMemTop, name='tcamMemBlock7x64', ios=moduleIOs) + moduleName = os.path.basename(filePath).replace('.sv', '') + tcamMemTop.verilogCode = convert(tcamMemTop, name=moduleName, ios=moduleIOs) logging.info('Generated TCAM Memory Top Wrapper verilog module RTL') # * write verilog code to a file with open(filePath, 'w', encoding='utf-8') as rtl: rtl.write(str(tcamMemTop.verilogCode)) - logging.info('Created rtl file {:s}'.format(filePath)) + logging.info('Created rtl file "{:s}"'.format(filePath)) return str(tcamMemTop.verilogCode) \ No newline at end of file From c8ee2d55073c9c29efbbe8ef6b17abf0bf037857 Mon Sep 17 00:00:00 2001 From: usman1515 Date: Sun, 5 Mar 2023 03:27:45 +0500 Subject: [PATCH 37/41] formatted various rtl gen py classes using pylint --- compiler/src/andGate.py | 15 ++++--- compiler/src/mainTcamMemTopWrapper.py | 55 +++++++++++------------ compiler/src/mainTcamRTLGenerator.py | 12 ++--- compiler/src/priorityEncoder.py | 22 ++++----- compiler/src/tcamMemBlock7x64.py | 54 +++++++++++----------- compiler/src/tcamMemTopWrapper.py | 64 +++++++++++++-------------- 6 files changed, 111 insertions(+), 111 deletions(-) diff --git a/compiler/src/andGate.py b/compiler/src/andGate.py index 63f134e..f8b890b 100644 --- a/compiler/src/andGate.py +++ b/compiler/src/andGate.py @@ -11,7 +11,7 @@ # ======================================= Begin Class ======================================= # =========================================================================================== -class andGate(Module): +class AndGate(Module): """ Generates the verilog code for an AND gate with N inputs each input M bits wide. The output is M bits wide. @@ -48,15 +48,16 @@ def ioPorts(self): Create a list of Signal objects for N input ports each of width M. Create a Signal object for an output port of width M. """ for port in range(self.numInputs): - tempPort = Signal(self.numInputWidth, name_override='in_data{}'.format(port)) + tempPort = Signal(self.numInputWidth, name_override=f"in_data{port}") self.inputs.append(tempPort) - logging.info('Created AND gate input port: {:>s}{:d}[{:d}:0]'.format('in_data', port, self.numInputWidth-1)) + logging.info('Created AND gate input port: in_data%d[%d:%d]', port, self.numInputWidth-1, 0) self.outputs = Signal(self.numInputWidth, name_override='out_data') - logging.info('Created AND gate output port: {:>s}[{:d}:0]'.format('out_data', self.numInputWidth-1)) + logging.info('Created AND gate output port: out_data%d[%d:%d]', port, self.numInputWidth-1, 0) def logicBlock(self): """ - Setup the combinatorial logic for creating an AND gate using migen. Using the reduce() function to combine all input signals into a single output signal. + Setup the combinatorial logic for creating an AND gate using migen. + Using the reduce() function to combine all input signals into a single output signal. """ self.comb += self.outputs.eq(reduce(lambda x, y: x & y, self.inputs)) logging.info('Generated AND gate logic') @@ -77,7 +78,7 @@ def genVerilogAndGate(inputPorts, dataWidth, filePath): :return str: RTL code of the gate. """ # * instantiate the module - gate = andGate(inputPorts=inputPorts, dataWidth=dataWidth) + gate = AndGate(inputPorts=inputPorts, dataWidth=dataWidth) # * ----- setup the IO ports for the verilog module definition # * input port set @@ -96,6 +97,6 @@ def genVerilogAndGate(inputPorts, dataWidth, filePath): # * write verilog code to a file with open(filePath, 'w', encoding='utf-8') as rtl: rtl.write(str(gate.verilogCode)) - logging.info('Created rtl file "{:s}"'.format(filePath)) + logging.info('Created rtl file "%s"', filePath) return str(gate.verilogCode) diff --git a/compiler/src/mainTcamMemTopWrapper.py b/compiler/src/mainTcamMemTopWrapper.py index bfdbbe4..09f1f55 100644 --- a/compiler/src/mainTcamMemTopWrapper.py +++ b/compiler/src/mainTcamMemTopWrapper.py @@ -10,14 +10,13 @@ import shutil import logging import argparse -os.system('clear') +# os.system('clear') def main(): """ - _summary_ + main func for implementing py class TcamMemTopWrapper """ - # * ----- variables pwd = os.getcwd() logsDirPath = '' @@ -29,9 +28,9 @@ def main(): pathSram1kb = 'compiler/lib/tcam_block_rtl/sky130_sram_1kbyte_1rw1r_32x256_8.sv' # create logs dir if it doesn't exist - logsDirPath = os.path.join(pwd, "logs") + logsDirPath = os.path.join(pwd, 'logs') if os.path.exists(logsDirPath) is False: - os.makedirs("logs") + os.makedirs('logs') # create rtl dir if it doesn't exist tcamRtlDirPath = os.path.join(pwd, 'tcam_mem_rtl') if os.path.exists(tcamRtlDirPath) is False: @@ -39,24 +38,24 @@ def main(): # logging config logging.basicConfig( level=logging.DEBUG, - filename="./logs/tcamMemoryWrapper.log", + filename='./logs/tcamMemoryWrapper.log', format="%(asctime)s | %(filename)s | %(funcName)s | %(levelname)s | %(lineno)d | %(message)s", ) # set arguments for OpenTCAM RTL memory generator parser = argparse.ArgumentParser( - prog="OpenTCAM ", - usage="%(prog)s [options] path", - description="TCAM memory generator", - epilog="Python framework for generating configurable SRAM based TCAM memories", + prog='OpenTCAM', + usage='%(prog)s [options] path', + description='TCAM memory generator', + epilog='Python framework for generating configurable SRAM based TCAM memories', ) # list of all possible args for OpenTCAM - parser.add_argument('-conf','--tcamConfig', - type=str,default='tcam_64x28',metavar='',required=True,nargs='?',help='name of specific TCAM mem wrapper config') - parser.add_argument('-d','--debug', - type=int,default=0,metavar='',required=False,nargs='?',help='print debugging mode') + parser.add_argument('-conf', '--tcamConfig', + type=str, default='tcam_64x28', metavar='', required=True, nargs='?', help='name of specific TCAM mem wrapper config') + parser.add_argument('-d', '--debug', + type=int, default=0, metavar='', required=False, nargs='?', help='print debugging mode') parser.add_argument('-v','--verbose', - type=int,default=0,metavar='',required=False,nargs='?',help='print verbose mode') + type=int, default=0, metavar='', required=False, nargs='?', help='print verbose mode') arg = parser.parse_args() # ====================================================== code main body @@ -66,48 +65,48 @@ def main(): memLength=int(arg.tcamConfig[5:7]) memWidth=int(arg.tcamConfig[8:10]) if (memLength == 64) and (memWidth%7 == 0): - print('"VALID" TCAM memory wrapper config. tcam_[64]x[7*N] == {:s}\n'.format(arg.tcamConfig)) - logging.info('"VALID" TCAM memory wrapper config. tcam_[64]x[7*N] == {:s}'.format(arg.tcamConfig)) - logging.info('Total TCAM memory 64x7 blocks required: {:d}'.format(int(memWidth/7))) + print('"VALID" TCAM memory wrapper config. tcam_[64]x[7*N] == %s\n', arg.tcamConfig) + logging.info('"VALID" TCAM memory wrapper config. tcam_[64]x[7*N] == %s', arg.tcamConfig) + logging.info('Total TCAM memory 64x7 blocks required: %d', int(memWidth/7)) # * create rtl dir for specific tcam mem wrap config tcamRtlConfigDirPath = os.path.join(tcamRtlDirPath, arg.tcamConfig) if os.path.exists(tcamRtlConfigDirPath): shutil.rmtree(tcamRtlConfigDirPath) os.makedirs(tcamRtlConfigDirPath) - logging.info('Created TCAM memory RTL dir: {:s}'.format(tcamRtlConfigDirPath)) + logging.info('Created TCAM memory RTL dir: %s', tcamRtlConfigDirPath) # * copy sky130 block to required config dir shutil.copy(pathSram1kb, tcamRtlConfigDirPath) - logging.info('Copied file "{:s}" to dir "{:s}"'.format(pathSram1kb, tcamRtlConfigDirPath)) - print('Copied rtl file "{:s}" to dir "{:s}"'.format(os.path.basename(pathSram1kb), tcamRtlConfigDirPath)) + logging.info('Copied file "%s" to dir "%s"', pathSram1kb, tcamRtlConfigDirPath) + print('Copied rtl file "%s" to dir "%s"', os.path.basename(pathSram1kb), tcamRtlConfigDirPath) # * generate verilog for TCAM memory MxN top wrapper fileName = 'top_tcam_mem_' + str(memLength) + 'x' + str(memWidth) + '.sv' rtlFilePath = os.path.join(tcamRtlConfigDirPath, fileName) codeTcamMemTopWrapper = genVerilogTcamMemTopWrapper(memBlocks=int(memWidth/7), filePath=rtlFilePath) - print('Created rtl file: "{:s}"'.format(rtlFilePath)) + print('Created rtl file: "%s"', rtlFilePath) if arg.debug: print(codeTcamMemTopWrapper) # * generate verilog for TCAM memory block 7x64 rtlFilePath = os.path.join(tcamRtlConfigDirPath, 'tcam_mem_7x64.sv') codeTcamMemBlock7x64 = genVerilogTcamMemBlock7x64(filePath=rtlFilePath) - print('Created rtl file: "{:s}"'.format(rtlFilePath)) + print('Created rtl file: "%s"', rtlFilePath) if arg.debug: print(codeTcamMemBlock7x64) # * generate verilog for andgate rtlFilePath = os.path.join(tcamRtlConfigDirPath, 'and_gate.sv') codeAndGate = genVerilogAndGate(inputPorts=2, dataWidth=64, filePath=rtlFilePath) - print('Created rtl file: "{:s}"'.format(rtlFilePath)) + print('Created rtl file: "%s"', rtlFilePath) if arg.debug: print(codeAndGate) # * generate verilog for priority encoder rtlFilePath = os.path.join(tcamRtlConfigDirPath, 'priority_encoder_64x6.sv') codePriorityEncoder = genVerilogPriorityEncoder(inDataWidth=64, filePath=rtlFilePath) - print('Created rtl file: "{:s}"'.format(rtlFilePath)) + print('Created rtl file: "%s"', rtlFilePath) if arg.debug: print(codePriorityEncoder) else: - logging.info('"INVALID" TCAM memory wrapper config. tcam_[64]x[7*N] != {:s}'.format(arg.tcamConfig)) - sys.exit('"INVALID" TCAM memory wrapper config. tcam_[64]x[7*N] != {:s}'.format(arg.tcamConfig)) + logging.info('"INVALID" TCAM memory wrapper config. tcam_[64]x[7*N] != %s', arg.tcamConfig) + sys.exit('"INVALID" TCAM memory wrapper config. tcam_[64]x[7*N] != %s', arg.tcamConfig) if __name__ == '__main__': - main() \ No newline at end of file + main() diff --git a/compiler/src/mainTcamRTLGenerator.py b/compiler/src/mainTcamRTLGenerator.py index 3302e58..2087037 100644 --- a/compiler/src/mainTcamRTLGenerator.py +++ b/compiler/src/mainTcamRTLGenerator.py @@ -1,7 +1,7 @@ -from tcamRtlGenerator import * +from tcamRtlGenerator import * import argparse import os -os.system('clear') +# os.system('clear') def new_main(): # create logs dir if it doesnt exist @@ -32,12 +32,12 @@ def new_main(): parser.add_argument('-v','--verbose', type=int,default=0,metavar='',required=False,nargs='?',help='print verbose mode') arg = parser.parse_args() - - # ====================================================== code main body - + + # ====================================================== code main body + # class objects trwg1=TcamRtlWrapperGenerator() - + # get project dir trwg1.getPrjDir(arg.verbose) # get tcam table config yaml file path diff --git a/compiler/src/priorityEncoder.py b/compiler/src/priorityEncoder.py index 623f431..d905ee0 100644 --- a/compiler/src/priorityEncoder.py +++ b/compiler/src/priorityEncoder.py @@ -13,7 +13,7 @@ # ======================================= Begin Class ======================================= # =========================================================================================== -class priorityEncoder(Module): +class PriorityEncoder(Module): """ Generates the verilog code for a Priority Encoder with N-bit input and log2(N) bit output. """ @@ -49,19 +49,19 @@ def ioPorts(self): """ # * check if input port width is of 2^N if math.floor(math.log2(self.inputWidth)) == math.ceil(math.log2(self.inputWidth)): - logging.info('"VALID": priority encoder input width {:d} is of 2^N'.format(self.inputWidth)) + logging.info('"VALID": priority encoder input width %d is of 2^N', self.inputWidth) # * set output port width of log2(N) self.outputWidth = int(math.log2(self.inputWidth)) - logging.info('priority encoder output width: {:d}'.format(self.outputWidth)) + logging.info('priority encoder output width: %d', self.outputWidth) # * create IO port objects self.inputs = Signal(self.inputWidth, name_override='in_data') - logging.info('Created priority encoder input port: {:>s}[{:d}:0]'.format('in_data', self.inputWidth-1)) + logging.info('Created priority encoder input port: in_data[%d:0]', self.inputWidth-1) self.outputs = Signal(self.outputWidth, name_override='out_data') - logging.info('Created priority encoder output port: {:>s}[{:d}:0]'.format('out_data', self.outputWidth-1)) + logging.info('Created priority encoder output port: out_data[%d:0]', self.outputWidth-1) else: print('num isnt 2^N', type(self.inputWidth)) - logging.error('"INVALID": priority encoder input width {:d} isnt of 2^N'.format(self.inputWidth)) - sys.exit('"INVALID": priority encoder input width {:d} isnt of 2^N'.format(self.inputWidth)) + logging.error('"INVALID": priority encoder input width %d isnt of 2^N', self.inputWidth) + sys.exit('"INVALID": priority encoder input width %d isnt of 2^N', self.inputWidth) def logicBlock(self): """ @@ -75,7 +75,7 @@ def logicBlock(self): oneHotEncode = bin(pow(2,i)) # * add ith priority case priorityCases[int(oneHotEncode, 2)] = self.outputs.eq(i) - logging.info('Created priority case for {:3d} input bit'.format(i)) + logging.info('Created priority case for %3d input bit', i) # * concat using case self.comb += Case(self.inputs, priorityCases) @@ -85,7 +85,7 @@ def logicBlock(self): def genVerilogPriorityEncoder(inDataWidth, filePath): """ - Main user function for class priorityEncoder. + Main user function for class PriorityEncoder. Creates the IO ports for the verilog RTL module definition. Generates the verilog code for a Priority Encoder with N-bit input and log2(N) bit output. @@ -94,7 +94,7 @@ def genVerilogPriorityEncoder(inDataWidth, filePath): :return str: RTL code of the encoder. """ # * instantiate the module - encoder = priorityEncoder(inDataWidth=inDataWidth) + encoder = PriorityEncoder(inDataWidth=inDataWidth) # * ----- setup the IO ports for the verilog module definition # * input port set @@ -113,6 +113,6 @@ def genVerilogPriorityEncoder(inDataWidth, filePath): # * write verilog code to a file with open(filePath, 'w', encoding='utf-8') as rtl: rtl.write(str(encoder.verilogCode)) - logging.info('Created rtl file "{:s}"'.format(filePath)) + logging.info('Created rtl file "%s"', filePath) return str(encoder.verilogCode) diff --git a/compiler/src/tcamMemBlock7x64.py b/compiler/src/tcamMemBlock7x64.py index f16b66e..605e0d7 100644 --- a/compiler/src/tcamMemBlock7x64.py +++ b/compiler/src/tcamMemBlock7x64.py @@ -11,7 +11,7 @@ # ======================================= Begin Class ======================================= # =========================================================================================== -class tcamMemBlock7x64(Module): +class TcamMemBlock7x64(Module): """ Generates the verilog code for a TCAM 7x64 memory block. """ @@ -46,23 +46,23 @@ def ioPorts(self): """ # * setup input ports self.inClk = Signal(1, name_override='in_clk') - logging.info('Created tcamMemBlock7x64 input port: {:>s}'.format(self.inClk.name_override)) + logging.info('Created TcamMemBlock7x64 input port: %s', self.inClk.name_override) self.inCsb = Signal(1, name_override='in_csb') - logging.info('Created tcamMemBlock7x64 input port: {:>s}'.format(self.inCsb.name_override)) + logging.info('Created TcamMemBlock7x64 input port: %s', self.inCsb.name_override) self.inWeb = Signal(1, name_override='in_web') - logging.info('Created tcamMemBlock7x64 input port: {:>s}'.format(self.inWeb.name_override)) + logging.info('Created TcamMemBlock7x64 input port: %s', self.inWeb.name_override) self.inWmask = Signal(4, name_override='in_wmask') - logging.info('Created tcamMemBlock7x64 input port: {:>s}[{:d}:0]'.format(self.inWmask.name_override, 4)) + logging.info('Created TcamMemBlock7x64 input port: %s[%d:0]', self.inWmask.name_override, 4) self.inAddr = Signal(8, name_override='in_addr') - logging.info('Created tcamMemBlock7x64 input port: {:>s}[{:d}:0]'.format(self.inAddr.name_override, 8)) + logging.info('Created TcamMemBlock7x64 input port: %s[%d:0]', self.inAddr.name_override, 8) self.inWdata = Signal(32, name_override='in_wdata') - logging.info('Created tcamMemBlock7x64 input port: {:>s}[{:d}:0]'.format(self.inWdata.name_override, 32)) + logging.info('Created TcamMemBlock7x64 input port: %s[%d:0]', self.inWdata.name_override, 32) # * add all input ports to an input list self.inputs = [self.inClk, self.inCsb, self.inWeb, self.inWmask, self.inAddr, self.inWdata] logging.info('Created list of all input ports') # * setup output ports self.outRdata = Signal(64, name_override='out_rdata') - logging.info('Created tcamMemBlock7x64 output port: {:>s}[{:d}:0]'.format(self.outRdata.name_override, 64)) + logging.info('Created TcamMemBlock7x64 output port: %s[%d:0]', self.outRdata.name_override, 64) # * add all output ports to an output list self.outputs = [self.outRdata] logging.info('Created list of all output ports') @@ -92,27 +92,27 @@ def logicBlock(self): self.comb += rdata.eq(Cat(rdataLower, rdataUpper)) self.comb += self.outRdata.eq(rdata) - logging.info('Created upper and lower potential matcha address logic') + logging.info('Created upper and lower potential match address logic') # * ----- instantiate the sky130 1KB RAM module as submodule self.specials += Instance( - of=self.__sramModule, # module name - name='dut_vtb', # instance name + of=self.__sramModule, + name='dut_vtb', # Port 0: RW - i_clk0=self.inClk, # input port (use i_) - i_csb0=self.inCsb, # input port (use i_) - i_web0=self.inWeb, # input port (use i_) - i_wmask0=self.inWmask, # input port (use i_) - i_addr0=Mux(self.inWeb, arAddr1, awAddr), # input port (use i_) - i_din0=self.inWdata, # input port (use i_) - o_dout0=rdataLower, # output port (use o_) + i_clk0=self.inClk, + i_csb0=self.inCsb, + i_web0=self.inWeb, + i_wmask0=self.inWmask, + i_addr0=Mux(self.inWeb, arAddr1, awAddr), + i_din0=self.inWdata, + o_dout0=rdataLower, # Port 1: R - i_clk1=self.inClk, # input port (use i_) - i_csb1=self.inCsb, # input port (use i_) - i_addr1=arAddr2, # input port (use i_) - o_dout1=rdataUpper # output port (use o_) + i_clk1=self.inClk, + i_csb1=self.inCsb, + i_addr1=arAddr2, + o_dout1=rdataUpper ) - logging.info('Instantiated {:s} module'.format(self.__sramModule)) + logging.info('Instantiated %s module', self.__sramModule) # =========================================================================================== # ======================================== End Class ======================================== @@ -120,7 +120,7 @@ def logicBlock(self): def genVerilogTcamMemBlock7x64(filePath): """ - Main user function for class tcamMemBlock7x64. + Main user function for class TcamMemBlock7x64. Creates the IO ports for the verilog RTL module definition. Generates the verilog code for a TCAM 7x64 memory block. @@ -128,7 +128,7 @@ def genVerilogTcamMemBlock7x64(filePath): :return str: RTL code of the TCAM 7x64 memory. """ # * instantiate the module - tcamMem = tcamMemBlock7x64() + tcamMem = TcamMemBlock7x64() # * ----- setup the IO ports for the verilog module definition # * input port set @@ -146,6 +146,6 @@ def genVerilogTcamMemBlock7x64(filePath): # * write verilog code to a file with open(filePath, 'w', encoding='utf-8') as rtl: rtl.write(str(tcamMem.verilogCode)) - logging.info('Created rtl file "{:s}"'.format(filePath)) + logging.info('Created rtl file "%s"', filePath) - return str(tcamMem.verilogCode) \ No newline at end of file + return str(tcamMem.verilogCode) diff --git a/compiler/src/tcamMemTopWrapper.py b/compiler/src/tcamMemTopWrapper.py index b931f9d..e692349 100644 --- a/compiler/src/tcamMemTopWrapper.py +++ b/compiler/src/tcamMemTopWrapper.py @@ -12,7 +12,7 @@ # ======================================= Begin Class ======================================= # =========================================================================================== -class tcamMemTopWrapper(Module): +class TcamMemTopWrapper(Module): """ Generates the verilog code for a TCAM memory block N*64 Wrapper. """ @@ -64,24 +64,24 @@ def ioPorts(self): self.inputs = {} # * setup input ports self.inClk = Signal(1, name_override='in_clk') - logging.info('Created tcamMemTopWrapper input port: {:>s}'.format(self.inClk.name_override)) + logging.info('Created TcamMemTopWrapper input port: %s', self.inClk.name_override) self.inCsb = Signal(1, name_override='in_csb') - logging.info('Created tcamMemTopWrapper input port: {:>s}'.format(self.inCsb.name_override)) + logging.info('Created TcamMemTopWrapper input port: %s', self.inCsb.name_override) self.inWeb = Signal(1, name_override='in_web') - logging.info('Created tcamMemTopWrapper input port: {:>s}'.format(self.inWeb.name_override)) + logging.info('Created TcamMemTopWrapper input port: %s', self.inWeb.name_override) self.inWmask = Signal(4, name_override='in_wmask') - logging.info('Created tcamMemTopWrapper input port: {:>s}[{:d}:0]'.format(self.inWmask.name_override, 3)) + logging.info('Created TcamMemTopWrapper input port: %s[%d:0]', self.inWmask.name_override, 3) self.__inAddrWidth = self.memBlocks * 7 self.inAddr = Signal(self.__inAddrWidth, name_override='in_addr') - logging.info('Created tcamMemTopWrapper input port: {:>s}[{:d}:0]'.format(self.inAddr.name_override, self.__inAddrWidth-1)) + logging.info('Created TcamMemTopWrapper input port: %s[%d:0]', self.inAddr.name_override, self.__inAddrWidth-1) self.inWdata = Signal(32, name_override='in_wdata') - logging.info('Created tcamMemTopWrapper input port: {:>s}[{:d}:0]'.format(self.inWdata.name_override, 31)) + logging.info('Created TcamMemTopWrapper input port: %s[%d:0]', self.inWdata.name_override, 31) # * add all input ports to an input list self.inputs = [self.inClk, self.inCsb, self.inWeb, self.inWmask, self.inAddr, self.inWdata] logging.info('Created list of all input ports') # * setup output ports self.outPma = Signal(6, name_override='out_pma') - logging.info('Created tcamMemTopWrapper output port: {:>s}[{:d}:0]'.format(self.outPma.name_override, 5)) + logging.info('Created TcamMemTopWrapper output port: %s[%d:0]', self.outPma.name_override, 5) # * add all output ports to an output list self.outputs = [self.outPma] logging.info('Created list of all output ports') @@ -93,58 +93,58 @@ def logicBlock(self): # * ----- memory block selection for write logic # * setup wire self.__blockSel = Signal(self.memBlocks, name_override='block_sel') - logging.info('Created wire {:s}[{:d}:0]'.format(self.__blockSel.name_override, self.__blockSel.nbits-1)) + logging.info('Created wire %s[%d:0]', self.__blockSel.name_override, self.__blockSel.nbits-1) # * calculate width for inAddr slice inAddrWidth = int(math.ceil(math.log2(self.memBlocks))) + 8 - logging.info('Calculated bit slice for signal in_addr[{:2d}:{:2d}]'.format(inAddrWidth, 8)) + logging.info('Calculated bit slice for signal in_addr[%d:%d]', inAddrWidth, 8) # * combinational logic for block sel for i in range(self.memBlocks): self.comb += self.__blockSel[i].eq(self.inAddr[8:inAddrWidth] == i) - logging.info('Created logic for signal {:s}[{:d}]'.format(self.__blockSel.name_override, i)) + logging.info('Created logic for signal %s[%d]', self.__blockSel.name_override, i) # * ----- generating logic for write mask for i in range(self.memBlocks): # * setup wire - tempWmask = Signal(4, name_override='wmask{:d}'.format(i)) + tempWmask = Signal(4, name_override=f"wmask{i}") self.__wMaskList.append(tempWmask) - logging.info('Created wire {:s}[{:d}:0]'.format(self.__wMaskList[i].name_override, self.__wMaskList[i].nbits-1)) + logging.info('Created wire %s[%d:0]', self.__wMaskList[i].name_override, self.__wMaskList[i].nbits-1) # * combinational logic for write mask self.comb += self.__wMaskList[i].eq(Replicate(self.__blockSel[i], 4) & self.inWmask) - logging.info('Created logic for signal {:s}'.format(self.__wMaskList[i].name_override)) + logging.info('Created logic for signal %s', self.__wMaskList[i].name_override) # * ----- generating logic for write addresses for i in range(self.memBlocks): # * setup wire - tempAwAddr = Signal(8, name_override='aw_addr{:d}'.format(i)) + tempAwAddr = Signal(8, name_override=f"aw_addr{i}") self.__awAddrList.append(tempAwAddr) - logging.info('Created wire {:s}[{:d}:0]'.format(self.__awAddrList[i].name_override, self.__awAddrList[i].nbits-1)) + logging.info('Created wire %s[%d:0]', self.__awAddrList[i].name_override, self.__awAddrList[i].nbits-1) # * combinational logic for write addresses self.comb += self.__awAddrList[i].eq(Replicate(self.__blockSel[i], 8) & self.inAddr[0:8]) - logging.info('Created logic for signal {:s}'.format(self.__awAddrList[i].name_override)) + logging.info('Created logic for signal %s', self.__awAddrList[i].name_override) # * ----- generating address mux for all N blocks (selects between read or write addresses) for i in range(self.memBlocks): # * setup wire - tempVtbAddr = Signal(8, name_override='vtb_addr{:d}'.format(i)) + tempVtbAddr = Signal(8, name_override=f"vtb_addr{i}") self.__vtbAddrList.append(tempVtbAddr) - logging.info('Created wire {:s}[{:d}:0]'.format(self.__vtbAddrList[i].name_override, self.__vtbAddrList[i].nbits-1)) + logging.info('Created wire %s[%d:0]', self.__vtbAddrList[i].name_override, self.__vtbAddrList[i].nbits-1) # * combinational logic for address mux self.comb += If(self.inWeb, self.__vtbAddrList[i].eq(Cat(self.inAddr[i*7 : (i*7)+7], 0b0)), ).Else( self.__vtbAddrList[i].eq(self.__awAddrList[i]) ) - logging.info('Created logic for signal {:s}'.format(self.__vtbAddrList[i].name_override)) + logging.info('Created logic for signal %s', self.__vtbAddrList[i].name_override) # * ----- adding TCAM memory block instances # * setup rdata output signals for i in range(self.memBlocks): - tempRdata = Signal(64, name_override='out_rdata{:d}'.format(i)) + tempRdata = Signal(64, name_override=f"out_rdata{i}") self.__outRdataList.append(tempRdata) - logging.info('Created wire {:s}[{:d}:0]'.format(self.__outRdataList[i].name_override, self.__outRdataList[i].nbits-1)) + logging.info('Created wire %s[%d:0]', self.__outRdataList[i].name_override, self.__outRdataList[i].nbits-1) # * tcam memory block 7x64 instantiations - dutName = 'tcam_mem_7x64_dut{:d}'.format(i) + dutName = f"tcam_mem_7x64_dut{i}" self.specials += Instance( of='tcam_mem_7x64', name=dutName, @@ -156,15 +156,15 @@ def logicBlock(self): i_in_wdata=self.inWdata, o_out_rdata=self.__outRdataList[i] ) - logging.info('Created instance "{:s}" of module "tcamMemBlock7x64"'.format(dutName)) + logging.info('Created instance "%s" of module "tcamMemBlock7x64"', dutName) # * ------ AND gate instantiations for i in range(self.memBlocks-1): # * setup AND gate output signals - tempOutAndGate = Signal(64, name_override='out_andgate{:d}'.format(i)) + tempOutAndGate = Signal(64, name_override=f"out_andgate{i}") self.__outAndGateList.append(tempOutAndGate) - logging.info('Created wire {:s}[{:d}:0]'.format(self.__outAndGateList[i].name_override, self.__outAndGateList[i].nbits-1)) - dutName = 'and_gate_dut{:d}'.format(i) + logging.info('Created wire %s[%d:0]', self.__outAndGateList[i].name_override, self.__outAndGateList[i].nbits-1) + dutName = f"and_gate_dut{i}" if i == 0: self.specials += Instance( of='and_gate', @@ -181,7 +181,7 @@ def logicBlock(self): i_in_data1=self.__outAndGateList[i-1], o_out_data=self.__outAndGateList[i] ) - logging.info('Created instance "{:s}" of module "tcamMemBlock7x64"'.format(dutName)) + logging.info('Created instance "%s" of module "tcamMemBlock7x64"', dutName) # * ------ Priority encoder instantiations self.specials += Instance( @@ -198,7 +198,7 @@ def logicBlock(self): def genVerilogTcamMemTopWrapper(memBlocks, filePath): """ - Main user function for class tcamMemTopWrapper. + Main user function for class TcamMemTopWrapper. Creates the IO ports for the verilog RTL module definition. Generates the verilog code for a TCAM Mx64 memory block wrapper. @@ -207,7 +207,7 @@ def genVerilogTcamMemTopWrapper(memBlocks, filePath): :return str: RTL code of the TCAM 7x64 memory. """ # * instantiate the module - tcamMemTop = tcamMemTopWrapper(memBlocks) + tcamMemTop = TcamMemTopWrapper(memBlocks) # * ----- setup the IO ports for the verilog module definition # * input port set @@ -225,6 +225,6 @@ def genVerilogTcamMemTopWrapper(memBlocks, filePath): # * write verilog code to a file with open(filePath, 'w', encoding='utf-8') as rtl: rtl.write(str(tcamMemTop.verilogCode)) - logging.info('Created rtl file "{:s}"'.format(filePath)) + logging.info('Created rtl file "%s"', filePath) - return str(tcamMemTop.verilogCode) \ No newline at end of file + return str(tcamMemTop.verilogCode) From c2bb447068026205402125d25edcd3922e2ab120 Mon Sep 17 00:00:00 2001 From: usman1515 Date: Sun, 5 Mar 2023 03:35:18 +0500 Subject: [PATCH 38/41] formatted various rtl gen py classes using isort, black --- compiler/src/andGate.py | 20 +++-- compiler/src/mainTcamMemTopWrapper.py | 73 +++++++++--------- compiler/src/priorityEncoder.py | 32 ++++---- compiler/src/tcamMemBlock7x64.py | 70 +++++++++--------- compiler/src/tcamMemTopWrapper.py | 102 +++++++++++++------------- 5 files changed, 154 insertions(+), 143 deletions(-) diff --git a/compiler/src/andGate.py b/compiler/src/andGate.py index f8b890b..d1e2b71 100644 --- a/compiler/src/andGate.py +++ b/compiler/src/andGate.py @@ -4,6 +4,7 @@ import logging import os + from migen import * from migen.fhdl.verilog import convert @@ -11,6 +12,7 @@ # ======================================= Begin Class ======================================= # =========================================================================================== + class AndGate(Module): """ Generates the verilog code for an AND gate with N inputs each input M bits wide. @@ -50,9 +52,9 @@ def ioPorts(self): for port in range(self.numInputs): tempPort = Signal(self.numInputWidth, name_override=f"in_data{port}") self.inputs.append(tempPort) - logging.info('Created AND gate input port: in_data%d[%d:%d]', port, self.numInputWidth-1, 0) - self.outputs = Signal(self.numInputWidth, name_override='out_data') - logging.info('Created AND gate output port: out_data%d[%d:%d]', port, self.numInputWidth-1, 0) + logging.info("Created AND gate input port: in_data%d[%d:%d]", port, self.numInputWidth - 1, 0) + self.outputs = Signal(self.numInputWidth, name_override="out_data") + logging.info("Created AND gate output port: out_data%d[%d:%d]", port, self.numInputWidth - 1, 0) def logicBlock(self): """ @@ -60,12 +62,14 @@ def logicBlock(self): Using the reduce() function to combine all input signals into a single output signal. """ self.comb += self.outputs.eq(reduce(lambda x, y: x & y, self.inputs)) - logging.info('Generated AND gate logic') + logging.info("Generated AND gate logic") + # =========================================================================================== # ======================================== End Class ======================================== # =========================================================================================== + def genVerilogAndGate(inputPorts, dataWidth, filePath): """ Main user function for class andGate. @@ -87,15 +91,15 @@ def genVerilogAndGate(inputPorts, dataWidth, filePath): outPortsSet = {gate.outputs} # * combine input and output sets moduleIOs = inPortsSet.union(outPortsSet) - logging.info('Generated AND gate verilog module definition') + logging.info("Generated AND gate verilog module definition") # * generate the verilog code - moduleName = os.path.basename(filePath).replace('.sv', '') + moduleName = os.path.basename(filePath).replace(".sv", "") gate.verilogCode = convert(gate, name=moduleName, ios=moduleIOs) - logging.info('Generated AND gate verilog module RTL') + logging.info("Generated AND gate verilog module RTL") # * write verilog code to a file - with open(filePath, 'w', encoding='utf-8') as rtl: + with open(filePath, "w", encoding="utf-8") as rtl: rtl.write(str(gate.verilogCode)) logging.info('Created rtl file "%s"', filePath) diff --git a/compiler/src/mainTcamMemTopWrapper.py b/compiler/src/mainTcamMemTopWrapper.py index 09f1f55..c6cff3e 100644 --- a/compiler/src/mainTcamMemTopWrapper.py +++ b/compiler/src/mainTcamMemTopWrapper.py @@ -1,16 +1,16 @@ """ List of all pip packages imported """ +import argparse +import logging +import os +import shutil +import sys + from andGate import * from priorityEncoder import * from tcamMemBlock7x64 import * from tcamMemTopWrapper import * -import os -import sys -import shutil -import logging -import argparse -# os.system('clear') def main(): @@ -19,86 +19,85 @@ def main(): """ # * ----- variables pwd = os.getcwd() - logsDirPath = '' - tcamRtlDirPath = '' - tcamRtlConfigDirPath = '' - rtlFilePath = '' + logsDirPath = "" + tcamRtlDirPath = "" + tcamRtlConfigDirPath = "" + rtlFilePath = "" memLength = 0 memWidth = 0 - pathSram1kb = 'compiler/lib/tcam_block_rtl/sky130_sram_1kbyte_1rw1r_32x256_8.sv' + pathSram1kb = "compiler/lib/tcam_block_rtl/sky130_sram_1kbyte_1rw1r_32x256_8.sv" # create logs dir if it doesn't exist - logsDirPath = os.path.join(pwd, 'logs') + logsDirPath = os.path.join(pwd, "logs") if os.path.exists(logsDirPath) is False: - os.makedirs('logs') + os.makedirs("logs") # create rtl dir if it doesn't exist - tcamRtlDirPath = os.path.join(pwd, 'tcam_mem_rtl') + tcamRtlDirPath = os.path.join(pwd, "tcam_mem_rtl") if os.path.exists(tcamRtlDirPath) is False: - os.makedirs('tcam_mem_rtl') + os.makedirs("tcam_mem_rtl") # logging config logging.basicConfig( level=logging.DEBUG, - filename='./logs/tcamMemoryWrapper.log', + filename="./logs/tcamMemoryWrapper.log", format="%(asctime)s | %(filename)s | %(funcName)s | %(levelname)s | %(lineno)d | %(message)s", ) # set arguments for OpenTCAM RTL memory generator parser = argparse.ArgumentParser( - prog='OpenTCAM', - usage='%(prog)s [options] path', - description='TCAM memory generator', - epilog='Python framework for generating configurable SRAM based TCAM memories', + prog="OpenTCAM", + usage="%(prog)s [options] path", + description="TCAM memory generator", + epilog="Python framework for generating configurable SRAM based TCAM memories", ) # list of all possible args for OpenTCAM - parser.add_argument('-conf', '--tcamConfig', - type=str, default='tcam_64x28', metavar='', required=True, nargs='?', help='name of specific TCAM mem wrapper config') - parser.add_argument('-d', '--debug', - type=int, default=0, metavar='', required=False, nargs='?', help='print debugging mode') - parser.add_argument('-v','--verbose', - type=int, default=0, metavar='', required=False, nargs='?', help='print verbose mode') + parser.add_argument( + "-conf", "--tcamConfig", type=str, default="tcam_64x28", metavar="", required=True, nargs="?", help="name of specific TCAM mem wrapper config" + ) + parser.add_argument("-d", "--debug", type=int, default=0, metavar="", required=False, nargs="?", help="print debugging mode") + parser.add_argument("-v", "--verbose", type=int, default=0, metavar="", required=False, nargs="?", help="print verbose mode") arg = parser.parse_args() # ====================================================== code main body # * calculate how many tcam block are required if arg.tcamConfig: - memLength=int(arg.tcamConfig[5:7]) - memWidth=int(arg.tcamConfig[8:10]) - if (memLength == 64) and (memWidth%7 == 0): + memLength = int(arg.tcamConfig[5:7]) + memWidth = int(arg.tcamConfig[8:10]) + if (memLength == 64) and (memWidth % 7 == 0): print('"VALID" TCAM memory wrapper config. tcam_[64]x[7*N] == %s\n', arg.tcamConfig) logging.info('"VALID" TCAM memory wrapper config. tcam_[64]x[7*N] == %s', arg.tcamConfig) - logging.info('Total TCAM memory 64x7 blocks required: %d', int(memWidth/7)) + logging.info("Total TCAM memory 64x7 blocks required: %d", int(memWidth / 7)) # * create rtl dir for specific tcam mem wrap config tcamRtlConfigDirPath = os.path.join(tcamRtlDirPath, arg.tcamConfig) if os.path.exists(tcamRtlConfigDirPath): shutil.rmtree(tcamRtlConfigDirPath) os.makedirs(tcamRtlConfigDirPath) - logging.info('Created TCAM memory RTL dir: %s', tcamRtlConfigDirPath) + logging.info("Created TCAM memory RTL dir: %s", tcamRtlConfigDirPath) # * copy sky130 block to required config dir shutil.copy(pathSram1kb, tcamRtlConfigDirPath) logging.info('Copied file "%s" to dir "%s"', pathSram1kb, tcamRtlConfigDirPath) print('Copied rtl file "%s" to dir "%s"', os.path.basename(pathSram1kb), tcamRtlConfigDirPath) # * generate verilog for TCAM memory MxN top wrapper - fileName = 'top_tcam_mem_' + str(memLength) + 'x' + str(memWidth) + '.sv' + fileName = "top_tcam_mem_" + str(memLength) + "x" + str(memWidth) + ".sv" rtlFilePath = os.path.join(tcamRtlConfigDirPath, fileName) - codeTcamMemTopWrapper = genVerilogTcamMemTopWrapper(memBlocks=int(memWidth/7), filePath=rtlFilePath) + codeTcamMemTopWrapper = genVerilogTcamMemTopWrapper(memBlocks=int(memWidth / 7), filePath=rtlFilePath) print('Created rtl file: "%s"', rtlFilePath) if arg.debug: print(codeTcamMemTopWrapper) # * generate verilog for TCAM memory block 7x64 - rtlFilePath = os.path.join(tcamRtlConfigDirPath, 'tcam_mem_7x64.sv') + rtlFilePath = os.path.join(tcamRtlConfigDirPath, "tcam_mem_7x64.sv") codeTcamMemBlock7x64 = genVerilogTcamMemBlock7x64(filePath=rtlFilePath) print('Created rtl file: "%s"', rtlFilePath) if arg.debug: print(codeTcamMemBlock7x64) # * generate verilog for andgate - rtlFilePath = os.path.join(tcamRtlConfigDirPath, 'and_gate.sv') + rtlFilePath = os.path.join(tcamRtlConfigDirPath, "and_gate.sv") codeAndGate = genVerilogAndGate(inputPorts=2, dataWidth=64, filePath=rtlFilePath) print('Created rtl file: "%s"', rtlFilePath) if arg.debug: print(codeAndGate) # * generate verilog for priority encoder - rtlFilePath = os.path.join(tcamRtlConfigDirPath, 'priority_encoder_64x6.sv') + rtlFilePath = os.path.join(tcamRtlConfigDirPath, "priority_encoder_64x6.sv") codePriorityEncoder = genVerilogPriorityEncoder(inDataWidth=64, filePath=rtlFilePath) print('Created rtl file: "%s"', rtlFilePath) if arg.debug: @@ -108,5 +107,5 @@ def main(): sys.exit('"INVALID" TCAM memory wrapper config. tcam_[64]x[7*N] != %s', arg.tcamConfig) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/compiler/src/priorityEncoder.py b/compiler/src/priorityEncoder.py index d905ee0..ebb3985 100644 --- a/compiler/src/priorityEncoder.py +++ b/compiler/src/priorityEncoder.py @@ -4,8 +4,9 @@ import logging import math -import sys import os +import sys + from migen import * from migen.fhdl.verilog import convert @@ -13,6 +14,7 @@ # ======================================= Begin Class ======================================= # =========================================================================================== + class PriorityEncoder(Module): """ Generates the verilog code for a Priority Encoder with N-bit input and log2(N) bit output. @@ -32,7 +34,7 @@ def __init__(self, inDataWidth): # * variables self.inputWidth = inDataWidth self.outputWidth = 0 - self.verilogCode = '' + self.verilogCode = "" # * signals self.inputs = [] @@ -52,14 +54,14 @@ def ioPorts(self): logging.info('"VALID": priority encoder input width %d is of 2^N', self.inputWidth) # * set output port width of log2(N) self.outputWidth = int(math.log2(self.inputWidth)) - logging.info('priority encoder output width: %d', self.outputWidth) + logging.info("priority encoder output width: %d", self.outputWidth) # * create IO port objects - self.inputs = Signal(self.inputWidth, name_override='in_data') - logging.info('Created priority encoder input port: in_data[%d:0]', self.inputWidth-1) - self.outputs = Signal(self.outputWidth, name_override='out_data') - logging.info('Created priority encoder output port: out_data[%d:0]', self.outputWidth-1) + self.inputs = Signal(self.inputWidth, name_override="in_data") + logging.info("Created priority encoder input port: in_data[%d:0]", self.inputWidth - 1) + self.outputs = Signal(self.outputWidth, name_override="out_data") + logging.info("Created priority encoder output port: out_data[%d:0]", self.outputWidth - 1) else: - print('num isnt 2^N', type(self.inputWidth)) + print("num isnt 2^N", type(self.inputWidth)) logging.error('"INVALID": priority encoder input width %d isnt of 2^N', self.inputWidth) sys.exit('"INVALID": priority encoder input width %d isnt of 2^N', self.inputWidth) @@ -72,17 +74,19 @@ def logicBlock(self): # * create N priority cases for i in reversed(range(self.inputWidth)): # * generate one hot encoding - oneHotEncode = bin(pow(2,i)) + oneHotEncode = bin(pow(2, i)) # * add ith priority case priorityCases[int(oneHotEncode, 2)] = self.outputs.eq(i) - logging.info('Created priority case for %3d input bit', i) + logging.info("Created priority case for %3d input bit", i) # * concat using case self.comb += Case(self.inputs, priorityCases) + # =========================================================================================== # ======================================== End Class ======================================== # =========================================================================================== + def genVerilogPriorityEncoder(inDataWidth, filePath): """ Main user function for class PriorityEncoder. @@ -103,15 +107,15 @@ def genVerilogPriorityEncoder(inDataWidth, filePath): outPortsSet = {encoder.outputs} # * combine input and output sets moduleIOs = inPortsSet.union(outPortsSet) - logging.info('Generated Priority Encoder verilog module definition') + logging.info("Generated Priority Encoder verilog module definition") # * generate the verilog code - moduleName = os.path.basename(filePath).replace('.sv', '') + moduleName = os.path.basename(filePath).replace(".sv", "") encoder.verilogCode = convert(encoder, name=moduleName, ios=moduleIOs) - logging.info('Generated Priority Encoder verilog module RTL') + logging.info("Generated Priority Encoder verilog module RTL") # * write verilog code to a file - with open(filePath, 'w', encoding='utf-8') as rtl: + with open(filePath, "w", encoding="utf-8") as rtl: rtl.write(str(encoder.verilogCode)) logging.info('Created rtl file "%s"', filePath) diff --git a/compiler/src/tcamMemBlock7x64.py b/compiler/src/tcamMemBlock7x64.py index 605e0d7..c52f79f 100644 --- a/compiler/src/tcamMemBlock7x64.py +++ b/compiler/src/tcamMemBlock7x64.py @@ -4,6 +4,7 @@ import logging import os + from migen import * from migen.fhdl.verilog import convert @@ -11,6 +12,7 @@ # ======================================= Begin Class ======================================= # =========================================================================================== + class TcamMemBlock7x64(Module): """ Generates the verilog code for a TCAM 7x64 memory block. @@ -28,8 +30,8 @@ def __init__(self): :return str verilogCode: store RTL code of the encoder. """ # * variables - self.__sramModule = 'sky130_sram_1kbyte_1rw1r_32x256_8' - self.verilogCode = '' + self.__sramModule = "sky130_sram_1kbyte_1rw1r_32x256_8" + self.verilogCode = "" # * signals self.inputs = [] @@ -45,59 +47,59 @@ def ioPorts(self): Create Signal objects for all the input ports of various widths and output ports of various widths. """ # * setup input ports - self.inClk = Signal(1, name_override='in_clk') - logging.info('Created TcamMemBlock7x64 input port: %s', self.inClk.name_override) - self.inCsb = Signal(1, name_override='in_csb') - logging.info('Created TcamMemBlock7x64 input port: %s', self.inCsb.name_override) - self.inWeb = Signal(1, name_override='in_web') - logging.info('Created TcamMemBlock7x64 input port: %s', self.inWeb.name_override) - self.inWmask = Signal(4, name_override='in_wmask') - logging.info('Created TcamMemBlock7x64 input port: %s[%d:0]', self.inWmask.name_override, 4) - self.inAddr = Signal(8, name_override='in_addr') - logging.info('Created TcamMemBlock7x64 input port: %s[%d:0]', self.inAddr.name_override, 8) - self.inWdata = Signal(32, name_override='in_wdata') - logging.info('Created TcamMemBlock7x64 input port: %s[%d:0]', self.inWdata.name_override, 32) + self.inClk = Signal(1, name_override="in_clk") + logging.info("Created TcamMemBlock7x64 input port: %s", self.inClk.name_override) + self.inCsb = Signal(1, name_override="in_csb") + logging.info("Created TcamMemBlock7x64 input port: %s", self.inCsb.name_override) + self.inWeb = Signal(1, name_override="in_web") + logging.info("Created TcamMemBlock7x64 input port: %s", self.inWeb.name_override) + self.inWmask = Signal(4, name_override="in_wmask") + logging.info("Created TcamMemBlock7x64 input port: %s[%d:0]", self.inWmask.name_override, 4) + self.inAddr = Signal(8, name_override="in_addr") + logging.info("Created TcamMemBlock7x64 input port: %s[%d:0]", self.inAddr.name_override, 8) + self.inWdata = Signal(32, name_override="in_wdata") + logging.info("Created TcamMemBlock7x64 input port: %s[%d:0]", self.inWdata.name_override, 32) # * add all input ports to an input list self.inputs = [self.inClk, self.inCsb, self.inWeb, self.inWmask, self.inAddr, self.inWdata] - logging.info('Created list of all input ports') + logging.info("Created list of all input ports") # * setup output ports - self.outRdata = Signal(64, name_override='out_rdata') - logging.info('Created TcamMemBlock7x64 output port: %s[%d:0]', self.outRdata.name_override, 64) + self.outRdata = Signal(64, name_override="out_rdata") + logging.info("Created TcamMemBlock7x64 output port: %s[%d:0]", self.outRdata.name_override, 64) # * add all output ports to an output list self.outputs = [self.outRdata] - logging.info('Created list of all output ports') + logging.info("Created list of all output ports") def logicBlock(self): """ Setup the sequential logic for creating a TCAM 7x64 memory block using migen. """ # * ----- setup write address logic - awAddr = Signal(8, name_override='aw_addr') + awAddr = Signal(8, name_override="aw_addr") self.comb += awAddr.eq(Cat(Replicate(~self.inWeb, 8)) & self.inAddr) - logging.info('Created write address logic') + logging.info("Created write address logic") # * ----- setup Read/Search address - arAddr1 = Signal(8, name_override='ar_addr1') - arAddr2 = Signal(8, name_override='ar_addr2') + arAddr1 = Signal(8, name_override="ar_addr1") + arAddr2 = Signal(8, name_override="ar_addr2") # * always read/search lower 128 rows self.comb += arAddr1.eq(Cat(self.inAddr[0:7], 0b0)) # * always read/search upper 128 rows self.comb += arAddr2.eq(Cat(self.inAddr[0:7], 0b1) & Cat(Replicate(self.inWeb, 8))) - logging.info('Created read/search address logic') + logging.info("Created read/search address logic") # * ----- PMA - rdataLower = Signal(32, name_override='rdata_lower') - rdataUpper = Signal(32, name_override='rdata_upper') - rdata = Signal(64, name_override='rdata') + rdataLower = Signal(32, name_override="rdata_lower") + rdataUpper = Signal(32, name_override="rdata_upper") + rdata = Signal(64, name_override="rdata") self.comb += rdata.eq(Cat(rdataLower, rdataUpper)) self.comb += self.outRdata.eq(rdata) - logging.info('Created upper and lower potential match address logic') + logging.info("Created upper and lower potential match address logic") # * ----- instantiate the sky130 1KB RAM module as submodule self.specials += Instance( of=self.__sramModule, - name='dut_vtb', + name="dut_vtb", # Port 0: RW i_clk0=self.inClk, i_csb0=self.inCsb, @@ -110,14 +112,16 @@ def logicBlock(self): i_clk1=self.inClk, i_csb1=self.inCsb, i_addr1=arAddr2, - o_dout1=rdataUpper + o_dout1=rdataUpper, ) - logging.info('Instantiated %s module', self.__sramModule) + logging.info("Instantiated %s module", self.__sramModule) + # =========================================================================================== # ======================================== End Class ======================================== # =========================================================================================== + def genVerilogTcamMemBlock7x64(filePath): """ Main user function for class TcamMemBlock7x64. @@ -139,12 +143,12 @@ def genVerilogTcamMemBlock7x64(filePath): moduleIOs = inPortsSet.union(outPortsSet) # * generate the verilog code - moduleName = os.path.basename(filePath).replace('.sv', '') + moduleName = os.path.basename(filePath).replace(".sv", "") tcamMem.verilogCode = convert(tcamMem, name=moduleName, ios=moduleIOs) - logging.info('Generated TCAM Memory 7x64 verilog module RTL') + logging.info("Generated TCAM Memory 7x64 verilog module RTL") # * write verilog code to a file - with open(filePath, 'w', encoding='utf-8') as rtl: + with open(filePath, "w", encoding="utf-8") as rtl: rtl.write(str(tcamMem.verilogCode)) logging.info('Created rtl file "%s"', filePath) diff --git a/compiler/src/tcamMemTopWrapper.py b/compiler/src/tcamMemTopWrapper.py index e692349..0a54330 100644 --- a/compiler/src/tcamMemTopWrapper.py +++ b/compiler/src/tcamMemTopWrapper.py @@ -5,6 +5,7 @@ import logging import math import os + from migen import * from migen.fhdl.verilog import convert @@ -12,6 +13,7 @@ # ======================================= Begin Class ======================================= # =========================================================================================== + class TcamMemTopWrapper(Module): """ Generates the verilog code for a TCAM memory block N*64 Wrapper. @@ -40,7 +42,7 @@ def __init__(self, memBlocks): # * variables self.memBlocks = memBlocks # 4 self.__inAddrWidth = 0 - self.verilogCode = '' + self.verilogCode = "" # * signals self.__blockSel = Signal() @@ -63,28 +65,28 @@ def ioPorts(self): """ self.inputs = {} # * setup input ports - self.inClk = Signal(1, name_override='in_clk') - logging.info('Created TcamMemTopWrapper input port: %s', self.inClk.name_override) - self.inCsb = Signal(1, name_override='in_csb') - logging.info('Created TcamMemTopWrapper input port: %s', self.inCsb.name_override) - self.inWeb = Signal(1, name_override='in_web') - logging.info('Created TcamMemTopWrapper input port: %s', self.inWeb.name_override) - self.inWmask = Signal(4, name_override='in_wmask') - logging.info('Created TcamMemTopWrapper input port: %s[%d:0]', self.inWmask.name_override, 3) + self.inClk = Signal(1, name_override="in_clk") + logging.info("Created TcamMemTopWrapper input port: %s", self.inClk.name_override) + self.inCsb = Signal(1, name_override="in_csb") + logging.info("Created TcamMemTopWrapper input port: %s", self.inCsb.name_override) + self.inWeb = Signal(1, name_override="in_web") + logging.info("Created TcamMemTopWrapper input port: %s", self.inWeb.name_override) + self.inWmask = Signal(4, name_override="in_wmask") + logging.info("Created TcamMemTopWrapper input port: %s[%d:0]", self.inWmask.name_override, 3) self.__inAddrWidth = self.memBlocks * 7 - self.inAddr = Signal(self.__inAddrWidth, name_override='in_addr') - logging.info('Created TcamMemTopWrapper input port: %s[%d:0]', self.inAddr.name_override, self.__inAddrWidth-1) - self.inWdata = Signal(32, name_override='in_wdata') - logging.info('Created TcamMemTopWrapper input port: %s[%d:0]', self.inWdata.name_override, 31) + self.inAddr = Signal(self.__inAddrWidth, name_override="in_addr") + logging.info("Created TcamMemTopWrapper input port: %s[%d:0]", self.inAddr.name_override, self.__inAddrWidth - 1) + self.inWdata = Signal(32, name_override="in_wdata") + logging.info("Created TcamMemTopWrapper input port: %s[%d:0]", self.inWdata.name_override, 31) # * add all input ports to an input list self.inputs = [self.inClk, self.inCsb, self.inWeb, self.inWmask, self.inAddr, self.inWdata] - logging.info('Created list of all input ports') + logging.info("Created list of all input ports") # * setup output ports - self.outPma = Signal(6, name_override='out_pma') - logging.info('Created TcamMemTopWrapper output port: %s[%d:0]', self.outPma.name_override, 5) + self.outPma = Signal(6, name_override="out_pma") + logging.info("Created TcamMemTopWrapper output port: %s[%d:0]", self.outPma.name_override, 5) # * add all output ports to an output list self.outputs = [self.outPma] - logging.info('Created list of all output ports') + logging.info("Created list of all output ports") def logicBlock(self): """ @@ -92,61 +94,60 @@ def logicBlock(self): """ # * ----- memory block selection for write logic # * setup wire - self.__blockSel = Signal(self.memBlocks, name_override='block_sel') - logging.info('Created wire %s[%d:0]', self.__blockSel.name_override, self.__blockSel.nbits-1) + self.__blockSel = Signal(self.memBlocks, name_override="block_sel") + logging.info("Created wire %s[%d:0]", self.__blockSel.name_override, self.__blockSel.nbits - 1) # * calculate width for inAddr slice inAddrWidth = int(math.ceil(math.log2(self.memBlocks))) + 8 - logging.info('Calculated bit slice for signal in_addr[%d:%d]', inAddrWidth, 8) + logging.info("Calculated bit slice for signal in_addr[%d:%d]", inAddrWidth, 8) # * combinational logic for block sel for i in range(self.memBlocks): self.comb += self.__blockSel[i].eq(self.inAddr[8:inAddrWidth] == i) - logging.info('Created logic for signal %s[%d]', self.__blockSel.name_override, i) + logging.info("Created logic for signal %s[%d]", self.__blockSel.name_override, i) # * ----- generating logic for write mask for i in range(self.memBlocks): # * setup wire tempWmask = Signal(4, name_override=f"wmask{i}") self.__wMaskList.append(tempWmask) - logging.info('Created wire %s[%d:0]', self.__wMaskList[i].name_override, self.__wMaskList[i].nbits-1) + logging.info("Created wire %s[%d:0]", self.__wMaskList[i].name_override, self.__wMaskList[i].nbits - 1) # * combinational logic for write mask self.comb += self.__wMaskList[i].eq(Replicate(self.__blockSel[i], 4) & self.inWmask) - logging.info('Created logic for signal %s', self.__wMaskList[i].name_override) + logging.info("Created logic for signal %s", self.__wMaskList[i].name_override) # * ----- generating logic for write addresses for i in range(self.memBlocks): # * setup wire tempAwAddr = Signal(8, name_override=f"aw_addr{i}") self.__awAddrList.append(tempAwAddr) - logging.info('Created wire %s[%d:0]', self.__awAddrList[i].name_override, self.__awAddrList[i].nbits-1) + logging.info("Created wire %s[%d:0]", self.__awAddrList[i].name_override, self.__awAddrList[i].nbits - 1) # * combinational logic for write addresses self.comb += self.__awAddrList[i].eq(Replicate(self.__blockSel[i], 8) & self.inAddr[0:8]) - logging.info('Created logic for signal %s', self.__awAddrList[i].name_override) + logging.info("Created logic for signal %s", self.__awAddrList[i].name_override) # * ----- generating address mux for all N blocks (selects between read or write addresses) for i in range(self.memBlocks): # * setup wire tempVtbAddr = Signal(8, name_override=f"vtb_addr{i}") self.__vtbAddrList.append(tempVtbAddr) - logging.info('Created wire %s[%d:0]', self.__vtbAddrList[i].name_override, self.__vtbAddrList[i].nbits-1) + logging.info("Created wire %s[%d:0]", self.__vtbAddrList[i].name_override, self.__vtbAddrList[i].nbits - 1) # * combinational logic for address mux - self.comb += If(self.inWeb, - self.__vtbAddrList[i].eq(Cat(self.inAddr[i*7 : (i*7)+7], 0b0)), - ).Else( - self.__vtbAddrList[i].eq(self.__awAddrList[i]) - ) - logging.info('Created logic for signal %s', self.__vtbAddrList[i].name_override) + self.comb += If( + self.inWeb, + self.__vtbAddrList[i].eq(Cat(self.inAddr[i * 7 : (i * 7) + 7], 0b0)), + ).Else(self.__vtbAddrList[i].eq(self.__awAddrList[i])) + logging.info("Created logic for signal %s", self.__vtbAddrList[i].name_override) # * ----- adding TCAM memory block instances # * setup rdata output signals for i in range(self.memBlocks): tempRdata = Signal(64, name_override=f"out_rdata{i}") self.__outRdataList.append(tempRdata) - logging.info('Created wire %s[%d:0]', self.__outRdataList[i].name_override, self.__outRdataList[i].nbits-1) + logging.info("Created wire %s[%d:0]", self.__outRdataList[i].name_override, self.__outRdataList[i].nbits - 1) # * tcam memory block 7x64 instantiations dutName = f"tcam_mem_7x64_dut{i}" self.specials += Instance( - of='tcam_mem_7x64', + of="tcam_mem_7x64", name=dutName, i_in_clk=self.inClk, i_in_csb=self.inCsb, @@ -154,48 +155,47 @@ def logicBlock(self): i_in_wmask=self.inWmask, i_in_addr=self.__vtbAddrList[i], i_in_wdata=self.inWdata, - o_out_rdata=self.__outRdataList[i] + o_out_rdata=self.__outRdataList[i], ) logging.info('Created instance "%s" of module "tcamMemBlock7x64"', dutName) # * ------ AND gate instantiations - for i in range(self.memBlocks-1): + for i in range(self.memBlocks - 1): # * setup AND gate output signals tempOutAndGate = Signal(64, name_override=f"out_andgate{i}") self.__outAndGateList.append(tempOutAndGate) - logging.info('Created wire %s[%d:0]', self.__outAndGateList[i].name_override, self.__outAndGateList[i].nbits-1) + logging.info("Created wire %s[%d:0]", self.__outAndGateList[i].name_override, self.__outAndGateList[i].nbits - 1) dutName = f"and_gate_dut{i}" if i == 0: self.specials += Instance( - of='and_gate', + of="and_gate", name=dutName, i_in_data0=self.__outRdataList[i], - i_in_data1=self.__outRdataList[i+1], - o_out_data=self.__outAndGateList[i] + i_in_data1=self.__outRdataList[i + 1], + o_out_data=self.__outAndGateList[i], ) else: self.specials += Instance( - of='and_gate', + of="and_gate", name=dutName, - i_in_data0=self.__outRdataList[i+1], - i_in_data1=self.__outAndGateList[i-1], - o_out_data=self.__outAndGateList[i] + i_in_data0=self.__outRdataList[i + 1], + i_in_data1=self.__outAndGateList[i - 1], + o_out_data=self.__outAndGateList[i], ) logging.info('Created instance "%s" of module "tcamMemBlock7x64"', dutName) # * ------ Priority encoder instantiations self.specials += Instance( - of='priority_encoder_64x6', - name='priority_encoder_dut0', - i_in_data=self.__outAndGateList[-1], - o_out_data=self.outputs[0] + of="priority_encoder_64x6", name="priority_encoder_dut0", i_in_data=self.__outAndGateList[-1], o_out_data=self.outputs[0] ) logging.info('Created instance "priority_encoder_dut0" of module "priority_encoder"') + # =========================================================================================== # ======================================== End Class ======================================== # =========================================================================================== + def genVerilogTcamMemTopWrapper(memBlocks, filePath): """ Main user function for class TcamMemTopWrapper. @@ -218,12 +218,12 @@ def genVerilogTcamMemTopWrapper(memBlocks, filePath): moduleIOs = inPortsSet.union(outPortsSet) # * generate the verilog code - moduleName = os.path.basename(filePath).replace('.sv', '') + moduleName = os.path.basename(filePath).replace(".sv", "") tcamMemTop.verilogCode = convert(tcamMemTop, name=moduleName, ios=moduleIOs) - logging.info('Generated TCAM Memory Top Wrapper verilog module RTL') + logging.info("Generated TCAM Memory Top Wrapper verilog module RTL") # * write verilog code to a file - with open(filePath, 'w', encoding='utf-8') as rtl: + with open(filePath, "w", encoding="utf-8") as rtl: rtl.write(str(tcamMemTop.verilogCode)) logging.info('Created rtl file "%s"', filePath) From 97b1743e30226fb71ed5b51e99cb241b077c1131 Mon Sep 17 00:00:00 2001 From: usman1515 Date: Sun, 5 Mar 2023 03:35:36 +0500 Subject: [PATCH 39/41] updated pylint config file --- .pylintrc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.pylintrc b/.pylintrc index c1e3d1b..b54a74c 100644 --- a/.pylintrc +++ b/.pylintrc @@ -4,7 +4,7 @@ [C0303(trailing-whitespace)] disable=C0303 -# disable recommend using enumerate in for loops +# disable recommend using enumerate in for loops [C0200(consider-using-enumerate)] disable=C0200 @@ -16,10 +16,13 @@ disable=R0902 [E1137(unsupported-assignment-operation)] disable=E1137 -# diable unsubscriptable object +# disable unsubscriptable object [E1136(unsubscriptable-object)] disable=E1136 +# disable no-member +[E1101(no-member)] +disable=E1101 # ======================================================================================= # ======================================================================================= @@ -67,7 +70,7 @@ max-public-methods=20 # Maximum number of return / yield for function / method body. max-returns=5 # Maximum number of statements in function / method body. -max-statements=50 +max-statements=100 # Minimum number of public methods for a class (see R0903). min-public-methods=2 From 0a6f753f7fec874950ceeda1b8bc8e181d237983 Mon Sep 17 00:00:00 2001 From: usman1515 Date: Sun, 5 Mar 2023 03:37:31 +0500 Subject: [PATCH 40/41] updated makefile --- Makefile | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 7f18403..d8af0ce 100755 --- a/Makefile +++ b/Makefile @@ -99,7 +99,7 @@ run_coverage: gen_apidocs: @ echo " " @ echo ------------------------ OpenTCAM API Documentation ------------------------ - @ pdoc ./compiler/src/tableMapping.py -o ${DIR_DOCS} + @ pdoc ./compiler/src/*.py -o ${DIR_DOCS} @ echo ------------------------------------ DONE ---------------------------------- @ echo " " @@ -107,26 +107,24 @@ run_pylint: @ echo " " @ echo ------------------------------ Running PyLint ------------------------------ @ [ -d ${DIR_LOGS} ] || mkdir -p ${DIR_LOGS} - @ pylint ${DIR_COMP_SRC}/mainTableMapping.py \ + @ pylint ${DIR_COMP_SRC}/*.py \ --output-format=${FORMAT}:./logs/pylint.log,${COLOR} \ --score=${SCORE} --reports=${REPORTS} \ --rcfile=.pylintrc @ echo ------------------------------------ DONE ---------------------------------- @ echo " " -# @ pylint ${DIR_COMP_SRC}/*.py \ - run_isort: @ echo " " @ echo ------------------------------ Running iSort ------------------------------ - @ isort -v compiler/src/mainTableMapping.py + @ isort -v compiler/src/*.py @ echo ------------------------------------ DONE ---------------------------------- @ echo " " run_black: @ echo " " @ echo ------------------------------ Running Black ------------------------------ - @ black -v compiler/src/mainTableMapping.py + @ black -v compiler/src/*.py @ echo ---------------------------------- DONE ----------------------------------- @ echo " " @@ -196,7 +194,7 @@ clean_coverage: @ echo ------------------------------------ DONE ---------------------------------- @ echo " " -clean_all: +clean_all: @ make clean_logs clean_sramtablemap clean_tcamrtl clean_tests clean_coverage clean_apidocs deepclean: @@ -229,7 +227,7 @@ help: @ echo " " @ echo " tcamrtl: generate TCAM memory RTL wrapper" @ echo " TCAMWRAPCONFIG=tcamMemWrapper_XxY tcam memory config name" - @ echo " TIMEUNIT=1ns set timeunit resolution" + @ echo " TIMEUNIT=1ns set timeunit resolution" @ echo " TIMEPRECISION=1ps set timeprecision resolution" @ echo " DEBUG=1/0 debugging on/off" @ echo " VERBOSE=1/0 verbosity on/off" From 1b424ec2255df48471677579a3f8185e4514e45a Mon Sep 17 00:00:00 2001 From: usman1515 Date: Sun, 5 Mar 2023 03:44:40 +0500 Subject: [PATCH 41/41] updated .vscode configs --- .vscode/extensions.json | 1 - .vscode/settings.json | 20 ++++++++++++++------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 7edfc1c..6213129 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -12,7 +12,6 @@ "ms-python.vscode-pylance", "ms-python.python", "kevinrose.vsc-python-indent", - "mshr-h.systemverilog", "mshr-h.veriloghdl", "redhat.vscode-yaml" ] diff --git a/.vscode/settings.json b/.vscode/settings.json index 11946ab..8bb0c50 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,11 @@ { + // only change these settings as you prefer + "editor.fontSize": 13, + "terminal.integrated.fontSize": 13, + "editor.fontFamily": "'CaskaydiaCove Nerd Font Mono'", + "terminal.integrated.fontFamily": "CaskaydiaCove Nerd Font Mono", + // dont change these settings "python.defaultInterpreterPath": ".pyVenvOpenTcam/bin/python", - "editor.fontSize": 12, "editor.tabSize": 4, "editor.insertSpaces": true, "editor.bracketPairColorization.enabled": true, @@ -9,10 +14,9 @@ "editor.detectIndentation": true, "editor.lineHeight": 0, "editor.minimap.enabled": false, - "terminal.integrated.fontSize": 11, "terminal.integrated.lineHeight": 1, "terminal.integrated.shellIntegration.enabled": true, - // "files.trimTrailingWhitespace": true, + "files.trimTrailingWhitespace": true, "markdown.preview.fontSize": 10, "markdown.preview.lineHeight": 1.0, "markdown-preview-github-styles.colorTheme": "light", @@ -26,10 +30,14 @@ "cSpell.enabled": true, "cSpell.caseSensitive": true, "cSpell.words": [ + "combinational", "damerau", + "dataframe", "levenshtein", - "tcam", "TCAM", - "sram", "SRAM", - "dataframe" + "sram", + "SRAM", + "tcam", + "TCAM", + "verilog" ] }