跳转至

指令实现伪代码函数

该篇用来介绍微指令执行过程中使用的通用伪代码函数。

解析参数

// UInt()
// ======

integer UInt(bits(width) x)
    integer index = 0;
    for i = 0 to width-1
        if x<i> == 1 then index += 2^i;     // 2^i:表示2的i次方
    return index;

通用寄存器读写函数

// R[] - 通用寄存器读
// ==================
// 从一个通用寄存器中读 32 或 64 位值。

bits(width) R[integer index, integer width]
    assert index >= 0 && index <= 31;
    assert width in {32, 64};

    if index <= 23 then
        return R[index]<width-1 : 0>;    //全局的R寄存器
    else if index <= 27 then
        return TR[index-23]<width-1 : 0>;    // 块内T队列寄存器
    else
        return UR[index-27]<width-1 : 0>;    // 块内U队列寄存器

// R[] - 通用寄存器写
// ==================
// 向一个通用寄存器中写 32 或 64 位值。

R[integer index, integer width] = bits(width) value
    assert index >= 0 && index <= 31;
    assert width in {32, 64};

    if 0 < index && index <= 23 then
        R[index] = SignExtend(value);
    else if index == 30 then
        UR[id] = SignExtend(value);
    else if index == 31 then
        TR[id] = SignExtend(value);
    else
        return;

系统寄存器读写函数

// SSR[] - 系统寄存器读
// =====================
// 从一个系统寄存器中读 32 或 64 位值。
bits(width) SSR[bits(16) SSR_ID, integer width]
    return System_Register[SSR_ID]<width-1 : 0>;

// SSR[] - 系统寄存器写
// ====================
// 向一个系统寄存器中写 32 或 64 位值。
bits(width) SSR[bits(16) SSR_ID, integer width] = bits(width) value
    System_Register[SSR_ID] = SignExtend(value);

系统寄存器读函数-特定指令

// SSRRD[] - 系统寄存器读
// ======================
// 从一个系统寄存器中读 32 或 64 位值。

bits(width) SSRRD[integer index, integer width]
    assert index >= 0 && index <= 31;
    assert width in {32, 64};

    when index == 0
        return System_Register[0x0010]<width-1 : 0>;    // TP
    when index == 1
        return System_Register[0x0011]<width-1 : 0>;    // GP
    when index == 2
        return System_Register[0x0012]<width-1 : 0>;    // EBSTATEP
    when index >=3 
        return 0;

将操作数左移

// LeftShift()
// ============

bits(width) LeftShift(bits(width) value, integer shift)
    assert shift >= 0;
    return (value << shift)<width-1 : 0>;

对操作数符号扩展

// SignExtend()
// =============

bits(width) SignExtend(bits(N) value)
    integer width = 64;
    for i = N to width-1
        value<i> = value<N-1>;
    return value<width-1 : 0>;

对操作数无符号扩展

// ZeroExtend()
// =============

bits(width) ZeroExtend(bits(N) value)
    integer width = 64;
    for i = N to width-1
        value<i> = 0;
    return value<width-1 : 0>;

对操作数按位取反

// Not()
// =====

bits(width) Not(bits(width) value){
    for i = 0 to width-1
        if value<i> == 0 then value<i> = 1;
        else value<i> = 0;
    return value<width-1 : 0>;
}

对操作数按位取反加一

// Negative()
// ============

bits(width) Negative(bits(width) value){
    bits(width) result = Not(value) + 1;
    return result<width-1 : 0>;
}

获取操作数置位最高位

// HighestSetBit()
// ===============

bit HighestSetBit(bits(width) value):
    for i = width-1 to 0
        if value<i> == 1 then return i;
    return -1;

解析逻辑立即数

// DecodeImm()
// ===========

