Re: [myhdl-list] reusable blocks with different interfaces
Brought to you by:
jandecaluwe
From: Henry G. <he...@ca...> - 2015-01-16 13:47:05
|
On 15/01/15 19:15, Henry Gomersall wrote: > At risk of asking an XY problem (in which I describe a different problem > to the more fundamental one), I would like to know if it is possible > with MyHDL 0.9 to define a reusable convertible block that does > something like the following: > > from myhdl import * > > class Interface(object): > def __init__(self): > self.a = Signal(intbv(0)[5:]) > self.b = Signal(intbv(0)[7:]) > > def block_factory(input_interface, output_interface, clock, reset): > > @always_seq(clock.posedge, reset) > def block(): > output_interface.next = input_interface > > return block > > foo = Interface() > bar = Interface() > clock = Signal(bool(1)) > reset = ResetSignal(bool(0), active=1, async=False) > > toVerilog(block_factory, foo, bar, clock, reset) > > Running this yields "Object type is not supported in this context: > output_interface". > > Now, my use case for this is to create a block that takes an interface > as its argument, and from which I can create a buffer (or a small FIFO) > of the attributes defined by the interface. The point is to match the > propagation of state information alongside data processing inside a > pipeline. <snip> So, the way this can be done in my situation is by instantiating a new block for each signal in the interface. If each element of the interface can be considered independently (which is sort of the point, otherwise I'm not sure how my question is meaningful), then I suspect the below would be about as good as I could get. It produces pretty sensible looking v*. The names within the converted files are kept in line with the interface by accessing the locals() dict directly. If one creates an intermediate variable, the output names are created at conversion time and are a bit non-helpful (also, they are not all consistent with one another). Cheers, Henry from myhdl import * import myhdl class Interface(object): def __init__(self): self.a = Signal(intbv(0)[5:]) self.b = Signal(intbv(0)[7:]) self.c = Signal(bool(0)) def single_signal_processor(input_signal, output_signal, clock, reset): @always_seq(clock.posedge, reset) def block(): output_signal.next = input_signal return block def interface_processor(input_interface, output_interface, clock, reset): process_blocks = [] for attr_name in input_interface.__dict__: locals()['input_' + attr_name] = getattr(input_interface, attr_name) locals()['output_' + attr_name] = getattr(output_interface, attr_name) if isinstance(locals()['input_' + attr_name], myhdl._Signal._Signal): process_blocks.append( single_signal_processor( locals()['input_' + attr_name], locals()['output_' + attr_name], clock, reset)) return process_blocks foo = Interface() bar = Interface() clock = Signal(bool(1)) reset = ResetSignal(bool(0), active=1, async=False) toVerilog(interface_processor, foo, bar, clock, reset) toVHDL(interface_processor, foo, bar, clock, reset) |