Re: [myhdl-list] Dynamically Generated Assignments
Brought to you by:
jandecaluwe
|
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
|