bits(width) DecodeImm(bit N, bits(6) imms, bits(6) immr)
    integer length;
    if N == 1 then
        length = 6;
    else
        length = HighestSetBit((~imms)&0x3f);

    if length < 1 then undefined;

    integer esize = 1<<length           // 模式串长度
    integer setBits = imms&(esize-1)    // 连续的置1位数
    if setBits == esize-1 then undefined;

    bits(esize) elem = (1<<(setBits+1))-1    // 模式串
    integer r = immr&(esize-1)               // 有效的循环右移位数
    bits(esize) nelem = ((elem>>r)|(elem<<(esize-r)))&((1<<esize)-1)    // 循环右移

    while esize < 64    // 扩展到64bit
        nelem |= nelem<<esize
        esize = esize<<1
    nelem &= (1<<64)-1

    return nelem;

解析整型输入参数

// DecodeINT()
// ============

{integer, DataType} DecodeINT(bits(10) x)
    integer index = 0;
    DataType datatype;

    for i = 0 to 6
        if x<i> == 1 then index += 2^i;     // 2^i:表示2的i次方

    when x[9:7] == 000 : datatype = Unsigned INT64;
    when x[9:7] == 001 : datatype = Unsigned INT32;
    when x[9:7] == 010 : datatype = Unsigned INT16;
    when x[9:7] == 011 : datatype = Unsigned INT8;
    when x[9:7] == 100 : datatype = Signed INT64;
    when x[9:7] == 101 : datatype = Signed INT32;
    when x[9:7] == 110 : datatype = Signed INT16;
    when x[9:7] == 111 : datatype = Signed INT8;

    return {index, datatype};

解析浮点型输入参数

// DecodeFP()
// ==========

{integer, DataType} DecodeFP(bits(10) x)
    integer index = 0;
    DataType datatype;

    for i = 0 to 6
        if x<i> == 1 then index += 2^i;     // 2^i:表示2的i次方

    when x[9:7] == 000 : datatype = FP64;
    when x[9:7] == 001 : datatype = FP32;
    when x[9:7] == 010 : datatype = FP16;
    when x[9:7] == 011 : datatype = FP8;
    when x[9:7] == 100 : datatype = undefined;
    when x[9:7] == 101 : datatype = undefined;
    when x[9:7] == 110 : datatype = BF16;
    when x[9:7] == 111 : datatype = FP8.1;

    return {index, datatype};

解析输出参数

// DecodeDst()
// ============

{integer, integer} DecodeDst(bits(10) x)
    integer index = 0;
    integer datawidth;

    for i = 0 to 6
        if x<i> == 1 then index += 2^i;     // 2^i:表示2的i次方

    when x[8:7] == 00 : datawidth = 64;
    when x[8:7] == 01 : datawidth = 32;
    when x[8:7] == 10 : datawidth = 16;
    when x[8:7] == 11 : datawidth = 8;

    return {index, datawidth};
// V[] - 寄存器读
// ===============
// 从一个全局寄存器或并行块私有寄存器中读 8, 16, 32 或 64 位值。

bits(width) V[integer index, integer width]
    assert index in [0, 127];
    assert width in {8, 16, 32, 64};

    if      index in [0, 7]   then return TR[index+1]<width-1:0>;    // 块内T寄存器队列
    else if index in [8, 15]  then return UR[index-7]<width-1:0>;    // 块内U寄存器队列
    else if index in [16, 23] then return MR[index-15]<width-1:0>;   // 块内M寄存器队列
    else if index in [24, 31] then return NR[index-23]<width-1:0>;   // 块内N寄存器队列
    else if index in [32, 55] then return  R[index-32]<width-1:0>;   // 全局的R寄存器
    else if index == 64 then return SSR[0x0020]<width-1:0>;          // LC0
    else if index == 65 then return SSR[0x0021]<width-1:0>;          // LB0
    else if index == 68 then return SSR[0x0024]<width-1:0>;          // LC1
    else if index == 69 then return SSR[0x0025]<width-1:0>;          // LB1
    else if index == 72 then return SSR[0x0028]<width-1:0>;          // LC2
    else if index == 73 then return SSR[0x0029]<width-1:0>;          // LB2
    else undefined;

// V[] - 寄存器写
// ===============
// 向一个全局寄存器或并行块私有寄存器中写 8, 16, 32 或 64 位值。

