LOGIN   :::   RECOVER PASS   :::   GET ACCOUNT    
Browse
  • Projects
  • Code (CVS)
  • Forums
  • News
  • Articles
  • Polls
  •  
    OpenCores
  • FAQ
  • CVS HowTo
  • Mission
  • Media
  • Tools
  • Advertise
  • Mirrors
  • Logos
  • Contact us
  • Job Opportunity
  •  
    Tools
  • Search
      
  • Download Cores (CVSGet)
  •  
    More
  • Wishbone
  • Perlilog
  • EDA tools
  • OpenTech CD
  •  
    Navigation: All forums > Cores > Message List > Message Post

    Message

    Reply | Reply all
    Date Prev | Date Next | Thread Prev | Thread Next Date Index | Thread Index

    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?
    Top
    -----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-----

    Follow upAuthor
    [oc] wb_z80 bug; Next instruction ignored after "ret z" when ~z?Stephen Warren

     
    Copyright (c) 1999 OPENCORES.ORG. All rights reserved.