MyHDL中文手册(十二完结)——MyHDL编程参考

45 篇文章 14 订阅
35 篇文章 9 订阅

MyHDL作为一个名为myhdl的Python包实现。本章介绍此程序包导出的对象。

仿真

仿真类simulation class

class Simulation(arg[, arg ...])

类,构造新的仿真。
每个参数都应该是MyHDL实例。在MyHDL中,一个实例被递归地定义为一个实例序列、一个MyHDL生成器或一个协同仿真对象。
有关MyHDL生成器的定义及其与仿真对象的交互,请参见MyHDL生成器和触发器对象一节。
最多可以将一个协同仿真对象传递给仿真构造函数,请参见协同仿真对象的部分。

仿真对象具有run, quit方法

Simulation.run([duration])

永远(默认情况下)或指定持续时间运行仿真。

Simulation.quit()

仿真运行指定持续时间后退出。
在创建另一个仿真实例之前,应调用该方法(必须退出仿真实例)。
仿真永远运行时,默认情况下会调用该方法。

仿真支持函数(now,StopSimulation)

now()

返回当前仿真时间。

exception StopSimulation

由simulation.run()方法捕获以停止仿真的基本异常。

波形跟踪,traceSignal

traceSignals(func [, *args] [, **kwargs])

启用信号跟踪VCD文件以查看波形。func是一个返回实例的函数。traceSignals在其控制下调用func,并将args和kwargs传递给该调用。这样,它就可以找到要跟踪的层次结构和信号。返回值与调用func(*args,*kwargs)返回的值相同。
默认情况下,顶级实例名称和VCD输出文件名的基础部分Basename是func.func_name。
如果VCD文件已经存在,则在创建新文件之前,将通过向其附加时间戳将其移动到备份文件。

traceSignals 可调用属性

name

name属性用于覆盖默认顶级实例名称和VCD输出文件名的basename。

directory

directory属性用于设置VCD文件写入到的目录。
默认情况下,使用当前工作目录。

filename

filename属性用于设置写入VCD文件的文件名。
默认情况下,使用attribute名称。

timescale

timescale属性用于根据VCD格式设置与单位步数对应的时间刻度。指定的值应该是字符串。
默认时间刻度为“1 ns”。

建模

模块修饰器block

block

块修饰器支持基于方法的API,该API更加一致,简化了实现,并减小了myhdl命名空间的大小。这些方法对块实例起作用,这些实例是通过调用由块装饰器修饰的函数创建的:

@block
def myblock(<ports>):
...
return <instances>

inst = myblock(<port-associations>)
# inst supports the methods of the block instance API

块实例上的API如下所示:

blockxxx.run_sim()

<block_instance>.run_sim(duration=None)

运行仿真“永久”(默认)或指定持续时间。

可选仿真配置:
后端:默认为“myhdl”
跟踪:启用波形跟踪,默认为假。

blockxxx.quit_sim()

<block_instance>.quit_sim()

退出活动仿真。
当前需要此方法,因为只能激活单个仿真。

blockxxx.convert()

<block_instance>.convert(hdl='Verilog', **kwargs)

将MyHDL代码转换为目标HDL。HDL:‘VHDL’或‘Verilog’。默认为Verilog。
支持的关键字参数:
路径:目标文件夹。默认为当前工作方向。默认值为self.mod.name
跟踪:测试台是否应该转储所有的信号波形。默认值为false。
测试工作台:仅限Verilog。指定是否应创建测试工作台。默认值为True。
时间刻度:时间刻度参数。默认为“%1 ns/10ps”。仅限Verilog。

blockxxx.verify_convert()

	<block_instance>.verify_convert()

通过比较目标HDL仿真日志和MyHDL仿真日志,验证转换输出。

<block_instance>.analyze_convert()

用目标HDL编译器编译分析转换输出。

信号SignalType类型

	class SignalType

此类型是所有信号的抽象基类型。
它不用于构造信号,但可用于检查对象是否为信号。

普通信号Signal()

class Signal([val=None] [, delay=0])	

此类用于构造新信号并将其值初始化为val。
(可选)可以指定延迟。
信号对象具有以下属性:

posedge

属性,该属性表示要在灵敏度列表中使用的信号的正边缘。

negedge

属性,该属性表示要在灵敏度列表中使用的信号的负边缘。

next

表示信号下一个值的读写属性。

val

