6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Sep 28, 2024 11:18 pm

All times are UTC




Post new topic Reply to topic  [ 353 posts ]  Go to page Previous  1 ... 4, 5, 6, 7, 8, 9, 10 ... 24  Next
Author Message
 Post subject:
PostPosted: Thu Feb 23, 2012 10:42 am 
Offline
User avatar

Joined: Tue Nov 16, 2010 8:00 am
Posts: 2353
Location: Gouda, The Netherlands
ElEctric_EyE wrote:
Opcodes for the B Accumulator are simple, not thought through at all.
For example, an LDA #$xxxx would look like $00A9, $xxxx in Hex Editor.
With a B Accumulator, a Macro/.BYTE on As65 using an LDB #$xxxx presently looks like $A9A9, $xxxx.


How about using $00A9 for LDA and $01A9 for LDB. That way you can use bit 8 as an override bit to switch from 'A' to 'B'. It's a small change, and it works seamlessly for any instruction currently using 'A', including LDA, STA, ASL A, PHA, TXA, or TAY. It is also easily extended to 'C' and 'D' accumulators by using an additional instruction bit.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Thu Feb 23, 2012 3:06 pm 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
I think I follow you. So it should look something like this?:
Code:
always @(posedge clk)
     if( state == DECODE && RDY )
        casex( IR[15:0] )           // decode all 16 bits
      16'b0000_0000_1110_1000,   // INX
      16'b0000_0000_1100_1010,   // DEX
      16'b0000_0000_101x_xx10,   // LDX, TAX, TSX
      16'b0000_0001_101x_xx10:   //TBX
            dst_reg <= SEL_X;

      16'b0000_0000_0x00_1000,   // PHP, PHA
      16'b0000_0000_1001_1010,   // TXS
      16'b0000_0001_0x00_1000:   //PHB
            dst_reg <= SEL_S;

      16'b0000_0000_1x00_1000,   // DEY, DEX
      16'b0000_0000_101x_x100,   // LDY
      16'b0000_0000_1010_x000,    // LDY #imm, TAY
      16'b0000_0001_1010_x000:   //TBY
            dst_reg <= SEL_Y;
         
      16'bxxxx_xxx1_xxxx_xxxx:
            dst_reg <= SEL_B;
      16'bxxxx_xxx0_xxxx_xxxx:
            dst_reg <= SEL_A;
   endcase


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Thu Feb 23, 2012 3:23 pm 
Offline
User avatar

Joined: Tue Nov 16, 2010 8:00 am
Posts: 2353
Location: Gouda, The Netherlands
ElEctric_EyE wrote:
I think I follow you. So it should look something like this?:
Code:
always @(posedge clk)
     if( state == DECODE && RDY )
        casex( IR[15:0] )           // decode all 16 bits
      16'b0000_0000_1110_1000,   // INX
      16'b0000_0000_1100_1010,   // DEX
      16'b0000_0000_101x_xx10,   // LDX, TAX, TSX
      16'b0000_0001_101x_xx10:   //TBX
            dst_reg <= SEL_X;

      16'b0000_0000_0x00_1000,   // PHP, PHA
      16'b0000_0000_1001_1010,   // TXS
      16'b0000_0001_0x00_1000:   //PHB
            dst_reg <= SEL_S;

      16'b0000_0000_1x00_1000,   // DEY, DEX
      16'b0000_0000_101x_x100,   // LDY
      16'b0000_0000_1010_x000,    // LDY #imm, TAY
      16'b0000_0001_1010_x000:   //TBY
            dst_reg <= SEL_Y;
         
      16'bxxxx_xxx1_xxxx_xxxx:
            dst_reg <= SEL_B;
      16'bxxxx_xxx0_xxxx_xxxx:
            dst_reg <= SEL_A;
   endcase

No, because now you have overlapping cases. For instance, the INX opcode now matches both SEL_X and SEL_A.

For SEL_X, SEL_Y, and SEL_S, bit 8 can be a don't care. So you could write something like this:
Code:
always @(posedge clk)
     if( state == DECODE && RDY )
        casex( IR[15:0] )           // decode all 16 bits
                16'b0000_000x_1110_1000,   // INX
                16'b0000_000x_1100_1010,   // DEX
                16'b0000_000x_101x_xx10,   // LDX, TAX, TBX, TSX
                      dst_reg <= SEL_X;

And similarly for SEL_Y and SEL_S. For SEL_A/SEL_B, something like this:
Code:
default:        dst_reg <= IR[8] ? SEL_B : SEL_A;


Basically, whenever something doesn't apply to the accumulator, just put an 'x' instead of a '0' in bit 8 position. When it does apply to the accumulator, add in an extra mux for bit 8 to choose between A and B. ETA: instead of using the "? :" operator, you can also add extra cases, but then you'd have to list all opcode patterns matching the accumulator(s), without overlapping any of the X/Y/S based patters.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Thu Feb 23, 2012 7:51 pm 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
Excellent! I believe it's working. I was able to see the B reg change value to the $00A5 I had in LDB #$xxA5. That's it. A very small Sim.

