谷动谷力

 找回密码
 立即注册
查看: 1185|回复: 0
打印 上一主题 下一主题
收起左侧

【Verilog】for循环的综合实现

[复制链接]
跳转到指定楼层
楼主
发表于 2023-9-21 21:35:49 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
【Verilog】for循环的综合实现


1.采用for循环来计算1的数量  

采用for循环语句,逐个bit位判断是否为1,为1则累加,否则保持不变,最终输出输入信号中1的数量。

       很多朋友认为如下for循环是不可综合的,实际上并非如此。      
  1. module try_top #(
  2.     parameter   DATA_WIDTH    =       8                                       ,   //
  3.     parameter   CNT_WIDTH     =       ($clog2(DATA_WIDTH)+1)                      //
  4. )
  5. (

  6.     input                                               clk                                     ,   //
  7.     input                                               rst_n                                   ,   //
  8.     input               [DATA_WIDTH-1:0]                data_in                                 ,   //
  9.     output  reg         [CNT_WIDTH-1:0]                 one_cnt                                     //

  10. );


  11. always@(*) begin
  12.     one_cnt  =    'b0             ;   
  13.     for(int i=0; i<DATA_WIDTH;i=i+1) begin : one_cnt_gen
  14.         if(data_in[i])
  15.         one_cnt             =          one_cnt + 1'b1    ;  
  16. else
  17.         one_cnt             =          one_cnt         ;   
  18.     end
  19. end

  20. endmodule
复制代码

综合实现--实际就是一团组合逻辑     
  1. module try_top ( clk, rst_n, data_in, one_cnt );
  2. input [7:0] data_in;
  3. output [3:0] one_cnt;
  4. input clk, rst_n;
  5. wire   n12, n13, n14, n15, n16, n17, n18, n19, n20, n21, n22;

  6. NAND3_X1N_*Cell_TYPE*   U12 ( .A(n22), .B(n14), .C(n13), .Y(n20) );
  7. AND2_X1N_*Cell_TYPE*   U13 ( .A(n14), .B(n13), .Y(n21) );
  8. OA1B2_X1N_*Cell_TYPE*   U14 ( .B0(n14), .B1(n13), .A0N(n21), .Y(one_cnt[0])
  9.          );
  10. ADDF_X1N_*Cell_TYPE*   U15 ( .A(data_in[7]), .B(data_in[6]), .CI(n12), .CO(
  11. n17), .S(n14) );
  12. ADDF_X1N_*Cell_TYPE*   U16 ( .A(data_in[1]), .B(data_in[0]), .CI(data_in[2]),
  13. .CO(n16), .S(n12) );
  14. ADDF_X1N_*Cell_TYPE*   U17 ( .A(data_in[3]), .B(data_in[5]), .CI(data_in[4]),
  15. .CO(n15), .S(n13) );
  16. ADDF_X1N_*Cell_TYPE*   U18 ( .A(n17), .B(n16), .CI(n15), .CO(n18), .S(n22) );
  17. INVP_X1R_*Cell_TYPE*   U19 ( .A(n18), .Y(n19) );
  18. NOR2_X1F_*Cell_TYPE*   U20 ( .A(n20), .B(n19), .Y(one_cnt[3]) );
  19. AOI21_X1N_*Cell_TYPE*  U21 ( .A0(n20), .A1(n19), .B0(one_cnt[3]), .Y(
  20. one_cnt[2]) );
  21. OA21_X1N_*Cell_TYPE*   U22 ( .A0(n22), .A1(n21), .B0(n20), .Y(one_cnt[1]) );
  22. endmodule
复制代码

                     

2.综合实现解读


综合工具基本原理也是for循环不断计算,提取电路结构,只不过最后一级for循环的电路结果会覆盖之前的计算结果,for循环结束,电路结构也就确定了。因此综合工具要求for循环的次数一定是固定值,而不能是个变量。此处需要注意的是:除了协议中明确规定是属于测试类的语法格式,其他语法格式理论上都是可以综合的,关键在于综合工具是否支持。所以是否可综合完全取决于综合工具的版本迭代。     
   
3.人工实现解读

刚才说过了综合工具的实现方式,接下来我们试试人工翻译for循环。为了简化分析流程,以DATA_WIDTH为2为例进行讲解。首先进行穷举操作,列出所有的情况,因为dat_in只有2bit,所以本案例中只有4种情况,然后计算cnt_one的表达式,将cnt_one的表达式进行逻辑化简,最终得出电路图。        
         
data_in[1]data_in[0]cnt_one[1]cnt_one[0]求值表达式
0000NA
0101cnt_one[0]=(!data_in[1])&&data_in[0]
1001cnt_one[0]=(data_in[1])&&(!data_in[0])
1110cnt_one[1]=(data_in[1])&&(data_in[0])
         


来源:IC的世界


+10
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|深圳市光明谷科技有限公司|光明谷商城|Sunshine Silicon Corpporation ( 粤ICP备14060730号|Sitemap

GMT+8, 2024-11-17 11:03 , Processed in 0.271595 second(s), 42 queries .

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表