The RTF65002 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
Rob Finch
Posts: 465
Joined: 29 Dec 2002
Location: Canada
Contact:

Re: The RTF65002 Core

Post by Rob Finch »

The core failed to increment the pc when it was supposed to, and then it executed the same instruction twice.
The instruction happened to be the mode switch instruction, so the processor didn't switch modes. Then it eventually went crazy executing invalid instructions until it finally got a bus error.

I think this may be timing related, the FPGA being 85% full and running at near max for the core. So the next thing to do is try decreasing the clock frequency to see if that helps. Otherwise I'm stumped because the code is in a loop and executes successfully a number of times before it fails.
E11AFail.gif
Last edited by Rob Finch on Mon Oct 21, 2013 3:09 am, edited 1 time in total.
User avatar
Rob Finch
Posts: 465
Joined: 29 Dec 2002
Location: Canada
Contact:

Re: The RTF65002 Core

Post by Rob Finch »

Found out it wasn't timing related at all. The core had a bug in it having to do with the emulation flag being set during interrupts.
The set flag caused the core to write out only the upper half of the interrupt return address, if the interrupt occurred while the core was in emulation mode.

It's fixed now. I hope to have the updated code posted shortly.
User avatar
BigEd
Posts: 11464
Joined: 11 Dec 2008
Location: England
Contact:

Re: The RTF65002 Core

Post by BigEd »

How did you find it? Are you in simulation or running live? Do you have ChipScope?
User avatar
Rob Finch
Posts: 465
Joined: 29 Dec 2002
Location: Canada
Contact:

Re: The RTF65002 Core

Post by Rob Finch »

Quote:
How did you find it? Are you in simulation or running live? Do you have ChipScope?
I found it running live. I figured it would take to long to find running in simulation since it didn't occur until several seconds after a key was pressed.
First I tried to change the noise profile by altering timing several different ways. When that didn't work,
I had had finally turned on history capture during interrupts, and saw the return address was screwy. It either had to be the store or the load of the PC. I figured out that the store of the PC wasn't working by back tracking through the code. I had code like this:

Code: Select all

	cyc_o <= 1'b1;
	stb_o <= 1'b1;
	we_o <= 1'b1;
	if (em || isStb) begin
		case(wadr2LSB)
		2'd0:	sel_o <= 4'b0001;
		2'd1:	sel_o <= 4'b0010;
		2'd2:	sel_o <= 4'b0100;
		2'd3:	sel_o <= 4'b1000;
		endcase
	end
	else
		sel_o <= 4'hf;
The em flag was set to true while trying to store a 32 bit value, causing only one byte to be stored.
I fixed it by cleaning up the code, and having a task accept a parameter for the store.
User avatar
BigEd
Posts: 11464
Joined: 11 Dec 2008
Location: England
Contact:

Re: The RTF65002 Core

Post by BigEd »

Thanks - history capture is a feature of your CPU?
User avatar
Rob Finch
Posts: 465
Joined: 29 Dec 2002
Location: Canada
Contact:

Re: The RTF65002 Core

Post by Rob Finch »

Quote:
Thanks - history capture is a feature of your CPU?
It's primarily meant for debugging the cpu. I'm not sure if I'd include it as a feature or not. It's only present in the cpu if the DEBUG option is set.
I found having a history capture valuable enough that I end up including it in the processor I'm working on. I included it in several different processors now. When it's combined with a bus error support, it makes finding some problems easy. I just run the sucker until it hits a bus error at which point the fault address is displayed. then it's possible to refer back to the source code.

It's only a handful of lines of code to include a history capture:

Code: Select all

		if (hist_capture) begin
			history_buf[history_ndx] <= pc;
			history_ndx <= history_ndx+7'd1;
		end
Then have a register somewhere where the history can be read back:

Code: Select all

		4'hA:	res <= history_buf[index];
User avatar
BigEd
Posts: 11464
Joined: 11 Dec 2008
Location: England
Contact:

Re: The RTF65002 Core

Post by BigEd »

Very useful!
User avatar
Rob Finch
Posts: 465
Joined: 29 Dec 2002
Location: Canada
Contact:

Re: The RTF65002 Core

Post by Rob Finch »

The random lines program doesn't work. This has led me to a long debug session. The random lines program is a little program that draws lines randomly on a bitmapped screen. I developed it to test a line-draw accelerator and the bitmcp screen controller.

The program hangs big time. It locks up the machine and not even interrupts work. It looks like a hardware problem of some sort. It looks like the cpu state machine is hung, because there's no bus error, and interrupts stop being processed.

An small interrupt routine is a trick to getting a processor up and working. To begin I just have a a flashing character on-screen (or a flashing LED). It can differentiate between a hardware and a sfotware problem. If there's a software problem, interrupts likely still work. If interrupts are stalled, then it's likely a hardware problem.

The core is now running @50MHz !
User avatar
Rob Finch
Posts: 465
Joined: 29 Dec 2002
Location: Canada
Contact:

Re: The RTF65002 Core

Post by Rob Finch »

Yup it was hardware. Two more hardware problems fixed. The second page of opcodes didn't work when a cache miss occurred during hte fetch of a page two opcode. And multiply, divide, and mod operations of more than eight immediate bits didn't work. All fixed now.
The random lines program works !
User avatar
Rob Finch
Posts: 465
Joined: 29 Dec 2002
Location: Canada
Contact:

