diff options
Diffstat (limited to 'triscv/README.md')
| -rw-r--r-- | triscv/README.md | 272 |
1 files changed, 272 insertions, 0 deletions
diff --git a/triscv/README.md b/triscv/README.md new file mode 100644 index 0000000..3b8beeb --- /dev/null +++ b/triscv/README.md @@ -0,0 +1,272 @@ +# `triscv`, a trinary riscv-like ISA simulator + +An attempt at creating a trinary computer simulator capable of running simple +operating systems, with virtual memory and user/system separation. + +Natural bases of three used as trit groupings, i.e. +3^0 = trit +3^1 = nit (likely not actually used?) +3^2 = tryte (base size of characters etc, similar to byte) +3^3 = tri (base word size) + +Ideally I would like to extend support up to 3^4 (tril?) that would be +equivalent to 64 bit groupings on conventional hardware, but the my trinary +arithmetic library underlying the simulator doesn't support 81 trits due to +efficiency/portability concerns. 128 bit integers could be usable on at least +x86, but not really portable. Something like `gmp` could also be used, but would +be very slow. Alternatively, consider 45 trit as an equivalence to 64 bit +computers, as they are approximately the same in value and divisible by three. + +Heavy inspiration taken from riscv. + +M-mode/S-mode/U-mode fits pretty nicely into trinary, heh. + +# Operation set + +27 trit ops, registers 3^4? + + 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 + 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 +|-----------------------------------------------------| +| fn5 | rs2 | rs1 | fn0 | rd | opcode | R-type +|-----------------------------------------------------| +| imm9 | rs1 | fn0 | rd | opcode | I-type +|-----------------------------------------------------| +| imm5 | rs2 | rs1 | fn0 | imm4 | opcode | S-type +|-----------------------------------------------------| +| imm18 | rd | opcode | U-type +|-----------------------------------------------------| +| imm5 | rs2 | rs1 | immd | rd | opcode | D-type +|-----------------------------------------------------| +(D is a variant of R, where immd is actually fn0, but used as an immediate) + +Compressed instructions probably possible to implement in future but left alone +for now. + +Exact instructions still TBD, but R type probably reserves one fn trit value for +diops. It's unclear to me how readily diops can be implemented in hardware, so +consider this more exploratory than anythin else. + +Similarly, I-type reserved on fn trit value to unops. + +Turns out it's literally just a mapping, i.e. unops use a three-way mux with +the input value as the selection trit and the three control bits inputs to the +mux. Similarly, diops are just a nine-way mux. + +# Registers + +81, of which x0 is constant 0. ABI TBD but probably similar to riscv. + +# Virtual memory + +Physical memory consists of PPN[2], PPN[1], PPN[0] and page offset. 27 trits is enough +for about 7 teratrytes of memory, which probably doesn't need range extensions +like 32bit computers tend to use. + +Page table entries: + + 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 + 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 +|-----------------------------------------------------| +| PPN[2] | PPN[1] | PPN[0] |RSW|G|U|X|A|R|V| +|------------------------------------------------D-W--| +| TAG | +|-----------------------------------------------------| +| Reserved | +|-----------------------------------------------------| + +TAG is a tag that allows us to separate one address space into multiple regions, +similar to CODOMS system but scaled down a lot. If left 0, code executing in the +region is allowed to access other regions but outside regions are not allowed to +access the zero region, except executing a migration jump. + +The reserved region might come +in handy for 'extensions' in the future, but can probably be set to zero for +now. + +R/W and A/D work by the following table: + +N => both (R and W, A and D) +O => none +P => top (R, A) + +RSW is reserved for S-mode usage. + +The idea here is a page marked write must also be marked read, and a dirty page +must also have been accessed. Whether an interrupt is raised when A/D is updated +is set by a status CSR, to be determined later. Three-level page tables. + +Each base page is 3^8 = 6561, and since each PTE +takes up 9 trytes, each base page can fit 3^6 PTEs. Therefore, to cover the full +27 bit address space, we need three `satp` CSRs, `satpn`, `satpo`, `satpp`, +corresponding to the first trit in the address. This can give reasonably +efficient separation of user/kernelspace, for example -1 for kernel and 1 for +user. Still about 2.5 tera per space. + +This can be extended to 81 bits, although with no nice whole number that maps to +81. Not a huge deal, by any means, although kind of annoying that the number of +elements per PTE shrinks to 243. Maybe not a huge issue, but might limit +useability somewhat as the number of page levels has to be increased much more +rapidly to get larger virtual address spaces. + +Requiring physical addresses to be the same width as virtual addresses +simplifies hypervisor stuff somewhat, could be useful? Not that allocating some +pages in series is too big of an issue, but still feels like an unnecessary +complication in the RISC-V specs. Apparently the explanation given is that is +can be useful to emulate larger physical address spaces than virtual spaces, +though I'd like to see some examples. I guess easier masking of some addresses? +Dunno. + +I might want to add in a bus error to separate it from pmp errors, there's been +some discussion about it in riscv mailing lists. + +# CSRs + +TDB + +# Extensions + +## I + +addi, slti +|-----------------------------------------------------| +| imm0 | rs1 | fn0 | rd | OP-IMM | I-type +|-----------------------------------------------------| + +unop (some macro instructions might be available in assembler) +|-----------------------------------------------------| +| 0 |N|O|P| rs1 | fn0 | rd | OP-IMM | I-type +|-----------------------------------------------------| + +slli, srli (shifts work differently in balanced forms, have to be careful) + (shmt is 'unsigned', i.e. the actual shift amount is shmt + 13) +|-----------------------------------------------------| +| imm0 |shmt | rs1 | fn0 | rd | OP-IMM | I-type +|-----------------------------------------------------| + +lui +|-----------------------------------------------------| +| imm9 | rd | LUI | U-type +|-----------------------------------------------------| + +auipc +|-----------------------------------------------------| +| imm9 | rd | AUIPC | U-type +|-----------------------------------------------------| + +add, slt, sge, seq, sne, sll, srl, sub +|-----------------------------------------------------| +| 0 | rs2 | rs1 | fn0 | rd | OP | R-type +|-----------------------------------------------------| + +diop +|-----------------------------------------------------| +|N|O|P|N|O| rs2 | rs1 |P|N|O|P|0| rd | DIOP | D-type +|-----------------------------------------------------| + +nop +|-----------------------------------------------------| +| 0 | x0 | 0 | x0 | OP-IMM | I-type +|-----------------------------------------------------| + +jal +|-----------------------------------------------------| +| imm9 | rd | JAL | U-type +|-----------------------------------------------------| + +jalr +|-----------------------------------------------------| +| imm0 | rs1 | 0 | rd | JALR | I-type +|-----------------------------------------------------| + +beq, bne, blt, bge +|-----------------------------------------------------| +| imm0 | rs2 | rs1 | fn0 | imm4 | BRANCH | S-type +|-----------------------------------------------------| + +load (w = width, i = 1 tryte, 0 = 3 trytes, 1 = 9 trytes) +|-----------------------------------------------------| +| imm0 | rs1 |w| 0 | rd | LOAD | I-type +|-----------------------------------------------------| + +store +|-----------------------------------------------------| +| imm5 | rs2 | rs1 |w| 0 | imm4 | STORE | S-type +|-----------------------------------------------------| + +fence (todo) +|-----------------------------------------------------| +| imm0 | rs1 | fn0 | rd | MEM | I-type +|-----------------------------------------------------| + +ecall, ebreak, pcall +|-----------------------------------------------------| +| imm0 | x0 | fn0 | x0 | SYSTEM | I-type +|-----------------------------------------------------| + +hints, any OP-IMM or OP with rd = x0. Additionally, +a number of maybe-instructions in SYSTEM for future use, if unimplemented +just write 0 to rd. + +## M + +mul +|-----------------------------------------------------| +| fn5 | rs2 | rs1 | fn0 | rd | OP | R-type +|-----------------------------------------------------| + +div +|-----------------------------------------------------| +| fn5 | rs2 | rs1 | fn0 | rd | OP | R-type +|-----------------------------------------------------| + +rem +|-----------------------------------------------------| +| fn5 | rs2 | rs1 | fn0 | rd | OP | R-type +|-----------------------------------------------------| + +## A + +stt (start transaction) +cst (checked store) +ent (end transaction) +cat (cancel transaction) + +Each system has a buffer with at least three slots for checked transactions. +Each checked transaction is written to the buffer when an stc is encountered. +stc clears out this buffer and ent checks if all stores are valid and flushes +the buffer to real memory, or cache or wherever. A system is allowed to give +each core a buffer or use a global buffer, but the size should be given in a CSR +somewhere. Platforms may require at least n slots. Maybe? Reads inside +transaction read from memory. Slow commits, at least somewhat, but probably +somewhat simpler. Spinlock (and by extension, mutex) would then be + +spinlock: + // spin until a zero appears + lw x1, (x2) + bnez x1, spinlock + + // start transaction, try to write 1 + stt + li x1, 1 + stc x1, (x2) + ent x1 + // someone else tried at the same time, wait for next zero + // preferably also do a spin for a random but increasing time to try to + // avoid livelock, or rely on whatever system we're dealing with to + // provide it for us + beqz x1, spinlock + +could probably also provide simple atomics, like add or something, but eh + +## Zicsr + +csrrw, csrrs, csrrc +|-----------------------------------------------------| +| imm0 | rs | fn0 | rd | SYSTEM | I-type +|-----------------------------------------------------| + +The CSR numbers are specified in the future. + +Also, possibly floating point stuff in the future, though I haven't chosen a +floating point format yet. |
