65ORG16.b Core

Topics relating to PALs, CPLDs, FPGAs, and other PLDs used for the support or creation of 65-family processors, both hardware and HDL.
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Post by BigEd »

ElEctric_EyE wrote:
BigEd wrote:
... It would be good to see a settled final version of this core and this thread!)

Ed
Why is this your opinion?
Good question! Let me consider. I certainly don't mean anything hostile.

I think what I'm getting at is that I want to congratulate you for a finished core: whether it's a v1.0 of the .b core, or the final .b core. For my taste, it would be good to see the end of a long development thread (in which much has been learnt) a short announcement, and then the start of another development thread if there is an expanded spec to be considered.

(I also realise that git and github allows us to tag versions, which means people can readily download a tar or zip file of that version. A stable version is probably more attractive for other people to have a look at.)

But it is a matter of taste!

Cheers
Ed
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Post by ElEctric_EyE »

Oh ok. And thanks! Well I guess I can say I'm done adding to the .b core with the addition of the IN[A..Q], DE[A..Q]. They tested ok in ISim. Actually, I had to rename the Macro's to INCA...INCQ etc., because of IN[C] conflict with the INC command that's already there.

I have 928 Macro's typed out (this is not RISC, eh?) which I would like to add to Github. This would be useful for anyone not used to reading Verilog for the actual individual opcode values. All the Macro's have been tested in ISim, and some have even been tested successfully in my TFT graphics drivers.

How can I go about adding this .txt file?
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Post by BigEd »

It turns out you can't add a file direct from the website interface - you can if you use git from your PC.

What you can do, I think, is create a wiki on GitHub and paste into a page on that. Or create n issue and paste into there. Or even paste into an existing file like say the README
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Post by ElEctric_EyE »

Ok thanks. I changed 1 of the README files. It currently has 928 Macros defining some opcode values. They are in As65 format.
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Post by ElEctric_EyE »

There are many, many more opcodes that need Macro definitions. I don't have time to write them all down. Simulations have proven that the backbone is functional. Hopefully the 'RULES' I put at the head of this thread will help anyone interested in development! Fingers crossed... If not, ask away! My eyes are here at least once a day and I'm eager to help, and I know I'm not the only one.

Now I am off to do the .c core in a new thread here in the Programmable Logic section. It will also be based on the original 'architecture' of Arlet's NMOS6502, since it has proven itself after many modifications made for the .b core, while still maintaining the highest speeds. However, I think compatibility with even most of the original NMOS 6502 opcodes will suffer, due to what I have in mind... Shhhh! Accumulators and Index registers will become one as the Y!
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Post by ElEctric_EyE »

I was back at the verilog today. I have the beginnings of another 'W' register using this

Code: Select all

ABSX0  : regsel = index_y ? SEL_Y : index_w ? SEL_W : SEL_X;
as the foundation.

So far I have only defined INW and DEW, but they are working correctly side by side the X and Y registers. They have the opcodes $00D8, and $00F8. I should be able to fit all the new index register opcodes into $00xx, i.e. empty columns $2, $3, and $7, so that the source/destination transpostional opcodes will work on 'W' as well.

With all the other opcodes that go along with adding another index register with full capabilities, I think my original idea for a .c core will have to be redefined...

Since adding another register was in the realm of my intent for the .b core, I thought I would keep adding to it and continue posting here.
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Post by ElEctric_EyE »

Ok, adding the opcode decoding for the W register has forced me to clean up the opcode table I was using from WDC6C02. What a mess that is/was! Anyway, I have changed just a few values of some opcodes previously added. Like INC [A..Q] and DEC [A..Q] now match the WDC65C02 for the A Accumulator at $xx1A and $xx3A and a couple other new ones were moved to make decoding the W reg easy and only a column or 2 off from the Y reg. Yes, the W reg is like the Y reg.

Take a look, here is the bottom layer (i.e. upper 8 bits of opcodes = $00)of the FINAL 65ORG16.b core!!!!
Image

I have to finish re-editing the macro's I presently have, then I can start testing. The verilog is already done. Not too difficult at all to modify the machine. The difficulty is keeping all the opcode encodings from getting tangled!

I have a little bit more editing to do on the above table... The only opcodes I have left to add are TXW, TYW, TWX, TWY.

This will be it for the 65Org16.b! :D
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Post by ElEctric_EyE »

