Page 6 of 8
Re: The RTF65002 Core
Posted: Fri Oct 11, 2013 9:30 am
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.
Re: The RTF65002 Core
Posted: Fri Oct 11, 2013 4:00 pm
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.
Re: The RTF65002 Core
Posted: Fri Oct 11, 2013 4:06 pm
by BigEd
How did you find it? Are you in simulation or running live? Do you have ChipScope?
Re: The RTF65002 Core
Posted: Sat Oct 12, 2013 12:36 am
by Rob Finch
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.
Re: The RTF65002 Core
Posted: Sat Oct 12, 2013 10:00 am
by BigEd
Thanks - history capture is a feature of your CPU?
Re: The RTF65002 Core
Posted: Sat Oct 12, 2013 12:48 pm
by Rob Finch
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:
Re: The RTF65002 Core
Posted: Sat Oct 12, 2013 1:00 pm
by BigEd
Very useful!
Re: The RTF65002 Core
Posted: Sat Oct 19, 2013 12:22 am
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 !
Re: The RTF65002 Core
Posted: Sun Oct 20, 2013 2:31 pm
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 !
Re: The RTF65002 Core
Posted: Fri Dec 06, 2013 7:30 am
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.
Re: The RTF65002 Core
Posted: Tue Jan 14, 2014 1:08 am
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
Re: The RTF65002 Core
Posted: Tue Jan 14, 2014 3:39 pm
by Rob Finch
Sharp eyes.
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.
Re: The RTF65002 Core
Posted: Sun Mar 23, 2014 7:59 am
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.
Re: The RTF65002 Core
Posted: Sun Mar 23, 2014 7:55 pm
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
Re: The RTF65002 Core
Posted: Sun Mar 23, 2014 10:52 pm
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.
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.
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).