只读属性,表示信号的当前值。
此属性始终可用于访问当前值;但是,在许多实际情况中不需要此属性。
只要没有歧义,信号对象的当前值就会被隐式使用。
特别是,所有Python的标准数字、位、逻辑和比较运算符都是通过委托给信号对象的当前值来实现的。
例外情况是增量赋值。
这些运算符不会实现,因为它们将打破当前值应为只读属性的规则。
此外,当一个信号对象被指定给另一个信号对象的下一个属性时,它的当前值被指定给另一个信号对象。

min

只读属性,它是数字信号的最小值(包括),或者“无”(None)表示无最小值。

max

只读属性,它是数字信号的最大值(独占),或者“无”表示无最大值。

driven

可写属性,该属性可用于指示信号应该从MyHDL代码驱动,以及在转换后如何在verilog中声明该信号。允许的值为“reg”、“wire”、“true”和“false”。

当转换器无法自动推断是否以及如何驱动信号时,此属性非常有用。当信号由用户定义的代码驱动时,就会发生这种情况。‘reg’和‘wire’是“true”值,允许对Verilog情况进行更精细的控制。

read

可写bool属性,可用于指示读取信号。当转换器无法自动推断是否读取信号时,此属性非常有用。这发生在从用户定义的代码读取信号时。

信号对象还具有调用接口:

ResetSignal()

class ResetSignal(val, active, async)

此信号子类定义重置或复位信号。Val、Active和Async是必需的参数。val是指定初始值的布尔值,Active是指定活动级别的布尔值。Async是一个布尔值,它指定重置方式:异步(True)或同步(False)。
此类应与always_seq修饰器一起使用。

影子信号_SliceSignal()

class _SliceSignal(sig, left[, right=None])

此类实现只读结构切片和索引。
它创建父信号sig的切片或索引的新阴影信号。
如果省略了正确的参数,则会得到索引而不是切片。
参数“左”和“右”对于切片索引具有通常的含义:特别是,“左”是非包含性的,但“右”是包含性的。sig应该适合于切片和索引,这意味着在实践中应该以intbv为基础。
类构造函数不打算显式使用。相反,请使用常规信号的调用接口。以下调用是等效的:

sl = _SliceSignal(sig, left, right)
sl = sig(left, right)

ConcatSignal()

class ConcatSignal(*args)

此类创建其参数串联的新影子信号。

可以向构造函数传递任意数量的参数。参数应该是以位为导向的,并且定义了位数。支持以下参数类型:具有定义的位宽度的intbv对象、bool对象、先前对象的信号和位字符串。

新信号跟随信号参数的值变化。非信号参数用于定义串联中的常量值。

TristateSignal()

class TristateSignal(val)

这个类用于构造一个新的三态信号。基础类型由val参数指定。
它是一个信号子类,具有通常的属性,但有一个例外:它不支持next属性。因此,不支持对三态信号的直接信号分配。
初始值为“无(none)”三态值。
三态的当前值是通过解析来自其驱动程序的值来确定的。
当只有一个驱动程序值不同于“无”时,即解析的值;否则为“无”。当多个驱动程序值与无驱动程序值不同时,将发出竞争警告。
此类具有以下方法:

driver()

向三态信号返回新的驱动程序。
它被初始化为“无(none)”。
Driver对象是特殊SignalType子类的实例。
特别是,它的next属性可用于为其分配新值。

MyHDL生成器和触发器对象

MyHDL生成器是标准的Python生成器,具有专门的yield语句。
在硬件描述语言中,等效语句称为灵敏度列表。
MyHDL生成器中的yield语句的一般格式为:

yield clause [, clause …]

当生成器执行yield语句时,它的执行将在该点暂停。同时,每个子句都是一个触发器对象,它定义了生成器应该恢复的条件。但是,每次调用yield语句时,生成器只恢复一次,而不管子句的数量如何。这发生在第一个触发器上。在本节中,将介绍触发器对象及其功能。其他地方描述的一些MyHDL对象可以直接用作触发器对象。特别地,信号可以用作触发器对象。每当信号改变值时,生成器就会恢复。
同样,信号属性posedgfe和negedge所引用的对象也是触发器对象。
该发生器在信号上分别出现正边沿或负边沿时恢复。
当从false变为true(正数)或反之亦然(负数)时,就会出现边沿。有关Signal类及其属性的完整描述,请参见Signal部分。
此外,MyHDL生成器可以用作yield语句中的子句。
这样的生成器是分叉的,并立即开始运行,而原来的生成器等待它完成。
当分叉生成器返回时,原始生成器将恢复。
此外,以下函数返回触发器对象:

delay(t)

