Literals & Signals
Literals
Logic
Logic is three-state (0, 1, and X) and has an arbitrary length. Two bits are used to represent a three-state value: 00 as zero, 10 as one, and both 01 and 11 as the unknown state.
Logic(1,2) # 0...x1
Logic(3) # 0...11
Logic(-1) # 1...1
Logic('xx') # 0...xx
Logic('x1x1') | Logic('1x1x') # 0...1111
For convenience, == and != between Logic and other literals return a python bool.
Logic('11') == 3 # True
Logic('x1') == 3 # False
Logic(0,3) == Logic(3,3) # True
Explicit Logic literal are usually unnecessary.
BitPat
BitPat is three-state (0, 1, and don’t care) and has a fixed length. It is only used in comparation.
BitPat('11??') # 4'b11??
strings
Python strings are usually converted into Logic automatically.
'0011_1100' # 8'b00111100
'4:b111111' # 4'b1111
'8:hab' # 8'hab
'-d3' # 3'b101
'4:-d3' # 4'b1101
'16.x:habc' # 16'hxabc
Signals
PyHGL models digital circuits as a direct graph of Gate and SignalData nodes. Writer is the edge from gate to data, while Reader is the edge from data to gate.
Signals are
Reader, which contains aSignalTypeand aSignalDataSignalTypeindicates signal type and bit width.SignalDatacontains the real three-state singal value that is unique for each signal.
Type castings are only allowed for same bit length.
UInt
UInt[w] is the most basic signal type, similar as logic [w-1:0] in SystemVerilog. A SignalType is callable and return a signal instance.
# lines below are the same
UInt[8](1)
UInt[8]('1')
UInt('8:b1')
UInt(1, w=8)
Other
uint8_t = UInt[8] # signal type: 8-bit unsigned integer
sint32_t = SInt[32] # signal type: 32-bit signed integer
vector_t = 4 ** uint8_t # signal type: packed array of 4x8 bits
mem_t = MemArray[1024,8] # signal type: unpacked array of 1024x8 bits
struct_t = Struct(
a = vector_t @ 0, # field 'a' starts from 0
b = sint32_t @ 0, # field 'b' starts from 0
c = UInt[32] @ 32, # field 'c' starts from 32
) # signal type: 64-bit structure
x = struct_t({
'a': [1,2,3,4],
'c': Logic('xxxx1100'),
}) # signal x has an initial value of 64'hxc04030201
y = UInt[64](x) # type casting
Array
Array is not a hardware type, but a tree-like data struct like awkward-array. Array is used for vectorized operations and module ports.
Arraycan be either a named array likeDict[str, Any]or a listList[Any]supports advanced slicing
operators on
Arrayare vectorized and broadcastuse function
Bundleto generate a named array
# 1-d vector
Array([1,2,3,4])
Bundle(1,2,3,4)
# 2-d vector
Array([[1,2],[3,4]], recursive=True)
# named array
Array({'a':1, 'b':2})
Bundle(a=1, b=2)
Useful Functions
Array.zeros(2,3) # Array([[0,0,0],[0,0,0]], recursive=True)
UInt.zeros(2,3) # Array([[UInt(0), UInt(0), UInt(0)],[UInt(0),UInt(0),UInt(0)]], recursive=True)
Logic(-1).to_bin(4) # '1111'
Logic(-1).to_hex(16) # 'ffff'
Logic(-1).to_int(1) # -1