Your regex matches because [^X] also matches H. Use [^XH] instead:
use strict;
use warnings;
use Test::More tests => 3;
my $re = qr{X[^XH]*?H[^HD]*?D};
my $str = "RXVXCHHHZHDT";
unlike("RXVXCHHHZHDT", $re);
like( "RXVXCHBNDT", $re);
unlike("RXVXCHHHZHDT", $re);