Page 9 of 24

Posted: Fri Mar 02, 2012 1:16 pm
by ElEctric_EyE
Expanding the register file in such a way as I was doing (even though I was not aware of it) would most likely affect the top speed a little more than what I have done so far, which has only brought it down to ~95MHz from 100MHz. And changing the state machine is not something I wanted to tackle for the .b version.
I'll try using your suggestion on src_reg, dst_reg manipulation for ADC and SBC. Since there is a common carry to the 4 Accumulators, I wonder what kind of problems this will pose?

Posted: Fri Mar 02, 2012 4:29 pm
by ElEctric_EyE
Now I get it! Manipulating the dst_reg to put the result into any 1 of 4 Acc for all addressing modes of ADC/SBC/AND/ORA/EOR would be awesome. Your idea is almost exactly like what I wanted to do with the transfer with logic opcodes. Although I don't think the shift functions ASL/LSR/ROL/ROR would be too useful to do this. Those I would still like to modify the upper 4 bits of those instructions to do a 1 - 15 bit shift.

Posted: Sat Mar 03, 2012 1:35 am
by ElEctric_EyE
I'm going to take this modification one step at a time not necessarily for review, but just to show what I am doing/have done. If there is an error, please point it out.

Looking at all the addressing modes for ADC/SBC/AND/ORA/EOR opcodes for NMOS 6502, I've come up with the following (binary on the left, hex on the right):

Code: Select all

0xxx_0001.....$01-$71
0xxx_0101.....$05-$75
0xxx_1001.....$09-$79
0xxx_1101.....$0D-$7D
0xx1_0010.....$12, $32, $52, $72
111x_0001.....$E1,$F1
111x_0101.....$E5,$F5
111x_1001.....$E9,$F9
1111_0010.....$F2

Posted: Sat Mar 03, 2012 12:22 pm
by ElEctric_EyE
To see what bits are still available on the MSB of 65Org16.b opcodes I am looking at the microcode state machine, which I am going to slightly modify first. Bits 8 and 9 of the MSB have already been used to specificy 1 of 4 Accumulators. I would like to use bits 10 & 11, as Arlet has suggested earlier, to specify which Accumulator the dst_reg will select. This is the Microcode state machine presently.
I am going to add an xx for bits [11:10] in the Microcode state machine wherever the bit patterns in my previous post match below. For ones that don't match, I will add the bit pattern to the state machine with the appropriate state.

Code: Select all

DECODE  : 
	    casex ( IR[15:0] )  							 // decode all 16 bits
		16'b0000_0000_0000_0000:	state <= BRK0;
		16'b0000_0000_0010_0000:	state <= JSR0;
		16'b0000_0000_0010_1100:	state <= ABS0;  // BIT abs
		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'b0000_00xx_0x00_1000:	state <= PUSH0;
		16'b0000_00xx_0x10_1000:	state <= PULL0;
		16'b0000_00xx_0xx1_1000:	state <= REG;   // CLC, SEC, CLI, SEI
		16'b0000_0000_1xx0_00x0:	state <= FETCH; // IMM
		16'b0000_0000_1xx0_1100:	state <= ABS0;  // X/Y abs
		16'b0000_00xx_1xxx_1000:	state <= REG;   // DEY, TYA, ...
		16'b0000_00xx_xxx0_0001:	state <= INDX0;
		16'b0000_00xx_xxx0_01xx:	state <= ZP0;
		16'b0000_00xx_xxx0_1001:	state <= FETCH; // IMM
		16'b0000_00xx_xxx0_1101:	state <= ABS0;  // even D column
		16'b0000_00xx_xxx0_1110:	state <= ABS0;  // even E column
		16'b0000_0000_xxx1_0000:	state <= BRA0;  // odd 0 column
		16'b0000_00xx_xxx1_0001:	state <= INDY0; // odd 1 column
		16'b0000_00xx_xxx1_01xx:	state <= ZPX0;  // odd 4,5,6,7 columns
		16'b0000_00xx_xxx1_1001:	state <= ABSX0; // odd 9 column
		16'b0000_00xx_xxx1_11xx:	state <= ABSX0; // odd C, D, E, F columns
		16'b0000_00xx_xxxx_1010:	state <= REG;   // <shift> A, TXA, ...  NOP
		16'b0000_00xx_10xx_1011:	state <= REG;	 // TBA,TCA,TDA,TAB,TCB,TDB,TAC,TBC,TDC,TAD,TBD,TCDode]

