Verilog HDL三种建模方式

2020-02-27 21:08发布

       如果总结使用verilog HDL进行建模的各种语法,可以将verilog HDL建模方式简单的归纳为三类:结构化描述方式、数据流描述方式、行为描述方式。一个模块中往往是将三种建模方式混合起来使用,来描述一个完整的功能。这三种建模方式是业界在使用verilog HDL的过程中不断归纳总结出来的,与IEEE 1364-2001的划分方式不太一样。这种简化后的归纳分类十分清晰,更利于掌握Verilog HDL的设计方法。学习笔记将会用四小节来分别介绍这三种建模方式的特点,以及如何使用三种方式混合建模。每小节都会介绍各种建模方式的基本概念,同时会给出详细的示例,便于读者对三种建模方式有一个概括性的了解。笔记中会以博主注的形式,说明一些需要注意的知识点并做一定延伸,并介绍三种建模方式的应用特点。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
8条回答
星星之火红
2020-02-28 10:08
    在前三节分别介绍了结构描述方式、数据流描述方式、行为描述方式这三种建模手段,在实际的设计中,往往是将这三种描述方式混合起来使用。一般而言,对顶层模块,会更多的采用结构描述方式,通过对低层模块的调用来描述顶层模块的功能,当然也会使用到数据流建模和行为建模来描述一些简单的功能,对于一些复杂的逻辑一般是放在低层模块中来实现。对于底层模块,更多的是采用数据流和行为描述方式来描述模块的功能,也会通过调用其它更低层模块来实现更细化的功能。
     下面举例说明使用三种方式混合建模:



[例1]

图1.两输入4bits数值比较器代码:
`timescale 1 ns / 1 ps

//module function is:if data < datb,Value =0;else Value = 1.
module compare(Data,Datb,Value);

input   [3:0]   Data;
input   [3:0]   Datb;
output          Value;
reg               Value;
wire              Value0;
wire              Value1;
wire              Value2;
wire              Value3;

assign Value0 = (Data[0] ^ Datb[0]) ? Data[0] : 1'b1;
assign Value1 = (Data[1] ^ Datb[1]) ? Data[1] : 1'b1;
assign Value2 = (Data[2] ^ Datb[2]) ? Data[2] : 1'b1;
assign Value3 = (Data[3] ^ Datb[3]) ? Data[3] : 1'b1;

always@(Value0 or Value1 or Value2 or Value3)
begin
    if(Value0 == 1'b1)
        Value = 1'b1;
    else if(Value1 == 1'b1)
        Value = 1'b1;
    else if(Value2 == 1'b1)
        Value = 1'b1;
    else if(Value3 == 1'b1)
        Value = 1'b1;
    else
        Value = 1'b0;
end

endmodule



      上例中,通过数据流描述方式和行为描述方式,描述了一个二输入4bits数值比较器。二输入4bits数值比较器的功能为:当Data大于等于Datb时,Value为1;否则Value为0。作为一个底层module,compare模块实现的是一个具体的、较小的功能,不需要例化其他更低层模块。compare模块内部,简单的逻辑可以用数据流描述方式来实现,相对复杂一些的逻辑由行为描述方式来实现,相互搭配使用,使得代码不仅可读性好,而且简洁。



[例2]
                                                                       图2.三输入求最大最小值差额
代码:
//calculate the the result of the max data and min dat
module calc(Dat0,Dat1,Dat2,Result);

input   [3:0]   Dat0;
input   [3:0]   Dat1;
input   [3:0]   Dat2;
output  [3:0]  Result;
reg     [3:0]    MaxDat;
reg     [3:0]    MinDat;
wire               CmpResult0;
wire               CmpResult1;
wire               CmpResult2;

compare U_compare_0(
        .Data (Dat0),
        .Datb (Dat1),
        .Value(CmpResult0));

compare U_compare_1(
        .Data (Dat0),
        .Datb (Dat2),
        .Value(CmpResult1));

compare U_compare_2(
        .Data (Dat1),
        .Datb (Dat2),
        .Value(CmpResult2));

always@(CmpResult0 or CmpResult1 or CmpResult2 or Dat0 or Dat1 or Dat2)
begin
    case({CmpResult0,CmpResult1,CmpResult2})
        3'b110  : MaxDat = Dat0;
        3'b111  : MaxDat = Dat0;
        3'b001  : MaxDat = Dat1;
        3'b011  : MaxDat = Dat1;
        3'b000  : MaxDat = Dat2;
        3'b100  : MaxDat = Dat2;
        default  : MaxDat = Dat0;
    endcase
end

always@(CmpResult0 or CmpResult1 or CmpResult2 or Dat0 or Dat1 or Dat2)
begin
    case({CmpResult0,CmpResult1,CmpResult2})
        3'b000  : MinDat = Dat0;
        3'b001  : MinDat = Dat0;
        3'b100  : MinDat = Dat1;
        3'b110  : MinDat = Dat1;
        3'b011  : MinDat = Dat2;
        3'b111  : MinDat = Dat2;
        default  : MinDat = Dat2;
    endcase
end

assign Result = MaxDat - MinDat;
endmodule



         上例中实现的功能是三数据输入计算最大最小值的差值,模块内三种建模方式都使用到了。通过例化三个数值比较器(结构化建模),比较出三个数值的相对大小,然后通过分析数值比较的结果获得最大值和最小值(使用行为描述方式),最后使用数据流描述方式完成减法运算。通过上次可以看出,对于相对复杂的逻辑,用行为描述方式更为方便,而对于简单的逻辑,使用数据流描述方式就可以了。灵活的应用三种建模方式,就可以写出高效、易读、简洁的代码了。

一周热门 更多>