Skip to content

Datatypes

Sunny Chen edited this page Feb 21, 2020 · 7 revisions

All circuit elements that defined in PyHCL have to specify their datatyps. The circuit elements supported by PyHCL will describe in details later in section 5. Now we just need to know some of them which are common to use, such as Reg, Wire, and I/O ports.

Basic Datatypes

The datatypes in PyHCL could be divided into two categories: the basic/grand datatypes and the composite types. The basic datatypes include unsigned integer, signed integer, and boolean. Corresponds to U, S, and Bool respectively. First we give some example of constant or literal values of those datatypes:

U(1)	# 1-bit unsigend decimal value 1
U(0x126) # 12-bit unsigned hexadecimal value 0x126
U.w(4)(10) # 4-bit unsigned decimal value 10
S.w(16)(0x11) # 16-bit signed hexadecimal value 0x11
Bool(True)	# Boolean literal values True

There are two ways to specify a unsigned or signed integer literal values:

U(12)	# without width
U.w(4)(12)	# with width 

In general, format of defined a unsigned or signed integer literal values is:

U.w(<width>)(<values>)

The values could be decimal, octal, hexadecimal, and binarial in Python format. We give some examples that define several circuit elements using basic datatypes:

s = Reg(U.w(16))	# 16-bit unsigned integer register
alt = Wire(S.w(32))	# 32-bit signed integer wire
cout = Output(Bool)	# Boolean output port

In PyHCL implementation, Bool is actually a 1-bit unsigned integer. For basic datatypes, unsigned integer and signed integer could not put together for operation, they must cast to the same datatype. We use to_uint() and to_sint() for casting:

S(12).to_uint()	# Cast signed integer to unsigned integer
U.w(4)(3).to_sint() # Cast signed integer to signed integer
s.to_sint()	# Cast unsigned integer register 's' to signed integer (see above)

Note that Bool is 1-bit unsigned integer, so it could directy operate with unsigned integers.

In PyHCL library core, basic datatypes are call cdatatype. There is actually another cdatatype be defined in PyHCL library, which is Clock. However, the clock and reset port of a module are pre-defined in based class, so we don't have to worry about how to use Clock type.

Composite Datatypes

Vector

Vector is most commonly used to defined an array of register. To defined a vector, we use Vec to do so:

Vec(<size>, <cdatatype>)

size indicate the size of the vector, cdatatype indicate the datatype of the vector, and it must be a basic datatype(U, S, Bool). For example, we define an array of register:

rarray = Reg(Vec(4, U.w(16)))	# A 16-bit 4 length unsigned integer register array

We could also index the register array with the operator [], as the built-in operator of Python:

# rarray = [U(0), U(1), U(2), U(3)]
for i in range(0, 4):
  rarray[i] <<= U(i)

Another commonly used of Vec is using in I/O ports. We define a input port a using Vec:

a=Input(Vec(4, U.w(16)))

Which is convenience for multiple inputs or outputs.

Vec in PyHCL would translate as the array definition in FIRRTL, and compile to Verilog. However, the array features may lost in Verilog code. For example, the vector of input port a above, after compile to Verilog:

input  [15:0] io_a_0,
input  [15:0] io_a_1,
input  [15:0] io_a_2,
input  [15:0] io_a_3,

We could see that it has divide into 4 individual ports.

Bundle

Bundle is a collection of different datatypes. It is similar to Chisel Bundle. Actually, in PyHCL's core library, IO is actually a Bundle and translate to FIRRTL later on. As a beginner of PyHCL, you could simply treat Bundle as the struct data structure of C/C++. The way we define a Bundle is similar to IO:

bun = Bundle(
  x=U.w(16),
  y=S.w(16),
  z=Bool
)

x, y, and z are the subfield of Bundle. Bundle is a datatype, so it must used in a circuit element:

breg = Reg(Bundle(
  x=U.w(16),
  y=S.w(16),
  z=Bool
))

We use . operator to access the subfield of the Bundle, similar to IO:

breg.x <<= U(12)
breg.y <<= S(4)
breg.z <<= Bool(False)
io.out <<= breg.x

Bundle is still an experimental feature of PyHCL, we suggest that you only include basic types in Bundle.

<<Prev(A Simple Example) >>Next(Operations)