Posted: Sat Mar 03, 2012 1:09 pm
by ElEctric_EyE
Ok, not too difficult. Only one opcode, $F2, unaccounted for. But this is a 65C02 instruction! Old habit, I am looking at the WDC datasheet for the opcode matrix...
Next in true hacker fashion (i.e. one who is just learning), I look for where else these opcodes occur after the state machine. I find a piece of code for load_reg and modify bits [11:10] for the matching opcodes (not shown).

Modified Microcode State Machine. Bits 11 & 10 will point to a dst_reg. The src_reg will also read these bits.

Code: Select all

DECODE  : 
	    casex ( IR[15:0] )  							 // decode all 16 bits
		16'b0000_0000_0000_0000:	state <= BRK0;
		16'b0000_0000_0010_0000:	state <= JSR0;
		16'b0000_0000_0010_1100:	state <= ABS0;  // BIT abs
		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'b0000_00xx_0x00_1000:	state <= PUSH0;
		16'b0000_00xx_0x10_1000:	state <= PULL0;
		16'b0000_00xx_0xx1_1000:	state <= REG;   // CLC, SEC, CLI, SEI
		16'b0000_0000_1xx0_00x0:	state <= FETCH; // IMM
		16'b0000_0000_1xx0_1100:	state <= ABS0;  // X/Y abs
		16'b0000_00xx_1xxx_1000:	state <= REG;   // DEY, TYA, ...
		16'b0000_xxxx_xxx0_0001:	state <= INDX0;
		16'b0000_xxxx_xxx0_01xx:	state <= ZP0;
		16'b0000_xxxx_xxx0_1001:	state <= FETCH; // IMM
		16'b0000_xxxx_xxx0_1101:	state <= ABS0;  // even D column
		16'b0000_00xx_xxx0_1110:	state <= ABS0;  // even E column
		16'b0000_0000_xxx1_0000:	state <= BRA0;  // odd 0 column
		16'b0000_xxxx_xxx1_0001:	state <= INDY0; // odd 1 column
		16'b0000_xxxx_xxx1_01xx:	state <= ZPX0;  // odd 4,5,6,7 columns
		16'b0000_xxxx_xxx1_1001:	state <= ABSX0; // odd 9 column
		16'b0000_xxxx_xxx1_11xx:	state <= ABSX0; // odd C, D, E, F columns
		16'b0000_00xx_xxxx_1010:	state <= REG;   // <shift> A, TXA, ...  NOP
		16'b0000_00xx_10xx_1011:	state <= REG;	 // TBA,TCA,TDA,TAB,TCB,TDB,TAC,TBC,TDC,TAD,TBD,TCD

Posted: Sat Mar 03, 2012 6:49 pm
by ElEctric_EyE
Ok, I believe I got it working!
For opcode bits [11:10] of ADC/SBC/AND/ORA/EOR the function I have looks like this:

Code: Select all

[11:10]      FUNCTION
  0: 0     original ADC/SBC/AND/ORA/EOR on 4 Acc's (as defined by bits [9:8])
  0: 1     add value in operand to A Acc and store in B Acc
  1: 0     add value in operand to B Acc and store in C Acc
  1: 1     add value in operand to C Acc and store in D Acc
This small chunk of assembly is working in ISim:

Code: Select all

$FFFFE0000        LDA #$07
                  TAB          ;Transfer A Acc to B Acc
                  CLC
                  ADC #$01
                  TAC          ;Transfer A Acc to C Acc
                  ADC #$01
                  TAD          ;Transfer A Acc to D Acc
