diff options
Diffstat (limited to 'rvcontroller.lua')
| -rw-r--r-- | rvcontroller.lua | 73 |
1 files changed, 71 insertions, 2 deletions
diff --git a/rvcontroller.lua b/rvcontroller.lua index 25e66f9..a8d8915 100644 --- a/rvcontroller.lua +++ b/rvcontroller.lua @@ -7,7 +7,7 @@ Emulated system specifications: -Single RISC-V core, RV32IMACB_Zicntr_Zicond_Zicsr_Zifencei_Zihintpause_Zilsd_Zabha_Zacas_Zcb_Zclsd_Zcmp_Zcmt_Zbkb_Zbkx instruction set, little-endian +Single RISC-V core, RV32IMACB_Zicntr_Zicond_Zicsr_Zifencei_Zihintpause_Zilsd_Zimop_Zabha_Zacas_Zalasr_Zawrs_Zcb_Zclsd_Zcmop_Zcmp_Zcmt_Zbkb_Zbkx instruction set, little-endian 65536 bytes of RAM (configurable in settings below) starting at base address 0 Intended to be compliant with the following specifications: @@ -17,6 +17,7 @@ Intended to be compliant with the following specifications: * "Zicsr" Extension for Control and Status Register (CSR) Instructions, Version 2.0 * "Zicond" Extension for Integer Conditional Operations, Version 1.0.0 * "Zicntr" Extension for Counters, Version 2.0 +* "Zimop" Extension for May-Be-Operations, Version 1.0 * "M" Extension for Integer Multiplication and Division, Version 2.0 - Note: This implies the following: - * Zmmul Extension, Version 1.0 @@ -31,6 +32,7 @@ Intended to be compliant with the following specifications: - Note: This implies the following: - * "Zca" Extension for Code Size Reduction, Version 1.0.0 * Zcb: Extension for Code Size Reduction, Version 1.0.0 +* "Zcmop" Compressed May-Be-Operations Extension, Version 1.0 * Zcmp: Extension for Code Size Reduction, Version 1.0.0 * Zcmt: Extension for Code Size Reduction, Version 1.0.0 * "B" Extension for Bit Manipulation, Version 1.0.0 @@ -42,6 +44,8 @@ Intended to be compliant with the following specifications: * Zilsd, Zclsd: Extensions for Load/Store pair for RV32, Version 1.0 * "Zabha" Extension for Byte and Halfword Atomic Memory Operations, Version 1.0 * "Zacas" Extension for Atomic Compare-and-Swap (CAS) Instructions, Version 1.0.0 +* "Zalasr" Atomic Load-Acquire and Store-Release Instructions, Version 1.0 +* "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 @@ -283,6 +287,12 @@ local function writeram(address,data,bytes) if mem.reservationset then if mem.reservationset + 4 >= address and mem.reservationset <= address+bytes-1 then mem.reservationset = nil + if mem.rswaiting then + if mem.rswaiting == "nto" then digiline_send("monitordisp","CPU started") end + mem.rswaiting = false + mem.running = true + interrupt(0,"tick") + end end end for i=0,bytes-1 do @@ -1518,6 +1528,25 @@ local operations = { setreg(rd,getreg(rs1)) end end, + mopr = function(rd,rs1,imm) + setreg(rd,0) + end, + moprr = function(rd,rs1,rs2,imm) + setreg(rd,0) + end, + cmop = function(rd,imm) + --Does nothing until/unless redefined by another extension + end, + wrsnto = function(rd,rs1) + mem.rswaiting = "nto" + mem.running = false + digiline_send("monitordisp","Waiting for\nreservation set") + return false,true + end, + wrssto = function(rd,rs1) + mem.rswaiting = "sto" + return false,true + end, } local function runinst(instruction) @@ -1705,6 +1734,10 @@ local function runinst(instruction) operations.ecall() elseif imm == 0x1 then operations.ebreak() + elseif rs1 == 0 and rd == 0 and imm == 0x0d then + return operations.wrsnto() + elseif rs1 == 0 and rd == 0 and imm == 0x1d then + return operations.wrssto() end elseif f3 == 0x1 then operations.csrrw(rd,rs1,imm) @@ -1712,6 +1745,12 @@ local function runinst(instruction) operations.csrrs(rd,rs1,imm) elseif f3 == 0x3 then operations.csrrc(rd,rs1,imm) + elseif f3 == 0x4 and bits[31] and bits[24] and bits[23] and bits[22] and not (bits[29] or bits[28] or bits[25]) then + local immbits = implodebits({[0] = bits[20],bits[21],bits[26],bits[27],bits[30]},5) + operations.mopr(rd,rs1,imm) + elseif f3 == 0x4 and bits[31] and bits[25] and not (bits[28] or bits[29]) then + local immbits = implodebits({[0] = bits[26],bits[27],bits[30]},3) + operations.moprr(rd,rs1,rs2,imm) elseif f3 == 0x5 then operations.csrrwi(rd,rs1,imm) elseif f3 == 0x6 then @@ -1827,6 +1866,14 @@ local function runinst(instruction) elseif f5 == 5 then --amocas.w operations.amocasw(rd,rs1,rs2) + elseif f5 == 6 and rs2 == 0 then + --lw.aq/lw.aqrl + --The normal lw instruction implementation already meets these requirements + operations.lw(rd,rs1,0) + elseif f5 == 7 and rd == 0 then + --sw.rl/sw.aqrl + --The normal sw instruction implementation already meets these requirements + operations.sw(rs1,rs2,0) end elseif f3 == 3 then if f5 == 5 then @@ -1864,6 +1911,14 @@ local function runinst(instruction) elseif f5 == 5 then --amocas.b operations.amocasb(rd,rs1,rs2) + elseif f5 == 6 and rs2 == 0 then + --lb.aq/lb.aqrl + --The normal lb instruction implementation already meets these requirements + operations.lb(rd,rs1,0) + elseif f5 == 7 and rd == 0 then + --sb.rl/sb.aqrl + --The normal sb instruction implementation already meets these requirements + operations.sb(rs1,rs2,0) end elseif f3 == 1 then if f5 == 1 then @@ -1896,6 +1951,14 @@ local function runinst(instruction) elseif f5 == 5 then --amocas.h operations.amocash(rd,rs1,rs2) + elseif f5 == 6 and rs2 == 0 then + --lh.aq/lh.aqrl + --The normal lh instruction implementation already meets these requirements + operations.lh(rd,rs1,0) + elseif f5 == 7 and rd == 0 then + --sh.rl/sh.aqrl + --The normal sh instruction implementation already meets these requirements + operations.sh(rs1,rs2,0) end end elseif opcode == 0x0f then @@ -2011,18 +2074,22 @@ local function runcinst(instruction) operations.addi(rd,0,imm) elseif opcode == 1 and f3 == 3 then local immbits = {[0] = bits[2],bits[3],bits[4],bits[5],bits[6],bits[12]} + local imm = implodebits(immbits,6) local rd = implodebits({[0] = bits[7],bits[8],bits[9],bits[10],bits[11]},5) if rd == 2 then --c.addi16sp (CI) --For whatever reason this has a completely different immediate format than c.lui imm = implodebits({[0] = false,false,false,false,bits[6],bits[2],bits[5],bits[3],bits[4],bits[12]},10,true) operations.addi(2,2,imm) - else + elseif imm ~= 0 then --c.lui (CI) signextend(immbits,6,20) local imm = implodebits(immbits,20) imm = imm*2^12 operations.lui(rd,imm) + elseif rd%2 == 1 and rd <= 15 then + --c.mop + operations.cmop(rd,imm) end elseif opcode == 1 and f3 == 0 then --c.addi (CI) @@ -2311,6 +2378,7 @@ if event.type == "program" or event.iid == "reset" then mem.registers.pc = 0 mem.running = false mem.inputwaiting = false + mem.rswaiting = false mem.stdout = {} mem.starttime = os.time() mem.csr = { @@ -2454,6 +2522,7 @@ elseif event.channel == "monitorkb" then elseif argv[1] == "stop" then mem.running = false mem.inputwaiting = false + mem.rswaiting = false digiline_send("monitordisp","Stopped by user") elseif argv[1] == "h" then --Easter egg |
