Last visit was: Wed Oct 28, 2026 8:34 pm
It is currently Wed Oct 28, 2026 8:34 pm



 [ 321 posts ]  Go to page Previous  1 ... 18, 19, 20, 21, 22  Next
 Qupls (Q+) 
Author Message

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2534
Location: Canada
Managed to get the core size small enough to allow a DRAM controller to fit as well as the rest of the system. A video frame buffer is small enough that it may fit as well. So, I am just trying that out ATM.

The multi-port memory controller is too large to fit though, so some simpler control logic was added to mux between the CPU and a video frame buffer.

100 MHz timing for the system was missed by 200ps. It may or may not work depending on the chip. But I did not feel in a gambling mood, so the clock was reduced to 89.29 MHz. In theory it should work at 96 MHz.

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


Thu Apr 09, 2026 3:30 am WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2534
Location: Canada
The design occupies over 90% of the FPGA. Timing was not met by a few hundred pico-seconds in the scratchpad RAM. The miss is entirely due to routing delay. The routing delay is over 98% of the time required. Only 200 ps are needed by the logic. I chalk this up to the fullness of the FPGA.

Shelving the multi-port memory controller. It is not as great a component as I thought, having thought about it some more. The issue is that it creates a lot of duplication of logic. The controller contains FIFOs for high-speed buffering of the data. The issue is that there are also FIFOs for data buffering in the devices connected to the memory controller. I wonder if double-FIFOing is really necessary. Started working on a newer better version.

For the Qupls SoC I created a simple DRAM bridge instead, which is used with a MUX at the inputs. It is much smaller than the memory controller and probably about 90% as effective.

I tried building the system out to a bitstream that can be loaded into the FPGA. Nothing worked of course. Just a blank screen with a few scrambled characters. There are about 15k LUTs left to use, which are being reserved to fix future mistakes.

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


Sat Apr 11, 2026 2:49 am WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2534
Location: Canada
Added a POLY instruction to the ISA which evaluates polynomials using Horner’s method. This is similar to the POLY instruction on the historic VAX mainframe computer. My version will only evaluate polynomials of degree seven or less, but it can be called multiple times to evaluate polynomials of higher degree.

I decided to limit the polynomial evaluated to a degree seven or less, but provided the option to continue evaluating a polynomial using an additional instruction. A seventh-degree polynomial is the largest one evaluated in the library.
Code:
FPOLY r10, r20, r30, #7      ; evaluate terms 0 to 7
FPOLY r10, r20, r38, #7|64   ; evaluate terms 8 to 14
FPOLY r10, r20, r45, #7|64   ; evaluate terms 15 to 21

The issue is the use of the micro-op translator to supply micro-ops for evaluating the polynomial. The number of micro-ops is kept to a minimum. There is a max of 16 micro-ops per ISA instruction.

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


Wed Apr 15, 2026 5:53 am WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2534
Location: Canada
Got the system to build out to a bitstream again that could be loaded into the FPGA. It missed timing by 400 ps and took about 6 hours to build. Still just a display of random characters, with no hi-res graphics. I was expecting random bits of data to appear for the bitmapped graphics. Lack of graphics data means the interface to DRAM likely is not working.

Started work on version 5 in the meantime, a major update to Q+. Shrunk the instruction down to 40-bits from 48 by removing the Rs3 and Op3 fields of the instruction. FMA and other instructions requiring a third register will now need to use a prefix supplying the third register.

There are still 128 registers, but float instructions now have access to only the last 64 registers. Integer instructions can be used to operate on float values as they have access to all registers.

Branches are handled completely differently, using condition code registers ala PowerPC.

Most recent additions are two floating-point exception status registers. For floating-point operations r1 is defined to hold the value +1.0. r0 is defined to hold the value +0.0.

FADDI and FMULI (float add immediate and float multiply immediate) were added to improve code density for those operations.

There are two floating-point exception status registers primarily so that a status register update can be ignored by specifying the second register.

Still undecided on how to manage the status and condition registers. Whether to rename them like the GPRs, or use the re-order buffer for storage and renaming. There are only a handful of registers so it is tempting to allocate storage in the re-order buffer.

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


Sat Apr 18, 2026 3:50 am WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2534
Location: Canada
Reviewed the MMU specs for Qupls. It has been months since I did any computer work. The MMU is very powerful and has some features similar to the 68030 MMU. The plan is to have the MMU always enabled (no way to turn it off).

I decided to keep the page size register a global register for all page tables. Using a different page size register for different operating modes was considered. But it would make the software complex if mapping pages between different operating modes.

The MMU has four sets of transparent translation registers which allow a 1:1 mapping between virtual and physical addresses to occur for a block of addresses. Either instruction or data or both types of addresses may be mapped using a single register. A block of addresses can be write-protected. One of the transparent translation register may be defaulted to point to a block of memory needed for boot-up.

There are four root pointers that point to the root of translation tables. One pointer for each processor mode. The pointers are 128-bit structured values that contain a 64-bit address and other control bits.

Page tables entries consist of one of four types of descriptors - invalid, indirect, leaf and branch. Descriptors are 128-bit values.

Descriptors contain mapping information for a 64-bit physical address space, a 31-bit upper or lower indexing limit value for the table, and some other control bits.

Some of the higher order bits of the virtual address are used to specify the access level. Up to eight bits may be used to specify the access level, leaving 56 bits of virtual address space.

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


Wed Sep 09, 2026 5:05 am WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2534
Location: Canada
Q+ v4 block diagram in the docs is seriously out-of-date. I have been reading the docs to see where I left things off.

The docs show many function units in the execute stage result queues and dynamic result multiplexing and dynamic register multiplexing. The dynamic result multiplexing and queues and register multiplexing has been removed. There are now just six execution pipes with functional units stacked up in the execution pipes. This is a simpler design, more similar to the MC88000.

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


Tue Sep 15, 2026 4:24 am WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2534
Location: Canada
I got around to rebuilding Q+ v4 today after having let it sit for a few months. I changed the number of architectural registers supported from 128 to 64. I did not change the instruction set which has seven-bit register spec fields. The register spec field is also used to specify seven-bit constants. Only six bits are needed to specify a register. The extra bit might be used to specify negative or complement.

There were some hiccups running the build; I guess I did not leave it in a buildable state when I last worked on it. I had been working on the PRED modifier, adapting it to support multiple threads.
Support for multiple threads is probably going to be dropped. It adds a level of complexity and increases the required size of the physical register file.

The register renamer is up to version 9. It now reserves eight rename registers for each pair of architectural registers. A small bitmap for each register pair is used to indicate which of the eight registers are in use. This does not have the same kind of depth available with a FIFO approach, but it is smaller and fast. It will also stall more often compared to a FIFO.

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


Thu Sep 24, 2026 12:47 am WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2534
Location: Canada
At work again on Qupls4. Certain aspects seem to be stabilizing, like the use of 48-bit instructions. The CPU currently has 64 GPRs. 8 GPRs may be selected as carry registers and are selected by three-bit code in some instructions.

Added the SUBDIV (subtract and divide) instruction, used mainly with pointer arithmetic. The integer divider shortcuts divisions by powers of two. This was previously called PTRDIF which only did a right shift instead of a divide.

Figured out the best way to implement the following operation was as two separate micro-ops.
{Co, Rd} = Rs1 + Rs2 + Ci
Micro-op1: Rd = Rs1 + Rs2 + Rs3
Micro-op2: Rd = carry of (Rs1 + Rs2 + Rs3)

Added detection of instructions that are not implemented by any execution pipeline. These now cause an unimplemented instruction fault. Previously such instructions would likely eventually hang the machine. They needed to be marked as done and exceptioning (FLT_UNIMP) to allow the machine to proceed. This is detected in the instruction dispatcher and marked in the main clocked process.
dispatcher
Code:
   foreach (rob[nn]) begin
      // If valid ...
      if (rob[nn].dispatchable &&
         // and was not dispatched in the last cycle
         // It takes a clock cycle to set flags.
         !rob_dispatched[nn] &&
         !rob_dispatched_o[nn] &&
         !rob_dispatched2[nn]
      ) begin
