Re: [myhdl-list] Restrictions for conversion
Brought to you by:
jandecaluwe
From: Christopher F. <chr...@gm...> - 2012-05-21 12:07:23
|
On 5/21/2012 6:28 AM, Norbo wrote: >> * Adding support for None in the intbv (also setting None as the default >> value?) >> * Creating initial values in Verilog/VHDL (when not None) >> * Changing the verilog continuous assignment to the behavioral statement >> in the verilog conversion >> * Work through the implementation changes needed, because of the None in >> the intbv (boundchecks, etc ..) > > I started to try to implement these points. > the real issues started where i came to the : > * Work through the implementation changes needed, because of the None in > the intbv (boundchecks, etc .. > the issue arises when the intbv has a value of None in the myhdl > implementation, and something like this is done: > > sig1=Signal(intbv(None)[8:)) > sig2=Signal(intbv(None)[8:)) > > @always(clk.posedge) > def aritmetic(): > square.next=sig1*sig1+sig2*sig2 I am not sure of the answer right now but what is the correct course? To propagate the "None" or to raise and exception? > > i first changed all __add__ and __mult__ operater of the intbv to return > None as a value if one of the operands > is None. But as the two multiplications are done first the last plus > operation has two None values (None+None) which > doesnt works. So i returned for every operation a new intbv(None). Anyway > there seem to be some operators where intbv() are > returned and other operaters there is just the value returned (in the > orginal code -> has this any special reson?). This has been discussed briefly in the past. IIRC it is for performance? I might be plausible to to return intbv type for all operations (I have prototyped this in the past, again IIRC it didn't break anything). But I think we would want very good reason to modify before doing so. > > But there was an other case: > > mem=[Signal(intbv(0)[8:]) for i in range(200)] > > @always(clk.posedge) > def mem_read(): > our.next=mem[addr] > > if here the addr._val is None then it also crashes. > So my short just to try workaround was to subclass list and accept the > None as a index > > class listx(list): > def __getitem__(self, key): > if key==None: > bits=super(listx, self).__getitem__(0)._nrbits > return intbv(None)[bits:] > return super(listx, self).__getitem__(key) > > then the implementation would have to look like this: > > mem=listx([Signal(intbv(0)[8:]) for i in range(200)]) > > @always(clk.posedge) > def mem_read(): > our.next=mem[addr] > > then the issue with the bool arised because if you write code like this: > > sig=Signal(bool(None)) > > because bool(None) evaluates to false the _val of the Signal gets false an > not None > So i tried with a bool definition like the following: > I think that might be an ok behavior. I know it doesn't match the other non-initialized but the bool not having a non-initialize is probably acceptable. > def boolx(val=None): > if val in (0, 1): > return bool(val) > else: > return None > > Then i changed all Signal operators (__add__, __sub__, etc..) that they > return None if one of the operaters is None > which brings the same problem with the plus to the signal as i had in the > intbv() which is that two None values can't be added or multiplyed or etc. > like in the intbv. > > then i realized that it probably would just be better to make the Signal > as a base class and derive every other type from it, wheter it is (intbv, > bool"x" or modbv, enum, etc.). This probably doesnt made sense once when > only the intbv existed? > or is it done the way it is done because of performance reason? > Hmmm, I am not sure about that. In some cases, mainly modeling, I want to use intbv directly and do not want it to be a Signal. Example, I don't want to have to call the "update" explicitly or implicitly to have the get the value. As I write this, I think the rules should be : 1. intbv can have a type None but not the other Python built-in types: bool, int, long, etc. (I realize only bool is convertible). 2. If an intbv with a value of None is used an exception should be raised. The main use of the "None" was to control if initial values were written to the lower (v)HDLs. Which I think is fair. But MyHDL currently does not have this concept in conversion or modeling. That is, you can't have an unknown value. I think we preserve this by raising an exception. The rules is changed slightly, currently you cannot have a type with an unknown value and proposed you can't use a type with an unknown (a.k.a None). And there is the limitation that the Python built-in types will always be initialized. Only the intbv can not be initialized. I believe the only arguable reason for not initializing so far is for large arrays (memories). Or did I quickly forget? Regards, Chris |