This is exciting to think of how many more opcodes just came to life! I have to wait until I get on a real computer to do some further testing because this laptop is agonizingly slow. Hopefully I can post an ISim tonight of a simple program:
Code:
   .CODE
  .ORG   $FFFFE000

LDBi              .MACRO          ;LDB #$xxxx
                  .BYTE $01A9
                  .ENDM
LDBa              .MACRO          ;LDB $xxxxxxxx
                  .BYTE $01AD
                  .ENDM
STBa              .MACRO          ;STB $xxxxxxxx
                  .BYTE $018D
                  .ENDM
DECBa             .MACRO          ;DECB $xxxxxxxx
                  .BYTE $01CE   
                  .ENDM                 
CMPBi             .MACRO          ;CMPB #$xxxx
                  .BYTE $01C9
                  .ENDM
                 
                                       
START             LDBi                           
                  .BYTE $00A5                 ;load $00A5 in B Accumulator
                  STBa
                  .WORD $00000400             ;store B Accumulator @$00000400
AA                DECBa
                  .WORD $00000400             ;***I was confused here***, no need for a DECB, still DEC $00000040
                  LDBa
                  .WORD $00000400             ;load B Accumulator with value @$00000040
                  CMPBi                               
                  .BYTE $00A0                 ;CMPBi #$00A0
                  BNE AA
                  RTS                         ;leads to BRK since no JSR


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Feb 24, 2012 2:29 am 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
This is awesome. It is working! I/we have a B Accumulator!
Will post a Sim soon after I get a better program than above to display proof of opcode recognition within the core. But the program above worked as expected on ISim... I would just like to include most if not all of the opcodes that use the Accumulator in a short cycle program.

Now, an observation about this line of code (which does work by the way):
Code:
default:        dst_reg <= IR[8] ? SEL_B : SEL_A;

After I got home from work tonight, I had to go read my 'Digital Design Using Digilent FPGA Boards (Verilog Edition)' by Haskell and Hanna and see how they implemented a 2 to 1 MUX, a very basic building block one must know the syntax of, obviously I do not. But I want to learn...
I saw the very same syntax as above, on pg.69. In their example, the expression was:
Code:
assign y = s ? b : a;
which reads: 'if s is true (logical 1) then y=b, else y=a.

Now I will quote them regarding this syntax: "This shortcut method of writing an if statement was inherited from the programming language C but its use should be discouraged because it is more difficult to understand than writing out the if statement as in Listing 5.3"
Listing 5.3 goes something like this:
Code:
...
always @(*)
    if (s == 0)
        y = a;
      else
        y = b;

endmodule

But, can we put an IF statement after a Default?
__________________________________________________________________________________________________________________________

The 2:1 MUX is good for IR[8] to choose SEL_A or SEL_B.

Now, going forward to the C and D Accumulators in addition to the A and B Accumulators, we will need a 4:1 MUX to put the DCBAXYS regsel data into the src_reg or dst_reg. I might be tempted to write something like this:
Code:
default:        dst_reg <= IR[9:8] ? SEL_D : SEL_C : SEL_B : SEL_A;

or this:
Code:
default:        dst_reg <= IR[9:8] ?? SEL_D : SEL_C : SEL_B : SEL_A;

but it seems this is not the proper syntax...


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Feb 24, 2012 6:44 am 
Offline

Joined: Sun Nov 08, 2009 1:56 am
Posts: 398
Location: Minnesota
Quote:
Posted: Thu Feb 23, 2012 8:29 pm Post subject:

but it seems this is not the proper syntax...


I doubt it. IMO it's the difficulty of extending the relatively simple:

Code:
(cond_expr) ? (true_expr) : (false_expr)


to more deeply nested cases that prompts so much advice to avoid it altogether. And it is hard to push it further and still be understandable (to humans, anyway).

Anyway, what you seem to be after is a four-way branch based on two conditions. I think it parses this way:

