Re: [myhdl-list] TypeError: Unexpected type
Brought to you by:
jandecaluwe
From: Josy B. <jos...@gm...> - 2015-03-24 15:46:33
|
Christopher Felton <chris.felton <at> gmail.com> writes: > > On 3/24/2015 9:30 AM, Guy Eschemann wrote: > > from myhdl import * > > > > def mpegChannel(clk, rst): > > > > s_tx_data_xor_mask_r = Signal(intbv(0)[1 + 31:]) > > > > <at> always_seq(clk.posedge, rst) > > def fsm_seq(): > > for i in range(4): > > if i == 0: > > s_tx_data_xor_mask_r.next[1 + 7:0] = 0 > > elif i == 1: > > s_tx_data_xor_mask_r.next[1 + 15:8] = 1 > > elif i == 2: > > s_tx_data_xor_mask_r.next[1 + 23:16] = 2 > > else: > > s_tx_data_xor_mask_r.next[1 + 31:24] = 3 > > > > return instances() > > I think this is a bug / limitation and an issue should > to be created (but there might be a good reason for the > limitation that I can't think of right now). > > You can work around it with: > > In [5]: from myhdl import * > ...: > ...: def mpegChannel(clk, rst): > ...: > ...: s_tx_data_xor_mask_r = Signal(intbv(0)[1 + 31:]) > > ...: # *** limited range type for switch *** > ...: full_case = intbv(0, min=0, max=4) > > ...: <at> always_seq(clk.posedge, rst) > ...: def fsm_seq(): > ...: for i in range(4): > ...: full_case[:] = i > ...: if full_case == 0: > ...: s_tx_data_xor_mask_r.next[1 + 7:0] = 0 > ...: elif full_case == 1: > ...: s_tx_data_xor_mask_r.next[1 + 15:8] = 1 > ...: elif full_case == 2: > ...: s_tx_data_xor_mask_r.next[1 + 23:16] = 2 > ...: else: > ...: s_tx_data_xor_mask_r.next[1 + 31:24] = 3 > ...: > ...: return instances() > > The limitation is, when evaluating an if-else structure > the conversion code wants to determine if it full-case > or not, because the variable switched on is an `int` it > throws the type error. But the code example seems reasonable, > I think? ><snip> I traced the process, and the exception is thrown after the 'else:' has ben processed. Replacing the 'else:' with 'elif i == 3:' gets the same exception. I tried two other workarounds: def mpegChannel(clk, rst, s_tx_data_xor_mask_r): @always_seq(clk.posedge, reset=rst) def fsm_seq(): for i in range(4): s_tx_data_xor_mask_r.next[(i+1)*8:i*8] = i return instances() and: def mpegChannel(clk, rst, s_tx_data_xor_mask_r): table = tuple([9,8,7,6]) @always_seq(clk.posedge, reset=rst) def fsm_seq(): for i in range(4): s_tx_data_xor_mask_r.next[(i+1)*8:i*8] = table[i] return instances() The second allows for any value to be loaded. Both convert fine. I also found a fix which works for Verilog: in _analyze in function def visit_If(self, node): change line if (len(choices) == _getNritems(var1.obj)) or node.else_ : into: if node.else_ or (len(choices) == _getNritems(var1.obj)) : which is probably the original intention? A final 'else' in the RTL code is than mandatory It gets another exception in the toVHDL conversion: File "C:\Python27\lib\site-packages\myhdl\conversion\_toVHDL.py", line 713, in BitRepr return '"%s"' % bin(item, len(var)) TypeError: object of type '_loopInt' has no len() (The line number doesn't match, as my MyHDL source is heavily annotated with tracing and inspect code) Regards, Josy |