class Control(wiring.Component): class Cmd(csr.Register, access = 'w'): start: csr.Field(csr.action.W, 1) stop: csr.Field(csr.action.W, 1) class Status(csr.Register, access = 'r'): state: csr.Field(csr.action.R, 2) class Level(csr.Register, access = 'r'): def __init__(self, depth): super().__init__({ 'level': csr.Field(csr.action.R, range(depth + 1)), }) class Data(csr.Register, access = 'r'): data: csr.Field(csr.action.R, 8) class Annotation(meta.Annotation): schema = { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://zyp.no/schema/foo/0.1/ila.json", "type": "object", "properties": { "buffer_width": { "type": "integer", }, "buffer_depth": { "type": "integer", }, "signals": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string", }, "width": { "type": "integer", }, }, "additionalProperties": False, "required": [ "name", "width", ], }, }, }, "additionalProperties": False, "required": [ "buffer_width", "buffer_depth", ], } def __init__(self, origin): self._origin = origin @property def origin(self): return self._origin def as_json(self): instance = { 'buffer_width': self.origin.ila_capture.width, 'buffer_depth': self.origin.ila_capture.depth, 'signals': [ { 'name': name, 'width': len(signal), } for name, signal in self.origin.ila_capture._signals.items() ], } self.validate(instance) return instance def __init__(self, ila_capture): super().__init__({ 'bus': wiring.In(csr.Signature(addr_width = 8, data_width = 8)), }) regs = csr.Builder(addr_width = 8, data_width = 8) self._cmd = regs.add('cmd', self.Cmd()) self._status = regs.add('status', self.Status()) self._level = regs.add('level', self.Level(ila_capture.depth)) self._data = regs.add('data', self.Data()) self._bridge = csr.Bridge(regs.as_memory_map()) self.bus.memory_map = self._bridge.bus.memory_map self.bus.memory_map.add_annotation(self.Annotation(self)) self.ila_capture = ila_capture def elaborate(self, platform): m = Module() m.submodules.serializer = serializer = Serializer(data.ArrayLayout(self.bus.data_width, (self.ila_capture.width + self.bus.data_width - 1) // self.bus.data_width)) m.d.comb += [ self.ila_capture.output.ready.eq(serializer.input.ready), serializer.input.valid.eq(self.ila_capture.output.valid), serializer.input.payload.eq(self.ila_capture.output.payload), ] m.submodules.bridge = self._bridge wiring.connect(m, wiring.flipped(self.bus), self._bridge.bus) m.d.comb += [ self.ila_capture.start.eq(self._cmd.f.start.w_stb & self._cmd.f.start.w_data), self.ila_capture.stop.eq(self._cmd.f.stop.w_stb & self._cmd.f.stop.w_data), self._status.f.state.r_data.eq(self.ila_capture.state), self._level.f.level.r_data.eq(self.ila_capture.storage.level), self._data.f.data.r_data.eq(serializer.output.payload), serializer.output.ready.eq(self._data.f.data.r_stb), ] return m