Last visit was: Sun Sep 19, 2021 11:32 am
It is currently Sun Sep 19, 2021 11:32 am



 [ 507 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6, 7, 8 ... 34  Next
 Thor Core / FT64 
Author Message

Joined: Sat Feb 02, 2013 9:40 am
Posts: 1484
Location: Canada
Got a clue as to what's going on but I'm not sure what to make of it.
During the ram test routine on rare occasions the ram test fails and displays a code address as the failing data. This means somehow a code address is getting into the data stream. I can guess that the opposite might also be true (data showing up as a code address). A second clue is after running the ram test routine the processor frequently encounters a break (byte 00) instruction when it shouldn't.
All the devices in the system force the data bus to zero when not accessed so that all the outputs can be wire or'd together rather than multiplexed.
So it looks like the instruction cache may be loading that zero rather than valid instructions. Is the cache getting a ack pulse too soon ?
Is it a bad store operation ? Or a cache load problem ?
Note this is only a problem after the processor runs for millions of cycles.

I'm trying to get a small graphics demo running on the board but not having much luck.

_________________
Robert Finch http://www.finitron.ca


Sat Apr 30, 2016 4:16 am WWW

Joined: Wed Jan 09, 2013 6:54 pm
Posts: 1632
Is it at all possible this is a timing problem - a hold time violation?


Sat Apr 30, 2016 9:12 am

Joined: Sat Feb 02, 2013 9:40 am
Posts: 1484
Location: Canada
Quote:
Is it at all possible this is a timing problem - a hold time violation?

It looks to me too like it might be a timing problem. I tried lowering the operating frequency but got the same effect. Of course if it's a hold time problem that might not make a difference. The code address appearing for data doesn't happen all the time. Which is another clue. I can run the test a dozen times and it'll work. So it's inconsistent. Something is borderline working I think. The other problem of getting a break instruction is fairly consistent. I do get a "failed to reach timing requirements" message but it has to do with the ddr ram interface and I think cross clock domain crossing were you would get that message without specifying an ignore false paths. I haven't been able to figure out yet how to specify *all* the timing constraints for the ddr. Or rather the tools ignore some of the specs claiming there's syntax errors (which is maybe true). I followed a suggested procedure to generate the constraints automatically but it didn't work.
The tools are supposed to take care of timing problems for you, so I wouldn't expect a hold problem.
I've seen the BRK instruction error before, even in simulation, when there's a bit error in the data. The '01' predicate changes to a '00' predicate which is the break instruction. The other time it's happened occurs when there's a bit error in the instruction length (or address) causing the instruction address to fall one short. A lot of instructions end in '00' so a failing address bit causes a BRK. But right now I try to work on the consistent errors, not the spurious bit errors that occur naturally.

_________________
Robert Finch http://www.finitron.ca


Sat Apr 30, 2016 1:56 pm WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 1484
Location: Canada
I managed to eliminate most of the potential timing errors by being able to specify constraints better. The tools now ignore a number more of the false paths. But I'm still not having any better luck getting the system to work reliably. As far as I can tell what's reported as potential timing errors are all false paths that shouldn't cause a problem.

I managed to prove the bitmap controller *doesn't* work when plotting pixels for the graphics demo. It accesses the correct 16 byte memory strip that contains the pixel to plot, but then it sets most of the strip to zero (black) rather than keeping the current colours. Drawing a diagonal line then draws a series of black rectangles on the screen. The controller first reads the strip, modifies it, then writes it back. So I'm going to try leaving out the modification part to see if the read-write piece at least works.

_________________
Robert Finch http://www.finitron.ca


Tue May 10, 2016 5:20 am WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 1484
Location: Canada
Got the bitmap controller to work a little better. There was a wire defined as only 32 bit when it should have been 128 bits, which caused the upper 96 bits to display black. So now the controller almost displays a diagonal line rather than a series of rectangles. The display has me a bit mystified at the moment as it displays a saw-tooth type pattern with the first pixel in a strip displaying 10 lines too low, and the remaining pixels displaying okay. The horizontal position of the pixels seems fine, it's just the vertical position of the first pixel of a strip that is off. In order for it to be off by 10 scanlines, the y coordinate must have an extra 10 added to it somehow. The calculation isn't fundamentally that difficult to understand. mem address = number of displayed strips * y-coordinate + number of strips for x coord. It's just a multiply and an add, and I can't see any logical errors to it. The other thing that is screwy is the pixel color. It's supposed to be orange but it's coming out black most of the time (sometimes it's orange).

On the processor front I added an extra cycle of setup time to memory addressing. I also changed how immediate prefixes are processed slightly. The result appears to be the same. The program still hangs in the same manner.

_________________
Robert Finch http://www.finitron.ca


Wed May 11, 2016 8:16 am WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 1484
Location: Canada
Here is the line draw code:
Code:
      ; Draw a diagonal line to test bitmap controller
    ldi   r1,#0            ; start at (0,0)
    ldi   r3,#0xEA4        ; 12 bit orange color
    ldi   r4,#$10002       ; 2 = plot pixel, 1 = raster op copy
    sh    r3,BMP_COLOR     ; set color register
.su4:
      sh    r1,BMP_PX        ; set pixel X-coord
      sh    r1,BMP_PY        ; set pixel Y-coord
.su3:
   lvh   r2,BMP_PCMD       ; load volatile from I/O
    tst   p0,r2            ; check that last command completed
p0.ne     br   .su3           ; not likely to branch back
      sh    r4,BMP_PCMD      ; issue plot command
      addui r1,r1,#1         ; increment pixel co-ordinate
      cmpi  p0,r1,#192       ; 192 pixels
p0.lt     br   .su4


_________________
Robert Finch http://www.finitron.ca


Wed May 11, 2016 8:42 am WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 1484
Location: Canada
Figured out the saw-tooth pattern I think. I re-arranged the line draw code to set the pixel coordinates just before the plot command is issued as illustrated in the following code. I think what was happening was the PY coordinate was changing while the plot command was taking place. I also figured out the black vs orange color problem, it was simple, the line draw code was actually in two places, one at the ram test routine and again in the mainline of the boot code. The second time the line draw code was encountered it was drawing the line in black.

Code:
      ; Draw a diagonal line to test bitmap controller
    ldi   r1,#0            ; start at (0,0)
    ldi   r3,#0xEA4        ; 12 bit orange color
    ldi   r4,#$10002       ; 2 = plot pixel, 1 = raster op copy
    sh    r3,BMP_COLOR     ; set color register
.su4:
.su3:
   lvh   r2,BMP_PCMD       ; load volatile from I/O
    tst   p0,r2            ; check that last command completed
p0.ne     br   .su3           ; not likely to branch back
      sh    r1,BMP_PX        ; set pixel X-coord
      sh    r1,BMP_PY        ; set pixel Y-coord
      sh    r4,BMP_PCMD      ; issue plot command
      addui r1,r1,#1         ; increment pixel co-ordinate
      cmpi  p0,r1,#192       ; 192 pixels
p0.lt     br   .su4


The pixel plot functionality of the controller seems to be working. There is just a small glitch in the display now.

_________________
Robert Finch http://www.finitron.ca


Thu May 12, 2016 3:37 am WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 1484
Location: Canada
I found one problem with the compiler that is causing some grief. It's outputting code to adjust the stack after a function call when it shouldn't be. The base pointer gets toasted, the stack pointer gets toasted then the return address is wrong. I found this by running code in the emulator. set_vector() is declared as having the pascal calling convention which means the called function cleans up the stack parameters.

Code:
FFFC3027 01 47 1B FC                                        addui   sp,sp,#-16
FFFC302B 50 08 FC FF 00 01 6F 03 18                         ldi     r3,#_FMTK_SystemCallj
FFFC3034 01 93 DB 80 C0                                     sw      r3,8[sp]
FFFC3039 01 6F 03 01                                        ldi     r3,#4
FFFC303D 01 93 DB 00 C0                                     sw      r3,0[sp]
FFFC3042 01 A2 01 F7 86 FC                                  jsr     _set_vector
FFFC3048 01 47 1B 04                                        addui   sp,sp,#16


So a fix to the compiler is needed.

I haven't seen some of the intermittent errors recently after adding a cycle of setup time and additional timing specs.

_________________
Robert Finch http://www.finitron.ca


Mon May 23, 2016 4:37 am WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 1484
Location: Canada
After a fix to the compiler, it still doesn't work. The compiler now accepts an unsigned or signed variable of the same type as matching during signature matches.
A problem was that the compiler couldn't match a function signature (eg from a prototype) to a function call instance.
So a prototype like:
void functA(unsigned int, unsigned int);
would not match a function call:
functA(10,20);
Because the parameters get parsed as signed ints which doesn't match the unsigned spec in the prototype.

Anyway, I''m changing the way segmentation works to be more like the PowerPC style. Rather than using a field in the instruction to specify the segment, the upper three bits of a register will contain the segment register number. I hope this will make segmentation invisible to user mode code. It also gives three more bits in every load / store instruction with which to form addresses. Problems were appearing with the current implementation of which segment to use in a called function given a pointer to information.

_________________
Robert Finch http://www.finitron.ca


Wed Jul 20, 2016 5:18 am WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 1484
Location: Canada
Wondering if to add a custom instruction to set the segment number bits in a register. The goal would be to conserve memory space over a simple LDI# (load immediate) since it's the upper bits of the register that need to be set. Setting the segment number bits can be done without additional instructions but the code density is gone.
The problem is how do the segment register number bits get set in the target register ?
If the address of a variable or function is being loaded into a register usually the load immediate (LDI) instruction is used.
Code:
LDI R6,#MyAddress

The bitfield insert immediate (BFINSI) instruction could be used to set the segment register number bits.
Code:
BFINSI R6,61,63,#Segment(MyAddress)

But the instruction takes 6 bytes! It’s really no better than the following:
Code:
LDI R6,#MyAddress|(Segment(MyAddress) << 61)

This is ugly because it turns every address load operation into a 64 bit immediate load that takes about 10 bytes.
My other thought is to allow the segment register number to be specified by the immediate load instruction. Code would look like:
Code:
LDISEG R6,#MyAddress

There would be a three bit field build into the LDI instruction in order to specify the segment. If offers the best code density.

_________________
Robert Finch http://www.finitron.ca


Thu Jul 21, 2016 5:15 am WWW

Joined: Wed Apr 24, 2013 9:40 pm
Posts: 205
Location: Huntsville, AL
Rob:

Can't say that I'm following everything that you're posting on this thread regarding to the problem you're encountering with your Thor core, but I think that your last proposal appears to be the best. I think it appears to be the simplest of the proposed solutions to setting a bit field in one of your registers, but it also appears to me that it allows you the best option on the code generation side of the problem: it's simple and direct.

Quote:
My other thought is to allow the segment register number to be specified by the immediate load instruction. Code would look like:
Code:
Code:
LDISEG R6,#MyAddress


There would be a three bit field build into the LDI instruction in order to specify the segment. If offers the best code density.

_________________
Michael A.


Thu Jul 21, 2016 9:59 am

Joined: Sat Feb 02, 2013 9:40 am
Posts: 1484
Location: Canada
Well I went to add the code to support the LDISEG instruction, then I changed my mind and decided to leave it out for now, though the opcode is allocated. There are other ways to set the bits as previously mentioned. The code to queue an immediate operand looks like:
Code:
    iqentry_a0[tail]   <=
`ifdef VECTOROPS
          (opcode1==`LVX || opcode1==`SVX) ? {vel,3'b0} :
`endif         
          (opcode1==`INT || opcode1==`SYS || opcode1==`RTF || opcode1==`JSF) ? fnImm(fetchbuf1_instr) :
          fnIsBranch(opcode1) ? {{DBW-12{fetchbuf1_instr[11]}},fetchbuf1_instr[11:8],fetchbuf1_instr[23:16]} :
          (queued1 && opcode0==`IMM) ? {fnImmImm(fetchbuf0_instr)|fnImm8(fetchbuf1_instr)} :
          (!queued1 && iqentry_op[(tail-3'd1)&7]==`IMM) && iqentry_v[(tail-3'd1)&7] ? {iqentry_a0[(tail-3'd1)&7][DBW-1:8],fnImm8(fetchbuf1_instr)} :
          opcode1==`IMM ? fnImmImm(fetchbuf1_instr) :
          fnImm(fetchbuf1_instr);

and I'd have to add another mux and comparator for the high order bits. Handling of immediates was something I wanted to simplify. The number of logic levels is probably a performance killer.

I'm sacrificing the top three address bits in my system as a quick way to get the seg. reg. number. Eight banks of memory will all alias to same physical memory.
$2xxxxxxx references the same memory as $0xxxxxxx, etc. I can then origin variables in bank 001 as data segment variables and just use the assemblers calculated address to load both the address and seg. reg. number.
Memory Bank (corresponding to seg. reg. num)
000
001 = data segment
110 = stack segment
111 = code segment
The segment referenced would then be available as the top three address bits.

_________________
Robert Finch http://www.finitron.ca


Fri Jul 22, 2016 1:49 am WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 1484
Location: Canada
The problem looked at tonight is that there is nothing preventing the manipulation of an address to reference any segment. Since the top three bits of an address determine the segment register in use, in theory a user mode program could set these bits to reference any segment register. If all the segment registers are not initialized for the user program, then the user program could gain access to segments it’s not supposed to have access to.
Should all the segment register be setup when the OS switches between user mode programs (Simplest solution) ? A user mode program should only be using the DS,SS, and CS. Would it be worthwhile to add a hardware check that in user mode when an access occurs it’s within the DS, SS or CS ? Could instead just set all the segment registers to reference the data segment by default.
The problem with setting up all the segment registers when the user program switches is that it could be time consuming as descriptors have to be loaded from memory. And memory protection checks would be performed by software.

GS is used by the OS to reference OS variables. So it might be nice if this register were not switched around. But then how do you prevent a user program from referencing it ?

_________________
Robert Finch http://www.finitron.ca


Sun Jul 24, 2016 8:28 am WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 1484
Location: Canada
The most recent update to the Thor core was to support compressed instructions.
I wrote a compressed instruction test routine that loads the compressed instruction table (CIT) from a table in memory then runs a ram test routine using compressed instructions. Well it worked ! So the basic concept of compressed instructions is workable. However after running the ram test routine the core hung. (It hangs the same way whether or not the compressed instructions are used).
I’ve little incentive to debug the problem as I’m working on a newer better core.

_________________
Robert Finch http://www.finitron.ca


Tue Nov 08, 2016 10:30 am WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 1484
Location: Canada
I've been working away on version 2 of the Thor core. (Also maybe called DSD11). Predication and segmentation are being dropped from the core in order to reduce the size and enhance performance. Also the byte oriented variable word length instructions are being dropped in favor of a fixed 40 bit instruction size. I may change this to 41 bits but 40 bits display more attractively in listings.

Currently work on implementing extended immediates uses constant prefixes. Thor only ever required a single prefix instruction so this was searched for when an instruction was enqueued. Thor2 may use multiple prefixes so a prefix queue may be used rather than the regular queue for instructions.

_________________
Robert Finch http://www.finitron.ca


Wed Apr 12, 2017 8:25 am WWW
 [ 507 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6, 7, 8 ... 34  Next

Who is online

Users browsing this forum: CCBot, PetalBot and 0 guests


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

Jump to:  
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software