copy from

http://www.cnblogs.com/linjie-swust/archive/2012/03/27/FPGA_verilog.html

  

在FPGA设计中经常使用到逻辑复制,逻辑复制也用在很多场合。

1.    信号驱动级数非常大,扇出很大,需要增加驱动力

  逻辑复制最常使用的场合时调整信号的扇出。如果某个信号需要驱动后级很多单元,此时该信号的扇出非常大,那么为了增加这个信号的驱动能力,一种办法就是插入多级Buffer,但是这样虽然能增加驱动能力,但是也增加了这个信号的路径延时。

  为了避免这种情况这时可以复制生成这个信号的逻辑,用多路同频同相的信号驱动后续电路,使平均到每路的扇出变低,这样不需要插入Buffer就 能满足驱动能力增加的要求,从而节约该信号的路径延时。如从图1.1到图1.2转变所 示。                                                                                                    图1.1  逻辑复制前

                            图1.2  逻辑复制后

  由于现在综合器都已经非常智能,此种场合的逻辑复制工作大多由综合器完成,不需要人手动调整。各大FPGA厂商的综合器以及第三方综合器都有这种功能。

2.    FPGA中需要做很多重复工作

  在某些FPGA设计中,需要很多重复设计的时候,这时候逻辑复制也就有用了。

  例如:在某个特殊应用场合需要设计方向可以任意改变的240位宽的三态IO管脚。我们先看看常用的一个位宽的三态管脚怎么设计。

module inout_interface(
dat_in,
io_out,
io_dir,
dat_out
);
input dat_in;
input io_dir;
output dat_out;
inout io_out; assign io_out = io_dir ? dat_in : 1'bz;
assign dat_out = io_out; endmodule

  如上述程序所示为单个双向IO口的典型设计代码,中间由IO输入方向控制数据和高阻之间的切换,难题出现了,怎么设计240位宽的双向IO口呢?难道如下列程序所示:

module inout_interface(
dat_in,
io_out,
io_dir,
dat_out
);
input [239 : 0] dat_in;
input [239 : 0] io_dir;
output [239 : 0] dat_out;
inout [239 : 0] io_out; assign io_out = io_dir ? dat_in : 240'bz;
assign dat_out = io_out; endmodule

  显然这样是不行的,因为当io_dir为240位的时候只有当全为0的时候此式才为假,其余时候都为真,显然达不到想要的每个IO都是双向口的设计。

修改代码如下:

module inout_interface(

    dat_in,

    io_out,

    io_dir,

    dat_out

    );

    input  [239 : 0]     dat_in;

    input  [239 : 0]     io_dir;

    output [239 : 0]     dat_out;

    inout  [239 : 0]     io_out;

    assign      io_out[0]  = io_dir[0] ? dat_in[0] : 1'bz;

    assign      dat_out[0] = io_out[0];

    assign      io_out[1]  = io_dir[1] ? dat_in[1] : 1'bz;

    assign      dat_out[1] = io_out[1];

    assign      io_out[2]  = io_dir[2] ? dat_in[2] : 1'bz;

    assign      dat_out[2] = io_out[2];

    .

    .       // 此处略去1万行

    .

    assign      io_out[239]  = io_dir[239] ? dat_in[239] : 1'bz;

    assign      dat_out[239] = io_out[239];

endmodule

  显然这种办法能实现240位宽的独立方向控制IO,但是估计写代码要累死人,有没得更好的办法呢?

  当然有,在verilog2001中有个逻辑复制语法——generate,可以对verilog模块进行无限复制。有了这个模块我们即可轻松通过逻辑复制来达到我们的要求了。

// 单个双向IO实现模块

module  pin_inout(

    indat,

    indir,

    outdat,

    outdatin

    );

    input       indat;

    input       indir;

    inout       outdat;

    output      outdatin;

    assign      outdat   = indir ? indat : 1'bz;

    assign      outdatin = outdat;

endmodule

module inout_interface(

    dat_in,

    io_out,

    io_dir,

    dat_out

    );

    input  [239 : 0]     dat_in;

    input  [239 : 0]     io_dir;

    output [239 : 0]     dat_out;

    inout  [239 : 0]     io_out;

    // 逻辑复制240次

    genvar  i;

    generate

        for(i = 0; i < 240; i = i + 1)

        begin : pin_loop

            pin_inout   pin_inout_inst(

                .indat          (   dat_in[i]       ),

                .indir          (   io_dir[i]       ),

                .outdat         (   io_out[i]       ),

                .outdatin       (   dat_out[i]      )

            );

        end

    endgenerate

endmodule

  由上面代码可看出,巧妙利用verilog语法能减少自身工作量。

3.    总结

  在FPGA设计中有些情况的逻辑复制不需要我们做,但是有些情况的逻辑复制不得不手工完成,因此,熟练掌握verilog语法是设计出好的模型、减少工作量的前提。

