6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Mon May 20, 2024 5:04 pm

All times are UTC




Post new topic Reply to topic  [ 20 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: 6502 Emulator in Verilog
PostPosted: Fri Jul 14, 2017 4:15 am 
Offline

Joined: Sun Mar 19, 2017 2:21 am
Posts: 25
I've been developing a cycle-accurate 6502 core that I plan to implement in a Xilinx FPGA using the internal block RAM as the full 64KB address range. The design uses two clocks, one for the processor and another for the memory, which runs 10X the speed of the processor. To test it, I've been building memory maps containing instructions that I've manually placed throughout the file. Right now the program is extremely simple:

8000: EA EA 4C 00 80 EA EA ....
...
...
FFFC 00
FFFD 80

The general idea is that the processor comes out of reset, gets the reset vector, and then just executes two NOP instructions followed by a JMP over and over. I'm having a hard time figuring out if the timing is correct though - does anyone see anything wrong with what I've got now? The code for it can be found here: https://github.com/gmcastil/6502.


Attachments:
timing_diagram.png
timing_diagram.png [ 107.82 KiB | Viewed 7194 times ]
Top
 Profile  
Reply with quote  
PostPosted: Fri Jul 14, 2017 4:31 am 
Online
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10802
Location: England
Nice project! I haven't studied your waveforms very closely, but for comparison here's how to use visual6502 for this kind of question:
http://visual6502.org/JSSim/expert.html ... ogmore=res

Edit: it looks like JMP should take three cycles, but you have five.


Top
 Profile  
Reply with quote  
PostPosted: Fri Jul 14, 2017 7:13 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8440
Location: Southern California
Yes, there's some minor pipelining, so for example ADC#<operand> takes only two cycles, STA ZP takes only three, etc.. WDC's data sheets tell what's on the buses in every cycle. I also strongly recommend getting the programming manual "Programming the 65816—Including the 6502, 65C02 and 65802" by David Eyes and Ron Lichty. The best! It's far better than the description there lets on.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Fri Jul 14, 2017 8:28 am 
Offline

Joined: Sat Jul 28, 2012 11:41 am
Posts: 442
Location: Wiesbaden, Germany
Pipelining

DECODE and OPER_A1 happen in the same cycle. The 6502 always fetches the second byte of an instruction, wether it is needed or not. The decode (PLA) then decides, wether the PC must be incremented or not. So after a one byte instruction the next instruction is fetched a second time.

EXECUTE and the next FETCH happen in the same cycle. If you need to run a byte through the ALU it happens in parallel with the next instruction beeing fetched. In case of the JMP abs EXECUTE is not needed. The address is plugged into the PC without going through the ALU. I am not sure however, if the 6502 skips the EXECUTE part or if there is a dummy EXECUTE with the next FETCH.

There is more parallel operation when it comes to address generation. Address generation also needs the ALU. For example: During indexed addressing the index is added to the low address during OPER_A2. If the result has a carry (page crossing) then an extra cycle is needed to add the carry to the high address.

_________________
6502 sources on GitHub: https://github.com/Klaus2m5


Last edited by Klaus2m5 on Fri Jul 14, 2017 8:46 am, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Fri Jul 14, 2017 8:31 am 
Offline

Joined: Sun Mar 19, 2017 2:21 am
Posts: 25
BigEd wrote:
Edit: it looks like JMP should take three cycles, but you have five.


Yep, I noticed that - I went back and removed some of the states I had and I think I have it now. I'm posting a revised waveform.

GARTHWILSON wrote:
Yes, there's some minor pipelining, so for example ADC#<operand> takes only two cycles, STA ZP takes only three, etc.. WDC's data sheets tell what's on the buses in every cycle. I also strongly recommend getting the programming manual "Programming the 65816—Including the 6502, 65C02 and 65802" by David Eyes and Ron Lichty. The best! It's far better than the description there lets on.


I'll start using that manual as my template then, thanks.

Thanks for the help guys - much appreciated.


Attachments:
timing_diagram_revised.png
timing_diagram_revised.png [ 93.43 KiB | Viewed 7170 times ]
Top
 Profile  
Reply with quote  
PostPosted: Fri Jul 14, 2017 8:37 am 
Offline

Joined: Sun Mar 19, 2017 2:21 am
Posts: 25
Klaus2m5 wrote:
Pipelining

DECODE and OPER_A1 happen in the same cycle. The 6502 always fetches the second byte of an instruction, wether it is needed or not. The decode (PLA) then decides, wether the PC must be incremented or not. So after a one byte instruction the next instruction is fetched a second time.

EXECUTE and the next FETCH happen in the same cycle. If you need to run a byte through the ALU it happens in parallel with the next instruction beeing fetched. In case of the JMP abs EXECUTE is not needed. The address is plugged into the PC without going through the ALU. I am not sure however, if the 6502 skips the EXECUTE part or if there is a dummy EXECUTE with the next FETCH.


Thanks for taking a look - I revised the FSM and pipelined everything so that I'm basically always reading one state earlier than I need it. Check out the updated waveform and the code here: https://github.com/gmcastil/6502/blob/master/src/proc.v.


Top
 Profile  
Reply with quote  
PostPosted: Sat Jul 15, 2017 6:21 pm 
Offline

Joined: Sun Mar 19, 2017 2:21 am
Posts: 25
So I've got the following program at $8000:

8000: NOP
8001: NOP
8002: LDA #$44
8004: LDA #$FF
8006: JMP $8000

Does the timing look correct for what I've implemented so far? If it looks good, I'm going to take a little bit of time to start working out some regression tests to add to the core so that as I add more features and support for more opcodes, I can make sure I don't break something. Also, if anyone has any additional suggestions or advice, I'd really appreciate it. Thanks.


Attachments:
timing_diagram_3_inst.png
timing_diagram_3_inst.png [ 120.57 KiB | Viewed 7126 times ]
Top
 Profile  
Reply with quote  
PostPosted: Sat Jul 15, 2017 6:52 pm 
Online
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10802
Location: England
I think that's right. There's already a number of 6502 test suites. See
http://visual6502.org/wiki/index.php?ti ... stPrograms


Top
 Profile  
Reply with quote  
PostPosted: Sat Jul 15, 2017 7:53 pm 
Offline

Joined: Sun Mar 19, 2017 2:21 am
Posts: 25
BigEd wrote:
I think that's right. There's already a number of 6502 test suites. See
http://visual6502.org/wiki/index.php?ti ... stPrograms


I'd like to take a more incremental approach to verification though - if there is something deeply wrong at this point, I'd rather fix it now. Or do those test suites identify things like which instruction works and which one doesn't?


Top
 Profile  
Reply with quote  
PostPosted: Sat Jul 15, 2017 8:22 pm 
Online
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10802
Location: England
Well, Klaus' popular suite will quit when it hits a broken instruction, so if you tackle your instructions in roughly the order it uses and tests them, that might feel like a good fit.

Or of course you could start by writing some number of short tests.

Ultimately, you intend to end up implementing everything though, so I'm not sure how much difference it makes. You probably need to be prepared to make some mistakes and rip up some code at some point.


Top
 Profile  
Reply with quote  
PostPosted: Sat Jul 15, 2017 8:59 pm 
Offline

Joined: Sun Mar 19, 2017 2:21 am
Posts: 25
BigEd wrote:
Or of course you could start by writing some number of short tests.


I might actually take a shot at doing something like this - I've been meaning to learn how to do constrained random verification in SystemVerilog and this might be a good project to start on. How are most community-developed 6502 cores verified?


Top
 Profile  
Reply with quote  
PostPosted: Sat Jul 15, 2017 9:51 pm 
Online
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10802
Location: England
They are all verified ad-hoc, really, some very lightly and some with more thoroughness. A few projects had their own test suite, and Lorenz had a very large one, and then Klaus came up with his and that helped find latent bugs in quite a few projects. I don't know of any project which has used coverage, or systematic test generation.


Top
 Profile  
Reply with quote  
PostPosted: Tue Jul 18, 2017 6:27 am 
Offline

Joined: Sun Mar 19, 2017 2:21 am
Posts: 25
So I think I'm going to try to develop a constrained random verification testbench for the processor - it's a simple enough design that I don't think it will be too difficult (and I've been looking for a project to learn more about that on anyway). As I started going through the opcodes this evening, I realized that there were some that were specific to the 65C02, so I'm going to try implementing both of them. So the core will eventually have a selection parameter of some sort, where you can choose to run it in MOS 6502 mode (which I want, because my end goal is building an 8-bit NES) or 65C02, with a lot of the earlier bugs fixed and some additional functionality. Anyone have any other suggestions as to what people might want to see?


