Function VHDL,使用for generate语句中的函数

Function VHDL,使用for generate语句中的函数,function,vhdl,Function,Vhdl,VHDL,使用for generate语句中的函数 我有一个应该被实例化8000次的组件,我使用一些常量值来帮助生成语句以减少代码量,但是我必须声明一个用于组件连接参数化的函数 我的函数如下所示: ins_test : test_comp port map ( clk => clk, test_port(1) => test_sig(2) test_port(2) => test_sig(3)

VHDL,使用for generate语句中的函数

我有一个应该被实例化8000次的组件,我使用一些常量值来帮助生成语句以减少代码量,但是我必须声明一个用于组件连接参数化的函数

我的函数如下所示:

    ins_test : test_comp port map (
        clk          => clk,
        test_port(1)  => test_sig(2)
        test_port(2)  => test_sig(3)
        test_port(3)  => test_sig(4)
        );
函数dim1\u计算(
cmp_指数:整数;
prt_索引:整数
)返回整数为
变量updw:整数:=0;
变量shft_v:整数:=0;
变量结果:整数:=0;
开始
如果(cmp指数<最大值),则
updw:=1;
其他的
updw:=2;
如果结束;
案例prt_指数为
当1=>
shft_v:=cnst_rom(updw)(1)+(i-1);
当2=>
shft_v:=cnst_rom(updw)(2)+(i);
--
--
--
当32=>
shft_v:=cnst_rom(updw)(32)+(i);
当其他人=>
shft_v:=0;
终例;
如果(updw=1),则
如果(shft_v=min_up&(prt_指数mod 2)=0),则
结果b2p(dim1_计算(i,32))(dim2_计算(i,32)),
pn_至_bn=>p2b(i)
);
终端生成;
我知道通常情况下使用太多的顺序语句是不合适的,我会尽量避免使用它们,但在这种情况下,我假设这个函数不会合成成一些真实的硬件,合成器只计算输出值,并将其放入该组件的相应实例化中。我说得对吗?或者,与8000个实例相比,这种编码方式会带来额外的硬件

PS1:最初我使用“0到…”来定义数组的第二维度和第三维度的范围,但由于基于for generate语句参数的维度计算函数中存在混淆,我将它们替换为“1到…”。这是一个好主意!编码风格还是应该避免

PS2:以上代码中的端口映射部分是否有一种方式可以组合成如下内容: (我知道这是大错特错的,这只是我想要的澄清)

gen_pn:for i in(1到pn_num)生成
ins\U pn:pn\U cmpn端口映射(
时钟=>clk,
gen_bn_至_pn:对于j in(1至32)生成
bn_to_pn(j)=>b2p(dim1_计算(i,j))(dim2_计算(i,j)),
终端生成;
pn_至_bn=>p2b(i)
);
终端生成;
让我再举一个例子 假设我有一个如下的组件实例化:

    ins_test : test_comp port map (
        clk          => clk,
        test_port(1)  => test_sig(2)
        test_port(2)  => test_sig(3)
        test_port(3)  => test_sig(4)
        );
有没有一种方法可以在这里生成?比如:

    ins_test : test_comp port map (
        clk          => clk,
        gen_pn : for i in (1 to 3) generate
            test_port(i)  => test_sig(i+1)
        end generate;
        );

PS3:可以在VHDL中调用另一个函数中的函数吗?

函数可以这样使用。如果您遇到问题,我相信他们会关注设计或设计工具中的细节,而不是基本方法

一个潜在的问题是,函数引用了一些外部“事物”,例如
max\u up,i,cnst\u rom
,它们的声明既不是函数的一部分,也不是函数的参数。这使得它成为一个“不纯函数”,因为它引用了外部状态,甚至修改了外部状态,所以对调用它有限制(因为外部状态可能会改变,结果可能取决于评估顺序等)

如果你能使它纯净,那么就这样做。我觉得
max\u up,cnst\u rom
都是常量:如果它们没有在其他地方使用,就声明它们是函数的本地值。而
i
可能应该是一个参数

如果不可能,则将外部声明设为常量,最好将它们和函数包装在一个包中

这将以一种小的、可理解的、可维护的形式生成所需的值,而不是无限量的硬件。我使用了一组复杂的函数来执行浮点运算,然后巧妙地进行范围缩减和整数舍入来初始化查找表,因此从根本上说,这种方法确实有效

潜在陷阱:

一些设计工具在使用完全有效的VHDL时遇到了问题,如果它的使用有点非正统的话。Synplicity无法合成某些形式的函数(生成硬件),尽管通过OUT参数返回结果的等效过程没有问题!。XST要好得多

XST解析我的查找表init的速度慢得离谱,函数调用的数量是二次的。但仅当您使用旧的VHDL解析器(Spartan-3的默认解析器)时。Spartan-6使用了新的解析器,与Modelsim和Isim一样工作正常(不到半小时,只需一秒钟)。(尚未在该项目上尝试Synplicity)

有些工具反对端口映射中的非正统事物:在端口映射中,您可能会忽略函数调用;或者,您可能必须通过使用调用初始化常量并在端口映射中使用这些常量来解决工具错误

以及你的补充质询:

PS1)数组范围的正确编码样式是。。。无论你的意图是什么。 如果你发现自己在心理上被1抵消,感到困惑甚至出错,停止!改进设计

一些好的数组索引样式:

type colour is (red, green, blue);
subtype brightness is natural range 0 to 255;

hue : array (colour) of brightness;
gamma : array (brightness) of brightness;
-- here 0 is a legitimate value
channel : array (1 to 99) of frequency; 
PS2)我想你是在问是否可以嵌套生成语句。对

细节可能是尴尬和困难的,但确实如此

PS3)当然可以!您甚至可以声明其他人的本地函数;消除了他们在某个毫无意义的地方被意外呼叫的可能性。它们(不纯函数)可以访问外部函数(或过程)的执行范围,从而简化参数列表

Q1 - in this case I assumed that this function won't synthesize into some ...  
这取决于你使用的合成器。请参阅下面的相关问题和评论


当然可以。请允许我们在这里发布关于编码风格的建议。(来自)
定义循环参数规范时,可以使用类型(或子类型)定义,也可以使用预定义的对象属性(例如预定义的对象属性)
Q3 - PS2: Is there a way that port mapping part in above code combines into ...  
Q4 - Is it possible to call a function inside another function in VHDL?