V[integer index, integer dstwidth] = bits(width) value
    assert index in [0, 55];
    assert dstwidth in {8, 16, 32, 64};

    if      index == 0 then TR[id]<dstwidth-1:0> = value<dstwidth-1:0>;    // 块内T寄存器队列
    else if index == 1 then UR[id]<dstwidth-1:0> = value<dstwidth-1:0>;    // 块内U寄存器队列
    else if index == 2 then MR[id]<dstwidth-1:0> = value<dstwidth-1:0>;    // 块内M寄存器队列
    else if index == 3 then NR[id]<dstwidth-1:0> = value<dstwidth-1:0>;    // 块内N寄存器队列
    else if index in [33, 55] then R[index-32]<63:0> = value<63:0>;    // 全局R寄存器
    else undefined;

浮点类型判断

// FP_Class
// =========
// 结果返回浮点数类型与符号位

(fptype, sign) FP_Class(Type value)
    assert Type in {fp8, fp16, fp32, fp64, fp8.1, bf16};

    bit sign;                                 // 符号位
    exponent;                                 // 指数部分
    fraction;                                 // 尾数部分

    when type == fp64 : 
        sign = value<63>;
        bits(11) exponent = value<62:52>;
        bits(52) fraction = value<51:0>;
    when type == fp32 :
        sign = value<31>;
        bits(8)  exponent = value<30:23>;
        bits(23) fraction = value<22:0>;
    when type == fp16 :
        sign = value<15>;
        bits(5)  exponent = value<14:10>;
        bits(10) fraction = value<9:0>;
    when type == bf16 :
        sign = value<15>;
        bits(8) exponent = value<14:7>;
        bits(7) fraction = value<6:0>;
    when type == fp8 :
        sign = value<7>;
        bits(4) exponent = value<6:3>;
        bits(3) fraction = value<2:0>;
    when type == fp8.1 :
        sign = value<7>;
        bits(5) exponent = value<6:2>;
        bits(2) fraction = value<1:0>;

    // 指数全部为0
    if exponent == 0 then
        if fraction == 0 then return (FP_Zero, sign);    // 尾数全部为0,表示0.0
        else return (FP_Subnormal, sign);                // 尾数不为0,表示非规格数
    // 指数全部为1
    else if exponent == -1 then
        if fraction == 0 then return (FP_INF, sign);     // 尾数全部为0,表示无穷数
        else                                             // 尾数非0,表示非数
            if fraction<XLEN> == 0 then return (FP_SNaN, -);   // 尾数最高位为0,表示发信非数
            else return (FP_QNaN, -);                          // 尾数最高位为1,表示静默非数
    else
        return (FP_Normal, sign);     // 其他情况为规格数Normal

浮点求倒数函数

// FRECIP()
// =========

bits(width) FRECIP(Type value, integer width)
    assert width in {8, 16, 32, 64};
    assert Type in {fp8, fp16, fp32, fp64, fp8.1, bf16};

    bits(width) result;
    (fptype, sign) = FP_Class(Type value);     // 判断浮点数据类型

    if fptype == FP_Zero then
        if sign == 0 then result = +infinity;   // 输入为+0,返回正无穷大
        else result = -infinity;                // 输入为-0,返回负无穷大
    else if fptype == FP_INF then
        if sign == 0 then result = +0;    // 输入为正无穷大,返回+0
        else result = -0;                 // 输入为负无穷大,返回-0
    else if fptype == FP_Normal then
        result = 1.0 / value;    // 输入为规格化浮点数,返回其倒数
    else if fptype == FP_QNaN then
        result = value;          // 输入为静默非数,返回原值
    else if fptype == FP_SNaN then
        result = value;
        case Type of:                       // 输入为发信非数,返回尾数最高位置1的静默非数
            when fp8   then result<2> = 1;
            when fp8.1 then result<1> = 1;
            when fp16  then result<9> = 1;
            when bf16  then result<6> = 1;
            when fp32  then result<22> = 1;
            when fp64  then result<51> = 1;
        // 输入为发信非数,根据SSR寄存器的Enables位决定是否产生异常
        ProcessException(InvalidOp, Enables);    
    else undefined;

    return result;