Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug fix: set shift count on MOV and OUT #2

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

monkbroc
Copy link

@monkbroc monkbroc commented Nov 21, 2021

Hi. This is a great project. It helped me simulate a PIO algorithm for a quadrature encoder. I was also blown away by the documentation. You did such a spectacular job 👏

I ran into what I think is an oversight in the implementation of the MOV and OUT instructions.

According to the RP2040 datasheet, the MOV instruction clears the ISR and OSR shift counters. Additionally, when the destination for OUT instruction is the ISR register, it sets the ISR shift counter to the bit count.

image

image

I implemented the changes to the simulator. I'm providing test cases for the three operations. These test case PIO programs don't do anything useful but they show the issue and the fix.

Steps to reproduce the issue with mov isr

reset
enter -a 0 -v 0xe023 #  0: set    x, 3                       
enter -a 1 -v 0x4022 #  1: in     x, 2                       
enter -a 2 -v 0xa0c3 #  2: mov    isr, null                  
enter -a 3 -v 0x0000 #  3: jmp    0                  
sm --pio=0 --sm=0 --enable=true
trace --cycles=4
registers

Expect ISR_SHIFT_COUNT=00000000 after mov isr, null,

Before fix:

> (pio0:sm0) X=00000003, Y=00000000, PC=03
           ISR=00000000, ISR_SHIFT_COUNT=00000002
           OSR=00000000, OSR_SHIFT_COUNT=00000020

After fix:

> (pio0:sm0) X=00000003, Y=00000000, PC=03
           ISR=00000000, ISR_SHIFT_COUNT=00000000
           OSR=00000000, OSR_SHIFT_COUNT=00000020

Steps to reproduce the issue with mov osr

reset
enter -a 0 -v 0xe023 #  0: set    x, 3                       
enter -a 1 -v 0xa0e1 #  1: mov    osr, x                     
enter -a 2 -v 0x6022 #  2: out    x, 2                       
enter -a 3 -v 0x0000 #  3: jmp    0       
fifo --tx --shift-right
sm --pio=0 --sm=0 --enable=true
trace --cycles=3
registers

Expect OSR_SHIFT_COUNT=00000000 after mov osr, x

Before fix:

> (pio0:sm0) X=00000003, Y=00000000, PC=02
           ISR=00000000, ISR_SHIFT_COUNT=00000000
           OSR=00000003, OSR_SHIFT_COUNT=00000020

After fix:

> (pio0:sm0) X=00000003, Y=00000000, PC=02
           ISR=00000000, ISR_SHIFT_COUNT=00000000
           OSR=00000003, OSR_SHIFT_COUNT=00000000

Steps to reproduce the issue with out isr

reset
enter -a 0 -v 0xe023 #  0: set    x, 3                       
enter -a 1 -v 0xa0e1 #  1: mov    osr, x                     
enter -a 2 -v 0x60c2 #  2: out    isr, 2                     
enter -a 3 -v 0x0000 #  3: jmp    0                          
fifo --tx --shift-right
sm --pio=0 --sm=0 --enable=true
trace --cycles=4
registers

Expect ISR_SHIFT_COUNT=00000002 after out isr, 2

Before fix:

> (pio0:sm0) X=00000003, Y=00000000, PC=03
           ISR=00000003, ISR_SHIFT_COUNT=00000000
           OSR=00000000, OSR_SHIFT_COUNT=00000020

After fix:

> (pio0:sm0) X=00000003, Y=00000000, PC=03
           ISR=00000003, ISR_SHIFT_COUNT=00000002
           OSR=00000000, OSR_SHIFT_COUNT=00000002

Section 3.4.8. MOV of the RP2040 Datasheet say that using OSR or ISR as the destination of MOV clears the ISR or OSR shift counter to 0
Section 3.4.5. OUT of the RP2040 Datasheet say that using ISR as the destination of OUT sets the ISR shift counter to the bit count of the OUT instruction
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant