|
Message
From: Stephen Warren<s-t-opencores@w...>
Date: Tue Jun 5 08:12:59 CEST 2007
Subject: [oc] wb_z80 bug; Next instruction ignored after "ret z" when ~z?
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Well, the workaround I mentioned below (adding extra decoding entries, which jump to I1_R2R) seems to work for me. LCD and UART IO are now working on my board:-)
Stephen Warren wrote: > 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 _______________________________________________ http://www.opencores.org/mailman/listinfo/cores
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.2 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFGZP7rhk3bo0lNTrURAkEDAKD5Hjx3ZRpV+KFCAzLXQlFaPTKNbgCdGvNk Dm9ra32ZbQPcJWWwsYpi618= =WbBK -----END PGP SIGNATURE-----
|
 |