summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcheapie <cheapiephp@gmail.com>2026-11-07 16:25:42 -0600
committercheapie <cheapiephp@gmail.com>2026-11-07 16:25:42 -0600
commit9ae11c52355e8a362d34d7cabfbc573ddf8c2f80 (patch)
treed5543de18e410daa4f0efbcec323d1ad7f8513c9
parent15d38061302f61304e276f0045d8e4b3f1548e33 (diff)
downloadrvcontroller-9ae11c52355e8a362d34d7cabfbc573ddf8c2f80.tar
rvcontroller-9ae11c52355e8a362d34d7cabfbc573ddf8c2f80.tar.gz
rvcontroller-9ae11c52355e8a362d34d7cabfbc573ddf8c2f80.tar.bz2
rvcontroller-9ae11c52355e8a362d34d7cabfbc573ddf8c2f80.tar.xz
rvcontroller-9ae11c52355e8a362d34d7cabfbc573ddf8c2f80.zip
Add Zknh
-rw-r--r--assembly/zknhtest/Makefile24
l---------assembly/zknhtest/rvcontroller.ld1
-rw-r--r--assembly/zknhtest/zknhtest.S36
-rw-r--r--assembly/zknhtest512/Makefile24
l---------assembly/zknhtest512/rvcontroller.ld1
-rw-r--r--assembly/zknhtest512/zknhtest512.S99
-rw-r--r--doc/_start_here.txt4
-rw-r--r--doc/instructions.txt12
-rw-r--r--rvcontroller.lua166
9 files changed, 365 insertions, 2 deletions
diff --git a/assembly/zknhtest/Makefile b/assembly/zknhtest/Makefile
new file mode 100644
index 0000000..0eb056f
--- /dev/null
+++ b/assembly/zknhtest/Makefile
@@ -0,0 +1,24 @@
+MARCH ?= rv32imacbzicntr_zicond_zicsr_zifencei_zihintpause_zilsd_zclsd_zabha_zacas_zbkb_zbkx_zcb_zcmp_zcmt_zicboz_zknh
+
+.PHONY: all dump load clean
+
+all: zknhtest.hex
+
+zknhtest.o: zknhtest.S
+ riscv32-none-elf-as -I../rvcontroller-libraries -march=${MARCH} -o zknhtest.o zknhtest.S
+
+zknhtest.elf: zknhtest.o
+ riscv32-none-elf-ld -T rvcontroller.ld --no-warn-rwx-segments -o zknhtest.elf zknhtest.o
+
+dump: zknhtest.elf
+ riscv32-none-elf-objdump -d zknhtest.elf
+
+zknhtest.hex: zknhtest.elf
+ riscv32-none-elf-objcopy -O ihex zknhtest.elf zknhtest.hex
+
+load: zknhtest.hex
+ bash -c "wl-copy < zknhtest.hex"
+
+clean:
+ rm -f zknhtest.hex zknhtest.elf zknhtest.o
+
diff --git a/assembly/zknhtest/rvcontroller.ld b/assembly/zknhtest/rvcontroller.ld
new file mode 120000
index 0000000..bc01402
--- /dev/null
+++ b/assembly/zknhtest/rvcontroller.ld
@@ -0,0 +1 @@
+../../rvcontroller.ld \ No newline at end of file
diff --git a/assembly/zknhtest/zknhtest.S b/assembly/zknhtest/zknhtest.S
new file mode 100644
index 0000000..98bd647
--- /dev/null
+++ b/assembly/zknhtest/zknhtest.S
@@ -0,0 +1,36 @@
+li a0,0x12345678
+sha256sig0 s0,a0
+sha256sig1 s1,a0
+sha256sum0 s4,a0
+sha256sum1 s5,a0
+
+# Sigma0
+rori s2,a0,7
+rori t0,a0,18
+xor s2,s2,t0
+srli t0,a0,3
+xor s2,s2,t0
+
+# Sigma1
+rori s3,a0,17
+rori t0,a0,19
+xor s3,s3,t0
+srli t0,a0,10
+xor s3,s3,t0
+
+# Sum0
+rori s6,a0,2
+rori t0,a0,13
+xor s6,s6,t0
+rori t0,a0,22
+xor s6,s6,t0
+
+# Sum1
+rori s7,a0,6
+rori t0,a0,11
+xor s7,s7,t0
+rori t0,a0,25
+xor s7,s7,t0
+
+li a7,10
+ecall
diff --git a/assembly/zknhtest512/Makefile b/assembly/zknhtest512/Makefile
new file mode 100644
index 0000000..83a92dc
--- /dev/null
+++ b/assembly/zknhtest512/Makefile
@@ -0,0 +1,24 @@
+MARCH ?= rv32imacbzicntr_zicond_zicsr_zifencei_zihintpause_zilsd_zclsd_zabha_zacas_zbkb_zbkx_zcb_zcmp_zcmt_zicboz_zknh
+
+.PHONY: all dump load clean
+
+all: zknhtest512.hex
+
+zknhtest512.o: zknhtest512.S
+ riscv32-none-elf-as -I../rvcontroller-libraries -march=${MARCH} -o zknhtest512.o zknhtest512.S
+
+zknhtest512.elf: zknhtest512.o
+ riscv32-none-elf-ld -T rvcontroller.ld --no-warn-rwx-segments -o zknhtest512.elf zknhtest512.o
+
+dump: zknhtest512.elf
+ riscv32-none-elf-objdump -d zknhtest512.elf
+
+zknhtest512.hex: zknhtest512.elf
+ riscv32-none-elf-objcopy -O ihex zknhtest512.elf zknhtest512.hex
+
+load: zknhtest512.hex
+ bash -c "wl-copy < zknhtest512.hex"
+
+clean:
+ rm -f zknhtest512.hex zknhtest512.elf zknhtest512.o
+
diff --git a/assembly/zknhtest512/rvcontroller.ld b/assembly/zknhtest512/rvcontroller.ld
new file mode 120000
index 0000000..bc01402
--- /dev/null
+++ b/assembly/zknhtest512/rvcontroller.ld
@@ -0,0 +1 @@
+../../rvcontroller.ld \ No newline at end of file
diff --git a/assembly/zknhtest512/zknhtest512.S b/assembly/zknhtest512/zknhtest512.S
new file mode 100644
index 0000000..1af00d1
--- /dev/null
+++ b/assembly/zknhtest512/zknhtest512.S
@@ -0,0 +1,99 @@
+li a0,0x12345678
+li a1,0xdeadbeef
+
+
+
+sha512sig0l s0,a0,a1
+
+srli s1,a0,1
+srli t0,a0,7
+xor s1,s1,t0
+srli t0,a0,8
+xor s1,s1,t0
+slli t0,a1,31
+xor s1,s1,t0
+slli t0,a1,25
+xor s1,s1,t0
+slli t0,a1,24
+xor s1,s1,t0
+
+
+
+sha512sig0h s2,a0,a1
+
+srli s3,a0,1
+srli t0,a0,7
+xor s3,s3,t0
+srli t0,a0,8
+xor s3,s3,t0
+slli t0,a1,31
+xor s3,s3,t0
+slli t0,a1,24
+xor s3,s3,t0
+
+
+
+sha512sig1l s4,a0,a1
+
+slli s5,a0,3
+srli t0,a0,6
+xor s5,s5,t0
+srli t0,a0,19
+xor s5,s5,t0
+srli t0,a1,29
+xor s5,s5,t0
+slli t0,a1,26
+xor s5,s5,t0
+slli t0,a1,13
+xor s5,s5,t0
+
+
+
+sha512sig1h s6,a0,a1
+
+slli s7,a0,3
+srli t0,a0,6
+xor s7,s7,t0
+srli t0,a0,19
+xor s7,s7,t0
+srli t0,a1,29
+xor s7,s7,t0
+slli t0,a1,13
+xor s7,s7,t0
+
+
+
+sha512sum0r s8,a0,a1
+
+slli s9,a0,25
+slli t0,a0,30
+xor s9,s9,t0
+srli t0,a0,28
+xor s9,s9,t0
+srli t0,a1,7
+xor s9,s9,t0
+srli t0,a1,2
+xor s9,s9,t0
+slli t0,a1,4
+xor s9,s9,t0
+
+
+
+sha512sum1r s10,a0,a1
+
+slli s11,a0,23
+srli t0,a0,14
+xor s11,s11,t0
+srli t0,a0,18
+xor s11,s11,t0
+srli t0,a1,9
+xor s11,s11,t0
+slli t0,a1,18
+xor s11,s11,t0
+slli t0,a1,14
+xor s11,s11,t0
+
+
+
+li a7,10
+ecall
diff --git a/doc/_start_here.txt b/doc/_start_here.txt
index 0ca3f65..0d06129 100644
--- a/doc/_start_here.txt
+++ b/doc/_start_here.txt
@@ -5,7 +5,7 @@ RVController is a program for use in Luacontrollers (from the mesecons mod) in L
It emulates a single RISC-V hart and a configurable amount (64KiB default) of RAM.
Features:
-* RV32IMACBZicboz_Zicfilp_Zicntr_Zicond_Zicsr_Zifencei_Zihintpause_Zihpm_Zilsd_Zimop_Zabha_Zacas_Zalasr_Zawrs_Zcb_Zclsd_Zcmop_Zcmp_Zcmt_Zbc_Zbkb_Zbkc_Zbkx_Zkr_Xh3bextm_Xh3misa instruction set provides:
+* RV32IMACBZicboz_Zicfilp_Zicntr_Zicond_Zicsr_Zifencei_Zihintpause_Zihpm_Zilsd_Zimop_Zabha_Zacas_Zalasr_Zawrs_Zcb_Zclsd_Zcmop_Zcmp_Zcmt_Zbc_Zbkb_Zbkc_Zbkx_Zknh_Zkr_Xh3bextm_Xh3misa instruction set provides:
- 32-bit address space
- 32 32-bit registers (31 general-purpose + 1 zero register)
- Selectable endianness
@@ -21,6 +21,7 @@ Features:
- Single-instruction function prologues/epilogues and jump tables
- Compatibility with future MOP-based extensions
- Forward-edge control-flow integrity via landing pads
+ - SHA-256 and SHA-512 hash acceleration
- Compatibility with most code (not involving I/O) written for the WCH CH32V003, Espressif ESP32-C2/C3/C5/C6/C61/H2, Renesas R9A02G020/R9A02G021/R9A06G150, the RISC-V cores of the Raspberry Pi Pico 2, and many other chips
* Mutable ISA via writable bits in misa CSR
* Mesecons and digilines I/O
@@ -77,6 +78,7 @@ RVController is intended to be compliant with the following specifications:
* "Zawrs" Extension for Wait-on-Reservation-Set instructions, Version 1.01
* Zbkb: Extension for Bit-manipulation for Cryptography, Version 1.0.0
* Zbkx: Extension for Crossbar permutations, Version 1.0.0
+* Zknh - NIST Suite: Hash Function, Version 1.0.1
* Zkr - Entropy Source Extension, Version 1.0.1
- Note: Virtual source, backed by Lua math.random(), 16 bits available per clock cycle
* Zicfilp: Control Flow Integrity - Landing Pad
diff --git a/doc/instructions.txt b/doc/instructions.txt
index 524a2b8..b7a0b86 100644
--- a/doc/instructions.txt
+++ b/doc/instructions.txt
@@ -298,6 +298,18 @@ Zbkx: Extension for Crossbar permutations, Version 1.0.0
* xperm4 rd,rs1,rs2 | Crossbar permutation (nibbles)
* xperm8 rd,rs1,rs2 | Crossbar permutation (bytes)
+Zknh - NIST Suite: Hash Function
+* sha256sig0 rd,rs1 | SHA2-256 Sigma0
+* sha256sig1 rd,rs1 | SHA2-256 Sigma1
+* sha256sum0 rd,rs1 | SHA2-256 Sum0
+* sha256sum1 rd,rs1 | SHA2-256 Sum1
+* sha512sig0h rd,rs1,rs2 | SHA2-512 Sigma0 high
+* sha512sig0l rd,rs1,rs2 | SHA2-512 Sigma0 low
+* sha512sig1h rd,rs1,rs2 | SHA2-512 Sigma1 high
+* sha512sig1l rd,rs1,rs2 | SHA2-512 Sigma1 low
+* sha512sum0r rd,rs1,rs2 | SHA2-512 Sum0
+* sha512sum1r rd,rs1,rs2 | SHA2-512 Sum1
+
Xh3bextm: Hazard3 bit extract multiple
* h3.bextm rd,rs1,rs2,imm | Bit extract multiple, offset by register
* h3.bextmi rd,rs1,imm1,imm2 | Bit extract multiple, offset by immediate
diff --git a/rvcontroller.lua b/rvcontroller.lua
index 8033a01..ee66cd3 100644
--- a/rvcontroller.lua
+++ b/rvcontroller.lua
@@ -483,7 +483,7 @@ local function readcsr(address)
true, --Zihintpause
false, --Zknd
false, --Zkne
- false, --Zknh
+ true, --Zknh
false, --Zksed
false, --Zksh
true, --Zkt
@@ -2068,6 +2068,150 @@ local operations = {
end
setreg(rd,implodebits(outputbits,32))
end,
+ sha256sig0 = function(rd,rs1)
+ local outputbits = {}
+ local function xor(index,new)
+ if new then outputbits[index] = not outputbits[index] end
+ end
+ local srcbits = explodebits(getreg(rs1),32)
+ for i=0,31 do outputbits[i] = srcbits[(i+7)%32] end
+ for i=0,31 do xor(i,srcbits[(i+18)%32]) end
+ for i=0,31 do xor(i,srcbits[i+3]) end
+ setreg(rd,implodebits(outputbits,32))
+ end,
+ sha256sig1 = function(rd,rs1)
+ local outputbits = {}
+ local function xor(index,new)
+ if new then outputbits[index] = not outputbits[index] end
+ end
+ local srcbits = explodebits(getreg(rs1),32)
+ for i=0,31 do outputbits[i] = srcbits[(i+17)%32] end
+ for i=0,31 do xor(i,srcbits[(i+19)%32]) end
+ for i=0,31 do xor(i,srcbits[i+10]) end
+ setreg(rd,implodebits(outputbits,32))
+ end,
+ sha256sum0 = function(rd,rs1)
+ local outputbits = {}
+ local function xor(index,new)
+ if new then outputbits[index] = not outputbits[index] end
+ end
+ local srcbits = explodebits(getreg(rs1),32)
+ for i=0,31 do outputbits[i] = srcbits[(i+2)%32] end
+ for i=0,31 do xor(i,srcbits[(i+13)%32]) end
+ for i=0,31 do xor(i,srcbits[(i+22)%32]) end
+ setreg(rd,implodebits(outputbits,32))
+ end,
+ sha256sum1 = function(rd,rs1)
+ local outputbits = {}
+ local function xor(index,new)
+ if new then outputbits[index] = not outputbits[index] end
+ end
+ local srcbits = explodebits(getreg(rs1),32)
+ for i=0,31 do outputbits[i] = srcbits[(i+6)%32] end
+ for i=0,31 do xor(i,srcbits[(i+11)%32]) end
+ for i=0,31 do xor(i,srcbits[(i+25)%32]) end
+ setreg(rd,implodebits(outputbits,32))
+ end,
+ sha512sig0l = function(rd,rs1,rs2)
+ local outputbits = {}
+ local function xor(index,new)
+ if new then outputbits[index] = not outputbits[index] end
+ end
+ local src1bits = explodebits(getreg(rs1),32)
+ local src2bits = explodebits(getreg(rs2),32)
+ for i=0,31 do
+ outputbits[i] = src1bits[i+1]
+ xor(i,src1bits[i+7])
+ xor(i,src1bits[i+8])
+ xor(i,src2bits[i-31])
+ xor(i,src2bits[i-25])
+ xor(i,src2bits[i-24])
+ end
+ setreg(rd,implodebits(outputbits,32))
+ end,
+ sha512sig0h = function(rd,rs1,rs2)
+ local outputbits = {}
+ local function xor(index,new)
+ if new then outputbits[index] = not outputbits[index] end
+ end
+ local src1bits = explodebits(getreg(rs1),32)
+ local src2bits = explodebits(getreg(rs2),32)
+ for i=0,31 do
+ outputbits[i] = src1bits[i+1]
+ xor(i,src1bits[i+7])
+ xor(i,src1bits[i+8])
+ xor(i,src2bits[i-31])
+ xor(i,src2bits[i-24])
+ end
+ setreg(rd,implodebits(outputbits,32))
+ end,
+ sha512sig1h = function(rd,rs1,rs2)
+ local outputbits = {}
+ local function xor(index,new)
+ if new then outputbits[index] = not outputbits[index] end
+ end
+ local src1bits = explodebits(getreg(rs1),32)
+ local src2bits = explodebits(getreg(rs2),32)
+ for i=0,31 do
+ outputbits[i] = src1bits[i-3]
+ xor(i,src1bits[i+6])
+ xor(i,src1bits[i+19])
+ xor(i,src2bits[i+29])
+ xor(i,src2bits[i-13])
+ end
+ setreg(rd,implodebits(outputbits,32))
+ end,
+ sha512sig1l = function(rd,rs1,rs2)
+ local outputbits = {}
+ local function xor(index,new)
+ if new then outputbits[index] = not outputbits[index] end
+ end
+ local src1bits = explodebits(getreg(rs1),32)
+ local src2bits = explodebits(getreg(rs2),32)
+ for i=0,31 do
+ outputbits[i] = src1bits[i-3]
+ xor(i,src1bits[i+6])
+ xor(i,src1bits[i+19])
+ xor(i,src2bits[i+29])
+ xor(i,src2bits[i-26])
+ xor(i,src2bits[i-13])
+ end
+ setreg(rd,implodebits(outputbits,32))
+ end,
+ sha512sum0r = function(rd,rs1,rs2)
+ local outputbits = {}
+ local function xor(index,new)
+ if new then outputbits[index] = not outputbits[index] end
+ end
+ local src1bits = explodebits(getreg(rs1),32)
+ local src2bits = explodebits(getreg(rs2),32)
+ for i=0,31 do
+ outputbits[i] = src1bits[i-25]
+ xor(i,src1bits[i-30])
+ xor(i,src1bits[i+28])
+ xor(i,src2bits[i+7])
+ xor(i,src2bits[i+2])
+ xor(i,src2bits[i-4])
+ end
+ setreg(rd,implodebits(outputbits,32))
+ end,
+ sha512sum1r = function(rd,rs1,rs2)
+ local outputbits = {}
+ local function xor(index,new)
+ if new then outputbits[index] = not outputbits[index] end
+ end
+ local src1bits = explodebits(getreg(rs1),32)
+ local src2bits = explodebits(getreg(rs2),32)
+ for i=0,31 do
+ outputbits[i] = src1bits[i-23]
+ xor(i,src1bits[i+14])
+ xor(i,src1bits[i+18])
+ xor(i,src2bits[i+9])
+ xor(i,src2bits[i-18])
+ xor(i,src2bits[i-14])
+ end
+ setreg(rd,implodebits(outputbits,32))
+ end,
}
local function runinst(instruction)
@@ -2092,6 +2236,18 @@ local function runinst(instruction)
operations.add(rd,rs1,rs2)
elseif f3 == 0x0 and f7 == 0x20 then
operations.sub(rd,rs1,rs2)
+ elseif f3 == 0x0 and f7 == 0x28 then
+ operations.sha512sum0r(rd,rs1,rs2)
+ elseif f3 == 0x0 and f7 == 0x29 then
+ operations.sha512sum1r(rd,rs1,rs2)
+ elseif f3 == 0x0 and f7 == 0x2a then
+ operations.sha512sig0l(rd,rs1,rs2)
+ elseif f3 == 0x0 and f7 == 0x2b then
+ operations.sha512sig1l(rd,rs1,rs2)
+ elseif f3 == 0x0 and f7 == 0x2e then
+ operations.sha512sig0h(rd,rs1,rs2)
+ elseif f3 == 0x0 and f7 == 0x2f then
+ operations.sha512sig1h(rd,rs1,rs2)
elseif f3 == 0x4 and f7 == 0x0 then
operations.xor(rd,rs1,rs2)
elseif f3 == 0x6 and f7 == 0x0 then
@@ -2200,6 +2356,14 @@ local function runinst(instruction)
operations.andi(rd,rs1,imm)
elseif f3 == 0x1 and math.floor(imm/0x20) == 0x0 then
operations.slli(rd,rs1,imm%0x20)
+ elseif f3 == 0x1 and imm == 0x100 then
+ operations.sha256sum0(rd,rs1)
+ elseif f3 == 0x1 and imm == 0x101 then
+ operations.sha256sum1(rd,rs1)
+ elseif f3 == 0x1 and imm == 0x102 then
+ operations.sha256sig0(rd,rs1)
+ elseif f3 == 0x1 and imm == 0x103 then
+ operations.sha256sig1(rd,rs1)
elseif f3 == 0x5 and math.floor(imm/0x20) == 0x0 then
operations.srli(rd,rs1,imm%0x20)
elseif f3 == 0x5 and math.floor(imm/0x20) == 0x20 then