Forums - Open Redstone Engineers
My new and most thought out IS. - Printable Version

+- Forums - Open Redstone Engineers (https://forum.openredstone.org)
+-- Forum: ORE General (https://forum.openredstone.org/forum-39.html)
+--- Forum: Projects & Inventions (https://forum.openredstone.org/forum-19.html)
+---- Forum: Completed Projects (https://forum.openredstone.org/forum-21.html)
+---- Thread: My new and most thought out IS. (/thread-5218.html)



My new and most thought out IS. - Chibill - 12-12-2014

Hello everyone. Today I am giving you a sneak peak at my IS.

https://docs.google.com/file/d/0B8hDI6MCMcjnWTVyY0E5RzlqYXc/edit?usp=docslist_api

The one thing is that this supports a stack and a machine without a stack. It also have a Instruction to say that there last instruction is repeated many times.


RE: My new and most thought out IS. - LordDecapo - 12-12-2014

I do like the repeat inst. Is there a way to tell it to repeat like several instructions in a row over and over? Like "repeat inst 1,2,, and 3, 10times"?
Also first and within 5 min of posting


RE: My new and most thought out IS. - Chibill - 12-12-2014

I might set that up it would be interesting to make work.


RE: My new and most thought out IS. - LordDecapo - 12-12-2014

That it would, I have tossed around doing that a bunch, if u have conditional branching and a way to incriment a register by 1, u can simulate that kinda inst in software.
K and question time..
what bit size is the IS? 16bit?
what's the intended data width? 8bit?
also, how many registers u gonna have?


RE: My new and most thought out IS. - Chibill - 12-12-2014

What do you mean by IS bit size?

Its ment for an 8 bit CPU but it can handle up to 32 bit numbers using the Register bit mode selection instruct and also the one for the stack.

16 registers which when in 32 bit mode goes down to 4.

I will also have a stack 32 deep.


RE: My new and most thought out IS. - LordDecapo - 12-12-2014

Like how many bits wide is ur IS..? ???
Is that stack hardware or or in RAM, cause that's A HUGE stack for MC CPUs,
and u have a mode for registers? If u have AddC or SubB (or SubC, depending on what ur reading, they r the same) then u don't need the register mode cause you will have the ability to just do a calculation then extend it with the Add/Sub © and it will simulate larger bit values with out having the weird register mode.. Cause reading them (registers) like that hardware based could slow ur clock down by a factor of 4 or more.. unless ur heavily pipelining, and that would still have to stall for a while to catch up with the random bit sizes


RE: My new and most thought out IS. - Chibill - 12-13-2014

Not sure still need to get the Imediates wrote out and the structure.
Hardware stack using minecarts!
The modes are so you can have a huge 32 bit number saved then say change to 8 bit mode and take each chunk of it. And the stack and Regards change mode seapreatly.


RE: My new and most thought out IS. - GISED_Link - 12-13-2014

Aaaarg ! 00000 for NOP seems to be a bad idea. I really recommand to put the NOP instruction somewhere else and show an alert when the opcode (binary code of the instruction) is 00000.

And yes I think that addc and subc are very important.


RE: My new and most thought out IS. - Chibill - 12-13-2014

I don't have addc or subc what do they do?


RE: My new and most thought out IS. - Chibill - 12-13-2014

Noop shoud always be 00000 because then if a line is blank its noop.


RE: My new and most thought out IS. - GISED_Link - 12-13-2014

I think that if you have no opcode (00000) in the Instruction bus, that say that you have a huge error on the bus (it miss a redstone repeater, wires are too long, etc...). So I recommand to unuse the 00000 instruction (or use it to stop the computer and show a "stop" message).

And Addc and Subc is a good way to use the carry flag. By example :

I will add 2 numbers (unsigned) of 16 bits, with a 8 bit ALU. How can I proceed ?

Code:
Example :
  0011'0001 ' 1001'1010     //MSB  '  LSB
+ 0001'1000 ' 1110'0000
-----------------------
  0100'1010 ' 0111'1010

  1. I add the 2 LSB bytes (1001'1010 + 1110'0000)
  2. The result of this is 1'0111'1010, so you have a Carry out (carry is set to 1)
  3. You store this 8 byte value at Registre x
  4. So, the next instruction will be ADDC (add with carry) the 2 MSB bytes. With this you include the carry out of the previous operation. And the result will be 0100'1010 (with the carry !).
  5. You store this value at Registre x+1 (or x-1 ... depend of big or little Indian)



RE: My new and most thought out IS. - Chibill - 12-13-2014

I have registers resevered for the carry already I just have to make that sheet neat.


RE: My new and most thought out IS. - LordDecapo - 12-15-2014

(12-13-2014, 07:01 AM)GISED_Link Wrote: Aaaarg ! 00000 for NOP seems to be a bad idea. I really recommand to put the NOP instruction somewhere else and show an alert when the opcode (binary code of the instruction) is 00000.

And yes I think that addc and subc are very important.

No just no.. that means when ur not running anything at all, u will get an error. A noop should ALWAYS ALWAYS ALWAYS be 00000. So if u do something like pipeline and u have to stall, it simply just closes a read lock and nothing else can come though. Leaving the busses idling at 00000 during the stall, Hensel Noop.


RE: My new and most thought out IS. - GISED_Link - 12-15-2014

(12-15-2014, 05:10 PM)LordDecapo Wrote: A nop should ALWAYS ALWAYS ALWAYS be 00000. So if u do something like pipeline and u have to stall, it simply just closes a read lock and nothing else can come though. Leaving the busses idling at 00000 during the stall, Hensel Noop.

I've joined the HCS12 instruction set (not only the picture), made by Freescale. See by yourself, NOP isn't at 0x00. Here, 0x00 is used to put the CPU in background mode.

[Image: 713407Exemplekl26.jpg]

You can set NOP at 0x00, but I suggest to put something else (that shows something special for the user). With that, when a problem happens with the instruction bus, you will immediately know where the error is and you will earn a lot of time. Or use NOP and turn on a Redstone lamp...

But you are lucky, with Minecraft you can do whatever you want.

[Image: 468143KCPSM3InstructionSet.jpg]
Here, "000000" is a load instruction (see in the manual).
I've join a Instruction Set from a CPU coded in VHDL from Xilinx. And you can see that it doesn't have the NOP instruction. So ... We are fighting for something that doesn't matter at all XD.

I hope that those examples will help you (chibill).

By the way :
- I think that 3 kind of jump is not enough
- You can devide, but how can you store the remainder ?
- Same instruction? Why ? But why not... It's funny XD
- addc and subc... if you have the place to use those instructions, use them.
- INC, Increment a register


RE: My new and most thought out IS. - LordDecapo - 12-15-2014

dude,, a background mode is literally a noop with just a monitors for an interrupt or a system that only does low priority backround ops...
and those IS's are the rarity,,, 90% of the ones i look at have noop as 0000, as its 50x easier to set that way by default


RE: My new and most thought out IS. - GISED_Link - 12-16-2014

(12-15-2014, 11:54 PM)LordDecapo Wrote: and those IS's are the rarity,,, 90% of the ones i look at have noop as 0000, as its 50x easier to set that way by default

1. We must stop to discuss about the NOP.. . 6 posts about an instruction that do nothing is really enough
2. Please post here a IS where NOP is set at 0x00. I'm sure that will be intersting to see one of them in my life...
3. X86 Opcode : NOP is at 0x90,
4. European logic != American logic Big Grin

Anyway. I don't recommand to use the 0x00 bytecode if you have enough free bytecode in your IS


RE: My new and most thought out IS. - Chibill - 12-16-2014

Still using 00000 as noop as it is how I learned from a book on making your own computer that was printed in 1980.


RE: My new and most thought out IS. - LordDecapo - 12-17-2014

^ and all tutorial and learning CPUs I have read about, both euro and Us..
also here: Nop Wiki
note that
MIPS, Intel 8051, ARM A32, Z80, and the PIC microcontroller all use 0 as Nop.


RE: My new and most thought out IS. - Chibill - 12-18-2014

I am thinking about deleting this topic and reposting it after I finish the memory map.


RE: My new and most thought out IS. - TSO - 12-23-2014

I should like to state (after my long hiatus) that I agree with GISED_Link to some extent. You should try to avoid mapping a real opcode to 0x00 if you have the room in your IS to do so. Then, you can map a memory read error or a STOP to the opcode of 0x00. If you have microcoding, then not having a 0x00 opcode becomes more important because much of the math that most microcoding performs can have issues working around zero for either pointers or opcodes. In programming, a common practice is to set something to zero (like a pointer), perform an allocation, and then see if it isn't zero, meaning that it worked, or is zero, meaning that it failed and it's time to perform the exception routine and commit software suicide. In microcoding, a similar thing happens, you allocate 0 to the micro-operation being considered, allocate a temporary space for it on the table (at zero, oddly enough), then run the opcode through the tabling program, and it gives it a nonzero micro-operation in return at a nonzero table address for your instruction pointer to work with. If zero remains in either location, you know you have a problem, but if zero actually is something that can be returned as a valid and useful output, then it's your best guess as to whether or not your allocation worked or failed. Therefore zero is a common sign of an error in allocations and basically all other programs, to the point that x86 has a FLAG that is set if the output is zero simply because a zero output is bad juju. So, from a programming standpoint, I would say to avoid zero for consistency, if nothing else.

Now, for your computer, a really nice thing about mapping STOP to 0x00 is that an opcode execution could be wired as the bitwise OR down the entire opcode AND'ed with the clock all added to the instruction pointer with ADDC being invoked by a starting signal (basically: if there is an opcode at line x or a start signal at any point, push 1 to the carry in of the instruction pointer accumulator). This is a convenient way to make the STOP opcode 0x00 without adding any loss to overall throughput and adding one phase to the instruction pointer's pipeline. It is therefore unrelated to the execution pipeline and gives you an opcode usually reserved for a microcoded environment.

LordDecapo Wrote:I do like the repeat inst. Is there a way to tell it to repeat like several instructions in a row over and over? Like "repeat inst 1,2,, and 3, 10times"?

I can tell you how to do it in general pretty easily, it will take me a bit of thinking to put it in terms of this specific instruction set. I have to be somewhere right now, but tell me what you want to know and I'll explain it (this one is fairly simple in it's general form on a stack machine.)


RE: My new and most thought out IS. - Chibill - 12-23-2014

I have no addc. I am going to be deleteing this thread after new years and reposting because of this 'war' on NOOP on 0000


RE: My new and most thought out IS. - TSO - 12-24-2014

My full reply and suggestions for alteration of your IS. This isn't all that edited, and considering how much time I spent formatting it, I'm sure you can see why I don't want to deal with this post anymore. I will also add that there is no reason to delete the thread simply because we disagree on the presence of an opcode at 0x00. This would be addressed at some point, and you were lucky enough to get stuck with it.


Code:
#    bin    hex    short    name        effect
___________________________________________________________________

0     00000    0x00    NOP    No Operation       Does Nothing
1     00001    0x01    AND    And                Logical And
2     00010    0x02    OR     Or                 Logical Or
3     00011    0x03    XOR    Xor                Logical Exclusive Or
4     00100    0x04    ADD    Add                Add
5     00101    0x05    SUB    Subtract           Subtract
6     00110    0x06    MUL    Multiply           Multiplies
7     00111    0x07    DIV    Divide             Divides
8     01000    0x08    PUH    Push               Push register to stack
9     01001    0x09    POP    Pop                Pops stack to register
10    01010    0x0A    PUI    Push Im            Push value to stack
11    01011    0x0B    SBM    Stack Bit Mode     Set Bit Mode Of Stack
12    01100    0x0C    STR    Store              Store to Register
13    01101    0x0D    LAD    Load               Load one register from another
14    01110    0x0E    STI    Store Im           Store immediate
15    01111    0x0F    RBM    Register Mode      Set bit size mode for register
16    10000    0x10    CSJ    Conditional Jmp    Jump stack conditionally
17    10001    0x11    JUP    Jump               Jump unconditionally
18    10010    0x12    CRJ    Cond. reg. jmp     Jump Register conditionally
19    10011    0x13    RTN    Return             Return point of subroutine
20    10100    0x14    SUT    Subroutine         Subroutine
21    10101    0x15    EBW    Bus Write          Write to external bus
22    10110    0x16    EBR    Bus Read           Read from external bus buffer
23    10111    0x17    RST    Reset              Clear all registers
24    11000    0x18    SME    Same               Same as previous operation
25    11001    0x19    HLT    Halt               Stop System
____________________________________________________________________________________

Groups:

Nop
Math (7, 3 logic, 4 arithmetic)
Stack (4, 2 redundant pairs)
Regs (4, 2 redundant pairs)
jumps (3, 1 redundant pair)
subroutines (2, semi-redundant to other instructions)
I/O (2)
Reset
SME (redundant)
HLT (could be better placed)
_____________________________________________________________________________

The first thing I'm going to do is define what I assume to be your machine
architecture, with a few modifications of my own.

This is a "stack machine" where there is only one directly operable stack as
well as a second stack on the instruction register. The individual registers
do not have their own stacks.

Registers: I will assume a total of 16 because 'cuz.

EAX-EJX (named E_X because 'cuz)
El Stacko (EST)
Instruction Stack (INS)
Instruction Pointer (INP)
I/O bus (IOP)
FLAGS:
    0: Carry Flag (set by add and mul)
    1: Overflow Flag (set by sub and div)
    2: Sign Flag (set if number is negative)
    3: Zero Flag (set if most recent output is zero)
    4&5: Register Bit flags (00: 4 bit, 01: 8 bit, 10: 16 bit, 11: 32 bit)
    6&7: Stack Bit flags (00: 4 bit, 01: 8 bit, 10: 16 bit, 11: 32 bit)

I will assume nothing about the instruction set except the following: the
Instruction set will be able to address two registers per instruction.

If we look at this instruction set immediately, issues, oversights, and
over-complications can be spotted. The most important: you have not defined a
Move operation. This means that you do not have a useful general operation
that simply moves values from one place to another. Instead, you define several
more complex operations for each case. This is important because SBM, STR, LAD,
STI (sort of), RBM, RTN, SME, EBW, and EBR are all the same instruction: MOV. This is why
all computers use a Move instruction.
    SBM nn: MOV val, FLAGS
    RBM nn: MOV val, FLAGS
    STR EAX, EBX: MOV EAX, EBX
    LAD EAX, EBX: MOV EBX, EAX
    STI EAX, val: MOV val, EAX
    RTN: MOV INS, INP
    SME: MOV INP-1, INP
    EBW EAX: MOV EAX, IOP
    EBR EAX: MOV IOP, EAX

So that fixes that, but still more repeats exist. If it is a dedicated stack
machine, then you should be fully aware that moving a value from a stack is
the same as popping it, so:
    POP EAX: MOV EST, EAX
    PUS EAX: MOV EAX, EST
    PUI val: MOV val, EST
    
Okay, so we have fixed some stuff. Now for useless opcodes and maybe even some
changes for better performance. (remember, the more directly your opcode
translates to actual hardware properties, the better)

Useless:
    CRJ/CSJ: what does CRJ even do? Anyway, it's a redundant pair, kill one.
    SME: are you really that lazy? Besides, how often do you perform
         sequential operations multiple times in a row on the same
         registers with the same opcode. Truly useless opcode.

So, a quick refresher:
    
0     00000    0x00    NOP    No Operation       Does Nothing
1     00001    0x01    AND    And                Logical And
2     00010    0x02    OR     Or                 Logical Or
3     00011    0x03    XOR    Xor                Logical Exclusive Or
4     00100    0x04    ADD    Add                Add
5     00101    0x05    SUB    Subtract           Subtract
6     00110    0x06    MUL    Multiply           Multiplies
7     00111    0x07    DIV    Divide             Divides
16    10000    0x10    CSJ    Conditional Jmp    Jumps conditionally
17    10001    0x11    JUP    Jump               Jumps unconditionally
20    10100    0x14    SUT    Subroutine         Subroutine
23    10111    0x17    RST    Reset              Clear all registers
25    11001    0x19    HLT    Halt               Stop System

            #MOV is in there somewhere

SUT is an interesting opcode. It codes as MOV INP, INS; MOV val, INP. In
English: push the instruction pointer to the stack, then jump somewhere.
Return then codes as, "pop the instruction stack," which would, of course, jump
back to the original location set by the SUT command. You can leave SUT out of
the instruction list if you know what it does, or you can keep it if you feel
lazy. That is entirely up to you.

Okay, so now we have (with move included):

0     00000    0x00    NOP    No Operation       Does Nothing
1     00001    0x01    AND    And                Logical And
2     00010    0x02    OR     Or                 Logical Or
3     00011    0x03    XOR    Xor                Logical Exclusive Or
4     00100    0x04    ADD    Add                Add
5     00101    0x05    SUB    Subtract           Subtract
6     00110    0x06    MUL    Multiply           Multiplies
7     00111    0x07    DIV    Divide             Divides
8     01000    0x08    CSJ    Conditional Jmp    Jumps conditionally
9     01001    0x09    JUP    Jump               Jumps unconditionally
10    01010    0x0A    RST    Reset              Clear all registers
11    01011    0x0B    HLT    Halt               Stop System
12    01100    0x0C    MOV    Move               Moves values between registers

So, now let's do some simple thought, and then we will reorganize.

ADD/SUB use the same unit, except that SUB EAX, EBX is ADC EAX, EBX', while
SBB is ADD EAX, EBX'. Therefore, those four operations are easily consolidated
into a single unit with opcodes where the 0 bit is the carry and the 1 bit is
the inverter. These all fall into the arithmetic group, along with the DIV and
MUL. Now, DIV will only return the integer portion of a division, so a special
operation is needed to determine the remainder: I call it MOD, and MOD EAX,
EBX = B mod(A), which is the remainder of B/A.

The logic unit can now be altered slightly using De Morgan's laws
AB = (A'+B')'
A+B = A+B = (A'B')'
(AB)' = A'+B'
(A+B)' = (A+B)' = A'B'
A XOR B = A'B + B'A = (A'B' + AB)'
A XNOR B = (A'B + B'A)' = A'B' + AB
A' = A'+0 = A'1 = A'0' = A'1 + 0A
AB' = (A'+B)'

This seems tricky, but it isn't once you think about it.
We have 8 opcodes in the logic unit and we have 3 different things to mess
with, piece of cake.

The selector is on bit 2. In section 0, the output inversion is bit 0, and the
AB inversion is on bit 1. In section 1, the output inversion is on bit 0 and
the A'B enable is on bit 1. If the A'B enable is zero, and the inversion is 1,
then A will be set to 0 throughout.

000 A+B
001 (A+B)'
010 A'+B'
011 (A'+B')'
100 AB'
101 A+B'
110 A'B + B'A
111 (A'B + B'A)'

Okay, now onto the "stack" section:
It's gone

The Register section:
I chose to keep MOV and MVI just for simplicity's sake. So moving an immediate
value is still a separate operation.

Jump:
We just have JMP and CSJ now, so that's that.

Subroutines and I/O were killed.

NOP, RST, and HLT are special control cases.

So, currently, NOP is on 0x00. This is... okay, but HLT is a much better
candidate for 0x00. If you make the instruction pointer increment by the OR of
all bits in the opcode AND'ed with the Clock, then if the opcode is zero, the
instruction pointer will not increment. OR the output of the mask with a Trap
control and you have the ability to override the HLT when the time comes. One
other thing comes to mind, though. NOP is only valid if the architecture has a
pipeline, so it isn't needed per se.

The new Instruction List now has several interesting properties that one would
not have forseen.

0     00000    0x00    HLT    Halt               Stop system
1     00001    0x01    MUL    Multiply           Multiplies
2     00010    0x02    DIV    Divide             Integer divide    
3     00011    0x03    MOD    Modulus            Remainder of divide
4     00100    0x04    ADD    Add                Add without carry
5     00101    0x05    ADC    Add Carry          Add with carry of 1
6     00110    0x06    SBB    Sub Borrow         Subtract with borrow of 1
7     00111    0x07    SUB    Subtract           Subtract without borrow
8     01000    0x08    OR     Logical OR         Bitwise OR of two registers
9     01001    0x09    NOR    Logical NOR        Bitwise NOR of two registers
10    01010    0x0A    NAND   Logical NAND       Bitwise NAND of two registers
11    01011    0x0B    AND    Logical AND        Bitwise AND of two registers
12    01100    0x0C    IMP    Implies            Bitwise AND of A with B'
13    01101    0x0D    NOT    Logical NOT        Bitwise inversion of register
14    01110    0x0E    XOR    Logical XOR        Bitwise XOR of two registers
15    01111    0x0F    XNOR   Logical XNOR       Bitwise XNOR of two registers
16    10000    0x10    MOV    Move               Move values between registers
19    10001    0x11    MVI    Move Immediate     Move Immediate value
17    10010    0x12    CSJ    Conditional jmp    Jump conditionally
18    10011    0x13    JMP    Jump               Jump unconditionally
19    10100    0x14    RST    Reset              Resets all registers
21-23 101xx    0x15-17 ???    ???                Undefined operations
24-32 11xxx    0x18-1F ROL    Rotate Left        Rotate to the left xxx places

I use rotate instead of shift because you can rotate an amount, then cut out
the bits that should be zero, therefore you can rotate in such a way as to
shift up or down all with the same instruction.

    ROL 111, EAX; AND 01111111, EAX = SHR 1, EAX
    ROL 001, EAX; AND 11111110, EAX = SHL 1, EAX

In this way, it becomes easy to perform any type of shift, but it doesn't stop
there. To shift a larger register, simply do the following (assuming a shift
up and [EBX,EAX] as the form):
    MOV EAX, ECX
    AND 00001111, EAX    
    ROT 100, EAX
    ROT 100, EBX
    AND 11110000, EBX
    AND 00001111, ECX
    OR  ECX, EBX
result: [EBX,EAX]

This is the 4 bit shift of a 16 bit number in two registers. The 4 bit
rotation has slightly more code.

One should note the opening of 3 undefined opcodes at 21-23. Do with
them as you may, they all are 101xx.

To finish, the groups are:

    00000: HLT
    00xxx: Arithmetic Operations
    01xxx: Logical Operations
    1000x: MOV, MVI
    1001x: Jump Operations
    10100: RST
    101xx: Undefined
    11xxx: Shift Operations

Or, more generally
    00000: HLT
    00xxx: Arithmetic
    01xxx: Logic
    10xxx: Data flow
    11xxx: Shift

As you can see, I broke the groups up by eight so that the related operations all have the same prefix. This, along with killing your MOV duplicates, was my goal the entire time.



RE: My new and most thought out IS. - Chibill - 12-24-2014

SBM and RBM are nothing like move.. They change how big of numbers they hold in bit size and actuall should be combined into Set Bit Mode to set you bit mod. Also I still don't understand what ADDC is used for because if that instrucrion exists the uses could break the whole Multi-bit system.


RE: My new and most thought out IS. - TSO - 12-24-2014

(12-24-2014, 07:03 PM)Chibill Wrote: SBM and RBM are nothing like move.. They change how big of numbers they hold in bit size and actuall should be combined into Set Bit Mode to set you bit mod. Also I still don't understand what ADDC is used for because if that instrucrion exists the uses could break the whole Multi-bit system.

That is because you don't understand how I was able to integrate your bit modes into MOV. I made it so that your FLAGS control the bit mode, and then you move the value you want your bit mode to be into the FLAGS. What you would have found is that this is pretty much how SBM and RBM would have worked anyway, except you would have just put each of them into their own arbitrary two bit control registers.

ADD EAX, EBX = A + B --> A
ADC EAX, EBX = A + B + 1 --> A, where 1 is the carry in. You're going to need this operation if you want your multi bit stuff to work.


RE: My new and most thought out IS. - Chibill - 12-24-2014

Multi- Bit stuff is all hardware based. And also every Register in the whole CPU (Prog counter,etc...) is addressable.


RE: My new and most thought out IS. - TSO - 12-24-2014

*head desk* all right, lets try this again.

No matter how you intend to do this, the SBM and RBM must store the value you set them to somewhere in the god damn computer. If you store these values somewhere in the computer, then you can perform a MOV to alter the location they were stored to because every register is addressable in the computer. To save registers, you then throw them all into your FLAGS register and you're done. It's still redundant to MOV.