// First field (first character in the line): I (instruction), S (semantic), P (prologue, only one) // Starting with // is a comment // Fields are separated by any number of spaces and tabs // For S: Followed by a single field in double-quotes (space allowed but not carriage return), the instruction semantic in SpinalHDL // For P: Followed by a single field in triple double-quotes (anything allowed), extra code to add // For I: Followed by 4-9 Fields: // 1) instruction name // 2) semantic name (usually idential between R and I form) // 3) pattern to match // 4) mux (group) name // 5-9) optional, (sub-)extension the instruction belongs to (up to 5) // Avoids non-ASCII (7 bit) characters, as some string ends up in SpinalHDL code // // Known differences with the specifications: // Zbb: doesn't include pack (to implement zext.h), grevi (to implement rev8), gorci (to implement orc.b) -> see data_bitmanip_ZbbOnly.txt // Zbp: // Zbs: // Zba: // Zbe: in a dedicated file for b[de]compress, 'data_bitmanip_compress.txt' // Zbf: // Zbc: in a dedicated file, 'data_clmul.txt' // Zbm: ignored, RV64-only // Zbr: in a dedicated file, 'data_crc.txt' // Zbt: (requires three-operands patch to VexRiscv) // B : should be Zbb, Zbp, Zbs, Zba, Zbe, Zbf, Zbc, Zbm // // INSTRUCTIONS // register-register // inst semant pattern group/mux ext1 ext2 ext3 ext4 ext5 // ---- ----- ------- --------- ---- ---- ---- ---- ---- I ANDN ANDN 0100000----------111-----0110011 bitwise Zbb Zbp Zbkb I ORN ORN 0100000----------110-----0110011 bitwise Zbb Zbp Zbkb I XNOR XNOR 0100000----------100-----0110011 bitwise Zbb Zbp Zbkb I SLO SLO 0010000----------001-----0110011 shift Zxx I SRO SRO 0010000----------101-----0110011 shift Zxx I ROL ROL 0110000----------001-----0110011 rotation Zbb Zbp Zbkb I ROR ROR 0110000----------101-----0110011 rotation Zbb Zbp Zbkb I SH1ADD SH1ADD 0010000----------010-----0110011 sh_add Zba I SH2ADD SH2ADD 0010000----------100-----0110011 sh_add Zba I SH3ADD SH3ADD 0010000----------110-----0110011 sh_add Zba I BCLR BCLR 0100100----------001-----0110011 singlebit Zbs I BSET BSET 0010100----------001-----0110011 singlebit Zbs I BINV BINV 0110100----------001-----0110011 singlebit Zbs I BEXT BEXT 0100100----------101-----0110011 singlebit Zbs I GORC GORC 0010100----------101-----0110011 grevroc Zbp I GREV GREV 0110100----------101-----0110011 grevroc Zbp I MIN MIN 0000101----------100-----0110011 minmax Zbb I MINU MINU 0000101----------101-----0110011 minmax Zbb I MAX MAX 0000101----------110-----0110011 minmax Zbb I MAXU MAXU 0000101----------111-----0110011 minmax Zbb I SHFL SHFL 0000100----------001-----0110011 shuffle Zbp I UNSHFL UNSHFL 0000100----------101-----0110011 shuffle Zbp //I BDECOMPRESS BDECOMPRESS 0100100----------110-----0110011 BDECOMPRESS //I BCOMPRESS BCOMPRESS 0000100----------110-----0110011 BCOMPRESS I PACK PACK 0000100----------100-----0110011 pack Zbp Zbe Zbf Zbkb I PACKU PACKU 0100100----------100-----0110011 pack Zbp //I BMATOR BMATOR 0000100----------011-----0110011 BMATOR //I BMATXOR BMATXOR 0100100----------011-----0110011 BMATXOR I PACKH PACKH 0000100----------111-----0110011 pack Zbp Zbe Zbf Zbkb I BFP BFP 0100100----------111-----0110011 BFP Zbf //I ADDdotUW ADDdotUW 0000100----------000-----0111011 ADDdotUW //I SLOW SLOW 0010000----------001-----0111011 SLOW //I SROW SROW 0010000----------101-----0111011 SROW //I ROLW ROLW 0110000----------001-----0111011 rotation Zbb Zbp //I RORW RORW 0110000----------101-----0111011 rotation Zbb Zbp //I SH1ADDdotUW SH1ADDdotUW 0010000----------010-----0111011 SH1ADDdotUW //I SH2ADDdotUW SH2ADDdotUW 0010000----------100-----0111011 SH2ADDdotUW //I SH3ADDdotUW SH3ADDdotUW 0010000----------110-----0111011 SH3ADDdotUW //I BCLRW BCLRW 0100100----------001-----0111011 singlebit Zbs //I BSETW BSETW 0010100----------001-----0111011 singlebit Zbs //I BINVW BINVW 0110100----------001-----0111011 singlebit Zbs //I BEXTW BEXTW 0100100----------101-----0111011 singlebit Zbs //I GORCW GORCW 0010100----------101-----0111011 GORCW //I GREVW GREVW 0110100----------101-----0111011 GREVW //I SHFLW SHFLW 0000100----------001-----0111011 shuffle Zbp //I UNSHFLW UNSHFLW 0000100----------101-----0111011 shuffle Zbp //I BDECOMPRESSW BDECOMPRESSW 0100100----------110-----0111011 BDECOMPRESSW //I BCOMPRESSW BCOMPRESSW 0000100----------110-----0111011 BCOMPRESSW //I PACKW PACKW 0000100----------100-----0111011 PACKW //I PACKUW PACKUW 0100100----------100-----0111011 PACKUW //I BFPW BFPW 0100100----------111-----0111011 BFPW I XPERMdotN XPERMdotN 0010100----------010-----0110011 xperm Zbp Zbkx I XPERMdotB XPERMdotB 0010100----------100-----0110011 xperm Zbp Zbkx I XPERMdotH XPERMdotH 0010100----------110-----0110011 xperm Zbp //I XPERMdotW XPERMdotW 0010100----------000-----0110011 XPERMdotW // register-immediate (7bits) I SLOI SLO 00100------------001-----0010011 shift Zxx I SROI SRO 00100------------101-----0010011 shift Zxx I RORI ROR 01100------------101-----0010011 rotation Zbb Zbp Zbkb I BCLRI BCLR 01001------------001-----0010011 singlebit Zbs I BSETI BSET 00101------------001-----0010011 singlebit Zbs I BINVI BINV 01101------------001-----0010011 singlebit Zbs I BEXTI BEXT 01001------------101-----0010011 singlebit Zbs I GORCI GORC 00101------------101-----0010011 grevorc Zbp I GREVI GREV 01101------------101-----0010011 grevorc Zbp I SLLIdotUW SLLIdotUW 00001------------001-----0011011 SLLIdotUW // register-immediate (6bits) I SHFLI SHFL 000010-----------001-----0010011 shuffle Zbp I UNSHFLI UNSHFL 000010-----------101-----0010011 shuffle Zbp // register-immediate (5bits) //I SLOIW SLOW 0010000----------001-----0011011 shift //I SROIW SROW 0010000----------101-----0011011 shift //I RORIW RORW 0110000----------101-----0011011 rotation //I BCLRIW BCLRW 0100100----------001-----0011011 singlebit //I BSETIW BSETW 0010100----------001-----0011011 singlebit //I BINVIW BINVW 0110100----------001-----0011011 singlebit //I GORCIW GORCW 0010100----------101-----0011011 grevroc //I GREVIW GREVW 0110100----------101-----0011011 grevroc // unary register I CLTZ CLTZ 01100000000------001-----0010011 countzeroes Zbb I CPOP CPOP 011000000010-----001-----0010011 countzeroes Zbb //I BMATFLIP BMATFLIP 011000000011-----001-----0010011 BMATFLIP I SEXTdotB SEXTdotB 011000000100-----001-----0010011 signextend Zbb I SEXTdotH SEXTdotH 011000000101-----001-----0010011 signextend Zbb I CRC32dotB CRC32dotB 011000010000-----001-----0010011 CRC32dotB I CRC32dotH CRC32dotH 011000010001-----001-----0010011 CRC32dotH //I CRC32dotW CRC32dotW 011000010010-----001-----0010011 CRC32dotW I CRC32dotD CRC32dotD 011000010011-----001-----0010011 CRC32dotD I CRC32CdotB CRC32CdotB 011000011000-----001-----0010011 CRC32CdotB I CRC32CdotH CRC32CdotH 011000011001-----001-----0010011 CRC32CdotH //I CRC32CdotW CRC32CdotW 011000011010-----001-----0010011 CRC32CdotW I CRC32CdotD CRC32CdotD 011000011011-----001-----0010011 CRC32CdotD //I CLZW CLZW 011000000000-----001-----0011011 countzeroes //I CTZW CTZW 011000000001-----001-----0011011 countzeroes //I CPOPW CPOPW 011000000010-----001-----0011011 countzeroes // register-register-register I CMIX CMIX -----11----------001-----0110011 ternary Zbt I CMOV CMOV -----11----------101-----0110011 ternary Zbt I FSL FSL -----10----------001-----0110011 ternary Zbt I FSR FSR -----10----------101-----0110011 ternary Zbt I FSRI FSR -----1-----------101-----0010011 ternary Zbt //I FSLW FSLW -----10----------001-----0111011 FSLW //I FSRW FSRW -----10----------101-----0111011 FSRW //I FSRIW FSRIW -----10----------101-----0011011 FSRIW // SEMANTIC S ROR "input(SRC1).rotateRight((input(SRC2)&31)(4 downto 0).asUInt)" S ROL "input(SRC1).rotateLeft((input(SRC2)&31)(4 downto 0).asUInt)" S GREV "fun_grev(input(SRC1), input(SRC2))" S GORC "fun_gorc(input(SRC1), input(SRC2))" S PACK "(input(SRC2)(15 downto 0) ## input(SRC1)(15 downto 0))" S PACKU "(input(SRC2)(31 downto 16) ## input(SRC1)(31 downto 16))" S PACKH "B"16'x0000" ## (input(SRC2)(7 downto 0) ## input(SRC1)(7 downto 0))" S SHFL "fun_shfl32(input(SRC1), input(SRC2))" S UNSHFL "fun_unshfl32(input(SRC1), input(SRC2))" S ANDN "(input(SRC1) & ~input(SRC2))" S ORN "(input(SRC1) | ~input(SRC2))" S XNOR "(input(SRC1) ^ ~input(SRC2))" S SH1ADD "((input(SRC1) |<< 1).asUInt + input(SRC2).asUInt)" S SH2ADD "((input(SRC1) |<< 2).asUInt + input(SRC2).asUInt)" S SH3ADD "((input(SRC1) |<< 3).asUInt + input(SRC2).asUInt)" S BSET "(input(SRC1) | (B"32'x00000001"|<<((input(SRC2)&31).asUInt)))" S BCLR "(input(SRC1) & ~(B"32'x00000001"|<<((input(SRC2)&31).asUInt)))" S BINV "(input(SRC1) ^ (B"32'x00000001"|<<((input(SRC2)&31).asUInt)))" S BEXT "((input(SRC1) |>> ((input(SRC2)&31).asUInt)) & B"32'x00000001")" S SLO "~((~input(SRC1)) |<< (input(SRC2)&31).asUInt)" S SRO "~((~input(SRC1)) |>> (input(SRC2)&31).asUInt)" S MIN "((input(SRC1).asSInt < input(SRC2).asSInt) ? input(SRC1) | input(SRC2))" S MAX "((input(SRC1).asSInt > input(SRC2).asSInt) ? input(SRC1) | input(SRC2))" S MINU "((input(SRC1).asUInt < input(SRC2).asUInt) ? input(SRC1) | input(SRC2))" S MAXU "((input(SRC1).asUInt > input(SRC2).asUInt) ? input(SRC1) | input(SRC2))" S XPERMdotN "fun_xperm_n(input(SRC1), input(SRC2))" S XPERMdotB "fun_xperm_b(input(SRC1), input(SRC2))" S XPERMdotH "fun_xperm_h(input(SRC1), input(SRC2))" S BFP "fun_bfp(input(SRC1), input(SRC2))" // if 'SRC2' doesn't appear in the semantic, the code assume unary S SEXTdotB "(Bits(24 bits).setAllTo(input(SRC1)(7)) ## input(SRC1)(7 downto 0))" S SEXTdotH "(Bits(16 bits).setAllTo(input(SRC1)(15)) ## input(SRC1)(15 downto 0))" S CLTZ "fun_cltz(input(SRC1), input(INSTRUCTION)(20))" S CPOP "fun_popcnt(input(SRC1))" // if 'SRC3' appear in the semantic, the code assume ternary S CMIX "((input(SRC1) & input(SRC2)) | (input(SRC3) & ~input(SRC2)))" S CMOV "((input(SRC2).asUInt =/= 0) ? input(SRC1) | input(SRC3))" S FSL "fun_fsl(input(SRC1), input(SRC3), input(SRC2))" S FSR "fun_fsr(input(SRC1), input(SRC3), input(SRC2))" // PROLOGUE P """ // function implementing the semantic of 32-bits generalized reverse def fun_grev( a:Bits, b:Bits ) : Bits = { val x1 = ((b&B"32'x00000001")===B"32'x00000001") ? (((a & B"32'x55555555") |<< 1) | ((a & B"32'xAAAAAAAA") |>> 1)) | a val x2 = ((b&B"32'x00000002")===B"32'x00000002") ? (((x1 & B"32'x33333333") |<< 2) | ((x1 & B"32'xCCCCCCCC") |>> 2)) | x1 val x4 = ((b&B"32'x00000004")===B"32'x00000004") ? (((x2 & B"32'x0F0F0F0F") |<< 4) | ((x2 & B"32'xF0F0F0F0") |>> 4)) | x2 val x8 = ((b&B"32'x00000008")===B"32'x00000008") ? (((x4 & B"32'x00FF00FF") |<< 8) | ((x4 & B"32'xFF00FF00") |>> 8)) | x4 val x16 = ((b&B"32'x00000010")===B"32'x00000010") ? (((x8 & B"32'x0000FFFF") |<<16) | ((x8 & B"32'xFFFF0000") |>>16)) | x8 x16 // return value } // function implementing the semantic of 32-bits generalized OR-combine def fun_gorc( a:Bits, b:Bits ) : Bits = { val x1 = ((b&B"32'x00000001")===B"32'x00000001") ? (a | ((a & B"32'x55555555") |<< 1) | ((a & B"32'xAAAAAAAA") |>> 1)) | a val x2 = ((b&B"32'x00000002")===B"32'x00000002") ? (x1 | ((x1 & B"32'x33333333") |<< 2) | ((x1 & B"32'xCCCCCCCC") |>> 2)) | x1 val x4 = ((b&B"32'x00000004")===B"32'x00000004") ? (x2 | ((x2 & B"32'x0F0F0F0F") |<< 4) | ((x2 & B"32'xF0F0F0F0") |>> 4)) | x2 val x8 = ((b&B"32'x00000008")===B"32'x00000008") ? (x4 | ((x4 & B"32'x00FF00FF") |<< 8) | ((x4 & B"32'xFF00FF00") |>> 8)) | x4 val x16 = ((b&B"32'x00000010")===B"32'x00000010") ? (x8 | ((x8 & B"32'x0000FFFF") |<<16) | ((x8 & B"32'xFFFF0000") |>>16)) | x8 x16 // return value } // helper function for the implementation of the generalized shuffles def fun_shuffle32_stage(src:Bits, maskL:Bits, maskR:Bits, N:Int) : Bits = { val x = src & ~(maskL | maskR) val x2 = x | ((src |<< N) & maskL) | ((src |>> N) & maskR); x2 // return value } // function implementing the semantic of 32-bits generalized shuffle def fun_shfl32(a:Bits, b:Bits) : Bits = { val x = a; val x1 = ((b&B"32'x00000008")===B"32'x00000008") ? fun_shuffle32_stage(x , B"32'x00FF0000", B"32'x0000FF00", 8) | x; val x2 = ((b&B"32'x00000004")===B"32'x00000004") ? fun_shuffle32_stage(x1, B"32'x0F000F00", B"32'x00F000F0", 4) | x1; val x3 = ((b&B"32'x00000002")===B"32'x00000002") ? fun_shuffle32_stage(x2, B"32'x30303030", B"32'x0C0C0C0C", 2) | x2; val x4 = ((b&B"32'x00000001")===B"32'x00000001") ? fun_shuffle32_stage(x3, B"32'x44444444", B"32'x22222222", 1) | x3; x4 // return value } // function implementing the semantic of 32-bits generalized unshuffle def fun_unshfl32(a:Bits, b:Bits) : Bits = { val x = a; val x1 = ((b&B"32'x00000001")===B"32'x00000001") ? fun_shuffle32_stage(x , B"32'x44444444", B"32'x22222222", 1) | x; val x2 = ((b&B"32'x00000002")===B"32'x00000002") ? fun_shuffle32_stage(x1, B"32'x30303030", B"32'x0C0C0C0C", 2) | x1; val x3 = ((b&B"32'x00000004")===B"32'x00000004") ? fun_shuffle32_stage(x2, B"32'x0F000F00", B"32'x00F000F0", 4) | x2; val x4 = ((b&B"32'x00000008")===B"32'x00000008") ? fun_shuffle32_stage(x3, B"32'x00FF0000", B"32'x0000FF00", 8) | x3; x4 // return value } // this is trying to look like DOI 10.2478/jee-2015-0054 def fun_clz_NLCi(x:Bits): Bits = { val r2 = (~(x(0) | x(1) | x(2) | x(3))) val r1 = (~(x(2) | x(3))) val r0 = (~(x(3) | (x(1) & ~x(2)))) val r = r2 ## r1 ## r0 r // return value } def fun_clz_BNE(a:Bits) : Bits = { val a01 = ~(a(0) & a(1)) val a23 = ~(a(2) & a(3)) val a45 = ~(a(4) & a(5)) val a67 = ~(a(6) & a(7)) val a0123 = ~(a01 | a23) // also r(2) val a4567 = ~(a45 | a67) val a56 = ~(a(5) & ~a(6)) val a024 = (a(0) & a(2) & a(4)) // AND not NAND val a13 = ~(a(1) & a(3)) val a12 = ~(a(1) & ~a(2)) val r3 = ((a0123 & a4567)) // AND not NAND val r2 = (a0123) val r1 = (~(a01 | (~a23 & a45))) val r0 = (~((~((a56) & (a024))) & (~((a13) & (a12) & (a(0)))))) val r = r3 ## r2 ## r1 ##r0 r // return value } // For trailing count, count using use leading count on bit-reversed value def fun_cltz(ino:Bits, ctz:Bool) : Bits = { val inr = ino(0) ## ino(1) ## ino(2) ## ino(3) ## ino(4) ## ino(5) ## ino(6) ## ino(7) ## ino(8) ## ino(9) ## ino(10) ## ino(11) ## ino(12) ## ino(13) ## ino(14) ## ino(15) ## ino(16) ## ino(17) ## ino(18) ## ino(19) ## ino(20) ## ino(21) ## ino(22) ## ino(23) ## ino(24) ## ino(25) ## ino(26) ## ino(27) ## ino(28) ## ino(29) ## ino(30) ## ino(31) val in = (ctz === True) ? (inr) | (ino) val nlc7 = fun_clz_NLCi(in(31 downto 28)) val nlc6 = fun_clz_NLCi(in(27 downto 24)) val nlc5 = fun_clz_NLCi(in(23 downto 20)) val nlc4 = fun_clz_NLCi(in(19 downto 16)) val nlc3 = fun_clz_NLCi(in(15 downto 12)) val nlc2 = fun_clz_NLCi(in(11 downto 8)) val nlc1 = fun_clz_NLCi(in( 7 downto 4)) val nlc0 = fun_clz_NLCi(in( 3 downto 0)) val a = nlc0(2) ## nlc1(2) ## nlc2(2) ## nlc3(2) ## nlc4(2) ## nlc5(2) ## nlc6(2) ## nlc7(2) val bne = fun_clz_BNE(a) val muxo = (bne(2 downto 0)).mux( B"3'b000" -> nlc7(1 downto 0), B"3'b001" -> nlc6(1 downto 0), B"3'b010" -> nlc5(1 downto 0), B"3'b011" -> nlc4(1 downto 0), B"3'b100" -> nlc3(1 downto 0), B"3'b101" -> nlc2(1 downto 0), B"3'b110" -> nlc1(1 downto 0), B"3'b111" -> nlc0(1 downto 0) ) val r = (bne(3)) ? B"6'b100000" | (B"1'b0" ## bne(2 downto 0) ## muxo(1 downto 0)) // 6 bits r.resize(32) // return value } // naive popcnt def fun_popcnt(in:Bits) : Bits = { val r = in(0).asBits.resize(6).asUInt + in(1).asBits.resize(6).asUInt + in(2).asBits.resize(6).asUInt + in(3).asBits.resize(6).asUInt + in(4).asBits.resize(6).asUInt + in(5).asBits.resize(6).asUInt + in(6).asBits.resize(6).asUInt + in(7).asBits.resize(6).asUInt + in(8).asBits.resize(6).asUInt + in(9).asBits.resize(6).asUInt + in(10).asBits.resize(6).asUInt + in(11).asBits.resize(6).asUInt + in(12).asBits.resize(6).asUInt + in(13).asBits.resize(6).asUInt + in(14).asBits.resize(6).asUInt + in(15).asBits.resize(6).asUInt + in(16).asBits.resize(6).asUInt + in(17).asBits.resize(6).asUInt + in(18).asBits.resize(6).asUInt + in(19).asBits.resize(6).asUInt + in(20).asBits.resize(6).asUInt + in(21).asBits.resize(6).asUInt + in(22).asBits.resize(6).asUInt + in(23).asBits.resize(6).asUInt + in(24).asBits.resize(6).asUInt + in(25).asBits.resize(6).asUInt + in(26).asBits.resize(6).asUInt + in(27).asBits.resize(6).asUInt + in(28).asBits.resize(6).asUInt + in(29).asBits.resize(6).asUInt + in(30).asBits.resize(6).asUInt + in(31).asBits.resize(6).asUInt r.asBits.resize(32) // return value } //XPERMs def fun_xperm_n(rs1:Bits, rs2:Bits) : Bits = { val i0 = rs2(3 downto 0).asUInt val i1 = rs2(7 downto 4).asUInt val i2 = rs2(11 downto 8).asUInt val i3 = rs2(15 downto 12).asUInt val i4 = rs2(19 downto 16).asUInt val i5 = rs2(23 downto 20).asUInt val i6 = rs2(27 downto 24).asUInt val i7 = rs2(31 downto 28).asUInt val r0 = (i0).mux( 0 -> rs1(3 downto 0), 1 -> rs1(7 downto 4), 2 -> rs1(11 downto 8), 3 -> rs1(15 downto 12), 4 -> rs1(19 downto 16), 5 -> rs1(23 downto 20), 6 -> rs1(27 downto 24), 7 -> rs1(31 downto 28), default -> B"4'b0000" ) val r1 = (i1).mux( 0 -> rs1(3 downto 0), 1 -> rs1(7 downto 4), 2 -> rs1(11 downto 8), 3 -> rs1(15 downto 12), 4 -> rs1(19 downto 16), 5 -> rs1(23 downto 20), 6 -> rs1(27 downto 24), 7 -> rs1(31 downto 28), default -> B"4'b0000" ) val r2 = (i2).mux( 0 -> rs1(3 downto 0), 1 -> rs1(7 downto 4), 2 -> rs1(11 downto 8), 3 -> rs1(15 downto 12), 4 -> rs1(19 downto 16), 5 -> rs1(23 downto 20), 6 -> rs1(27 downto 24), 7 -> rs1(31 downto 28), default -> B"4'b0000" ) val r3 = (i3).mux( 0 -> rs1(3 downto 0), 1 -> rs1(7 downto 4), 2 -> rs1(11 downto 8), 3 -> rs1(15 downto 12), 4 -> rs1(19 downto 16), 5 -> rs1(23 downto 20), 6 -> rs1(27 downto 24), 7 -> rs1(31 downto 28), default -> B"4'b0000" ) val r4 = (i4).mux( 0 -> rs1(3 downto 0), 1 -> rs1(7 downto 4), 2 -> rs1(11 downto 8), 3 -> rs1(15 downto 12), 4 -> rs1(19 downto 16), 5 -> rs1(23 downto 20), 6 -> rs1(27 downto 24), 7 -> rs1(31 downto 28), default -> B"4'b0000" ) val r5 = (i5).mux( 0 -> rs1(3 downto 0), 1 -> rs1(7 downto 4), 2 -> rs1(11 downto 8), 3 -> rs1(15 downto 12), 4 -> rs1(19 downto 16), 5 -> rs1(23 downto 20), 6 -> rs1(27 downto 24), 7 -> rs1(31 downto 28), default -> B"4'b0000" ) val r6 = (i6).mux( 0 -> rs1(3 downto 0), 1 -> rs1(7 downto 4), 2 -> rs1(11 downto 8), 3 -> rs1(15 downto 12), 4 -> rs1(19 downto 16), 5 -> rs1(23 downto 20), 6 -> rs1(27 downto 24), 7 -> rs1(31 downto 28), default -> B"4'b0000" ) val r7 = (i7).mux( 0 -> rs1(3 downto 0), 1 -> rs1(7 downto 4), 2 -> rs1(11 downto 8), 3 -> rs1(15 downto 12), 4 -> rs1(19 downto 16), 5 -> rs1(23 downto 20), 6 -> rs1(27 downto 24), 7 -> rs1(31 downto 28), default -> B"4'b0000" ) r7 ## r6 ## r5 ## r4 ## r3 ## r2 ## r1 ## r0 // return value } def fun_xperm_b(rs1:Bits, rs2:Bits) : Bits = { val i0 = rs2(7 downto 0).asUInt; val i1 = rs2(15 downto 8).asUInt; val i2 = rs2(23 downto 16).asUInt; val i3 = rs2(31 downto 24).asUInt; val r0 = (i0).mux( 0 -> rs1(7 downto 0), 1 -> rs1(15 downto 8), 2 -> rs1(23 downto 16), 3 -> rs1(31 downto 24), default -> B"8'b00000000" ) val r1 = (i1).mux( 0 -> rs1(7 downto 0), 1 -> rs1(15 downto 8), 2 -> rs1(23 downto 16), 3 -> rs1(31 downto 24), default -> B"8'b00000000" ) val r2 = (i2).mux( 0 -> rs1(7 downto 0), 1 -> rs1(15 downto 8), 2 -> rs1(23 downto 16), 3 -> rs1(31 downto 24), default -> B"8'b00000000" ) val r3 = (i3).mux( 0 -> rs1(7 downto 0), 1 -> rs1(15 downto 8), 2 -> rs1(23 downto 16), 3 -> rs1(31 downto 24), default -> B"8'b00000000" ) r3 ## r2 ## r1 ## r0 // return value } def fun_xperm_h(rs1:Bits, rs2:Bits) : Bits = { val i0 = rs2(15 downto 0).asUInt; val i1 = rs2(31 downto 16).asUInt; val r0 = (i0).mux( 0 -> rs1(15 downto 0), 1 -> rs1(31 downto 16), default -> B"16'x0000" ) val r1 = (i1).mux( 0 -> rs1(15 downto 0), 1 -> rs1(31 downto 16), default -> B"16'x0000" ) r1 ## r0 // return value } def fun_fsl(rs1:Bits, rs3:Bits, rs2:Bits) : Bits = { val rawshamt = (rs2 & B"32'x0000003F").asUInt val shamt = (rawshamt >= 32) ? (rawshamt - 32) | (rawshamt) val A = (shamt === rawshamt) ? (rs1) | (rs3) val B = (shamt === rawshamt) ? (rs3) | (rs1) val r = (shamt === 0) ? (A) | ((A |<< shamt) | (B |>> (32-shamt))) r // return value } def fun_fsr(rs1:Bits, rs3:Bits, rs2:Bits) : Bits = { val rawshamt = (rs2 & B"32'x0000003F").asUInt val shamt = (rawshamt >= 32) ? (rawshamt - 32) | (rawshamt) val A = (shamt === rawshamt) ? (rs1) | (rs3) val B = (shamt === rawshamt) ? (rs3) | (rs1) val r = (shamt === 0) ? (A) | ((A |>> shamt) | (B |<< (32-shamt))) r // return value } def fun_bfp(rs1:Bits, rs2:Bits) : Bits = { val off = rs2(20 downto 16).asUInt val rawlen = rs2(27 downto 24).asUInt val convlen = (rawlen === 0) ? (rawlen+16) | (rawlen) val len = ((convlen + off) > 32) ? (32 - off) | (convlen) val allones = B"16'xFFFF" val lenones = (allones |>> (16-len)) //val one = B"17'x00001" //val lenones = (((one |<< len).asUInt) - 1).asBits; val mask = (lenones.resize(32) |<< off); val data = (rs2 & lenones.resize(32)) |<< off; val r = (rs1 & ~mask) | data r // return value } """