I've "de-optimized" Arlet's opcode state machine in order to make sure I have every single bit perfect as it needs to be to obey the opcode table above, or the Sim will crash as it has been doing all day, at least on my fast machine, with ISE13.2, it is crashing. On my slow laptop, with ISE13.4, the Sim appears to be correct... I'm not blaming ISE at this point. I find errors in my opcode decoding frequently. It's not pretty, but progress will be made!

Code: Select all

/*
 * Microcode state machine */...
	    casex ( IR[15:0] )
  		16'b0000_0000_0000_0000:	state <= BRK0;
		16'b0000_0000_0010_0000:	state <= JSR0;
		16'b0000_0000_0100_0000:	state <= RTI0;  // 
		16'b0000_0000_0100_1100:	state <= JMP0;
		16'b0000_0000_0110_0000:	state <= RTS0;
		16'b0000_0000_0110_1100:	state <= JMPI0;
		16'bxxxx_xxxx_xxx0_01xx:	state <= ZP0;	 // even rows, columns 4,5,6,7
		16'b0000_0000_xxx1_0000:	state <= BRA0;  // odd rows, column 0
		
		16'bxxxx_xxxx_xxx0_0001:	state <= INDX0; // even rows, column 1 --(zp,x)
		
		16'bxxxx_xxxx_xxx1_0001:	state <= INDY0; // odd rows, column 1 --(zp),y
		16'bxxxx_xxxx_xxx1_0010:	state <= INDY0; // odd rows, column 2 --(zp),w
		
		16'bxxxx_xxxx_0xx1_0101:	state <= ZPX0;  // row 1,3,5,7, column 5
		16'bxxxx_xxxx_0xx1_0110:	state <= ZPX0;	 // row 1,3,5,7, column 6
		16'bxx00_xx00_10x1_010x:	state <= ZPX0;  // row 9,B, column 4,5
		16'b0000_0000_0111_0100:	state <= ZPX0;  // STW zpx
		16'bxxxx_xxxx_11x1_01xx:	state <= ZPX0;  // row D,F, column 4,5,6,7
		
		16'bxxxx_xxxx_0010_1100:	state <= ABS0;  // BIT abs
		16'bxxxx_xxxx_0xx0_1101:	state <= ABS0;  // row 0,2,4,6 even D column
		16'bxxxx_xxxx_0xx0_1110:	state <= ABS0;  // row 0,2,4,6 even E column
		16'b0000_0000_1xx0_11xx:	state <= ABS0;  // row 8,A,C,E, column C,D,E,F --X/Y/W abs
		
		16'bxxxx_xxxx_xxx1_1xx1:	state <= ABSX0; // odd rows, column 9,B,D,F
		16'bxxxx_xxxx_xxx1_1110:	state <= ABSX0; // odds rows, column E
				
		16'bxx00_xx00_0x00_1000:	state <= PUSH0; // PH[A..Q], PHP
		16'b0000_0000_x101_1010:	state <= PUSH0; // PHX, PHY
		16'b0000_0000_0100_1011:	state <= PUSH0; // PHW
		
		16'b00xx_00xx_0x10_1000:	state <= PULL0; // PL[A..Q], PLP
		16'b0000_0000_x111_1010:	state <= PULL0; // PLY, PLX
		16'b0000_0000_0110_1011:	state <= PULL0; // PLW
		
		16'b0000_0000_1xx0_00x0:	state <= FETCH; // IMM, row 8,A,C,E, column 0,2
		16'bxxxx_xxxx_xxx0_1001:	state <= FETCH; // IMM, even rows, column 9
		
		16'b0000_0000_0xx1_1000:	state <= REG;   // CLC, SEC, CLI, SEI
		16'bxxxx_xxxx_1xxx_1000:	state <= REG;   // DEY, TY[A..Q], T[A..Q]Y, INY, INX, INW, DEW
		16'bxxxx_xxxx_xxx0_1010:	state <= REG;   // <shift/rotate> [A..Q], TX[A..Q], NOP
		16'bxxxx_xxxx_00x1_1010:	state <= REG;   // INC/DEC [A..Q]
		16'bxxxx_xxxx_10x1_1010:	state <= REG;   // TSX, TXS
		16'bxxxx_xxxx_1xx0_1011:	state <= REG;	 // T[A..Q][A..Q],TYX,TXY
		16'bxxxx_xxxx_1111_00x0:	state <= REG;	 // TW[A..Q], T[A..Q]W
	  endcase
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Re: 65ORG16.b Core

