用于匹配正则表达式的vhdl代码生成器。
vhdre的Python项目详细描述
vhdre:vhdl regex匹配生成器
此模块允许您生成 在UTF-8编码字符串上操作的表达式匹配器。正则表达式 特性是有限的,regex编译是在合成之前完成的,并且 仅当字符串匹配时才告诉您,但它可以非常快地完成此操作。它是 用于大海捞针式搜索,其中 缩减是如此之大,以至于您可以让CPU计算出 允许vhdre进行初始筛选后匹配的字符串。
亮点
带错误检测的UTF-8字节流解码(对于大多数错误)。
与Axi4兼容的流接口。
可以使用共享解码同时匹配多个正则表达式 逻辑.
每个时钟周期可以匹配多个字节(甚至字符串),具体取决于 配置。
为具有6个输入lut的fpgas优化,关键路径只有2个lut 当为每个字节配置时,大多数正则表达式的每个周期 循环匹配。
不同的界面样式复杂程度不同。
依赖关系
python脚本:只有python 3.x和funcparserlib。
生成的vhdl:没有依赖项,应该使用任何 VHDL-93工具。
支持的regex功能
支持的语法
x
->;完全匹配x
。x*
->;匹配x
零次或多次。x+
->;匹配x
一次或多次。 < <代码> X?->;匹配x y
->;匹配x
后跟y
x y
->;匹配x
或y
(x)
->;括号仅用于消除歧义(没有捕获 组)。[x]
->;字符类(匹配x
)。[^x]
->;反转字符类(匹配除x
之外的所有字符类)。[a b]
->;匹配a
或b
[a-z]
->;匹配a-z
代码点范围(包括)中的任何内容。
x
零次或一次。转义序列
请注意,Unicode转义序列偏离了标准。
\xhh
->;hh
=2位十六进制码位\uhhhhh
->;hhhhh
=6位十六进制码位\d
->;[0-9]
\w
->;[0-9a-za-z纡]
\s
->;[\a\b\t\n\v\f\r]
\a\b\t\n\v\f\r
->;常用的控制字符转义序列- 任何其他内容都与\后面的字符匹配
注释
匹配器执行regex匹配。也就是说,给定的字符串必须与 正则表达式,就像它被
^
和$
包围一样。做 而是搜索,前缀和/或附加*
必须在字符类之外转义以下字符:
[\^$.?*+()
以下字符必须在字符类内转义:
]-
在这个引擎中贪婪匹配和懒惰匹配没有区别。任何 以任何方式符合regex的字符串都被视为匹配项。
很多更高级的regex功能不受支持,因为它们 需要回溯。这个引擎绝对做不到,因为 它基于一个NFAE。
用法
vhdre
是一个可执行的python 3模块。伦尼不加争论的话
提供一些基本使用信息:
$ python3 -m vhdre
Usage: python -m vhdre <entity-name> <regex> ... [-- <test-string> ...]
Generates a file by the name <entity-name>.vhd in the working directory
which matches against the given regular expressions. If one or more test
strings are provided, a testbench by the name <entity-name>_tb.vhd is
also generated. To insert a unicode code point, use {0xHHHHHH:u}. To
insert a raw byte (for instance to check error handling) use {0xHH:b}.
{{ and }} can be used for matching { and } literally.
脚本将把正则表达式编译成不确定的 有限自动机,然后为其构建vhdl单元。只是为了避免混乱 这里:是的,正则表达式在生成之后是固定的。它们不是 运行时可配置。你需要重新合成你的设计如果你想 更改正则表达式。
生成的vhdl单元可以以多种不同的方式实例化 在复杂性和速度上。这是最简单的形式:
lbl:entitywork.<entity-name>portmap(clk=>-- clock signal.in_valid=>-- signal indicating that there is an incoming byte.in_data=>-- the incoming byte.in_last=>-- signal indicating whether this byte is the last in-- the string.out_valid=>-- signal indicating that a string has been received.out_match=>-- indicates which regular expressions were matched if-- `out_valid` is high.);
上面的信号不支持空字符串。如果你需要,我们需要
添加一个"有效"标志,该标志独立于最后一个掩码中的:
。无论何时
接收到一个空字符串,只需在掩码中设置
低,在最后一个掩码中设置
高。
lbl:entitywork.<entity-name>portmap(clk=>-- clock signal.in_valid=>-- signal indicating that there is an incoming byte-- or empty string.in_mask(0)=>-- signal indicating that there is an incoming byte.in_data=>-- the incoming byte.in_last=>-- signal indicating that this byte is the last in the-- string, or if there is no byte, that the previous-- byte was the last one, if any.out_valid=>-- signal indicating that a string has been received.out_match=>-- indicates which regular expressions were matched if-- `out_valid` is high.);
在我们解决问题之前,您可以扩展列出的任何端口图 根据您的需要,这里有一个或多个以下信号:
复位
:激活的高同步复位。aresetn
:激活的低异步复位。clken
:激活的高全局时钟启用信号。输入就绪
&;输出就绪
:AXI4兼容背压信号,以防 你的输出可能会暂停。注意:背压的实现很简单。如果 它给你时间问题,阅读"背压说明 正时关闭"部分如下。输出错误
或输出错误
:指示UTF-8 出现解码错误。应使用"输出错误"而不是输出错误
仅限每个周期处理多个字符串的系统。
为了提高速度,vhdre支持每个周期处理多个字节。二 支持类型:每个周期字符串的数量仍为 仅限一人,无此限制者。后者 需要使用更复杂的输出流。
这是第一种味道(每个周期最多一个字符串):
lbl:entitywork.<entity-name>genericmap(BPC=>-- number of bytes per cycle.)portmap(clk=>-- clock signal.in_valid=>-- signal indicating that there are incoming control-- or data signals.in_mask=>-- signal indicating which of the incoming bytes are-- valid. Its width is equal to BPC.in_data=>-- the incoming bytes. Its width is equal to BPC*8.in_last=>-- signal indicating that the last byte received so far-- is the last byte of a string, if any.out_valid=>-- signal indicating that a string has been received.out_match=>-- indicates which regular expressions were matched if-- `out_valid` is high.);
这是第二种口味(没有限制)。我们用"插槽"这个词 参考平行匹配引擎,因为它们不再需要 对应于此时的有效字节。
lbl:entitywork.<entity-name>genericmap(BPC=>-- number of bytes per cycle.)portmap(clk=>-- clock signal.in_valid=>-- signal indicating that there are incoming control-- or data signals.in_mask=>-- signal indicating which of the incoming bytes are-- valid. Its width is equal to BPC.in_data=>-- the incoming bytes for each slot. Its width is equal-- to BPC*8.in_xlast=>-- signal indicating which of the byte slots are to be-- interpreted as string boundaries. Its width is-- equal to BPC.out_valid=>-- signal indicating that one or more strings have been-- received.out_xmask=>-- indicates which of the parallel slots received a-- string terminator. Its width is BPC.out_xmatch=>-- indicates which regular expressions were matched by-- each slot. Its width is BPC.);
保证匹配由同一插槽报告
已设置上一个中的。假设你有一个能处理8个字节的系统
每个周期,但字符串总是从4字节边界开始,您只需要
担心每个周期最多处理两个字符串。在这种情况下,你可以
仅在xlast(3)中使用
,在xlast(7)中使用
(适当设置
在掩码中(1..3)
和在掩码中(5..7)
低,对于不是乘法的字符串
,这意味着您只需查看out xmask(3)
因为这个保证,离开xmask(7)
。
默认情况下,vhdre是little endian;也就是说,较低的索引字节/插槽是
先匹配。作为大端系统的一个小便利,您可以
通过将big_endian
generic设置为true来交换顺序。当然是这个
意味着您需要在上面的示例中使用反向索引。
关于背压和正时关闭的说明
此单元中的输入准备
和输出准备
信号在
琐碎的方式:它们实际上只是通过整个单元
组合的。这可能会导致高吞吐量系统中的计时问题。
你可以做一些事情来解决这个问题 与定时改进相比:
在本单元输出后直接插入2级Axi4流片 从流接收器的就绪信号到 Matter,
在本单元输入之前直接插入一个2级Axi4流片 从regex匹配器的就绪信号到 数据如此URCE,
完全绕过vhdre的背压逻辑,在这之后放置fifo 单元的输出并将其几乎为空的信号绑定到源流的 准备信号。此单元的
in_valid
信号必须绑定到有效且准备就绪
,因此只有在确认传输时才对其进行冲程。 必须对fifo进行配置,使其释放几乎为空的信号 当fifo中有少于6个空闲条目时。这确保了 fifo永远不会满,因为vhdre的管道不深 足够在它没有收到任何输入时生成更多的数据。 这允许该单元忽略来自fifo的ready
信号。注: 不要将fifoready
信号连接到out\u ready
!这样做 从根本上说会通过vhdre愚蠢的背压造成错误的路径 系统:< /P>