Sunday 23 July 2023

Throwing an SD Card into the mix

Foreword

In the previous post we managed to get our 6502 based design to work with the DDR RAM on the Arty A7 board.

For this post I have originally planned to throw in SD Card access to our current design. However, this proofed to be a no brainer, so just covering this topic alone will yield a very short blog post.

Another topic I have thought of discussing in this post, was to prove that our 6502 based design works at a speed of an equivalent real 6502 processor at 8.33MHz. This is a doubt that pops up in me from time to time when mimicking retro system system that worked with asynchronous RAM, by means of synchronous RAM. This occasional doubt sprouts from the fact that with Synchronous RAM the data is only available when the clock transitions at the next clock cycle, whereas with asynchronous RAM the data is already available just before the next clock transition.

Proofing that our based design works at the same speed as an equivalent 8.33MHz based system, will put this doubt to rest.

Adding SD Card access to our design

I mentioned in the previous post that we need to ensure that we need ensure that we propagate all our SD Card ports of our retro module, all the way up to our top module.

With this done, we need to add the following constraints to our xdc file:

set_property -dict {PACKAGE_PIN G13 IOSTANDARD LVCMOS33} [get_ports cs]
set_property -dict {PACKAGE_PIN B11 IOSTANDARD LVCMOS33} [get_ports mosi]
set_property -dict {PACKAGE_PIN A11 IOSTANDARD LVCMOS33} [get_ports miso]
set_property -dict {PACKAGE_PIN D12 IOSTANDARD LVCMOS33} [get_ports sclk]
set_property -dict { PACKAGE_PIN D13   IOSTANDARD LVCMOS33 } [get_ports dat1]; #IO_L6N_T0_VREF_15 Sch=ja[7]
set_property -dict { PACKAGE_PIN B18   IOSTANDARD LVCMOS33 } [get_ports dat2]; #IO_L10P_T1_AD11P_15 Sch=ja[8]
set_property -dict {PACKAGE_PIN A18 IOSTANDARD LVCMOS33} [get_ports cd]
set_property -dict {PACKAGE_PIN K16 IOSTANDARD LVCMOS33} [get_ports wp]

Having done all this, I found that our design works perfectly with the flashing LED, as explained in this post: https://c64onfpga.blogspot.com/2023/04/sd-card-access-for-arty-a7-part-9.html. Only difference being that we use DDR for RAM and not Block RAM.

Another mission accomplished!!!

Benchmarking

Let us now see if we can determine the speed of our 6502 based design compared to an equivalent retro 6502 based system.

The benchmark I will be using, will be a bit of an unconventional one. I will be running a 6502 machine code program on a VICE Commodore64 emulator, constantly changing the border color. I will then run a similar program on our 6502 based FPGA, but flashing an LED. The comparison between the time changing the color of the border vs toggling an LED will be our benchmark.

This is perhaps an unfair comparison because the C64 looses execution time due to interrupts and the VIC-II that occasionally steels from the 6502 cycles to get extra display data. For this purpose we will be disabling interrupts and blanking the screen to avoid cycle stealing. The resulting C64 program is as follows:

    sei
    lda $d011
    and $ef
    sta $d011
    lda #0
    sta $4
    sta $5
    sta $6
    sta $7

lp1
    inc $4
    bne lp1
lp2
    inc $5
    bne lp1
lp3
    inc $6
    lda $6
    cmp #60
    bne lp1
    lda #$02
    eor $7
    sta $d020
    sta $7
    lda #0
    sta $6
    beq lp1

This program will blank the screen and alternate between red and black border. To determine how long it takes for the border color to transition, I made a video recording of the screen. I then played the recorded video back with VLC media player, making a note of the timestamp when screen transitions to red and when transitioning to black again.

Here is a screenshot of when screen turns red:


Here we see that screen turns red 26 seconds into the video. Next, the following screenshot show when screen turns black again:


Here we see see the screen turns black again 57 seconds into the video. Thus one color transition takes 57 - 26 = 31 seconds

Now, let us do a similar test with our FPGA based 6502 design. Here is the code:

    lda #$20
    sta $fb0b
    lda #0
    sta $fb0b

    lda #0
    sta $0
    sta $1
    sta $2
    sta $3

lp1
    inc $0
    bne lp1
lp2
    inc $1
    bne lp1
lp3
    inc $2
    lda $2
    cmp #60
    bne lp1
    lda #$20
    eor $3
    sta $fb0b
    sta $3
    lda #0
    sta $2
    beq lp1
Almost the same as our C64 variant, except that we are toggling a register for blinking an LED. This file will need to assembled and stored as a file boot.bin on the SD Card.

Now, this code takes 4 seconds to change from LED thats on, and turning off again. Let us do some math. 31/4 = 7.75, meaning our design is 8 times faster than a C64. Keeping in mind that a C64 operates at 1MHZ, this comes close to 8 MHz, which is more or less the speed of our FPGA based design.

In Summary

In this post we add SD Card access to our 6502 based design, bringing us to the point where our design can access an SD Card and DDR RAM.

We also ran a benchmark that confirms that our current design runs at around 8MHz.

In the next post I will start to develop a dual channel memory controller for accessing DDR RAM. The purpose will be so that our 6502 core and Amiga core can independently access DDR RAM at around 8MHz. This will enable the 6502 part of the system to read through a disk image and simulate disk access to the Amiga core.

Until next time! 

No comments:

Post a Comment