6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Nov 23, 2024 9:37 pm

All times are UTC




Post new topic Reply to topic  [ 4 posts ] 
Author Message
 Post subject: adc cycles?
PostPosted: Sat Aug 17, 2013 11:15 pm 
Offline

Joined: Sat May 11, 2013 2:58 am
Posts: 12
I read that adc takes two cycles. So the 6502 must load the alu b register, load the alu output register with the sum, and output the sum into the accumulator all in one cycle? I don't see how this is possible with the registers being rising edge triggered. How is all this accomplished on such a small amount of time?


Top
 Profile  
Reply with quote  
 Post subject: Re: adc cycles?
PostPosted: Sun Aug 18, 2013 12:54 am 
Online
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8546
Location: Southern California
Perhaps you're thinking of this recent post, and the one after it, referring to ADC#, which I copied from the programming manual? I'm sure Ed or someone else who has been working on the visual6502 project will be along to explain better; but the addition and the storing back to the accumulator happen while the next instruction's op code is being fetched. I will add a question to it myself for him, to verify that not all latches are edge-triggered. There seem to be transparent latches too. Obviously both the rise and the fall of phase 2 are significant, not just one edge.

_________________
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  
 Post subject: Re: adc cycles?
PostPosted: Sun Aug 18, 2013 2:24 am 
Offline
User avatar

Joined: Mon Apr 23, 2012 12:28 am
Posts: 760
Location: Huntsville, AL
Gadersd:

There is a block diagram available for the 6502 that several others on the forum will be able to point you to. The block diagram of the 65SC02 can be found in its datasheet in the documentation section of this site. It is essentially to original 65C02 and it follows the architectural plan of the 6502 so it should be sufficient for most of your purposes.

As Garth alluded to, the 6502 does not use conventional registers in the modern sense. Since it uses a two phase clocking system, it has the capability of using both edge-sensitive storage (registers) and level sensitive storage (latches). In my efforts, which are FPGA based, I only use edge-sensitive storage elements. That is the natural storage element of an FPGA, and it's the recommended design approach for modern designs.

With an FPGA or CPLD it is possible to implement latches, but it will be difficult to emulate the tightly regulated timing that the designers of the 6502 achieved. Thus, it is best to emulate the actions/activities of the 6502 using edge-sensitive registers. I don't recommend mixing rising and falling edge registers in a design to more closely emulate the timing of the 6502. It is possible to just use rising edge registers to emulate the cycle timing of the 6502.

Several of us have implemented FPGA soft-cores for the 6502, and we all use edge sensitive registers for the storage elements. None of us have been able to implement a 6502 processor in an FPGA with the efficiency demonstrated by the designers of the original 6502. However, you have access on this site and through GitHub and Opencores to several good 6502 soft-core implementations.

Although it appears that you are interested in making your own 6502 core, I would recommend studying the general approach taken by one or more of the designs already available, and to use that knowledge to help you design your own core. There's not a single way to design a soft-core, and almost every core that is available is implemented differently than any of the others.

You will need to develop a block diagram for your core. I've attached the block diagram for the ALU for my core below. My core is microprogrammed, so I started my design from the ALU. I laid out the block diagram of the ALU, and worked out how all of the operations that the 65C02 would require could be implemented, independent of the sequencer/control logic, by the ALU. I did my design from the instruction point of view, and without looking at the block diagram of the 6502. I did this because I was not particularly interested in implementing the 6502 per se as much as I was interested in implementing the instruction set of the 65C02.

If you'll examine the block diagram of the 65SC02 and the block diagram of my ALU, you'll find that there is a lot of similarities. First, one operand of the ALU is taken from a processor register, and the other is taken from a register which holds the value read from memory. Second, the inputs to the processor registers can, for the most part, are connected directly to the output of the ALU, which in turn drives a bus which can be driven out to memory.

Thus, if independent select logic is provided for the operand multiplexers on the input of the ALU and separate enables are provided for the processor registers, then in a single clock cycle the input operands of the ALU can be set up and the combinatorial output of the ALU can be written back into a processor register, or captured in a temporary output register for writing back to memory on the next memory cycle.

I hope that the preceding discussion and the block diagram which follows helps clarify in your mind how these operations can be performed in a single clock cycle.
Attachment:
File comment: M65C02 Core ALU Block Diagram
M65C02_ALU.JPG
M65C02_ALU.JPG [ 69.07 KiB | Viewed 751 times ]

_________________
Michael A.


Top
 Profile  
Reply with quote  
 Post subject: Re: adc cycles?
PostPosted: Sun Aug 18, 2013 7:10 am 
Offline
User avatar

Joined: Tue Nov 16, 2010 8:00 am
Posts: 2353
Location: Gouda, The Netherlands
As said before, the original 6502 used latches, but modern cores use edge triggered flip-flops. In my core, I also only use positive edge triggered flip-flops, but still have the same cycle time per instruction as the original NMOS 6502.

The trick is that the total instruction fetch and execution of an ADC takes more than 2 cycles, but there's overlap with previous and following instructions so that the effective delay is only 2 cycles. Below you can see the timing diagram of the execution of this bit of code on my core. It should be instructive to compare this to the same instructions executed on visual6502.
Code:
FD2D  69 1F     ADC #$1F 
FD2F  30 02     BMI $FD33 

There's a total of 5 cycles, from start to finish, but one overlaps with previous instruction, and two overlap with next instruction, so only 2 are counted for the ADC instruction time.

In the first cycle on the diagram, you see PC = FD2D, and also AB=FD2D. The AB signal is the Address Bus. So in this cycle, the memory is instructed to fetch the byte at location FD2D, which is the opcode of the ADC instruction. This cycle overlaps with the previous instruction, so we don't count it towards the ADC instruction.

In the second cycle, you see PC has incremented to FD2E and the AB follows it. The AB is actually not a register. It is a simple MUX, which happens to follow PC in this state. The default behavior is for the PC to increment and fetch the next byte. Either it is the operand, or it is the next instruction, but we'll need it anyway (there are some exceptions, like jumps). In the meantime, the memory read from cycle #1 has resulted in DI=69, which is the opcode for the ADC #$1F instruction. The state machine is now in the DECODE state, and decodes the instruction as an immediate. There's nothing it can do until it fetches the operand.

In the third cycle, DI=1F, so the operand has been fetched. Now, look at the ALU inputs. There's an AI (A Input) signal that is 41, and a BI (B Input) that's 1F. These values are the result of a set of MUXes. The AI MUX selects the accumulator (A=41), and the BI MUX selects DI (databus in). The CI is the carry input, which is set. So, there are no registers in front of the ALU. It's a combinatorial path straight from the data input bus and from the register file. At the same time, we see that PC=AB=FD2F, so the core is already telling memory to fetch the next instruction.

In the fourth cycle, the ADD output shows the output register of the ALU. This is a true register. It is equal to 61 (=41 + 1F + 1). On the DI input you can already see the opcode of the BMI instruction, and the core will start to decode it.

In the fifth cycle, the accumulator is written with new value (A=61), taken from ADD register in cycle #4. In the meantime, the core is in the BRA0 (Branch 0) state, and has to decide whether to take the branch or not. Just in time to use the results from previous instruction.


Attachments:
ADC.png
ADC.png [ 7.49 KiB | Viewed 743 times ]
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 44 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: