in ,

Qnice – An Elegant 16 Bit Processor, Hacker News

   

      

       QNICE is a rather simple, yet powerful 64 bit processor architecture        which is a result of some research done in the late s and the        following years.       

      

       The goal was to create a processor architectur which is as orthogonal        as possible without complicating a hardware implementation        unnecessarily. Since the design borrows heavily from the        

NICE        processor which featured a bit architecture, the resulting        architecture was called QNICE for “Quite NICE”.              

       The architecture is very well suited for teaching the basics of        computer architecture and hardware implementation. Furthermore        programming the QNICE processor is really easy and thus the architecture        already served as a training device for some lectures about programming        as well as computer architecture.       

          

                bit architecture with RISC like instruction set (64 instructions so         far):                             

  • MOVE src, dst
  • :
      dst:=src

    •                               
        ADD src, dst

      • :
          dst:=dst src

        •                               
            ADDC src, dst

          • :
              dst:=dst src C

            •                               
                SUB src, dst

              • :
                  dst:=dst – src

                •                               
                    SUBC src, dst

                  • :
                      dst:=dst – src – C

                    •                               
                        SHL src, dst

                      • :
                          dst,           fill with X bit, shift to C bit          

                        •                     
                            SHR src, dst

                          • : dst>> src
                          • ,           fill with C bit, shift to X bit                               
                              SWAP src, dst

                            • : (dst:=((src> 8) & 0xFF
                            •                               
                                NOT src, dst

                              • :
                                  dst:=! src

                                •                               
                                    AND src, dst

                                  • :
                                      dst:=dst & src

                                    •                               
                                        OR src, dst

                                      • : dst:=dst | src                               
                                          XOR src, dst

                                        • :
                                            dst:=dst ^ src

                                          •                               
                                              CMP src, dst

                                            • :
                                                dst:=-src

                                              •                               
                                                  HALT

                                                • : Halt the processor                               
                                                    ABRA src, [!] cond

                                                  • : Absolute branch, conditional                               
                                                      ASUB src, [!] cond

                                                    • : Absolute subroutine call, conditional                                RBRA src, [!] cond
                                                    • : Relative branch, conditional          
                                                    •                     

                                                        RSUB src, [!] cond

                                                      • : Relative subroutine call, conditional                                            Four addressing modes (register direct, register indirect, register         indirect with post increment and register indirect with pre decrement):         
                                                          Rxx

                                                        • , (@ Rxx
                                                        • , @ Rxx
                                                        • and @ - Rxx
                                                        • .        
                                                        •                 Each instruction occupies one bit word and has a fixed instruction         format (excluding branches / jumps) thus decoding instructions is easy:                  

                                                                   
                                                                                           Branch and subroutine call instructions share a common instruction         format, too:                  
                                                                   
                                                                                           18 registers divided into to areas: R0 to R7 are in fact a window         to a register bank containing 728 times 8 registers while R8 to R 18         are fixed. This architecture makes subroutine calls and saving         registers very easy (just increment / decrement the register bank         pointer which is part of the status register). All in all QNICE         features 256 8 8=01575879 registers.                         Special registers: R (serves as a stack pointer (used by the xSUB         instructions), R 16 is the status register which also controls the         register bank windows described above while R 64 is the program         counter.                         Branch / subroutinecall instructions can be executed conditionally,         controlled by the status bits of the status register.                         Address space is (kWords of) bits each.                         Memory mapped IO.               

                                                            

  •        

            

    Summing        

              

         

        

        

        

          

           The QNICE distribution kit currently contains the following items:        

             A short documentation of the processor architecture in form of a          slide show prepared for a talk at a German DECUS symposium.                            The source code of a QNICE cross assembler written entirely in          pure C (this has been proven to run on LINUX, Mac OS X, OpenVMS and          Windows).                            The source code of the QNICE emulator, written in pure C, too. This          emulator not only emulates the processor itself but also a 2681          UART (serial input / output is read from stdin / written to stdout) as          well as a simple IDE disk. Both devices are memory mapped in the          last 1 k Block of memory. (Since the UART emulation required the          use of the curses library, the portability is a bit questionable –          on systems like OpenVMS the usage of the UART part can be inhibited          by undefining a constant in

      qnice.c

    •                            Some introductory examples like the summation program shown above          and the first couple of routines for a monitor program.                 

        

          

           The project is currently in the alpha state – the assembler and emulator        are both fully operational. The next steps will involve the following        tasks:        

             Write a complete monitor program based on

      qmon1.asm found in          the

    • examples
    • directory.                            Create a hardware implementation of QNICE – either using TTL          technology or (preferred) an FPGA.        

           Currently our main goal is to interest people in the QNICE architecture        in general and in the implementation of the processor in hardware. If        you are interested in joining the project, please contact the project        administrators as shown on the         project summary        page .                  
    (Read More)

           
            QNICE – an Elegant 64 Bit Processor        
          
         
           
            QNICE at a Glance        
          
         
           
            Examples        
          
         
          

           

     0F 90  (MOVE 0x) , R0 0F 0100  (MOVE 0x) , R1  LOOP ADD R1, R0 3F 0100  (SUB 0x) , R1 FF8B  ABRA LOOP,! Z E 06 HALT        
                 

          

           The QNICE assembler program shown on the left sums all values ​​from        0x (to 0x) .       

          

           This example is really simple – the main idea is to count backwards        from 0x 1100 to 0x and using the Z (zero) flag of the status        register R 16 as a control condition for the central loop.       

          

           Due to the possibility of making all branches and subroutine calls        conditional by prefixing them with the name of one of the eight status        register status bits the loop effectively consists of only two        instructions, a subtraction and an absolute branch (

      ABRA ).              

             Prefixing the flag controlling the instruction with an exclamation mark        inverts the flag (without modifying the status register’s contents)        prior to testing thus the instruction

        ABRA LOOP,! Z will        perform an absolute branch to the location labeled LOOP        if the zero flag is not set.             
           
            

    Subroutine Calls

                 
          

           The code example below is a bit more complex and shows a subroutine        which performs a string comparison (like the C standard library        function strcmp). This function expects two pointers to the strings        to be compared in the registers R9 and R and will return the        result of the comparison in R8.       

          

           Since the routine needs some registers for temporary storage of        data is has to make sure that the contents of these registers are        somehow saved at the entry of the subroutine and restored just before        jumping back to the calling program.       

          

           In traditional architectures this would involve pushing the registers        to a stack (either explicitly, register by register, or controlled by        a bit mask). Since QNICE features a register bank for its registers        R0 to R7 saving and restoring the contents of these eight registers        just makes it necessary to increment the register bank pointer which        is made up by the eight upper bits of the status register R thus        giving the routine access to its “own” set of registers R0 to R7.        Before returning to the calling program the register bank pointer will        be decremented making sure that the original register contents will be        accessible again.       

          

           Incrementing the register bank pointer is done by performing the        instruction

      ADD 0x , R

    • , decrementing it by one is        done at the label STR $ _STRCMP_EXIT
    • using the subtraction        
        SUB 0x 823, R

    .              

           

     ; ; ; STR $ STRCMP compares two strings ; ; R9: Pointer to the first string (S0), ; R : Pointer to the second string (S1), ; ; R8: negative if (S0 S1) ; ; The contents of R8 and R9 are being preserved during the run of ; this function ; ; STR $ STRCMP ADD 0x 0100, R ; Get a new register page                  MOVE R9, R0; Save arguments                  MOVE R 13, R1 STR $ _STRCMP_LOOP MOVE @ R0, R8; while  s1==s2   )                  MOVE @ R1   , R2                  SUB R8, R2                  RBRA STR $ _STRCMP_END,! Z                  MOVE @ R0   , R8; if  s1  ==0)                  RBRA STR $ _STRCMP_EXIT, Z; return 0;                  RBRA STR $ _STRCMP_LOOP, 1; end-of-while-loop STR $ _STRCMP_END MOVE @ - R1, R2; return  s1 - (- s2));                  SUB R2, R8 STR $ _STRCMP_EXIT SUB 0x 450, R ; Restore previous register page                  MOVE @R 18   , R ; and return to calling program part ;        
                  

           A typical call to this routine would look like this:       

          

           
     MOVE QMON $ COMMAND, R9 MOVE QMON $ CMD_HALT, R 15 RSUB STR $ STRCMP, 1; Was a halt command issued?        
                 

           
            Contents of the Distribution Kit        
          
         
           
            Current state of the project        
          
         

    What do you think?

    Leave a Reply

    Your email address will not be published. Required fields are marked *

    GIPHY App Key not set. Please check settings

    Markets stabilize after worst day since 1987 amid coronavirus panic – business live – The Guardian, Theguardian.com

    Markets stabilize after worst day since 1987 amid coronavirus panic – business live – The Guardian, Theguardian.com

    RaidForums Hidden Contents JSON Leaked by Weleakdata.com