Arlet / verilog-6502

A Verilog HDL model of the MOS 6502 CPU
http://c-scape.nl/arlet/fpga/6502/
327 stars 93 forks source link

Store instruction seems to write to wrong address #3

Closed ghost closed 9 years ago

ghost commented 9 years ago

When trying to execute the BBC OS ROM v 1.2 I get a failure very early on.

D9CD LDA #&40 ;set NMI first instruction to RTI D9CF STA &0D00 ;NMI ram start

This writes #&40 to &0000 rather than &0D00

I've tested this with Verilator. But seeing similar behaviour (unconfirmed) on Xilinx and Cyclone III.

Arlet commented 9 years ago

I suspect it's not the core that's failing but the memory interface. Keep in mind that the 6502 core expects to work with synchronous RAM. If you're using asynchronous RAM, you need to add a delay, e.g. by adding extra registers on address/control bus.

If you can't solve it, please show some waveforms (include clk, PC, AB, RW, DI, DO, A, statename as ASCII)

ghost commented 9 years ago

I had a look at the memory model i was using here and it runs off an address that is latched by the same clock as the cpu is running at. I've tried adding an extra delay/removing the delay and it causes more issues.

Here is a vcd of the system running. I usually view with gtkwave. The offending instruction is at 1200ns

https://www.dropbox.com/s/mn8vaax9itvcnh6/bbc.vcd?dl=0

ghost commented 9 years ago

I may have an idea whats happening here. Its because i have two blocks of memory and a ternary to switch the inputs. The switch happens the instant the address bus changes. I'll confirm then close if thats the case,

Arlet commented 9 years ago

Looks like the core has a problem with single cycle RDY=1 pulses. It forwards DI (data in) to address bus msb, but your model changes DI when RDY=0, so the core forwards the wrong value. I'll have to look into a proper solution.

ghost commented 9 years ago

The problem was as I said.

My databus demux is based on the current address bus value (as is in real machines). There isnt a bug but unfortunately all my other modules use the standard bus timings and therefore it would be a significant rewrite to use this core. :( shame.

The main issue is that i need to use a delayed AB for chip selects when reading but just straight AB when writing. Rather irritating when there is alot of address space to decode.

ghost commented 9 years ago

After a bit of fiddlry i managed to use this core to boot a BBC B model in verilator, Papilio Pro and on the MiST board. One thing i'd like to request is that the core simply builds in its own delay latch for DI to save everyone who implements it doing themselves. code to make it work is ..

always @(posedge CLOCK) begin

if (RDY) begin DI_real <= DI; end

end

since 99% of people who use this core will end up doing that for themselves. You could put it in a generate block and make it a conditional parameter maybe?

Arlet commented 9 years ago

I don't think that's very useful. Internal block RAMs (at least on brand X) are already synchronous, so you can attach them without delay. For external RAMs, it's better if the user decides where to put the extra delay. Typically you'd want to register the address/control outputs so you don't get glitches. On internal peripherals, you may want to put the delay in the DI path so you can pipeline long logic paths.

On realistic systems, you may have all 3 methods in the same memory map.

ghost commented 9 years ago

Fair enough.

Could you at least update the readme to warn about the different read/write timings. As it stands one would expect things to work as a real 6502 or in my case like the T65 model.

ghost commented 9 years ago

Just so you know i was using internal block rams synchronously. Perhaps it would be better to make the core wishbone compliant. That way the behaviour is well defined.

Here is a fun demo of your core running in verilator..

https://youtu.be/tZHcf109_s4