Re: The RTF65002 Core

Post by Rob Finch »

The latest fix is adding missing TSB/TRB instructions in 32 bit mode. Found after reviewing the following post:viewtopic.php?f=2&t=48

Currently working on brk() and sbrk() functions which make use the bitmap instructions.
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: The RTF65002 Core

Post by barrym95838 »

Hey Rob,

I just noticed something interesting when re-reading your code sample posted earlier:

Code: Select all

....
   1372 00000A638                           putmsg3
   1373 00000A638 FA                            plx            ; pop the return address off the stack
   1374 00000A639                           pm5
   1375 00000A639 B5 20 01 00                   lb      r1,$0,x   ; load byte into accumulator
   1376 00000A63D E8                            inx
   1377 00000A63E 05 11 00                      ora      #0      ; test for end of string
   1378 00000A641 F0 06                         beq      pm6
   1379 00000A643 62 09 00                      bsr      putSer
   1380 00000A646 80 F2                         bra      pm5
   1381 00000A648                           pm6
   1382 00000A648 7C 00 00 00 00                jmp      ($0,x)   ; return to next code byte
                                            
                                            ; put character to serial port
                                            ; test and,bne,pha,pla,sta,lda,rts
                                            
   1387 00000A64D                           putSer
   1388 00000A64D 48                            pha               ; temporarily save character
...
It looks like your branch offsets are relative from the middle of the branch instruction, rather than the beginning of the next instruction. Does this require re-assembling old 6502 code, or does your processor somehow correct for this discrepancy when executing legacy code?

Mike
User avatar
Rob Finch
Posts: 465
Joined: 29 Dec 2002
Location: Canada
Contact:

Re: The RTF65002 Core

Post by Rob Finch »

Sharp eyes.
Quote:
It looks like your branch offsets are relative from the middle of the branch instruction, rather than the beginning of the next instruction. Does this require re-assembling old 6502 code, or does your processor somehow correct for this discrepancy when executing legacy code?
The discrepancy is corrected for when executing legacy code. When executing legacy code branches work as expected. When executing 32 bit code the branch is relative to the address of the branch instruction. This saves a hardware adder (or two) and a little bit of time. Otherwise an adder(s) would be needed to add a calculated length of the instruction to the PC as well as the branch displacement. The processor supports both eight and sixteen bit displacements in 32 bit mode. The processor fetches whole instructions at once from the cache rather than incrementing the PC a byte at a time and the address that's easily available to use is the address of the instruction. THe PC increment takes place in the DECODE stage at the same time the branch displacement is calculation.

This is an intentional feature of the processor. It's one of the things I mulled over as I didn't like the idea of two different starting points.
However I figured things are being assembled using software tools and not built by hand. As long as the tools are good it's not a huge problem.
User avatar
Rob Finch
Posts: 465
Joined: 29 Dec 2002
Location: Canada
Contact:

Re: The RTF65002 Core

Post by Rob Finch »

It was mentioned on comp.arch that the RTF65002 has only triple operand instructions (dst, src1, src2). So I've updated the core to support double operand instructions for some of the more common instructions. (inst dst, src). As there is room in the instruction set for them.

Triple operand format instructions are a more general approach to operands and easier for a compiler to use. However double operand instructions allow a more compact representation when they can be used. The instructions added consume just two bytes and two clock cycles.
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: The RTF65002 Core

Post by barrym95838 »

There was a slightly critical comment over there, but I wouldn't let it take up much space in my
head if I were you. It's your design, first and foremost, and you should tailor it to your liking.
I'm quite sure that it's impossible to please everyone, so I would concentrate on pleasing #1.

I took a bit of heat for exposing my 65m32 instruction pointer, but that's not going to change.

Mike
User avatar
Rob Finch
Posts: 465
Joined: 29 Dec 2002
Location: Canada
Contact:

Re: The RTF65002 Core

Post by Rob Finch »

Blowing off steam:

I had to search over 500 lines of BOOT code in order to find a sample where a 2 operand instruction saved code space over a 3 operand instruction.
Because of the byte oriented nature of the instruction set there is room for triple operand instructions, otherwise a nybble in the instruction would go wasted anyways. If desired, the assembler could be modified to accept a 2 operand format for instructions that it would then encode into a 3 operand instruction.
barrym95838 wrote:
There was a slightly critical comment over there, but I wouldn't let it take up much space in my
head if I were you. It's your design, first and foremost, and you should tailor it to your liking.
I'm quite sure that it's impossible to please everyone, so I would concentrate on pleasing #1.
Yes it was slightly critical, but a good comment. Many processors have 2 operand instructions and it's sometimes difficult to get one's head around porting software to a 3 operand format. It is also allows slightly shorter code in rare occasions.
barrym95838 wrote:
I took a bit of heat for exposing my 65m32 instruction pointer, but that's not going to change.
I've had the instruction pointer at least read-only in a couple of designs to allow formation of program counter relative addresses. If there are enough regs in the machine I like to include it as (eg reg 27). Fully exposing the pointer has been done before on some architectures. Not exposing the pointer turns it into a special register with dedicated special instructions to manipulate it. It may make the processor more difficult to implement though, having the ip exposed. Exposing the IP may make it necessary for an additional read/write port on the register file (pipelining).
Post Reply