Code:
(cond_expr1) ? ((cond_expr2) ? (t1_t2) : (t1_f2)) : ((cond_expr2) ? ((f1_t2) : (f1_f2))


I don't know if that's the syntax your tool requires (or even allows), but it's pretty straightforward to decode if you look at it as simply using a nested ternary expression for both the 'true' and 'false' branch expressions of the nesting ternary expression.

You can go even further, in the sense that it won't confuse a competent parser to do this to any depth, but it's generally a lot easier for humans to write now and read later to set anything beyond the simplest case use out as multi-way IF/ELSE branches.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Feb 24, 2012 8:08 am 
Offline
User avatar

Joined: Tue Nov 16, 2010 8:00 am
Posts: 2353
Location: Gouda, The Netherlands
ElEctric_EyE wrote:
Now I will quote them regarding this syntax: "This shortcut method of writing an if statement was inherited from the programming language C but its use should be discouraged because it is more difficult to understand than writing out the if statement as in Listing 5.3"
Listing 5.3 goes something like this:
Code:
...
always @(*)
    if (s == 0)
        y = a;
      else
        y = b;
endmodule



It's a matter of taste. For short expressions, I find the ?: operator easy enough to read, but as the expression gets more complicated, I usually switch to other methods. If you prefer the if/else, you could use that instead.
Quote:
Now, going forward to the C and D Accumulators in addition to the A and B Accumulators, we will need a 4:1 MUX to put the DCBAXYS regsel data into the src_reg or dst_reg. I might be tempted to write something like this:

There are several approaches. You can continue using the ?: operator in the following way, which is still fairly readable.
Code:
default: dst_reg <= IR[9:8] == 2'b11 ? SEL_D :
                                   IR[9:8] == 2'b10 ? SEL_C :
                                   IR[9:8] == 2'b01 ? SEL_B :
                                                                    SEL_A;
 

You could also write a 2nd case statement inside the default:
Code:
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

And if you like to be a bit clever, you can also pick special bit patterns for the 'SEL_*' constants. Suppose SEL_A = 4'b1000, and SEL_B = 4'b1001, etc. Then you could write:
Code:
default: dst_reg <= { 2'b10, IR[9:8] };


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Feb 24, 2012 11:00 pm 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
I'm learning alot, thanks for sharing that info about MUX's!
It's all about the syntax. I had tried to come up with a way to do a default: case, but my syntax was way off! I do prefer that method.

So today I finished off adding the 2 other accumulators. I did a Sim on the short listing below and it worked.

My last immediate goal as far as adding things, is to add a Z index. Before that I think I should see if the core can still run @100MHz. I'll do that when I get home, and get off this sloth machine!

Code:
START             LDA #$A5
                  TAY
                  TYB
                  TYC
                  TYD
                  CLC
                  ADC #$0001           ;Add #$01 to A accumulator
                  ADCBi
                  .BYTE $0002          ;Add #$02 to B accumulator
                  ADCCi
                  .BYTE $0003          ;Add #$03 to C accumulator
                  ADCDi
                  .BYTE $0004          ;Add #$04 to D accumulator


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sat Feb 25, 2012 1:55 am 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
The new core, with 4 Accumulators, did not pass a 10.0ns O2In constraint...
However, it did pass a 10.5ns constraint! for a max of 99.48MHz.

EDIT: 10.5ns not 9.5ns.


Last edited by ElEctric_EyE on Sat Feb 25, 2012 10:43 am, edited 1 time in total.

Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sat Feb 25, 2012 7:18 am 
Offline
User avatar

Joined: Tue Nov 16, 2010 8:00 am
Posts: 2353
Location: Gouda, The Netherlands
Did you convert all instructions to work with any of the 4 accumulators where it previously only had A ?

I think a useful next step would be to add accumulator-accumulator transfer instructions, such as TAC, and TDB. This requires adding some opcodes too.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sat Feb 25, 2012 2:13 pm 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
Arlet wrote:
Did you convert all instructions to work with any of the 4 accumulators where it previously only had A ?

Yes. All the states related to A were changed in the Microcode state machine. So all addressing modes, etc. should work with B, C, & D Accumulators.

Arlet wrote:
...I think a useful next step would be to add accumulator-accumulator transfer instructions, such as TAC, and TDB. This requires adding some opcodes too.

I agree. I think I see how to do that.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sat Feb 25, 2012 2:42 pm 
Offline
User avatar

Joined: Tue Nov 16, 2010 8:00 am
Posts: 2353
Location: Gouda, The Netherlands
An interesting option is to allocate 2 different bits in the opcode space, say, bits 11-10, for the src_reg indexing, and bits 9-8 for dst_reg.

That way, you can do all kinds of interesting stuff like ADC B, A, #10, where an ADC operation is performed on A, and the result is stored in B.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sat Feb 25, 2012 9:53 pm 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
That is what I would like to do with a 16x16 multiply opcode.

I recently read on Xilinx forums someone posed a question about how to infer the DSP48A1 slices which hold these multipliers. There was a link there point to a bunch of multiplier examples. Still I need to finish the transfer opcodes and the Z register, then recheck top speed... Busy at work today, so unfortunately no progress on the core.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Feb 26, 2012 3:26 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10938
Location: England
Interesting developments!

It might be worth casting an eye over John West's design of the opcode encodings for 65020 (which is purely a paper design.) The machine isn't what we have - different register sizes for a start - but the encodings are quite interesting and they fit into a 16-bit opcode space, as an extension to a 6502 base.

http://www.ucc.gu.uwa.edu.au/~john/65020.html
http://www.ucc.gu.uwa.edu.au/~john/6502 ... tions.html

By flipping a few of his definitions (make the P bit the opposite value for a start) you might get something you could implement piece by piece.

Cheers
Ed


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Feb 26, 2012 7:16 pm 
Offline

Joined: Tue Jul 05, 2005 7:08 pm
Posts: 1041
Location: near Heidelberg, Germany
BigEd wrote:


Do you know how old this design is? There is no date on the page

André


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 353 posts ]  Go to page Previous  1 ... 4, 5, 6, 7, 8, 9, 10 ... 24  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


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: