• CPLD/FPGA/Verilog_Verilog指令_assign用法


    转自:http://blog.csdn.net/yangtalent1206/article/details/6422701

    一、引入语法的概念

     1、只有寄存器类型的信号才可以在always和initial 语句中进行赋值,类型定义通过reg语句实现。
      2、always 语句是一直重复执行,由敏感表(always 语句括号内的变量)中的变量触发。
      3、always 语句从0 时刻开始。
      4、在begin 和end 之间的语句是顺序执行,属于串行语句。

     

    二、总结下几种assign用法:

    1.作为信号量输出,通过寄存器连续赋值

    output [3:0]oLED;


    //internal signal


    reg [3:0]sr_LED; //用独热码表示LED亮灯位置。


    assign  oLED[3:0] = ~ sr_LED[3:0]; //向LED灯接口输出信号。

    2.作为信号量输出,通过寄存器拼接数据位实现。

     

    output [15: 0] oSI_DATA;


    //internal signal

      reg [ 3: 0] s_HEX;

      reg [ 7: 0] s_SEGBINARY; // s_SEGBINARY[2] should be the DOT

      reg [ 3: 0] s_SEG_SEL;


    assign oSI_DATA = {iLED_SEL,s_SEG_SEL,s_SEGBINARY};

    3.作为信号量输出,通过判断条件,赋值给信号

     

     

    output[ 1: 0] oSEG_STATE;

    output        oCP_PLUSE;

    wire s_CNTEQCYCLE; 


    parameter PARAM_7SEG_CYCLE = 32'd2500000;


    reg [ 1: 0] sr_SEG_STATE;

    reg [31: 0] sr_cnt;

    reg         sr_cp_pluse;  

    assign oSEG_STATE = sr_SEG_STATE;

    assign oCP_PLUSE = sr_cp_pluse;

     

    assign s_CNTEQCYCLE = ( sr_cnt == PARAM_7SEG_CYCLE ) ? 1 : 0;

     

     

     

    4.作为输出信号量,通过输入信号量赋值给输出,同样可以输入信号量和寄存器组合逻辑,赋值给输出信号量。
    input        iCLK50M;
    input        iCP_PULSE;
    input[15:0]  iSI_DATA;
    output       oSI;
    output       oCP;
    reg [ 3: 0] sr_cnt;
    reg [15: 0] sr_si_data;
    reg sr_cp;
    reg sr_en;
    assign oSI = sr_si_data[15];
    assign oCP = sr_en & iCLK50M;
    三、对比输出寄存器变量和信号量

    下面是功能相同但写法不同的两段代码:

    第一段A

    module assign_test_a (
                           clk,
                           lhold,
                           lholda
    );

    input clk;
    input lhold;
    output lholda;

    reg lholda;

    always @(posedge clk)
    if (lhold)
     lholda<=lhold;
    else
     lholda<=0;

    endmodule


    第二段B
    module assign_test_b (
                           clk,
                           lhold,
                           lholda
    );
    input clk;
    input lhold;
    output lholda;

    reg lholda_r;
      always @(posedge clk)
      if (lhold)
         lholda_r<=lhold;
      else
         lholda_r<=0;

     assign  lholda=lholda_r;
    endmodule

     

    两端代码生成的电路时一样的,没有区别,只是在应用上有区别


    第一段A分析

     

     


    第二段B的分析

    Quartus RTL图

      加入assign风格的综合结果


    Xillinx RTL图

     

    分析:

    1. 从代码角度来看。 A是直接把内部reg信号做为输出,因此相对外部来说,外部信号引脚lholda没有选择的连接到reg输出信号。 这里其实暗含了用根导线直接把reg的输出与lholda连接起来。因此B代码就是把这个暗含的明显化。因此他们的RTL没有多大区别。
    2. 从实用角度来说,这里的意义比较大。当内部有多个信号需要输出,可是输出引脚只有一个,那么这时就可以进行选择。如下:
    assign  lholda= (条件)? (lholda_ra): lholda_rb;  可以嵌套使用。
       或者在这种情况下也非常有用。
         Lholda 与 内部的reg输出lholda_ra, lholda_rb,…., 存在逻辑函数关系。


  • 相关阅读:
    二分与三分
    NOIP应试技巧
    数论
    并差集
    最短路
    图的遍历

    最小生成树
    树状数组
    线段树
  • 原文地址:https://www.cnblogs.com/youngforever/p/3104745.html
Copyright © 2020-2023  润新知