What is Sayuri?
- We must have FreeCPU, as you know. Sayuri is one of them.
- 32 bit, Linux ready.(will be :-)
- It must be open sourced under GPL or something.
- My target is not a performance, not a code density, not a price, not a small power, but a small source code and "keep it simple".
- I don't care about TOOL itself should be open or not. I'm using ModelSim and Foundation.
- It is running at 75MHz now, with some modification for Foundation + XCV400-6.
Base architecture of Sayuri
31...24 23...16 15......00
Op , Dest, Imm16 or Source
only has 3 opecode. but Sayuri has ALU/compareter/logical functions as Register. so if you move some value to Add register, it will be "ADD".
(1)MOV Dest Source
Source register => Dest register.
Op code 1110 0000
(2)Test&Mov Dest Source
if(status bit = 0)
MOV Dest source
else
do nothing.
Opcode 1010 0000
(3)Immidiate Dest Imm16
write 16 bit immidiate to Dest register.
Op code 1101 0000
Normal instruction vs. Sayuri architecture
Add
MOV ALU_IN R1
MOV ALU_ADD R2
MOV R3 ALUOUT
Load R1(Address),R2(Read Data)
MOV DP R1
MOV R2 DD
32 bit immidiate
Imm ALU_IN Imm16
Imm ALU_SHIFT Imm16
MOV R1 ALU_OUT
Imm ALU_IN Imm16
MOV ALU_OR R1
Jump
MOV IP R1
JMP on Equal(S1, S2, Address)
MOV ALU_IN R1
MOV ALU_EQ R2
MOV ALU_OUT STATE
T&M IP R3
Call and Return
MOV ALU_IN IP
Imm ALU_ADD 5
MOV R1 ALU_OUT
//R1 is return address
MOV IP R2
MOV ALU_IN R3
: //sub routine
MOV IP R1
Sayuri brock diagram
VHDL
VHDL for simuration
register map
Simulation output
Sayuri is working for (1+2+3+4+5+....), it receives interrupt(test_cpu/intin), it jumps to interrupt vector, return and continue calcurating.
How Sayuri Works
This is a sample assembler code in ROM. it is interrupt vector setup, user code, and interrupt action routine.
-- set up code
To_StdLogicVector( X"D0_09_00_20"), -- IMM EJR 0x0020
To_StdLogicVector( X"D0_03_00_10"), -- IMM IPRET 0x0010
To_StdLogicVector( X"E0_42_42_00"),
To_StdLogicVector( X"E0_42_42_00"),
To_StdLogicVector( X"E0_42_42_00"),
To_StdLogicVector( X"E0_42_42_00"),
To_StdLogicVector( X"E0_42_42_00"),
To_StdLogicVector( X"E0_42_42_00"),
To_StdLogicVector( X"E0_42_42_00"),
To_StdLogicVector( X"E0_42_42_00"),
To_StdLogicVector( X"E0_42_42_00"),
To_StdLogicVector( X"E0_42_42_00"),
To_StdLogicVector( X"E0_42_42_00"),
To_StdLogicVector( X"E0_42_42_00"),
To_StdLogicVector( X"E0_42_42_00"),
To_StdLogicVector( X"E0_42_42_00"),
-- user mode code is , 1+2+3+4+5+6+7+8+9+10=55
To_StdLogicVector( X"D0_31_00_01"), -- Imm INC_BASE 0001 ; loop counter i.
To_StdLogicVector( X"D0_41_00_00"), -- Imm R1 0000 ; R1 is answer.
To_StdLogicVector( X"D0_42_00_14"), -- Imm R2 0014 ; Loop Label
To_StdLogicVector( X"D0_13_00_0B"), -- Imm CMP_REGA 000B; Counter = 0x0B
To_StdLogicVector( X"E0_0a_41_00"), -- MOV ALUBASE R1; tmp = tmp + i;
To_StdLogicVector( X"E0_0c_31_00"), -- MOV ALUADD INCBASE;
To_StdLogicVector( X"E0_41_0b_00"), -- MOV R1 ALUOUT;
To_StdLogicVector( X"E0_32_31_00"), -- MOV INC_BASE ++;
To_StdLogicVector( X"E0_17_31_00"), -- MOV CMP_GT INC; if i < 10 then loop
To_StdLogicVector( X"E0_01_14_00"), -- MOV STAT CMP_OUT;
To_StdLogicVector( X"A0_02_42_00"), -- Test&Mov IP R2;
To_StdLogicVector( X"D0_04_80_00"), -- Imm DP 8000; Store R1 to 8000h.
To_StdLogicVector( X"E0_05_41_00"), -- Mov DD R1;
To_StdLogicVector( X"E0_43_05_00"), -- Mov R3 DD;
To_StdLogicVector( X"D0_02_00_00"), -- JMP to TOP
To_StdLogicVector( X"E0_42_42_00"), -- NOP
-- interrupt code
To_StdLogicVector( X"D0_04_80_01"), -- Imm DP 8001
To_StdLogicVector( X"E0_05_08_00"), -- MOV DD EPR (just a IO write)
To_StdLogicVector( X"E0_03_08_00"), -- MOV IPRET EPR
To_StdLogicVector( X"E0_42_42_00"),
To_StdLogicVector( X"E0_42_42_00"),
To_StdLogicVector( X"E0_42_42_00"),
To_StdLogicVector( X"E0_42_42_00"),
Sayuri needs more
- MMU and Cash (ummm, how it can be simple... or I'm thinking about uCLinux, without MMU)
- Bus interface (maybe MPX like, SH-3's)
- "North Bridge". I'm investigating Vcuved V320USC
- GCC. Mr gNiibe(famous on SH-Linux) kindly told me he will work for it.