@theller
Here is a block that does what you want :
class MatchPattern():
def __init__(self, pattern="----"):
self.pattern = pattern
self.hdl = self.hdl1
@block
def hdl1(self,
i_Clk,
i_DataEn,
i_Data,
o_Match) :
assert len(i_Data) == len(self.pattern)
data_length = len(i_Data)
xor_init = 0
and_init = 0
for i,c in enumerate(reversed(self.pattern)) :
if c == '1' :
xor_init |= 1 << i
and_init |= 1 << i
elif c == '0' :
and_init |= 1 << i
elif c == '-' :
pass
else :
raise ValueError("Value should be '1', '0' or '-'")
xor_vect = Signal(intbv(xor_init)[data_length:])
xor_vect.read = True
xor_vect.driven = True
and_vect = Signal(intbv(and_init)[data_length:])
and_vect.read = True
and_vect.driven = True
@always_seq(i_Clk.posedge, reset=None)
def compare() :
if i_DataEn :
cmp = True
for i in range(data_length) :
if bool((i_Data[i] ^ xor_vect[i]) & and_vect[i]) :
cmp = False
o_Match.next = cmp
return compare
You can use it this way :
match_inst = MatchPattern("01-10--").hdl(clk, data_en, data, match)
During elaboration, we can do everything we want. Here, we create masking vectors.
xor_vect and and_vect should be constants but we don’t have this in MyHDL for now.
Another version of the compare() function is this one :
@always_seq(i_Clk.posedge, reset=None)
def compare() :
if i_DataEn :
cmp_vect = intbv(0)[data_length:]
for i in range(data_length) :
cmp_vect[i] = bool((i_Data[i] ^ xor_vect[i]) & and_vect[i])
if cmp_vect == 0 :
o_Match.next = True
else :
o_Match.next = False
Here we create a vector which content is compared to 0 to get the result.
I don’t know which version is best. I believe it will depend on the toolchain synthesiser.
This is not an optimised design since all bits are computed while they should not. With the following pattern “01–0--”, only 3 bits need to be computed.
This can be done in the following way :
@always_seq(i_Clk.posedge, reset=None)
def compare() :
if i_DataEn :
cmp_vect = intbv(0)[nb_bits_to_cmp:]
cmp_index = 0
for i in range(data_length) :
if and_vect[i] :
cmp_vect[cmp_index] = bool(i_Data[i] ^ xor_vect[i])
cmp_index += 1
if cmp_vect == 0 :
o_Match.next = True
else :
o_Match.next = False
This works in simulation but I think it will not synthesise (I have not tried).