From 38494d7bd8c6fff7933474493f46ffb82bd60c64 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sat, 23 May 2020 19:05:31 +0100 Subject: [PATCH] split out RegSpecs into separate module --- src/soc/experiment/compalu_multi.py | 65 ++--------------------------- src/soc/fu/regspec.py | 64 ++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 61 deletions(-) create mode 100644 src/soc/fu/regspec.py diff --git a/src/soc/experiment/compalu_multi.py b/src/soc/experiment/compalu_multi.py index fe42f07d..88ad5486 100644 --- a/src/soc/experiment/compalu_multi.py +++ b/src/soc/experiment/compalu_multi.py @@ -8,6 +8,7 @@ from nmutil.iocontrol import RecordObject from soc.decoder.power_decoder2 import Data from soc.decoder.power_enums import InternalOp +from soc.fu.regspec import RegSpec, RegSpecALUAPI """ Computation Unit (aka "ALU Manager"). @@ -68,22 +69,8 @@ def go_record(n, name): return r # see https://libre-soc.org/3d_gpu/architecture/regfile/ section on regspecs -def get_regspec_bitwidth(regspec, srcdest, idx): - bitspec = regspec[srcdest][idx] - wid = 0 - print (bitspec) - for ranges in bitspec[2].split(","): - ranges = ranges.split(":") - print (ranges) - if len(ranges) == 1: # only one bit - wid += 1 - else: - start, end = map(int, ranges) - wid += (end-start)+1 - return wid - - -class CompUnitRecord(RecordObject): + +class CompUnitRecord(RegSpec, RecordObject): """CompUnitRecord base class for Computation Units, to provide a uniform API @@ -100,14 +87,8 @@ class CompUnitRecord(RecordObject): see https://libre-soc.org/3d_gpu/architecture/regfile/ section on regspecs """ def __init__(self, subkls, rwid, n_src=None, n_dst=None, name=None): + RegSpec.__init__(self, rwid, n_src, n_dst) RecordObject.__init__(self, name) - self._rwid = rwid - if isinstance(rwid, int): - # rwid: integer (covers all registers) - self._n_src, self._n_dst = n_src, n_dst - else: - # rwid: a regspec. - self._n_src, self._n_dst = len(rwid[0]), len(rwid[1]) self._subkls = subkls src = [] @@ -143,44 +124,6 @@ class CompUnitRecord(RecordObject): self.busy_o = Signal(reset_less=True) # fn busy out self.done_o = Signal(reset_less=True) - def _get_dstwid(self, i): - if isinstance(self._rwid, int): - return self._rwid - return get_regspec_bitwidth(self._rwid, 1, i) - - def _get_srcwid(self, i): - if isinstance(self._rwid, int): - return self._rwid - return get_regspec_bitwidth(self._rwid, 0, i) - - -class RegSpecALUAPI: - def __init__(self, rwid, alu): - """RegSpecAPI - - * :rwid: regspec - * :alu: ALU covered by this regspec - """ - self.rwid = rwid - self.alu = alu # actual ALU - set as a "submodule" of the CU - - def get_out(self, i): - if isinstance(self.rwid, int): # old - testing - API (rwid is int) - return self.alu.out[i] - # regspec-based API: look up variable through regspec according to row number - return getattr(self.alu.n.data_o, self.rwid[1][i][1]) - - def get_in(self, i): - if isinstance(self.rwid, int): # old - testing - API (rwid is int) - return self.alu.i[i] - # regspec-based API: look up variable through regspec according to row number - return getattr(self.alu.p.data_i, self.rwid[0][i][1]) - - def get_op(self): - if isinstance(self.rwid, int): # old - testing - API (rwid is int) - return self.alu.op - return self.alu.p.data_i.ctx.op - class MultiCompUnit(RegSpecALUAPI, Elaboratable): def __init__(self, rwid, alu, opsubsetkls, n_src=2, n_dst=1): diff --git a/src/soc/fu/regspec.py b/src/soc/fu/regspec.py new file mode 100644 index 00000000..31931f57 --- /dev/null +++ b/src/soc/fu/regspec.py @@ -0,0 +1,64 @@ +# see https://libre-soc.org/3d_gpu/architecture/regfile/ section on regspecs + +def get_regspec_bitwidth(regspec, srcdest, idx): + bitspec = regspec[srcdest][idx] + wid = 0 + print (bitspec) + for ranges in bitspec[2].split(","): + ranges = ranges.split(":") + print (ranges) + if len(ranges) == 1: # only one bit + wid += 1 + else: + start, end = map(int, ranges) + wid += (end-start)+1 + return wid + + +class RegSpec: + def __init__(self, rwid, n_src=None, n_dst=None, name=None): + self._rwid = rwid + if isinstance(rwid, int): + # rwid: integer (covers all registers) + self._n_src, self._n_dst = n_src, n_dst + else: + # rwid: a regspec. + self._n_src, self._n_dst = len(rwid[0]), len(rwid[1]) + + def _get_dstwid(self, i): + if isinstance(self._rwid, int): + return self._rwid + return get_regspec_bitwidth(self._rwid, 1, i) + + def _get_srcwid(self, i): + if isinstance(self._rwid, int): + return self._rwid + return get_regspec_bitwidth(self._rwid, 0, i) + + +class RegSpecALUAPI: + def __init__(self, rwid, alu): + """RegSpecAPI + + * :rwid: regspec + * :alu: ALU covered by this regspec + """ + self.rwid = rwid + self.alu = alu # actual ALU - set as a "submodule" of the CU + + def get_out(self, i): + if isinstance(self.rwid, int): # old - testing - API (rwid is int) + return self.alu.out[i] + # regspec-based API: look up variable through regspec according to row number + return getattr(self.alu.n.data_o, self.rwid[1][i][1]) + + def get_in(self, i): + if isinstance(self.rwid, int): # old - testing - API (rwid is int) + return self.alu.i[i] + # regspec-based API: look up variable through regspec according to row number + return getattr(self.alu.p.data_i, self.rwid[0][i][1]) + + def get_op(self): + if isinstance(self.rwid, int): # old - testing - API (rwid is int) + return self.alu.op + return self.alu.p.data_i.ctx.op -- 2.30.2