<more code removed>
         // Ensure instruction is supported in a pipe somewhere.
         // Mark the instruction as unimplemented if not supported in any pipe.
         if ((rob[nn].op.decbus.expipe[pipe] & SUPPORT_XPIPE[pipe])==6'd0)   begin   // Is it supported?
            rob_unimplemented[nn] = TRUE;
            rob_dispatched[nn] = VAL;
         end
         
      end
   end

main process
Code:
   foreach (rob[nn])
      if (rob_unimplemented[nn]) begin
         rob[nn].excv <= VAL;
         rob[nn].exc <= FLT_UNIMP;
         rob[nn].done <= 2'b11;
      end


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


Fri Oct 16, 2026 2:00 am WWW

Joined: Mon Oct 07, 2019 2:41 am
Posts: 993
how do you handle signed divisions by 2?


Sat Oct 17, 2026 11:24 pm

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2534
Location: Canada
Quote:
how do you handle signed divisions by 2?
The divider does an arithmetic shift right for signed values.

Graphics on the mind today.

Additions
Added a TEX instruction which calculates the index into a 1,2 or 3D texture map. The texture map must have sides a power of two in size. For example, 256x256x8. It takes three co-ordinates (packed into two registers) and the map attributes (width, height and depth in pixel powers of two) in a third register. The co-ordinates are single precision floating point numbers.

To support the TEX instruction a specialized 3-input floating-point adder was created. This was to minimize latency compared to cascading two two-input adders. The inputs must all be positive numbers to work correctly. Scaled versions of the U, V, and W co-ordinates for the texture map needed to be added.

Added 24-bit load and store instructions, mainly for loading RGB888 graphics.

Added an RGBCVT instruction. It can change the RGB format to a larger or smaller format. For example: RGBCVT r2, r1,10,8 converts RGB8.8.8 into RGB10.10.10. One drawback is assuming the color components are all the same size. So, no support for RGB565.

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


Sun Oct 18, 2026 3:12 am WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2534
Location: Canada
Vectors on the mind today. Going back and fixing up the core.

Scalar indexed vector and vector indexed vector loads and stores were broken.

Vector indexed vector loads and stores were not accessing partial registers. For a vector indexed load (gather operation), the load of the second element of a vector might still be to the first register assigned to the vector if the element size is less than the width of the register. So, the same register may be updated multiple times for a vector indexed vector load. Different bytes would be updated.

Other vector load / stores were treated as independent memory ops for each element processed. They now load or store as many elements as will fit into a register. For example, previously a vector of eight bytes would take eight memory operations. Now the same vector uses only a single memory op.

Vector masking was not taking place on the vector memory ops.

Found out that I was previously building the system with support for vector operations. This increases the size of the core.

The ISA does not currently support strided vector memory operations. These operations can be emulated easily using vector indexed vector operations by setting the values in the indexing vector appropriately.

A small build of the core size by itself is 169k LUTs without vector ops. 178k LUTs with vector ops.

* Switched the core back to 128 regs to support vectors.

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


Wed Oct 21, 2026 12:25 am WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2534
Location: Canada
Mods
Increased the size of color components processed in the graphics BLEND instruction to 16 bits which is far more suitable for video editing.

Additions
Added the BMAPH (byte map hexibyte) instruction which maps bytes from a pair of registers to a destination register. This is similar to the BMAP instruction but may be useful for merging values from two different registers.

Added PACK6416 which packs 64-bit color pixels contained in four registers into 16-bit color pixels in a single register.

Added documentation for a few more instructions.

Moved some of the micro-op encoding cases out to separate files to make them more manageable. The micro-op cases are not real complex but are thousands of lines long.

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


Thu Oct 22, 2026 1:52 am WWW

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2534
Location: Canada
Got around to trying a simulation run today. Failed right away. The name supplier module had a bug in it. It would return the same rename register for the target register for each port if the architectural register was the same. The renamer needed to check that a rename register had not already been used. It needed to return a different rename register for each architectural register. Returning the same rename register caused the renamer to stall, which caused the front end of the pipeline to stall, which caused the whole machine to stall. The whole machine stalled because it is a startup condition where there are no valid instructions in execution pipelines. Normally the whole machine would not stall on a rename stall.

The renamer is more limited than a fifo based approach. The same target architectural register cannot be specified more than eight times in a row. If it is then the CPU will stall to free up rename registers.

It literally takes simulation and hour to start. For some reason it is recompiling all the vendor’s libraries every time a recompile is needed.

Having fixed the rename issue, the core is stalled now because the hardware interrupt flag in the pipeline has a simulation value of ‘X’. Somehow an uninitialized value is being placed in the register. The issue with ‘X’ values is they tend to spread all over the place. Meaning some work has to go into backtracking just where the ‘X’ first appeared.

The core does fit into the FPGA. It is configured to use three execution pipes instead the max six.

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


Sat Oct 24, 2026 1:31 am WWW

Joined: Mon Oct 07, 2019 2:41 am
Posts: 993
. A hour to boot in simulation is what speed in real time?


Sat Oct 24, 2026 9:19 pm

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2534
Location: Canada
Quote:
. A hour to boot in simulation is what speed in real time?
It is not the running simulation that takes an hour. It is compiling all the vendor's source libraries before a simulation run that takes hours to do. I am not sure how fast the simulation is compared to real-time but it is many orders of magnitude slower. ATM running the first 10 micro-seconds simulation only takes a few seconds. The simulation is logic exact. All the logic is simulated so it takes a lot of processing compared to the real-time.

It turns out after some searching, that the dependent instruction stream array was not being initialized at reset. This resulted in ‘X’s in the stomp logic, ultimately resulting in undefined values appearing at various points. In most cases resetting the FF’s at reset is not necessary for proper operation, and I have got in a habit of not bothering because it results in less hardware. But it matters to simulation. In this case it did matter.

Added some more decodes in the decoder to get rid of some ‘X’s. There were several signals I had not bothered to decode yet as they were not needed by the boot software. For instance: Rs4. There is still more to decode and some deprecated decodes to remove.

“Improved” the logic associated with stomping on pipeline registers when a branch resolves. If the instruction stream in the pipeline does not match the stream resolved to process, then the pipeline instruction is marked done and stomped on. This prevents it from being executed in the execute stage. This may also be handled by the stomp module.

Fixed an issue with stomped instructions. Stomped instructions were not being dispatched and sometimes they should be. If the instruction was stomped at the rename stage, then it may be turned into a “copy target” instruction. Copy target instructions need to be dispatched, other stomped on instructions do not go through the execution pipeline. Copy target instructions are only used if the CPU backout processing option is not selected. Otherwise, the backout process will restore register values making the target copy unnecessary.

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


Sun Oct 25, 2026 12:14 am WWW
 [ 321 posts ]  Go to page Previous  1 ... 18, 19, 20, 21, 22  Next

Who is online

Users browsing this forum: claudebot 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