返回一个触发器对象,该对象指定生成器应在延迟t之后恢复。

join(arg[, arg ...])

将多个触发器对象连接在一起,并返回一个联接的触发器对象。其效果是,当连接的触发器对象的所有参数都已触发时,将触发该对象。
最后,作为特例,Python none对象可以出现在yield语句中。它是不做任何事的触发器对象。生成器立即恢复,就像没有出现任何yield语句一样。
如果yield语句也包含生成器子句,这将非常有用:这些生成器是分叉的,而原始生成器将立即恢复。

用于创建生成器的装饰函数

MyHDL定义了许多装饰器函数,这些函数使得从本地生成器函数创建生成器变得更加容易。

instance()

instance()

实例修饰器是最通用的修饰器。
它通过调用修饰的生成器函数自动创建生成器。
其用途如下:

def top(...):
    ...
    @instance
    def inst():
        <generator body>
    ...
    return inst, ...

等效于

def top(...):
    ...
    def _gen_func():
        <generator body>
    ...
    inst = _gen_func()
    ...
    return inst, ...

always()

always(arg[, *args])

always 装饰器是一种专门针对广泛使用的编码模式的装饰器。
其用途如下:

def top(...):
    ...
    @always(event1, event2, ...)
    def inst()
        <body>
    ...
    return inst, ...

等效于

def top(...):
    ...
    def _func():
        <body>

    def _gen_func()
        while True:
            yield event1, event2, ...
            _func()
    ...
    inst = _gen_func()
    ...
    return inst, ...

修饰器的参数列表与灵敏度列表相对应。
仅允许信号、边沿说明符或延迟对象。
修饰函数应该是经典函数。

always_comb()

always_comb()

always_comb装饰器是用来描述组合逻辑的。

	def top(...):
    ...
    @always_comb
    def comb_inst():
        <combinatorial body>
    ...
    return comb_inst, ...

always_comb装饰器自动推断组合逻辑的输入和相应的灵敏度列表。
修饰函数应该是经典函数

always_seq()

always_seq(edge, reset)

always_seq修饰器用于描述顺序(时钟)逻辑。“edge”参数应为时钟边沿(clock.posedge或clock.negedge)。reset参数应为ResetSignal对象。

MyHDL数据类型。

MyHDL定义了许多对硬件描述有用的数据类型。

Intbv()类

class intbv([val=0] [, min=None] [, max=None])

此类表示类似于int的对象,并具有一些使其适合硬件设计的附加功能。
val参数可以是int、long、intbv或位字符串(只有‘0’s或‘1’s的字符串)。
对于位字符串参数,该值按int(bitstring,2)计算。
可选的min和max参数可用于指定intbv对象的最小值和最大值。
与标准Python实践中的范围一样,最小值是包含的,最大值是排斥的。
intbv对象的最小值和最大值可用作属性:

min

只读属性,它是intbv的最小值(包括),或者不包含任何最小值。

max

只读属性,即intbv的最大值(排斥),或无最大值时为“无”。

signed()

将MSB位表示为符号位,并将其扩展为底层对象值的高阶位。MSB位是对象位宽内的最高阶位。

Return type:	integer

与int对象不同,intbv对象是可变的;这也是它们存在的原因。正如硬件设计中常见的那样,需要可变才能支持对索引和切片的分配。出于同样的原因,intbv不是int的子类,尽管int提供了所需的大部分功能。(不可能从不可变的基类型派生可变子类型)。
intbv对象支持与int对象相同的比较、数字、按位、逻辑和转换操作。
有关此类操作的更多信息,请参见http://www.python.org/doc/current/lib/typeesminic.html。
在所有二进制操作中,intbv对象可以与int对象一起工作。对于混合型数值操作,结果类型为int或long。对于混合类型的按位操作,结果类型是intbv。此外,intbv还支持许多序列操作符。具体来说,len函数返回对象的位宽度。此外,intbv对象支持索引和切片操作:

操作结果说明
bv[i]bv第i项(1)
bv[i]=xbv第i项替换为x(1)
bv[i:j]切片[i:j](2)(3)
bv[i:j] =t切片[i:j] 替换为t(2)(4)

(1)索引遵循最常见的硬件设计约定:LSB位是最右边的位,索引为0。
这具有以下理想的性质:如果将intbv值分解为2的幂之和,则索引为i的位对应于术语2*i。
(2)与标准的Python排序约定相反,切片范围是向下的。
这是索引约定的结果,同时也是权重最大的数字是最左边的数字这一常见约定的结果。
遵循Python的半开放范围约定:不包括索引最高的位。
但是,在这种情况下,它是最左边的位。
与标准Python一样,这解决了许多实际情况中的一次性问题:特别是BV[i:]返回i位;BV[i:j]具有i-j位。如果省略低索引j,则默认为0。
当省略高索引i时,它的意思是“所有”高阶位。
(3)从切片访问操作返回的对象总是一个正的intbv;高阶位被隐式地假设为零。
位宽度隐式存储在返回对象中,因此可以在连接中使用,也可以作为迭代器使用。
此外,对于位宽度w,min和max属性分别隐式设置为0和2的w次幂。
(4)将切片设置为值时,将检查切片是否足够宽。
此外,intbv对象支持迭代器协议。这使得可以遍历其所有位,从高索引到索引0。这仅适用于具有定义的位宽度的intbv对象。

modbv()类

class modbv([val=0] [, min=None] [, max=None])

modbv类实现模块化的位向量类型。
它被实现为intbv的子类,并支持相同的参数和运算符。
不同之处在于最小和最大边界的处理。
超过这些约束时,modbv对象的值不会引发异常,而是根据以下公式环回:

val = (val - min) % (max - min) + min

此公式是在描述硬件系统行为时通常有用的模块环绕行为的推广。

枚举工厂功能

enum(arg [, arg ...] [, encoding='binary'])

返回枚举类型。
参数应该是表示枚举类型属性所需名称的字符串文字。
应将返回的类型分配给类型名称。
例如:

t_EnumType = enum('ATTR_NAME_1', 'ATTR_NAME_2', ...)

枚举类型标识符可用作类型名称的属性,例如:T_EnumType.ATTR_NAME_1。
可选的关键字参数编码指定Verilog输出中使用的编码方案。
可用的编码是‘二进制’、‘one_hot’和‘one_cold’。

建模支持函数

MyHDL定义了许多对硬件描述有用的附加支持函数。

bin

bin

返回位字符串表示形式。
如果提供了可选宽度,并且宽度大于默认表示的宽度,则位字符串将用符号位填充。
此函数是对标准Python转换函数十六进制和OCT的补充。
二进制字符串表示在硬件设计中通常很有用。

Return type:	string

concat

concat
concat(base[, arg ...])

返回由串联参数形成的intbv对象。
支持以下参数类型:具有定义的位宽度的intbv对象、bool对象、先前对象的信号和位字符串。
所有这些对象都具有定义的位宽度。
第一个参数基是特殊的,因为它不需要定义的位宽度。
除了前面提到的对象之外,还支持未调整大小的intbv、int和long对象以及这些对象的信号。

downrange

生成整数的向下范围列表。
此函数是按照标准范围函数建模的,但工作方向是向下的。
返回的间隔是半开的,不包括高索引。Low是可选的,默认值为零。
此函数与intbv类结合使用时特别有用,该类也可用于向下索引。

instances

在本地名称空间中查找所有MyHDL实例,并在列表中返回它们。

Return type:	list

协仿

MyHDL

class Cosimulation(exe, **kwargs)

类,构造新的协同仿真对象。
exe参数是执行HDL仿真的命令,可以是整个命令行的字符串,也可以是字符串列表。
在后一种情况下,第一个元素是可执行的,后面的元素是程序参数。
通过提供参数列表,Python可以正确处理程序参数中的空格或其他字符。
kwargs关键字参数提供HDL仿真器中的信号(regs和net)与MyHDL仿真器中的信号之间的命名关联。
每个关键字都应该是HDL代码中$ to_myhdl 或$ from_myhdl 调用中列出的名称。
每个参数都应该是MyHDL代码中声明的一个信号。

Verilog

$to_myhdl(arg, [, arg ...])

定义MyHDL仿真器应该读取哪些信号(规则和网)的任务。
应在仿真开始时调用此任务。

$from_myhdl(arg, [, arg ...])

任务,该任务定义哪些信号应由MyHDL仿真器驱动。
在verilog中,只能指定regs。
应在仿真开始时调用此任务。

转换成Verilog和VHDL

toVerilog

toVerilog(func [, *args] [, **kwargs])

将MyHDL设计实例转换为等效的Verilog代码,并生成一个测试平台对其进行验证。func是一个返回实例的函数。toVerilog在其控制下调用func,并将args和kwargs传递给调用。返回值与调用func(*args,*kwargs)返回的值相同。应将其分配给实例名称。
默认情况下,Verilog输出文件名的顶级实例名称和basename是function.func_name。
有关可转换MyHDL代码的限制的更多信息,请参见“转换为Verilog和VHDL”一章中的可转换子集一节。

toVerilog具有以下属性:

name

此属性用于覆盖默认顶级实例名称和Verilog输出文件名的Basename。

directory

此属性用于设置将转换的verilog文件写入其中的目录。
默认情况下,使用当前工作目录。

timescale

此属性用于以Verilog格式设置时间刻度。
指定的值应该是字符串。
默认时间刻度为“1 ns/10ps”。

toVHDL

toVHDL(func[, *args][, **kwargs])

将MyHDL设计实例转换为等效的VHDL代码。func是一个返回实例的函数。toVHDL在其控制下调用func,并将args和kwargs传递给调用。
返回值与调用func(*args,*kwargs)返回的值相同。
可以将其分配给实例名称。
默认情况下,Verilog输出文件名的顶级实例名称和basename是function.func_name。
ToVHDL具有以下属性:

name

此属性用于覆盖默认顶级实例名称和VHDL输出的Basename。

Directory

此属性用于设置要将转换后的VHDL文件写入其中的目录。
默认情况下,使用当前工作目录。

component_declarations

此属性可用于向VHDL输出添加组件声明。
当将字符串分配给它时,它将被复制到输出文件中的适当位置。

library

此属性可用于在VHDL输出文件中设置库。
指定的值应该是字符串。
默认库为Work。

std_logic_ports

此布尔属性可用于在顶级接口上仅具有std_logical类型端口(当为True时),而不是默认的有符号/无符号类型(当为False时为默认值)。

用户自定义Verilog和VHDL代码

用户定义的代码可以通过使用函数属性插入到Verilog或VHDL输出中。
假设函数func定义了一个硬件模块。
可以使用以下函数属性为函数指定用户定义的代码

<func>.vhdl_code

VHDL输出中用户定义代码的模板字符串。

<func>.verilog_code

verilog输出中用户定义代码的模板字符串。

当定义这样的函数属性时,将绕过正常的转换过程,而插入用户定义的代码。
模板字符串应该适用于标准字符串.Template构造函数。
它们可以包含上下文中所有信号的插值变量(由$前缀指示)。
请注意,函数属性可以在fun可见的任何地方进行定义,无论是在函数外部还是在函数内部。
这些函数属性不能与生成器函数或修饰的本地函数一起使用,因为在仿真或转换之前没有详细说明这些属性。
换句话说,它们只能与定义结构的函数一起使用。

转换输出验证

MyHDL提供了验证转换设计的接口。
这在包本身中被广泛使用,以验证转换功能。
此功能由软件包导出,以便用户也可以使用。

验证接口

所有与转换验证相关的函数都在myhdl.conversion 包中实现。

verify()

verify(func[, *args][, **kwargs])

使用如toVHDL和toVerilog。
它转换MyHDL代码,仿真MyHDL代码和HDL代码,并报告任何差异。
默认的HDL仿真器是GHDL。
此函数具有以下属性:

simulator

用于设置HDL仿真器的名称。
默认设置为“GHDL”。

analyze(func[, *args][, **kwargs])

使用如toVHDL和toVerilog。
它转换MyHDL代码,并分析生成的HDL。
用于验证HDL输出在语法上是否正确。
此函数具有以下属性:

simulator

用于设置用来分析代码的HDL仿真器的名称。
默认设置为“GHDL”。

HDL仿真器注册

要使用HDL仿真器验证转换,需要首先注册它。
每个仿真器都需要这一次。
在MyHDL发行版中预先注册了一些HDL仿真器,如下所示:

标识符仿真器
“GHDL”VHDL 仿真器
“vsim”ModelSim VHDL仿真器
“icarus”Icarus Verilog仿真器
“cver”cver Verilog仿真器
“vlog”Modelsim VHDL仿真器

当然,仿真器必须在安装后才能使用。
如果需要另一个仿真器,则必须由用户注册。
这是通过驻留在myhdl.Conversion.Verify模块中的函数tverSimulation来完成的。
同一模块还具有预定义仿真器的注册。
验证功能是通过比较HDL仿真器输出和MyHDL仿真器输出来实现的。
因此,他们必须处理每个HDL仿真器输出的具体细节,这可能有些棘手。
这反映在注册表仿真功能的界面中。
由于很少需要注册,此处不再对此接口进行进一步说明。
请参阅myhdl.Conversion._Verify中的源代码以了解注册是如何工作的。
如果您需要帮助,请联系MyHDL社区。

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值