cocotb 中的硬件数据类型

参考 cocotb 的源码中的注释

Logic

类型的定义

cocotb/type/logic.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
_0 = 0
_1 = 1
_X = 2
_Z = 3

_literal_repr: typing.Dict[LogicLiteralT, int] = {
    # 0 and weak 0
    False: _0,
    0: _0,
    "0": _0,
    "L": _0,
    "l": _0,
    # 1 and weak 1
    True: _1,
    1: _1,
    "1": _1,
    "H": _1,
    "h": _1,
    # unknown, unassigned, and weak unknown
    "X": _X,
    "x": _X,
    "U": _X,
    "u": _X,
    "W": _X,
    "w": _X,
    "-": _X,
    # high impedance
    "Z": _Z,
    "z": _Z,
}

低电平 0

False, 0, “0”, “L”, “l”

高电平1

True, 1, “1”, “H”, “h”

不定态 x

“X”, “x”, “U”, “u”, “W”, “w”, “_”

高阻态 z

“Z”, “z”

示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from cocotb.types import Logic
from cocotb.types import Bit

print('Logic("X") : ', Logic("X"))
print('Logic(True) : ', Logic(True))
print('Logic(1) : ', Logic(1))
print('Logic(Bit(0)) : ', Logic(Bit(0)))
print('Logic() : ', Logic())
print('Logic("Z") : ', Logic("Z"))
print('bool(Logic(0)) : ', bool(Logic(0)))
print('int(Logic(1)) : ', int(Logic(1)))
print('Bit(Logic("1")) : ', Bit(Logic("1")))

结果:

1
2
3
4
5
6
7
8
9
: Logic("X") :  X
: Logic(True) :  1
: Logic(1) :  1
: Logic(Bit(0)) :  0
: Logic() :  X
: Logic("Z") :  Z
: bool(Logic(0)) :  False
: int(Logic(1)) :  1
: Bit(Logic("1")) :  1

cocotb Logic 逻辑运算

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
from cocotb.types import Logic
from cocotb.types import Bit
import typing
def full_adder(a: Logic, b: Logic, carry: Logic) -> typing.Tuple[Logic, Logic]:
    res = a ^ b ^ carry
    carry_out = (a & b) | (b & carry) | (a & carry)
    return res, carry_out

ret = full_adder(a=Logic('0'), b=Logic('1'), carry=Logic('1'))
print('ret : ', ret)

结果:

1
: ret :  (Logic('0'), Logic('1'))

LogicArray

cocotb LogicArray基本用法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
from cocotb.types import LogicArray
from cocotb.types import Range
from cocotb.types import Logic
print('LogicArray("01XZ") : ', LogicArray("01XZ"))
print('LogicArray([0, True, "X"]) : ', LogicArray([0, True, "X"]))
print('LogicArray(0xA) : ', LogicArray(0xA))
print('LogicArray(-4, Range(0, "to", 3)) : ', LogicArray(-4, Range(0, "to", 3)))
print('LogicArray(range=Range(0, "to", 3)) : ', LogicArray(range=Range(0, "to", 3)))
la = LogicArray("1010")
print('la[0] : ', la[0])
print('la[1:] : ', la[1:])
print('Logic("0") in la : ', Logic("0") in la)
print('list(la) : ', list(la))

结果:

1
2
3
4
5
6
7
8
9
: LogicArray("01XZ") :  LogicArray('01XZ', Range(3, 'downto', 0))
: LogicArray([0, True, "X"]) :  LogicArray('01X', Range(2, 'downto', 0))
: LogicArray(0xA) :  LogicArray('1010', Range(3, 'downto', 0))
: LogicArray(-4, Range(0, "to", 3)) :  LogicArray('1100', Range(0, 'to', 3))
: LogicArray(range=Range(0, "to", 3)) :  LogicArray('XXXX', Range(0, 'to', 3))
: la[0] :  0
: la[1:] :  LogicArray('10', Range(1, 'downto', 0))
: Logic("0") in la :  True
: list(la) :  [Logic('1'), Logic('0'), Logic('1'), Logic('0')]

cocotb LogicArray切片 (slice)

1
2
3
4
5
6
from cocotb.types import LogicArray
la = LogicArray("1010")
la[3] = "Z"
print('la : ', la)
la[2:] = ['X', True, 0]
print('la : ', la)

结果:

1
2
: la :  LogicArray('Z010', Range(3, 'downto', 0))
: la :  LogicArray('ZX10', Range(3, 'downto', 0))

cocotb LogicArray Range

Range 类似于Verilog 中定义寄存器位宽时的约束如

1
reg [7:0] aaa = 8'b1111_0000;

对应于 cocotb 中的

1
aaa = LogicArray("11110000", Range(7, "downto", 0))
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from cocotb.types import LogicArray
from cocotb.types import Range
r = Range(-2, 3)
print('r.left, r.right, len(r) : ', r.left, r.right, len(r))
print('r : ', r)
print('r : ',  end=' ')
for i in r:
    print(i, end=' ')
print()
s = Range(8, 'downto', 1)
print('s.left, s.right, len(s) : ', s.left, s.right, len(s))
print('s : ', s)
print('s : ',  end=' ')
for i in s:
    print(i, end=' ')
print()

la = LogicArray(-4, Range(0, "to", 3))
la = LogicArray(-4, Range(3, "downto", 0))
print('la : ', la)
print('la : ',  end=' ')
for i in la:
    print(i, end=' ')
print()

la = LogicArray('x10z', Range(-2, 'to', 1))
print("la[-2], la[-1], la[0], la[1] : ", la[-2], la[-1], la[0], la[1])

结果:

1
2
3
4
5
6
7
8
: r.left, r.right, len(r) :  -2 3 6
: r :  Range(-2, 'to', 3)
: r :  -2 -1 0 1 2 3 
: s.left, s.right, len(s) :  8 1 8
: s :  Range(8, 'downto', 1)
: s :  8 7 6 5 4 3 2 1 
: la :  LogicArray('1100', Range(3, 'downto', 0))
: la :  1 1 0 0 

cocotb LogicArray数据转换 (Data Convert)

1
2
3
4
5
6
7
from cocotb.types import LogicArray
from cocotb.types import Range
from cocotb.types import Logic
la = LogicArray("1010")
print('la.binstr : ', la.binstr)
print('la.integer : ', la.integer)          # uses unsigned representation
print('la.signed_integer : ', la.signed_integer)   # uses two's complement representation

结果:

1
2
3
: la.binstr :  1010
: la.integer :  10
: la.signed_integer :  -6

cocotb LogicArray 逻辑运算

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
from cocotb.types import LogicArray
from cocotb.types import Range
from cocotb.types import Logic

def big_mux(a: LogicArray, b: LogicArray, sel: Logic) -> LogicArray:
    s = LogicArray([sel] * len(a))
    return (a & ~s) | (b & s)

la = LogicArray("0110")
p = LogicArray("1110")
sel = Logic('1')        # choose second option
ret = big_mux(la, p, sel)
print('ret : ', ret)

结果:

1
: ret :  LogicArray('1110', Range(3, 'downto', 0))
Licensed under CC BY-NC-SA 4.0