Top
 Profile  
Reply with quote  
PostPosted: Tue Jul 18, 2017 6:32 am 
Online
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10802
Location: England
It'll be interesting to see what you come up with - especially if it's relatively easy to apply your verifier to other, existing, cores.

One thought: by checking the revision history of cores and emulators, you can see which bugs have commonly been fixed late in development. You can test your generator by seeing if it finds those bugs.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Jul 18, 2017 7:16 am 
Offline

Joined: Sun Mar 19, 2017 2:21 am
Posts: 25
BigEd wrote:
It'll be interesting to see what you come up with - especially if it's relatively easy to apply your verifier to other, existing, cores.

One thought: by checking the revision history of cores and emulators, you can see which bugs have commonly been fixed late in development. You can test your generator by seeing if it finds those bugs.


Yeah, that'd be pretty cool - I don't think it'd be that difficult to incorporate other cores since the signals are going to be the same going in and out. I'll try to make it as portable as possible.

The problem I ran into relatively early was the issue of asynchronous memory - I'm using Xilinx BRAM, overclocking it with an external 10X clock, and pipelining the hell out of the core. I still have to think that the end results should still all work.

The good news is that the hard part is already done - the FSM and decoder took a couple afternoons to straighten out (probably because i'm relatively new at this). But at this point, it's a matter of just adding in opcodes and making it wiggle like it's supposed to. I'll post something in the next week - I'd appreciate if other people can take a look at what I've got and can hammer on it for a bit to see if I've got holes that I'm unaware of. But, until I've got complete opcode coverage, that is probably not a good idea. Maybe once I've got the entire thing up and running, I'll make a new post and request people to hammer on it and try to break it. That sort of thing sounds pretty cool to me. Thanks for the feedback.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 20 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron