Last visit was: Wed Oct 09, 2024 8:07 pm
|
It is currently Wed Oct 09, 2024 8:07 pm
|
Author |
Message |
robfinch
Joined: Sat Feb 02, 2013 9:40 am Posts: 2187 Location: Canada
|
I just literally spent several exasperating days trying to figure out why forwarding logic in the core was not working properly. It would run for 100us in SIM then return to a bad address. It turned out to be a software issue with the compiled code performing loads in the wrong order. The scale for scaled indexed address mode was not set correctly by the assembler.
_________________Robert Finch http://www.finitron.ca
|
Sat Nov 27, 2021 3:47 am |
|
|
robfinch
Joined: Sat Feb 02, 2013 9:40 am Posts: 2187 Location: Canada
|
Got things running in the FPGA to the point of writing to the text screen. But it looks like all the stack references are not translated correctly. The address is coming out referenced to zero rather than the stack segment base address.
_________________Robert Finch http://www.finitron.ca
|
Sun Nov 28, 2021 6:53 am |
|
|
robfinch
Joined: Sat Feb 02, 2013 9:40 am Posts: 2187 Location: Canada
|
The SLTIL instruction was encoded incorrectly leading to incorrect loop terminations. Branch instructions were computing the target address using the wrong IP pipeline register. This led to targets being off by one instruction in some cases. Setting stages valid after a branch was off by one leading to the first instruction after a branch being improperly marked invalid. Spent a couple of hours debugging why the clear screen was not working. According to the ILA traces the screen ram should have been updated just fine, but the display showed otherwise. It turns out that the clear screen was finishing before the text controller’s power on randomizer was finished. Meaning the clear screen worked but got overwritten by the display randomizer. I had put a LED flashing routine in, to account for start-up delays but trimmed it down for debugging in SIM. With the LED flash restored, the clear screen almost works. It clears the about the first 10 lines of the screen then hangs. Making progress in little steps.
The current version in the works is a classic five stage overlapped pipeline. I,D,X,M and W.
_________________Robert Finch http://www.finitron.ca
|
Mon Nov 29, 2021 4:46 am |
|
|
robfinch
Joined: Sat Feb 02, 2013 9:40 am Posts: 2187 Location: Canada
|
Modified the compiler to make use of the loop count register and decrement and branch instruction. If the compiler sees a loop like “for (n = 2112; n !=0; n--)” and n is not used in the loop body then it may turn it into a loop using the loop counter and DBRA. Remaining to be done is allocate storage for the current loop counter so that it may be saved and restored on function entry or exit. Not sure whether to add it to the return block or make it a local variable. The return block is already 96 bytes in size. Another option is to stack the loop counter whenever it is used as opposed to only on function entry or exit. The following loop fails after 512 iterations: Code: .00014: # p[n] = vc; sllp t0,r0,s0,3 sto s2,[t0+s1] add s0,s0,1 slt t0,s0,2112 bne t0,r0,.00014
This has me mystified. It would be a lot easier to debug if it were not somewhere in the middle. Given the number of successful iterations, items like results forwarding must be working. Well, it turns out the loop was not failing. It was the page mapping in the TLB. All the screen memory virtual addresses were mapped to same physical page. The physical page number should have been incremented. 512 iterations equals 4kB of memory or one page. Clearing the text screen now works. One step closer to getting text output. Homing the text cursor caused an exception as the text controller registers were not mapped into the address space.
_________________Robert Finch http://www.finitron.ca
|
Tue Nov 30, 2021 4:22 am |
|
|
robfinch
Joined: Sat Feb 02, 2013 9:40 am Posts: 2187 Location: Canada
|
Switch statements were only outputting the first statement in a case or default. Found by tracing through the debug putchar routine. The generation logic in the compiler needed to be altered to output the list of statements following the case up until the next case or default. Working on getting debug text output. Homing the cursor does not work, meaning there is still something amiss accessing the text controller registers.
_________________Robert Finch http://www.finitron.ca
|
Wed Dec 01, 2021 5:52 am |
|
|
robfinch
Joined: Sat Feb 02, 2013 9:40 am Posts: 2187 Location: Canada
|
Homing the cursor works now, another puzzle piece in place. The switch search tree was using BGE instructions when it should have been using BGT instructions. This led to some cases not being found at runtime. The PRNG I/O device was not mapped leading to an exception. I keep forgetting to map memory and I/O devices. Sprite data memory was not mapped leading to an exception. Exceptions are not currently handled so the system hangs when one occurs.
_________________Robert Finch http://www.finitron.ca
|
Fri Dec 03, 2021 4:36 am |
|
|
BigEd
Joined: Wed Jan 09, 2013 6:54 pm Posts: 1799
|
Could you add some kind of guru meditation so an exception at least gives you some information?
|
Fri Dec 03, 2021 8:03 am |
|
|
robfinch
Joined: Sat Feb 02, 2013 9:40 am Posts: 2187 Location: Canada
|
The length for 2R instructions were not set so a default of 2 was used when the length was really 4. The compiler was not generating code for the default case properly. Switch statements that do not use tables use a binary search tree approach instead. Once there are fewer than four cases to resolve to in the binary search, a linear search is used. Thinking of adding an option to the switch statement to allow how many linear searches are performed to be controlled. Is some cases a purely linear search through case values is desirable because the cases are ordered in priority. Quote: Could you add some kind of guru meditation so an exception at least gives you some information? There is a nano-exception handler which is supposed to display an ‘X’ on-screen when an exception occurs. However, I have yet to see the ‘X’ and exceptions are occurring, so there is likely something wrong with the way the exception vector is being set. When an exception occurs the IP goes to 0x0000C0, which is zero plus the offset for the operating mode. Just recollected that the primary exception vector must be aligned at a 256 byte boundary. That is probably what is missing.
_________________Robert Finch http://www.finitron.ca
|
Fri Dec 03, 2021 9:31 pm |
|
|
robfinch
Joined: Sat Feb 02, 2013 9:40 am Posts: 2187 Location: Canada
|
2R instructions were not updating the register file. Finally got text output via the DBGDisplayChar() routine. Still not getting proper exceptions. Displaying the hex number 0x1234 using the PutWyde() routine displays “123;”. I have yet to figure out why it displays a semicolon instead of the digit 4. Each digit goes through the same PutNybble() routine, so it is strange that it would work with 1,2, and 3, but not 4. Code: void PutNybble(int n) { n = n & 15; if (n > 9) n = n + 'A' - 10; else n = n + '0'; DBGDisplayChar(n); }
The demo program seems to exception on an update of main memory to set the sprite bitmaps. It works for the first 4kB block but then the IP jumps to 0x0000C0. 128kB of memory is being mapped. Code: a0 = 0x8000000000008300; // choose random way, entry $300, write = true a1 = 0x008E000000000300; for (m = 0; m < 32; m++) { MapPage(a0,a1); a0++; a1++; }
This is the first time that a random way is chosen for the update, so there may be issues in the TLB hardware. The next thing to test would be a fixed way which seem to be working.
_________________Robert Finch http://www.finitron.ca
|
Mon Dec 06, 2021 4:22 am |
|
|
robfinch
Joined: Sat Feb 02, 2013 9:40 am Posts: 2187 Location: Canada
|
I am wondering if all the I/O register access should occupy the same virtual page. The I/O is in different physical pages in the memory system, but that does not mean that apps need see all the different I/O addresses. At the moment, the I/O registers are mapped into the virtual address space at the same location as the physical address. The benefit of using just a single page for all I/O is that it does not use up multiple entries in the TLB.
Finally got the sprite image memory to clear, so the sprites are being blanked out. The demo prog is supposed to be setting the sprite to a constant color, but output from the RNG always seems to be zero.
The first 4MB of memory mapped in the TLB now, which seems to have fixed the sprite image issue.
The output from the RNG was zero because the wrong data bus was connected from the I/O bridge. This was the case with all three bridges.
The size of the memory operation for STT scaled indexed was set to ‘octa’ due to a typo when it should have been ‘tetra’.
_________________Robert Finch http://www.finitron.ca
|
Fri Dec 10, 2021 4:53 am |
|
|
BigEd
Joined: Wed Jan 09, 2013 6:54 pm Posts: 1799
|
I've a feeling Acorn's Archimedes arranged it so that user mode is always virtual and only sees RAM, whereas supervisor mode can see I/O and can also use physical addressing. In which case, I/O needn't cost any TLB entries... but all I/O accesses need a switch into the OS and supervisor mode, and then back out.
|
Fri Dec 10, 2021 7:43 am |
|
|
oldben
Joined: Mon Oct 07, 2019 2:41 am Posts: 649
|
Is it posible to define all I/O as system calls, or a generic object rather than bit banging the real hardware. We have virtual memory, but not virtual I/O yet. BIT #n maps to bit #x adr w maps to adr z. A 6551 acia and 6850 acia both have different hardware layouts, but you do all the same functions for a code segment. on interupt(n) if(input)read(input). Ben.
|
Fri Dec 10, 2021 12:13 pm |
|
|
robfinch
Joined: Sat Feb 02, 2013 9:40 am Posts: 2187 Location: Canada
|
Thor is always using virtual addressing regardless of operating mode. User apps running on FMTK will only see ram, requiring OS calls to perform I/O, so that is like Acorn’s Archimedes. There is enough value in the access rights to provide it for I/O as well as memory. Quote: Is it posible to define all I/O as system calls, or a generic object rather than bit banging the real hardware. We have virtual memory, but not virtual I/O yet. BIT #n maps to bit #x adr w maps to adr z. A 6551 acia and 6850 acia both have different hardware layouts, but you do all the same functions for a code segment. on interupt(n) if(input)read(input). That is what device drivers are for. That is an interesting idea, virtual I/O. It could be done by trapping to the OS for every load or store operation within the I/O page. The OS could then decide, given an address and data, what to do with it. That may involve emulating an I/O device. In the FMTK OS each app has a screen associated with it. The active app reads and writes to the real text screen, while deactivated apps read and write a buffer. The buffer is swapped with the real screen when the app is activated or deactivated. That is tending towards virtual I/O. It should be possible to setup the memory mapping so that the same set of addresses the app sees goes to either the screen buffer or the real screen. Now I am thinking of something really complex. Having an app id associated with each text cell which indicates which app owns the text cell. If the text cell is owned by the current app then loads and stores go to the text screen, otherwise they would go to a buffer. When the app focus switches the app id’s associated with the text cells are updated. Selecting between the buffer and the real text screen is selecting between two address mappings. That is two physical addresses for one virtual address. Two physical addresses could be mapped with the same virtual address using two different ways in the TLB. It would result in two hits. A way memory is needed to select which way to use. The branch target buffer was not completely connected effectively disabling it.
_________________Robert Finch http://www.finitron.ca
|
Sat Dec 11, 2021 4:12 am |
|
|
robfinch
Joined: Sat Feb 02, 2013 9:40 am Posts: 2187 Location: Canada
|
Adding macro instructions PUSH, POP, ENTER, and LEAVE. Macro instructions are good for code density.
The LEA instruction needed some fixes. I believe it was always returning a zero leading to variables being located at the same location.
The RNG seems to be outputting the same value all the time. I believe this occurs because a cached value is being read, rather than a read from the I/O device.
_________________Robert Finch http://www.finitron.ca
|
Mon Dec 13, 2021 7:36 am |
|
|
robfinch
Joined: Sat Feb 02, 2013 9:40 am Posts: 2187 Location: Canada
|
Turns out the data cache is not enabled so the RNG output is not due to cached values. It seems the RNG works the first time, but not subsequent times. So some experimentation with the RNG update is in order. Several things in the system are failing and I cannot seem to track down why. In the PutNybble() routine the ‘n > 9’ test fails sometimes resulting in the incorrect character being output. Code: void PutNybble(int n) { n = n & 15; if (n > 9) n = n + 'A' - 10; else n = n + '0'; DBGDisplayChar(n); } I thought it may have to do with branch prediction so the predictors were turned off, but the result is still the same. The failure is consistent, given the same input the output is the same.
_________________Robert Finch http://www.finitron.ca
|
Tue Dec 14, 2021 6:10 am |
|
Who is online |
Users browsing this forum: CCBot 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
|
|