FPGA中逻辑复制的更多相关文章

  1. verilog逻辑复制

    本文转自:http://www.cnblogs.com/linjie-swust/archive/2012/03/27/FPGA_verilog.html 在FPGA设计中经常使用到逻辑复制,逻辑复制 ...

  2. FPGA中改善时序性能的方法_advanced FPGA design

    本文内容摘自<advanced FPGA design>对应中文版是 <高级FPGA设计,结构,实现,和优化>第一章中的内容 FPGA中改善时序,我相信也是大家最关心的话题之一 ...

  3. FPGA中的delay与latency

    delay和latency都有延迟的意义,在FPGA中二者又有具体的区别. latency出现在时序逻辑电路中,表示数据从输入到输出有效经过的时间,通常以时钟周期为单位. delay出现在组合逻辑电路 ...

  4. 小梅哥FPGA数字逻辑设计教程——基于线性序列机的TLC5620型DAC驱动设计

    基于线性序列机的TLC5620型DAC驱动设计 目录 TLC5620型DAC芯片概述:    2 TLC5620型DAC芯片引脚说明:    2 TLC5620型DAC芯片详细介绍:    3 TLC ...

  5. FPGA中的时序分析(四)

    常用约束语句说明 关于Fmax      上述是实现Fmax的计算公式,clock skew delay的计算如下图, 就是两个时钟的差值.到头来,影响Fmax的值的大小就是组合逻辑,而Fmax是针对 ...

  6. 【转】关于FPGA中建立时间和保持时间的探讨

      时钟是整个电路最重要.最特殊的信号,系统内大部分器件的动作都是在时钟的跳变沿上进行, 这就要求时钟信号时延差要非常小, 否则就可能造成时序逻辑状态出错:因而明确FPGA设计中决定系统时钟的因素,尽 ...

  7. FPGA中的除法运算及初识AXI总线

    FPGA中的硬件逻辑与软件程序的区别,相信大家在做除法运算时会有深入体会.硬件逻辑实现的除法运算会占用较多的资源,电路结构复杂,且通常无法在一个时钟周期内完成.因此FPGA实现除法运算并不是一个&qu ...

  8. 【转载】FPGA 中的latch 锁存器

    以下这篇文章讲述了锁存器的一些概念和注意事项.原文标题及链接: FPGA 中的latch 锁存器 - 快乐至永远上的博客 - 与非博客 - 与网 http://www.eefocus.com/liuy ...

  9. FPGA中IBERT核的应用(转)

    https://wenku.baidu.com/view/50a12d8b9ec3d5bbfd0a74f7.html (必看)    摘要 IBERT即集成式比特误码率测试仪,是Xilinx专门用于具 ...

随机推荐

  1. UVA 10288 Coupons (概率)

    题意:有n种纸片无限张,随机抽取,问平均情况下抽多少张可以保证抽中所有类型的纸片 题解:假设自己手上有k张,抽中已经抽过的概率为 s=k/n:那抽中下一张没被抽过的纸片概率为 (再抽一张中,两张中,三 ...

  2. 【C#基本功 控件的用法】 Toolbar的用法

    之前从事Labview编程,Labview是一门快速编程的语言,虽然快速,但作为一门语言他灵活性不够,有些方面也不是很给力,就比如 Toolbar labview就没有Toolbar的基础控件,虽然可 ...

  3. WPF中的平移缩放和矩阵变换(TranslateTransform、ScaleTransform、MatrixTransform)

    在WPF中的平移缩放都是通过RenderTransform这个类来实现这些效果的,在这个类中,除了平移和缩放还有旋转.扭曲变换.矩阵变换.这些都差不多的,都是坐标的变换. 这里我就先简单弄个平移和缩放 ...

  4. shell基础复习笔记

    变量的设置 以等号连接,等号两边不能有空格 变量名首个字符必须是英文,可以使用下划线,不能使用标点符号,不能使用bash里的关键字 可以使用转义字符\将特殊符号(如Enter.$.空格.!等)变成一般 ...

  5. C# List 排序

    (转自:http://www.cnblogs.com/bradwarden/archive/2012/06/19/2554854.html) 第一种:实体类实现IComparable接口,而且必须实现 ...

  6. shell编程-变量

    Shell支持自定义变量. 定义变量 定义变量时,变量名不加美元符号($),如: VALUE=“tmp” 注意,变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样.同时,变量名的命名须遵 ...

  7. Foundations of Qt Development 学习笔记 Part1 Tips1-50

    1. 信号函数调用的时候仅仅会发送出信号,所以不需要执行 ,所以对于信号声明就行,但是不需要进行定义. 2. 只有槽函数可以声明为public,private,或者是protected的,而信号不行. ...

  8. 2017.11.18 IAP下载(STM8,PIC,STM32)

    客户要求用IAP下载,mark一下,客户还给了stm32的引导码.仅供参考. 1 PIC单片机的IAP  2 STm32 IAP https://www.cnblogs.com/WeyneChen/p ...

  9. Drools7在Intellij IDEA下的引入静态方法错误提示

    问题 在Intellij IDEA 2016下,默认安装了Drools的插件,但使用Drools7(其他版本应该也有问题)时发现,在DRL文件中引入的静态方法IDEA会提示"Cannot r ...

  10. istreambuf_iterator

    #include <set> #include <stdio.h> #include <iostream> #include <istream> #in ...