硬件描述语言程序:硬件描述语言中的泛型(hardware description languages)

我对 HD 描述语言相当陌生。我发现改变我的 C-ish 编程技能有点困难,我正在寻找一些 guaidance 来帮助我抛出以下问题。

我想实现一个完整的树,它的内部节点不同于它的叶子叶子的数量是通用(asuming 有 2 ^ k 叶子,所以树可以是满的)

每个内部节点都是由简单的组合电路组成的组件。

叶子与时钟同步,并连接到下一个叶子(打破树结构-并形成类似移位寄存器的东西)

这意味着我的设计必须有一个通用数量的组件,根据叶子的数量连接

虽然这可以在基于 C 的语言中立即递归解决。我无法掌握用 HDL 解决它的想法,因为这种通用形式与 n 位输入信号不同...

我的实现必须是可合成的,因此 SystemVerilog 不能在这方面大放异彩:(

是否有可能实现所描述的问题,同时保持我的代码可合成?任何人都可以指导我抛出这个或指向我关于这个主题的一个很好的参考?

2

您可以在 VHDL 中编写一个递归算法,该算法在详细说明期间执行,然后通过generate语句定义要合成的硬件结构。您几乎可以在 Verilog 中做到这一点,Verilog 自 2001 年以来就具有自动功能,但是它们不是完全自动的,而且我认为我在 Verilog 中没有看到任何可用的可合成示例。

张贴一些伪 C,这样我们就可以看到你想要什么。

EDIT参见this paper:它描述了 VHDL 中胖树结构的递归生成。这完全由递归组件实例化处理,而不是使用递归算法来预定义结构。

1

您可能想看看如何在 VHDL 中使用generate语句。将 generate 语句与for语句一起使用将根据需要生成尽可能多的组件。

但是,在构建 FPGA 时必须知道叶子的总数。您不能动态创建叶子。

0

我将尝试提供一个答案,它允许您构建一个泛型树,而无需递归,仅基于在编译时作为泛型提供的树高。对于我的口味来说,代码本身看起来有点棘手;但是,解决方案背后的原则是直截了当的。

想象一下,你的节点将被放置在一个网格上,尺寸为 V = TREE_HEIGHT + 1 和 H = 2 * * TREE_HEIGHT(参见的 ASCII-gram)。

要将树的一个级别连接到下一个级别,可以使用大小为 TREE_HEIGHT x 2 * * TREE_HEIGHT 的二维数组(请参见代码示例中的第 63 行)。

要实例化节点,请使用两个嵌套循环(VHDL 中的for-generate,请参见第 68-69 行)。您不会填充所有节点;对于 depth =i处的给定行,只需要 2 * * (i-1) 个节点(第 71 行)。

您可以为内部和叶节点实例化不同的实体,只需检查i的当前值是否等于 TREE_HEIGHT(第 74 和 84 行)。

最后,你只需要连接树的各层。算术有点棘手,但是一旦你做对了,你就完成了(第 78-80 行)。

依靠您的合成工具来删除未使用的导线。

这是高度 = 2 的“网格”的糟糕表现:

             j = 1           j = 2           j = 3           j = 4      
       +---------------+---------------+---------------+---------------+
i = 1  | Root Node     |    (empty)    |    (empty)    |    (empty)    |
       +---------------+---------------+---------------+---------------+
i = 2  | Internal Node | Internal Node |    (empty)    |    (empty)    |
       +---------------+---------------+---------------+---------------+
i = 3  | Internal Node | Internal Node | Internal Node | Internal Node |
       +---------------+---------------+---------------+---------------+

是代码示例:

/*  1 */  package tree_types_pkg is
/*  2 */      -- define a data type for the input and output values at each node
/*  3 */      subtype tree_data_type is integer range 0 to 255;
/*  4 */      -- define a vector type to propagate the output of a tree level to the next
/*  5 */      type layer_to_layer_channel_type is array (natural range <>) of tree_data_type;
/*  6 */  end;
/*  7 */  --------------------------------------------------------------------------------
/*  8 */  use work.tree_types_pkg.all;
/*  9 */
/* 10 */  entity internal_node is
/* 11 */      generic (
/* 12 */          TREE_HEIGHT: integer := 3
/* 13 */      );
/* 14 */      port (
/* 15 */          x: in integer range 1 to 2**TREE_HEIGHT;
/* 16 */          y: in integer range 1 to TREE_HEIGHT;
/* 17 */          input: in tree_data_type;
/* 18 */          output_left: out tree_data_type;
/* 19 */          output_right: out tree_data_type
/* 20 */      );
/* 21 */  end;
/* 22 */
/* 23 */  architecture rtl of internal_node is begin
/* 24 */      -- perform some calculation at the node
/* 25 */      output_left <= input + x * y;
/* 26 */      output_right <= input - x * y;
/* 27 */  end;
/* 28 */  --------------------------------------------------------------------------------
/* 29 */  use work.tree_types_pkg.all;
/* 20 */
/* 31 */  entity leaf_node is
/* 32 */      generic (
/* 33 */          TREE_HEIGHT: integer := 3
/* 34 */      );
/* 35 */      port (
/* 36 */          x: in integer range 1 to 2**TREE_HEIGHT;
/* 37 */          y: in integer range 1 to TREE_HEIGHT;
/* 38 */          input: in tree_data_type;
/* 39 */          output: out tree_data_type
/* 30 */      );
/* 41 */  end;
/* 42 */
/* 43 */  architecture rtl of leaf_node is begin
/* 44 */      -- perform some calculation at the node
/* 45 */      output <= input + x * y;
/* 46 */  end;
/* 47 */  --------------------------------------------------------------------------------
/* 48 */  use work.tree_types_pkg.all;
/* 49 */
/* 50 */  entity dirtybit_binary_tree is
/* 51 */      generic (
/* 52 */          TREE_HEIGHT: integer := 4
/* 53 */      );
/* 54 */      port (
/* 55 */          tree_input: in tree_data_type;
/* 56 */          tree_outputs: out layer_to_layer_channel_type(1 to 2**TREE_HEIGHT)
/* 57 */      );
/* 58 */  end;
/* 59 */
/* 60 */  architecture behavior of dirtybit_binary_tree is
/* 61 */      constant LEAF_NODES_COUNT: integer := 2**TREE_HEIGHT;
/* 62 */      type channel_array_type is array (natural range <>) of layer_to_layer_channel_type;
/* 63 */      signal connections: channel_array_type(1 to TREE_HEIGHT)(1 to LEAF_NODES_COUNT);
/* 64 */  begin
/* 65 */
/* 66 */      connections(1)(1) <= tree_input;
/* 67 */
/* 68 */      grid_y: for i in 1 to TREE_HEIGHT generate
/* 69 */          grid_x: for j in 1 to LEAF_NODES_COUNT generate
/* 70 */
/* 71 */              instantiate_nodes: if j <= 2**(i-1) generate
/* 72 */
/* 73 */                  internal_nodes: if (i /= TREE_HEIGHT) generate
/* 74 */                      internal_node: entity work.internal_node 
/* 75 */                          generic map (TREE_HEIGHT => TREE_HEIGHT)
/* 76 */                          port map (
/* 77 */                              x => j,
/* 78 */                              y => i,
/* 79 */                              input        => connections(i)(j),
/* 80 */                              output_left  => connections(i+1)((j-1)*i+1),
/* 81 */                              output_right => connections(i+1)((j-1)*i+2)
/* 82 */                          );
/* 83 */                  end generate;
/* 84 */
/* 85 */                  leaf_nodes: if (i = TREE_HEIGHT) generate
/* 86 */                      leaf_node: entity work.leaf_node 
/* 87 */                          generic map (TREE_HEIGHT => TREE_HEIGHT)
/* 88 */                          port map (
/* 89 */                              x => j,
/* 90 */                              y => i,
/* 91 */                              input  => connections(i)(j),
/* 92 */                              output => tree_outputs(j)
/* 93 */                          );
/* 94 */                  end generate;
/* 95 */
/* 96 */              end generate;
/* 97 */
/* 98 */          end generate;
/* 99 */      end generate;
/* 100 */
/* 101 */ end;

最后,以下是 Quartus 12.1(RTL Viewer)上的合成电路:

Tree circuit on Quartus RTL Viewer

0

Verilog(或 VHDL)generate语句可用于创建可伸缩系统,但隐含的硬件数量在编译时是固定的。您不能即时更改有多少硬件。Verilog 的链接生成onetwo

简短示例,将多条电线连接到逆变器

parameter DATA_W = 4;
parameter DEPTH  = 8;
wire [DATA_W-1:0] data   [0:DEPTH-1];
wire [DATA_W-1:0] data_n [0:DEPTH-1];
genvar index;  
generate  
  for (index=0; index < DEPTH; index=index+1) begin: gen_code_label  
    inv #(
      .WIDTH  ( DATA_W        ) 
    ) inv_i0 (  
      .rx     ( data[index]   ), // input  
      .tx     ( data_n[index] ), // output   
    );  
  end  
