|
Message
From: Stephen Warren<s-t-opencores@w...>
Date: Sun Jun 3 02:07:49 CEST 2007
Subject: [oc] wb_z80 bug; Next instruction ignored after "ret z" when ~z?
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Hi,
I've been experimenting with the wb_z80 core from opencores.org, and I believe I've found a bug.
When I simulate the code below, the "push hl" command appears to be completely ignored. I've reproduced this using "ModelSimXE III 6.1e" together with "Xilinx ISE 8.2 webpack". Also, there's definitely a problem with the code (I assume the same thing) when synthesized for a Spartan 3E device.
I think what's happening is this:
Part of the code that calculates mem_exec_dec is:
{I1DCNT {RETsC == ir1 & cf }} & I1_RET |// RET C ; D8 {I1DCNT {RETsM == ir1 & sf }} & I1_RET |// RET M ; F8 {I1DCNT {RETsNC== ir1 & ~cf }} & I1_RET |// RET NC ; D0 {I1DCNT {RETsP == ir1 & ~sf }} & I1_RET |// RET P ; F0 {I1DCNT {RETsPE== ir1 & pvf }} & I1_RET |// RET PE ; E8 {I1DCNT {RETsPO== ir1 & ~pvf}} & I1_RET |// RET PO ; E0 {I1DCNT {RETsNZ== ir1 & ~zf }} & I1_RET |// RET NZ ; C0 {I1DCNT {RETsZ == ir1 & zf }} & I1_RET |// RET Z ; C8
If the "ret z" is taken, then the next state is correctly defined as I1_RET. However, if the z flag is clear, then there's no matching entry in the decoding, which evaluates to value 0, which is the I1_CB state, which simply eats the next instruction byte, I think...
Note that other conditional instructions (e.g. jp z, call z) aren't decoded in this way, because they always jump to a single state in order to read the 2-byte address to jump to, and that state then somehow implements the conditional jump, although I haven't managed to trace exactly how yet.
I guess the solution is to expand the above decoding, by adding an extra entry for each conditional ret instruction when the condition is false. However, there's no I1_NOP state to use here. I see that the real nop instruction uses the I1_R2R state, so I assume I could do that, although I'd worry about how to ensure that state doesn't actually write to any registers!
Does this analysis seem correct? Is I1_R2R the correct next state?
code org #0000
reset: set_sp: ld sp, stack_top
bug_start: ; Initialize flags, so they're not X ; Probably isn't relevant, but is distracting in wave view ld de, #0000 push de pop af ; Random setup to ensure registers are initialized ld hl, 0xaa55 ld a, 7 ; Start code that exactly matches that where the bug was found cp 0 ret z ; Without this NOP ; nop ; This PUSH is ignored push hl call ret_test pop hl end_bug: jp end_bug
ret_test: ret
stack_top: equ #07ff -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.2 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFGYgZVhk3bo0lNTrURAo/OAJ9WtQ7vsSpJFTxlZU50JOU6k9VyCACePURU xI1Ru7f6W2B6C3jh6jQ/d7A= =dIr6 -----END PGP SIGNATURE-----
|
 |