Thread: [myhdl-list] Dynamically Generated Assignments
Brought to you by:
jandecaluwe
|
From: Evan B. <br...@mi...> - 2008-01-03 10:05:09
|
Hi -
I'm trying to write a (HDL) module to permute an input bit-vector
from a mapping list that's fed in when the module is initialized, but I
can't seem to get it to work. I've gone through a bunch of different
revisions trying to make this work, and finally settled on trying to
generate one generator for each assignment so that I could loop without
MyHDL trying to convert the loop to Verilog. I think that code will
explain this much better than I can, so:
def module(self, clock, in_perm, out_perm):
permutations = []
for i in range(len(mapping)):
input_index = mapping[i]
@always_comb
def permute():
out_perm.next[i] = in_perm.val[input_index]
permutations.append(permute)
return tuple(permutations)
For some reason, though, it seems that each generator overwrites the old
one, meaning that only the last bit of out_perm ever gets set.
Is there some way that I can make this work the way that I want?
Thanks,
Evan
|
|
From: Jan D. <ja...@ja...> - 2008-01-03 14:20:18
|
Evan Broder wrote:
> Hi -
> I'm trying to write a (HDL) module to permute an input bit-vector
> from a mapping list that's fed in when the module is initialized, but I
> can't seem to get it to work. I've gone through a bunch of different
> revisions trying to make this work, and finally settled on trying to
> generate one generator for each assignment so that I could loop without
> MyHDL trying to convert the loop to Verilog. I think that code will
> explain this much better than I can, so:
>
> def module(self, clock, in_perm, out_perm):
> permutations = []
> for i in range(len(mapping)):
> input_index = mapping[i]
> @always_comb
> def permute():
> out_perm.next[i] = in_perm.val[input_index]
>
> permutations.append(permute)
>
> return tuple(permutations)
>
> For some reason, though, it seems that each generator overwrites the old
> one, meaning that only the last bit of out_perm ever gets set.
This is a consequence from how "free variables" (i) are handled in Python.
Consider:
def f():
funcs = []
i = 0
def g():
print "func 1"
print i
funcs.append(g)
i = 1
def g():
print "func 2"
print i
funcs.append(g)
for h in funcs:
h()
f()
The output is:
> python tmp4.py
func 1
1
func 2
1
So, the functions are different, but the value of the free variable
is the "last" one in both cases.
>
> Is there some way that I can make this work the way that I want?
It would be quite easy to accomplish what you want with
lists for Signals instead of bit vectors modeled by intbv's.
Would that be acceptable?
Jan
--
Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com
Kaboutermansstraat 97, B-3000 Leuven, Belgium
From Python to silicon:
http://myhdl.jandecaluwe.com
|
|
From: Evan B. <br...@mi...> - 2008-01-03 19:52:56
|
Jan Decaluwe wrote: > Evan Broder wrote: >> Hi - >> I'm trying to write a (HDL) module to permute an input bit-vector >> from a mapping list that's fed in when the module is initialized, but I >> can't seem to get it to work. I've gone through a bunch of different >> revisions trying to make this work, and finally settled on trying to >> generate one generator for each assignment so that I could loop without >> MyHDL trying to convert the loop to Verilog. I think that code will >> explain this much better than I can, so: >> >> def module(self, clock, in_perm, out_perm): >> permutations = [] >> for i in range(len(mapping)): >> input_index = mapping[i] >> @always_comb >> def permute(): >> out_perm.next[i] = in_perm.val[input_index] >> >> permutations.append(permute) >> >> return tuple(permutations) >> >> For some reason, though, it seems that each generator overwrites the old >> one, meaning that only the last bit of out_perm ever gets set. > > This is a consequence from how "free variables" (i) are handled in Python. > Consider: > > def f(): > funcs = [] > i = 0 > def g(): > print "func 1" > print i > funcs.append(g) > i = 1 > def g(): > print "func 2" > print i > funcs.append(g) > > for h in funcs: > h() > > f() > > The output is: > > > python tmp4.py > func 1 > 1 > func 2 > 1 > > So, the functions are different, but the value of the free variable > is the "last" one in both cases. > >> Is there some way that I can make this work the way that I want? > > It would be quite easy to accomplish what you want with > lists for Signals instead of bit vectors modeled by intbv's. > Would that be acceptable? > > Jan > I don't want the interface to the module to change (I want the inputs and outputs to be bit vectors). Are you suggesting that I should change the arguments or convert the intbv's to lists within the module/function? |
|
From: Jan D. <ja...@ja...> - 2008-01-03 21:57:30
|
Evan Broder wrote:
> Jan Decaluwe wrote:
>
>>Evan Broder wrote:
>>
>>>Hi -
>>> I'm trying to write a (HDL) module to permute an input bit-vector
>>>from a mapping list that's fed in when the module is initialized, but I
>>>can't seem to get it to work. I've gone through a bunch of different
>>>revisions trying to make this work, and finally settled on trying to
>>>generate one generator for each assignment so that I could loop without
>>>MyHDL trying to convert the loop to Verilog. I think that code will
>>>explain this much better than I can, so:
>>>
>>>def module(self, clock, in_perm, out_perm):
>>> permutations = []
>>> for i in range(len(mapping)):
>>> input_index = mapping[i]
>>> @always_comb
>>> def permute():
>>> out_perm.next[i] = in_perm.val[input_index]
>>>
>>> permutations.append(permute)
>>>
>>> return tuple(permutations)
>>>
>>>For some reason, though, it seems that each generator overwrites the old
>>>one, meaning that only the last bit of out_perm ever gets set.
>>
>>This is a consequence from how "free variables" (i) are handled in Python.
>>Consider:
>>
>>def f():
>> funcs = []
>> i = 0
>> def g():
>> print "func 1"
>> print i
>> funcs.append(g)
>> i = 1
>> def g():
>> print "func 2"
>> print i
>> funcs.append(g)
>>
>> for h in funcs:
>> h()
>>
>>f()
>>
>>The output is:
>>
>> > python tmp4.py
>>func 1
>>1
>>func 2
>>1
>>
>>So, the functions are different, but the value of the free variable
>>is the "last" one in both cases.
>>
>>
>>>Is there some way that I can make this work the way that I want?
>>
>>It would be quite easy to accomplish what you want with
>>lists for Signals instead of bit vectors modeled by intbv's.
>>Would that be acceptable?
>>
>>Jan
>>
>
>
> I don't want the interface to the module to change (I want the inputs
> and outputs to be bit vectors). Are you suggesting that I should change
> the arguments or convert the intbv's to lists within the module/function?
No, just checking - with lists of signals you could make something
more general than just for bits.
With intbv's and Signals thereof you'll have to stay within a
single generator - otherwise the convertor will complain about
multiple Signal drivers. What you can do is index into the mapping,
represented as a tuple:
def module(in_perm, out_perm, mapping):
@always_comb
def permute():
j = intbv(0, min=0, max=len(mapping))
for i in range(len(mapping)):
j[:] = mapping[i]
out_perm.next[i] = in_perm[int(j)]
return permute
Note that j is an intbv, and the indexing is on a single
line. This is due to convertor restrictions, for pure
modeling this is not required of course. The convertor
can map this to a case statement. Now you can do:
mapping = (2, 3, 0, 1)
in_perm = Signal(intbv(0)[4:])
out_perm = Signal(intbv(0)[4:])
toVerilog(module, in_perm, out_perm, mapping)
and you'll get:
---
// File: module.v
// Generated by MyHDL 0.6dev6
// Date: Thu Jan 3 22:59:40 2008
module module (
in_perm,
out_perm
);
input [3:0] in_perm;
output [3:0] out_perm;
reg [3:0] out_perm;
always @(in_perm) begin: MODULE_PERMUTE
integer i;
reg [2-1:0] j;
j = 0;
for (i=0; i<4; i=i+1) begin
// synthesis parallel_case full_case
case (i)
0: j = 2;
1: j = 3;
2: j = 0;
default: j = 1;
endcase
out_perm[i] <= in_perm[j];
end
end
endmodule
---
Regards,
Jan
--
Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com
Kaboutermansstraat 97, B-3000 Leuven, Belgium
From Python to silicon:
http://myhdl.jandecaluwe.com
|