6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri Nov 22, 2024 5:02 pm

All times are UTC




Post new topic Reply to topic  [ 224 posts ]  Go to page Previous  1 ... 10, 11, 12, 13, 14, 15  Next
Author Message
 Post subject:
PostPosted: Thu Apr 14, 2011 5:13 am 
Offline
User avatar

Joined: Tue Nov 16, 2010 8:00 am
Posts: 2353
Location: Gouda, The Netherlands
To get into the microcode, means adding an extra 'if( RDY )' before the case statement, like so:

Code:
/*
 * Microcode state machine
 */
always @(posedge clk or posedge reset)
    if( reset )
        state <= BRK0;
    else if( RDY) case( state )
        DECODE  :
            casex ( IR )
                8'b0000_0000:   state <= BRK0;


It doesn't look like RDY support is all that complicated, but it requires some care if you want to do it with minimum of extra code/resources.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Thu Apr 14, 2011 6:56 pm 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
I tried inserting that bit of code, also declaring RDY in the cpu module. Ran a quick sim with the RDY pin grounded, and after a quick pulse to reset, it does indeed hold the state of the cpu. With the RDY pin high it runs normal.

Seems easy, but you must really know what you're doing with Verilog Arlet, if you can make a change like that with such a small amount of code!

I'll try it out in the hardware soon...

_________________
65Org16:https://github.com/ElEctric-EyE/verilog-6502


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Thu Apr 14, 2011 7:27 pm 
Offline
User avatar

Joined: Tue Nov 16, 2010 8:00 am
Posts: 2353
Location: Gouda, The Netherlands
Well, some more checks for RDY need to be added, otherwise things will go wrong with some instructions.

For instance, if you try holding RDY low while in RTI2 state, I think you'll see the AB value change every cycle, when it's supposed to be holding still.

As a minimum, I think you'll also need these changes:

Code:
always @(posedge clk)
    if( RDY ) begin
        ABL <= AB[7:0];
        ABH <= AB[15:8];
    end


And in ALU.v:

Code:
always @(posedge clk)
        if( RDY) begin
            OUT <= temp[7:0];
            CO  <= temp[8] | CO9;
            Z   <= ~|temp[7:0];
            N   <= temp[7];
            V   <= AI[7] ^ BI[7] ^ temp[7] ^ temp[8];
            HC  <= temp_HC;
        end


The ALU module needs to be extended with a 'RDY' input.

I haven't tested any of this, so I'm not 100% confident this is correct.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Thu Apr 14, 2011 9:29 pm 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
Arlet wrote:
...I haven't tested any of this, so I'm not 100% confident this is correct.


Consider me a beta tester then!

Granted, the software/hardware I am using now is not very taxing and doesn't test alot of different situations, but as I progress, the assembly will present more of a load and will put your alu/cpu modules through some tasks.
I'm planning to port over the 65C02 software I made for the PWA project where I was shifting and testing multiple sized character data and plotting the pixels on the 640x480 hi-res display. A little bit of math there...

I had already made a video of what the 3rd stage of the PWA project does @20MHz, and that was with discrete components. It consisted of a WDC65C02, 10ns 2Mx8 SRAM, 200ns 512Kx8 EEPROM, and a Spartan2 for a PS2 core and address decoding/RAM/EEPROM banking. It also used my "on the fly" O2 clock synchronizer to slow down the CPU and copy data from the EEPROM to RAM without program interruption. Looking back, it's too bad the Spartan 2 family doesn't have resources for internal RAM/ROM, or I'd still be experimenting with them...

I think it's time to do a comparison with the 6502SoC @38MHz and the 3rd stage PWA for my own "awe" factor, and for testing Arlet's 6502 core just to get the 6502SoC up to speed for further testing....

_________________
65Org16:https://github.com/ElEctric-EyE/verilog-6502


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Apr 15, 2011 11:56 am 
Offline
User avatar

Joined: Tue Nov 16, 2010 8:00 am
Posts: 2353
Location: Gouda, The Netherlands
This weekend, I'll probably have some time to play with the RDY changes myself.

I just started looking at it, and the changes I mentioned above are certainly not enough. First of all, the IR value gets messed up as soon as RDY is asserted in the DECODE state.

OK. This looks like it may work:

http://ladybug.xs4all.nl/arlet/fpga/6502/source/6502rdy.zip

I needed an extra MUX in the (already long) DI path, so I expect some impact on the timing.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Apr 18, 2011 1:44 am 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
Tonight after coming home from work, I was looking over previous posts and manually entering Arlet's (3) previous RDY mod's to be updated in the CPU.v / ALU.v modules in my new schematic. That is, before I realized his edit!
I would like to ask a Verilog beginners question at the very bottom...
Arlet wrote:

