[PyCDE] Simple transforms on channels (#7330)

Add 'transform' method to ChannelSignals to enable simple data
manipulations without worrying about signaling.
This commit is contained in:
John Demme 2024-07-17 06:04:09 -07:00 committed by GitHub
parent 458717bc24
commit d26d288249
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 30 additions and 1 deletions

View File

@ -13,7 +13,7 @@ from .circt import ir
from contextvars import ContextVar from contextvars import ContextVar
from functools import singledispatchmethod from functools import singledispatchmethod
from typing import Dict, List, Optional, Tuple, Union from typing import Callable, Dict, List, Optional, Tuple, Union
import re import re
import numpy as np import numpy as np
@ -736,6 +736,20 @@ class ChannelSignal(Signal):
stages=stages, stages=stages,
), self.type) ), self.type)
def transform(self, transform: Callable[[Signal], Signal]) -> ChannelSignal:
"""Transform the data in the channel using the provided function. Said
function must be combinational so it is intended for wire and simple type
transformations."""
from .constructs import Wire
from .types import Bits, Channel
ready_wire = Wire(Bits(1))
data, valid = self.unwrap(ready_wire)
data = transform(data)
ret_chan, ready = Channel(data.type).wrap(data, valid)
ready_wire.assign(ready)
return ret_chan
class BundleSignal(Signal): class BundleSignal(Signal):
"""Signal for types.Bundle.""" """Signal for types.Bundle."""

View File

@ -184,6 +184,21 @@ class RecvBundleTest(Module):
self.s1_out = to_channels['req'] self.s1_out = to_channels['req']
# CHECK-LABEL: hw.module @ChannelTransform(in %s1_in : !esi.channel<i32>, out s2_out : !esi.channel<i8>) attributes {output_file = #hw.output_file<"ChannelTransform.sv", includeReplicatedOps>} {
# CHECK-NEXT: %rawOutput, %valid = esi.unwrap.vr %s1_in, %ready : i32
# CHECK-NEXT: [[R0:%.+]] = comb.extract %rawOutput from 0 : (i32) -> i8
# CHECK-NEXT: %chanOutput, %ready = esi.wrap.vr [[R0]], %valid : i8
# CHECK-NEXT: hw.output %chanOutput : !esi.channel<i8>
@unittestmodule()
class ChannelTransform(Module):
s1_in = InputChannel(Bits(32))
s2_out = OutputChannel(Bits(8))
@generator
def build(self):
self.s2_out = self.s1_in.transform(lambda x: x[0:8])
# CHECK-LABEL: hw.module @MMIOReq() # CHECK-LABEL: hw.module @MMIOReq()
# CHECK-NEXT: %c0_i64 = hw.constant 0 : i64 # CHECK-NEXT: %c0_i64 = hw.constant 0 : i64
# CHECK-NEXT: %false = hw.constant false # CHECK-NEXT: %false = hw.constant false