zoukankan      html  css  js  c++  java
  • verilog逻辑复制

     本文转自: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语法是设计出好的模型、减少工作量的前提。


    made by qidaiYMM, your comment is appreciated.

    email:1519882610@qq.com

  • 相关阅读:
    ArcGIS 网络分析[8.1] 资料1 使用AO打开或创建网络数据集之【打开】
    【AO笔记】Addins的Toolbar 添加一条分割线
    ArcGIS 网络分析[4] 网络数据集深入浅出之连通性、网络数据集的属性及转弯要素
    ArcGIS 网络分析[2.5] VRP(车辆配送)【较难】
    ArcGIS 网络分析[2.4] OD成本矩阵
    Python中time模块详解
    python 读取文件、并以十六进制的方式写入到新文件
    【C++程序员学 python】python 之奇葩地方
    【C++程序员学 python】python 之变量
    校验值的计算----移位算法
  • 原文地址:https://www.cnblogs.com/qidaiymm/p/4888355.html
Copyright © 2011-2022 走看看