endgenerate 

我发现生成有时很难遵循,特别是如果使用连接了很多硬件,他们还引入了另一个层次,这往往是不可取的。

对于可伸缩的模板代码,我使用 erb(ruby),使用 gemruby-it
免责声明我编写了 gem 以使其更容易。

Anotherquestion showing use of erb.

本站系公益性非盈利分享网址,本文来自用户投稿,不代表边看边学立场,如若转载,请注明出处

(340)
怎么删除页脚:删除 mailchimp中的页脚
上一篇
脚本语言:脚本语言与编程语言(scripting languages list)
下一篇

相关推荐

  • docker游戏服务器:如何使用Docker搭建高性能的游戏服务器

    Docker游戏服务器是一种将游戏服务器部署到容器中的方式,它可以帮助游戏开发者快速、轻松地部署游戏服务器,并且可以更轻松地扩展游戏服务器的容量。…

    2023-04-27 09:55:33
    0 98 13
  • javascript数组:排序和搜索

    javascript数组是一种特殊的对象,它可以存储多个值,这些值可以是任何类型的数据。JavaScript数组的元素可以通过索引来访问,数组的索引从0开始,每个元素都有一个索引值。…

    2023-08-28 11:30:24
    0 84 37
  • coremail论客邮箱Coremail论客邮箱

    Coremail论客邮箱是一款专业的企业邮箱服务,可以满足企业对安全、可靠性和高效性的要求。它拥有强大的安全性能,可以提供多种安全保护,包括防止邮件被窃取、拦截恶意邮件、防止跨站脚本攻击等。此外,它还支持多种企业级功能,如组织架构管理、收发邮件管理、文件共享管理、联系人管理等,可以帮助企业提高工作效率,提升企业形象。…

    2023-02-25 04:36:55
    0 77 47
  • canvas下载安装:Unleash the Power of Canvas to Create Amazing Visuals

    Canvas是一种HTML5技术,可以在网页上创建和绘制2D图形。它是一个JavaScript API,可以使用JavaScript代码来绘制图形,并且可以添加各种效果,如阴影,渐变,动画等。…

    2023-03-08 00:48:14
    0 20 81
  • class定位:The Benefits of Using Class Selectors for Element Locati

    示例示例class定位是一种CSS布局技术,用于指定HTML元素的位置,可以使元素放置在页面的任何位置。代码示例:…

    2023-03-06 07:16:44
    0 41 95
  • security code怎么填保护您的数据和隐私

    示例示例code是一种防止自动提交表单的安全措施,通常会在表单中显示一个图片,用户需要输入图片中显示的字符。以下是一个简单的 code代码示例:…

    2023-03-20 09:31:54
    0 67 40
  • for循环中的continue:使用continue跳过循环中的某些步骤

    示例示例是 for 循环的一个控制语句,它用于跳过当前循环的剩余代码,然后继续执行下一次循环。下面是一个使用 语句的示例:…

    2023-07-11 15:34:46
    0 25 95
  • javascript 常量:如何利用JavaScript常量提高编程效率

    示例示例常量是一个不可变的值,它的值在声明之后不能更改。它们可以用来存储程序中使用的固定值,并且可以被多次使用。代码示例:…

    2023-06-16 03:01:55
    0 95 50

发表评论

登录 后才能评论

评论列表(30条)