Post by ElEctric_EyE »

Maybe I am misunderstanding something?. But as I understand it, the register select logic chooses the X or Y index registers here and only here (which I have modified):

Code: Select all

/*
 * register select logic. This determines which of the A thru Q, W, X, Y or
 * S registers will be accessed. 
 */

always @*  
    case( state )
	INDY1,
	INDX0,
	ZPX0,
    	ABSX0  : regsel = index_y ? SEL_Y : index_w ? SEL_W : SEL_X;
....
It appears to be under the absolute,x (ABSX0) but I assume the register select logic works for all addressing modes where the core has to select Y or X indexing?
User avatar
Arlet
Posts: 2353
Joined: 16 Nov 2010
Location: Gouda, The Netherlands
Contact:

Re: 65ORG16.b Core

Post by Arlet »

ElEctric_EyE wrote:
Maybe I am misunderstanding something?. But as I understand it, the register select logic chooses the X or Y index registers here and only here (which I have modified):

Code: Select all

always @*  
    case( state )
	INDY1,
	INDX0,
	ZPX0,
    	ABSX0  : regsel = index_y ? SEL_Y : index_w ? SEL_W : SEL_X;
....
It appears to be under the absolute,x (ABSX0) but I assume the register select logic works for all addressing modes where the core has to select Y or X indexing?
It's for all the states separated by the commas: INDY1, INDX0, ZPX0, and ABSX0. But yes, this is the only place.
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Re: 65ORG16.b Core

Post by ElEctric_EyE »

The comma, yes I should've recognized everything preceding a semicolon or colon is included in the argument. Thanks, learning continues...

So my MUX, is it good?

Code: Select all

regsel = index_y ? SEL_Y : index_w ? SEL_W : SEL_X;
I see BigEd deleted his post :wink: But the way I see the code is: Verilog will look at index_w first to see if it's a 1 or 0. Then it will look at index_y and regsel will be SEL_Y if index_y is 1, or SEL_W or SEL_X depending on the value of index_w.

If this is the case, I have all opcodes in place for indirect W addressing mode. There's just an error somewhere because after an INY in my test assembly code, it DECODEs a break $00, even though this is not in the assembly.
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Re: 65ORG16.b Core

Post by BigEd »

(I don't think I've ever deleted a post before... In this case I'd managed to say the same as Arlet, but got in just after he did, and was terse to the point of danger. So it had to go!)
User avatar
Arlet
Posts: 2353
Joined: 16 Nov 2010
Location: Gouda, The Netherlands
Contact:

Re: 65ORG16.b Core

Post by Arlet »

ElEctric_EyE wrote:
So my MUX, is it good?

Code: Select all

regsel = index_y ? SEL_Y : index_w ? SEL_W : SEL_X;
Yes, it'll work.

For clarity I would prefer an extra line:

Code: Select all

regsel = index_y ? SEL_Y :
         index_w ? SEL_W : SEL_X;
Or, as I suggested earlier:

Code: Select all

regsel = index_reg;
Where 'index_reg' is set up during DECODE, like src_reg, and dst_reg. This will improve clarity and timing when you add more registers.
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Re: 65ORG16.b Core

Post by ElEctric_EyE »

Excellent, thank you Arlet. At this point I would like to add just 1 more index register as I am using only a 16x16 opcode matrix to be compatible with all (except SED, CLD) NMOS6502 opcodes and a few more WDC65C02. I am very quickly running out of room on the 16x16 grid, so this will be the end of the .b core.

Something strange is going on, because on my laptop the core is functional. On my desktop speed machine, the core is crashing ISim. I will have to experiment further and figure it out...

I'm unsure if I should post what I have to Github?
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Re: 65ORG16.b Core

Post by ElEctric_EyE »

While looking for opcode decoding errors for load_reg in the .b core and comparing against Arlet's original posted on Github I noticed column 6 was not accounted for on Arlet's core. I think it should be, or am I mistaken?

I have a second 'W' register and indirect indexed store has tested ok, finally! Spent many days pouring over 1' and 0's, today finally found my issue as I expected in the decoding...

Will do some more testing, then see what top speed is. If all is ok, in a few days I'll post to Github.
Post Reply