在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 7333|回复: 12

[求助] verilog中generate的疑问

[复制链接]
发表于 2015-4-11 09:46:17 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
for-generate在和外部信号相连时,感觉很奇怪,因为generate中用一个循环就可以很方便生成很多个类似的模块,但是这些端口信号和外部信号相连却要全部逐个赋值。。。。。。有经验的大神请讲解一下呗,谢谢





  1. `timescale 1ns/1ps
  2. `define TWO
  3. module top(
  4.          clk
  5.         ,rst_n
  6.         ,din0
  7.         ,din1
  8.         ,din2
  9.         ,din3
  10.         ,dout0
  11.         ,dout1
  12.         ,dout2
  13.         ,dout3
  14. );

  15. parameter N=4;

  16. input clk;
  17. input rst_n;
  18. input        [3:0]        din0;
  19. input        [3:0]        din1;
  20. input        [3:0]        din2;
  21. input        [3:0]        din3;
  22. output        [3:0]        dout0;
  23. output        [3:0]        dout1;
  24. output        [3:0]        dout2;
  25. output        [3:0]        dout3;


  26. `ifdef ONE

  27. generate

  28.         genvar j;
  29.        
  30.         for(j=0;j<N;j=j+1) begin: fuck
  31.                
  32.                 wire         [3:0]        din;
  33.                 wire        [3:0]        dout;
  34.                
  35.                 gen                                        gen(
  36.                          .clk                                (clk        )
  37.                         ,.rst_n     (rst_n)
  38.                         ,.din       (din        )
  39.                         ,.dout      (dout        )
  40.                 );
  41.         end

  42. endgenerate

  43. assign fuck[0].din = din0;
  44. assign fuck[1].din = din1;
  45. assign fuck[2].din = din2;
  46. assign fuck[3].din = din3;

  47. assign dout0 = fuck[0].dout;
  48. assign dout1 = fuck[1].dout;
  49. assign dout2 = fuck[2].dout;
  50. assign dout3 = fuck[3].dout;

  51. `elsif TWO


  52. wire        [4*N-1:0] din_w;
  53. wire        [4*N-1:0] dout_w;

  54. generate

  55.         genvar j;       
  56.        
  57.         for(j=0;j<N;j=j+1) begin: fuck               
  58.                 gen                                        gen(
  59.                          .clk                                (clk                                                                        )
  60.                         ,.rst_n     (rst_n                                                                )
  61.                         ,.din       (din_w[(j+1)*4-1 : j*4]        )
  62.                         ,.dout      (dout_w[(j+1)*4-1 : j*4])
  63.                 );
  64.         end

  65. endgenerate

  66. assign din_w[3:0]         = din0;
  67. assign din_w[7:4]         = din1;
  68. assign din_w[11:8]         = din2;
  69. assign din_w[15:12] = din3;

  70. assign dout0 = dout_w[3:0]         ;
  71. assign dout1 = dout_w[7:4]         ;
  72. assign dout2 = dout_w[11:8] ;
  73. assign dout3 = dout_w[15:12];

  74. `endif

  75. endmodule


复制代码








  1. [code]`timescale 1ns/1ps


复制代码


module gen(
         clk
        ,rst_n
        ,din
        ,dout
);

//---------------------------------
// parameter
//---------------------------------

parameter PAR = 4'd1;

//---------------------------------
// Input and Output
//---------------------------------

input                                 clk;
input                                 rst_n;
input         [3:0] din;
output         [3:0]        dout;

reg                        [3:0]        dout;

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++

always @(posedge clk,negedge rst_n) begin
        if(!rst_n)
                dout <= 4'd0;
        else
                dout <= din + PAR;
end


endmodule
[/code]
 楼主| 发表于 2015-4-11 09:48:55 | 显示全部楼层
忘了说了,上面的代码已经仿真正确,能够通过ISE综合。
 楼主| 发表于 2015-4-11 10:47:00 | 显示全部楼层
应该有人用过的啊,求指教
发表于 2015-4-11 13:30:42 | 显示全部楼层
信号名也是醉了。。。。。
先看他第一种引用: assign fuck[0].din = din0;  你for的时候,生成很多fuck[n],n就是j的值,那么按照verilog引用模块内信号的原则,module_inst_name.sig 就可以访问例化名“module_inst_name”的模块内部的"sig"信号,那么他用din0赋值给fuck[0].din,就可以把din0引入到第一1个fuck模块的din信号上,往后以此把每一个din都引入到对应fuck[n]的din上,就是这样的。。

他的第二种引用: .din       (din_w[(j+1)*4-1 : j*4]        ),    这是for里例化模块的输入信号,很明显,随着j的不同,计算后,每次选的din_w的bit也不同,你自己计算一次就清楚了,这样就把din_w[15:0]不同的bit分配给了某个fuck模块的din。。。
 楼主| 发表于 2015-4-11 14:28:52 | 显示全部楼层
我知道这段代码什么意思啊,就是我写的,只不过我觉得for  generate对于多个类似模块的生成很有帮助,减小代码量,改个参数就可以实现很好的扩展性,但是和它相连的信号却不能用循环……是不是我太想偷懒了。。。?
 楼主| 发表于 2015-4-11 14:29:43 | 显示全部楼层
回复 4# glace12123


    我知道这段代码什么意思啊,就是我写的,只不过我觉得for&#160;&#160;generate对于多个类似模块的生成很有帮助,减小代码量,改个参数就可以实现很好的扩展性,但是和它相连的信号却不能用循环……是不是我太想偷懒了。。。?
发表于 2015-4-11 21:09:49 | 显示全部楼层
谁说不可以,说来说去只是简化代码的技巧而已,定义
reg [2:0]  Sig [7:0]; 一个二维变量。
现在你有8个sig[2:0]了,那么你在循环里写sig[n],就把sig[0]~ sig[7]对应到每个for里的模块了,定义n为多少,也是可以参数化的。。。。但是,二维变量不能用于输入输出噢,只能是模块内部变量
 楼主| 发表于 2015-4-12 07:30:08 | 显示全部楼层
回复 7# glace12123


    但是如果这种寄存器堆规模比较大,在FPGA中不仅仅消耗的是寄存器资源,同时还有为了给地址和存储内容建立映射关系的查找表,后者是完全没必要的资源浪费呀,而且寄存器堆由很多分散寄存器产生,很容易形成关键路径的吧………不知道我说的有问题没……
发表于 2015-4-12 11:22:04 | 显示全部楼层
回复 8# YoungZ1

我刚才有个错误的东西,那就是,应该用wire去定义二维,不该用reg。。。。反正你是连线而已这样就不会造成寄存器浪费了。。。
还有,别低估FPGA综合器的水平,不是每一种用reg定义的二维数组操作,都会给你综合成RAM实现,大多数情况的综合结果还是多个寄存器实现的。
发表于 2015-4-12 11:23:10 | 显示全部楼层
至于关键路径这种东西,貌似不会因为加寄存器产生吧?  相反,加寄存器恰恰是减少关键路径的方法
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /1 下一条


小黑屋| 手机版| 关于我们| 联系我们| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-12-27 14:17 , Processed in 0.022830 second(s), 9 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表