Excellent! I will be able to test the RDY in the hardware once I get the Flash successfully programmed. I'm currently working out a few issues now with system running @12MHz to accommodate the slow 70ns access time of the Flash. I'm trying to implement a top level bi-directional bus that goes to the Flash because I need to program it for a Chip Erase. Before, I was just trying to read from the Flash, but now I need to send 6 consecutive data at certain addresses for the Chip Erase. Got the software figured out, but...
Once I get it working, I'll be able to test RDY when the system is running @38MHz, and I plan to use a DCM, not just FF's. Will put wait states on everything accessed off chip, i.e. display, Flash, etc. Internal RAM and ROM will run full speed at all times.
As I mentioned before somewhere, I have my eye on the Spartan 6 and the same bi-directional bus structures apply to it. Although it seems to have different OBUF's, ISE auto-updates the design. Why Spartan 6? Because, I can solder it (a 144-pin QFP package) and when I put the current design on the Spartan 6, max speed (according to ISE) went from 51MHz to 89MHz...

My Verilog Newbie Question:
Are multiple "always" statements that are present inside of a module handled instantaneously, or is there a priority or a delay when instantiated? I ask this because I noticed you put RDY assignment last in the cpu module, while I had put it after reset. Was wondering if this minute detail affects anything?


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Apr 18, 2011 5:22 am 
Offline
User avatar

Joined: Tue Nov 16, 2010 8:00 am
Posts: 2353
Location: Gouda, The Netherlands
ElEctric_EyE wrote:
Are multiple "always" statements that are present inside of a module handled instantaneously, or is there a priority or a delay when instantiated? I ask this because I noticed you put RDY assignment last in the cpu module, while I had put it after reset. Was wondering if this minute detail affects anything?


All the "always" blocks are done simultaneously. So, if you have something like this:
Code:
reg RDY1 = 1;

always @(posedge clk )
    RDY1 <= RDY;

It gets implemented as a D-flipflop, clocked by 'clk', and with RDY as D-input, and RDY1 as the Q-output. It doesn't matter where this block is in the module.

On the other hand, when you have something like this:
Code:
always @(posedge clk )
    if( reset )
        IRHOLD_valid <= 0;
    else if( RDY ) begin

the 'reset' has a higher priority than 'RDY'.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Apr 19, 2011 4:15 pm 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
Thanks for the explanation...

I'm noticing a problem I'm having using the JSR.
Looking at ISim when a JSR $F0DE occurs, I see $20 on the 6502 DI, indicating the JSR. Then I see the $FO then $DE on the 6502 DO during the next 2 cycles. During this time on the 6502 address bus I see $01XX, and the internal RAM is active getting this bad address. Not sure how to proceed...

Image


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Apr 19, 2011 4:51 pm 
Offline
User avatar

Joined: Tue Nov 16, 2010 8:00 am
Posts: 2353
Location: Gouda, The Netherlands
It looks like those 2 cycles are pushing the return address (F0, DE) on the stack, and that you forgot to initialize the stack pointer.

Try adding 'statename' to the waveform, and the 'S' register.

This is what I get (without RDY), using this code:
Code:
FF69  20 D1 F7  JSR #F7D1 

Image

These are the states:

JSR0: push MSB return address on stack, fetch LSB destination (D1 on DI)
JSR1: push LSB return address on stack
JSR2: write stack pointer back to S register
JSR3: fetch MSB destination (F7 on DI)


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Apr 19, 2011 4:58 pm 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
Arlet wrote:
...you forgot to initialize the stack pointer....


How do I go about that?


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Apr 19, 2011 4:59 pm 
Offline
User avatar

Joined: Tue Nov 16, 2010 8:00 am
Posts: 2353
Location: Gouda, The Netherlands
Like you do on a real 6502:
Code:
LDX #$FF
TXS


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Apr 19, 2011 5:18 pm 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
I don't ever remember having to do this on the Commodore 64, but it used a 6510. Maybe there's a difference there? Maybe you just helped me fill in a long time knowledge gap... Either way, it works. Thanks again!

So, the $FF tells the 6502 that the stack will be $0100-$01FF?


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Apr 19, 2011 5:27 pm 
Offline
User avatar

Joined: Tue Nov 16, 2010 8:00 am
Posts: 2353
Location: Gouda, The Netherlands
No, the stack is always $0100-$01FF, but if you don't set the stack pointer, it will be initialized as a random value. On a real 6502, it may be initialized as $75 for instance. If you then do JSR, it will push the return address on $0175 and $0174. As the stack pointer reaches $00, and you push, it will wrap around to $FF. None of this causes any problems (except for debugging perhaps).

If you were to run this on an FPGA, it would initialize the stack pointer as $00 (default for any uninitialized flip flops), and everything would work fine.

The only problem is that the simulator treats unitialized variables as 'XX', which don't work as a valid address. If you want to avoid the TXS, you could add the following to cpu.v:

Code:
initial
     AXYS[SEL_S] = 8'hff;


This will initialize the stack pointer at the start of the simulation (and on the FPGA as well).


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Apr 19, 2011 5:40 pm 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
I will definately add that...

Can I think of AXYS as a 32 bit wide register, containing accumulator, x register, y register and stack, and that SEL_S is setting 8 bits of that register?


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Apr 19, 2011 5:43 pm 
Offline
User avatar

Joined: Tue Nov 16, 2010 8:00 am
Posts: 2353
Location: Gouda, The Netherlands
Yes, something like that. AXYS is defined as a small RAM, containing 4 locations, each containing 8 bits of data, holding the A, X, Y and S registers.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 224 posts ]  Go to page Previous  1 ... 10, 11, 12, 13, 14, 15  Next

All times are UTC


Who is online

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