$FFFFE00B         ADCAopBi     ;Add op value to A Acc, store in B Acc
                  .BYTE $0010
                  LDBi         ;LDB #$10
                  .BYTE $0010
                  TBA
                  CLC
--code trimmed here, due to waveform end--
Image

Posted: Sat Mar 03, 2012 8:53 pm
by ElEctric_EyE
I've updated the new 65Org16.b code on Github. The complete current Verilog listing is there as of today. It is partially tested but I believe it to be correct. If anyone sees errors please post here, I will do the same and I will continue testing and posting here...

Posted: Sun Mar 04, 2012 5:00 am
by ElEctric_EyE
Now I've been thinking, since the 'transposing stores' appear to be working using 2 bits, use 4 bits to maximize transposition. I will work on this next.
Just got done running synthesis, and the design still tops out at 94.6MHz using 2 bits!

Code: Select all

[13:10]      FUNCTION
  0: 0: 0: 0     original ADC/SBC/AND/ORA/EOR on 4 Acc's (as defined by bits [9:8])
  0: 0: 0: 1     add value in operand to A Acc and store in B Acc
  0: 0: 1: 0     add value in operand to A Acc and store in C Acc
  0: 0: 1: 1     add value in operand to A Acc and store in D Acc
  0: 1: 0: 0     add value in operand to B Acc and store in A Acc
  0: 1: 0: 1     add value in operand to B Acc and store in C Acc
  0: 1: 1: 0     add value in operand to B Acc and store in D Acc
  0: 1: 1: 1     add value in operand to C Acc and store in A Acc
  1: 0: 0: 0     add value in operand to C Acc and store in B Acc
  1: 0: 0: 1     add value in operand to C Acc and store in D Acc
  1: 0: 1: 0     add value in operand to D Acc and store in A Acc
  1: 0: 1: 1     add value in operand to D Acc and store in B Acc
  1: 1: 0: 0     add value in operand to D Acc and store in C Acc

Posted: Sun Mar 04, 2012 6:46 am
by Arlet
I don't get it. Are you still using bits 9:8 for the source selection ? If so, how does that combine with the extra 2 bits 13:12 ?

Posted: Sun Mar 04, 2012 12:15 pm
by ElEctric_EyE
I actually haven't thought it all the way through yet. I just thought I could do the same thing I did with regular 12 transfer opcodes. Maybe I have an error in the code there, even though it works in Sim.
I don't see what's so different from that though: If you have 4 Accumulators you have 16 viable possibilities for src_reg to dst_reg transfers...

Posted: Sun Mar 04, 2012 12:28 pm
by Arlet
Yes, but to encode those 16 possibilities, you only need 4 bits (11:8 ).

Posted: Sun Mar 04, 2012 1:58 pm
by ElEctric_EyE
Not sure what I was thinking. :roll:

Posted: Sun Mar 04, 2012 9:34 pm
by ElEctric_EyE
Question: I have observed that a

Code: Select all

always @(posedge clk)
     if( state == DECODE && RDY )
     	casex( IR[15:0] )
....
will execute first when the opcode matches the CASEX, then immediately after, on the next posedge clock

Code: Select all

default: case( IR[9:8] ) 
						2'b00: dst_reg <= SEL_A; 
						2'b01: dst_reg <= SEL_B; 
						2'b10: dst_reg <= SEL_C; 
						2'b11: dst_reg <= SEL_D;
					endcase 
default will execute?

Posted: Mon Mar 05, 2012 6:18 am
by Arlet
That shouldn't happen. The casex is only done when 'state == DECODE', and that only happens for 1 cycle.

Add 'statename' to your sim traces, and check for DECODE.

Posted: Mon Mar 05, 2012 7:26 pm
by ElEctric_EyE
I was misinterpreting what I was seeing, sorry... Too early and no coffee.

I've finished what I think will work for all the 'transposing store' opcodes. I'll have a very short amount of time tonight to do some preliminary testing. Bits [11:10] are dst_reg and [9:8] are src_reg.