从零学verilog系列(3)设计语言和描述方式

                               目录

1、数据流建模

1.1连续赋值

1.1.1显式连续赋值语句

1.1.2隐式 连续赋值语句

1.1.3连续赋值语句使用中的注意事项

2、行为级建模

2.1过程语句(initial、always)

2.1.1 initial过程语句

2.1.2 always过程语句

2.1.3 过程语句使用中的注意事项

2.2语句块

2.2.1串行语句块(begin...end)

2.2.2并行语句块(fork...join)

2.3过程赋值语句(在过程块中的赋值语句=、<=)

2.3.1阻塞赋值语句(=)

2.3.2非阻塞赋值语句(<=)

2.4条件分支语句

2.4.1 if_else语句

2.4.2 case语句

2.5 循环语句(多用于测试仿真)

2.5.1 forever语句

2.5.2 repeat语句

2.5.3 while语句

2.5.4 for语句

3、结构化建模

3.1模块级建模

3.2 门级建模

3.3开关级建

1、数据流建模(通过连续赋值语句进行逻辑描述的建模方式)

1.1连续赋值

        连续赋值语句(assign)只能对连线型(wire等)变量进行赋值,分为显式连续赋值语句、隐式连续赋值语句。

1.1.1显式连续赋值语句

格式如下:

连线型变量类型 位宽 名称

assign #(延时)名称=变量赋值表达式

1.1.2隐式 连续赋值语句

格式如下:

连续型变量类型 赋值驱动强度 位宽 #(延时)名称=变量赋值表达式

(赋值驱动强度和延时是可选项)

//例如:
wire [3:0] a,b,c;
assign #(2,1,3) c = a|b;  //显式



wire [3:0]#(2,1,3) c = a|b;  //隐式


1.1.3连续赋值语句使用中的注意事项

1)赋值目标只能是wire型,且assign连续赋值语句不能出现在过程块中

2)多个连续赋值语句之间是并行关系,与位置顺序无关。

2、行为级建模(从电路外部行为的角度对其进行逻辑描述的建模方式)

2.1过程语句(initial、always)

2.1.1 initial过程语句

格式如下:

initial
    begin
        语句1; 
        语句2;
        ...
        语句n;  
    end       //它在仿真过程中只执行一次,之后就不再执行。



//例:用initial产生测试信号
module initial_tb;
reg  s1;
initial
    begin
               s1=0;
        #10    s1=1;
        #20    s1=0;
        #100   $stop;
    end
endmodule

initial语句常出现于测试代码中,通常用于仿真模块中对激励向量的描述、或用于给reg型变量赋初值。

2.1.2 always过程语句

格式如下:

//例如:
always@(敏感事件列表)
    
        语句块                   //当列表中变量的值改变时,就会引发块内语句的执行

                        /*敏感信号分为边沿触发型、电平触发型两种。
                        电平触发:always@(a or b)
                        边沿触发:always@(posedge clk or negedge rst_n )*/


2.1.3 过程语句使用中的注意事项

1)在过程语句中,被赋值的信号必须定义为reg型

2)用其描述组合逻辑电路时,需把全部的输入的信号写入敏感列表 或always@(*)。

3)用其描述时序逻辑电路时,需把时间信号和部分输入信号写入敏感列表。

2.2语句块(当语句数超过一句时,需采用语句块)

2.2.1串行语句块(begin...end)

begin:块名         //当块内有变量时必须有块名,其他可有可无
    块内声明语句    //其为可选项
        语句1;
        语句2;
        ...
        语句n;    //特点:依据块中的排列顺序逐条执行
end

2.2.2并行语句块(fork...join)

fork:块名         //其只能用于仿真测试程序,不能用于可综合电路程序。
    块内声明语句;
    语句1;
    ...
    语句n;      //块内语句同时执行
join

2.3过程赋值语句(在过程块中的赋值语句=、<=)

2.3.1阻塞赋值语句(=)

变量=表达式

1)在串行语句块中,各条阻塞赋值语句将按照顺序依次执行;在并行语句块中,则同时执行

2)执行顺序:先计算等号右边表达式的值,然后立即将计算的值赋给左边的变量。与仿真时间无关

2.3.2非阻塞赋值语句(<=)

变量<=表达式

1)在串行语句块中,各句并行执行。

2)执行顺序:先计算等号右边表达式的值,然后等待延迟时间的结束,再将计算的值赋给左边的变量。

2.4条件分支语句

2.4.1 if_else语句

//形式1:                              //形式4:
if(条件表达式) 语句块                    if语句中允许多个if语句的嵌套

//形式2:                               if(条件表达式1)                                     
if(条件表达式)                                  if(条件表达式2)
    语句块1;                                         语句块;                           
else                                            else
    语句块2;                                         语句块;
                                        else
//形式3:                                        if(条件表达式3)
if(条件表达式1)                                      语句块;
    语句块1;                                    else
else if(条件表达式2)                                 语句块;
    语句块2;                            //形式多样,不一一列举了
    ...
else if(条件表达式n
    语句块n;
else
    语句块n+1;

注:

1)该语句本身隐含着一种优先级关系,条件表达式的优先级。这也是与case的不同之一。

2)if(a)= if(a==1),(对条件表达式进行判断时默认0、x、z按假处理,1按真处理)

2.4.2 case语句

case(控制表达式)
    值1:语句块1;
    值2:语句块2;
    ...
    值n:语句块n;
    default:语句块n+1;
endcase

//例:用case描述BCD数码管(看下图)
module BCD_decoder(out,in);
input  [3:0] in;
output [6:0] out:
reg [6:0] out;  //out在过程赋值语句always中赋值,得用reg类型赋值
always@(in)
    begin
        case(in)
            4'b0000: out = 7'b1111110;
            4'b0001: out = 7'b0110000;
            4'b0010: out = 7'b1101101;
            4'b0011: out = 7'b1111001;
            4'b0100: out = 7'b0110011;
            4'b0101: out = 7'b1011011;
            4'b0110: out = 7'b1011111;
            4'b0111: out = 7'b1110000;
            4'b1000: out = 7'b1111111;
            4'b1001: out = 7'b1111011;
            default: out = 7'bxxxxxxx;
        endcase
    end
endmodule

            

 

 注:

1)若值1到值n涵盖控制表达式的所有值可不用加default项;若未涵盖则需要加default,否则会产生锁存器

2)值1到值n必须各不相同,且他们的位宽必须与控制表达式位宽相同。(用于比较)

3)casez和casex时case的两种特殊形式:

在casez语句中,如果双方(控制表达式与值项)有一边的某一位的值是z,那么这一位的比较结果为真。

在casex语句中,如果双方(控制表达式与值项)有一边的某一位的值是x或z,那么这一位的比较结果为真。

2.5 循环语句(多用于测试仿真)

2.5.1 forever语句

       表示永久循环,直到遇到系统任务$finish或disable语句。其一般用在initial过程语句中,不能独立写在程序中(与always不同)

//格式:
forever 语句或语句块

//例:用forever语句产生时钟信号
·timescale 1ns/1ns
module forever_tb;
reg clk;
initial
    begin
        clk = 0;
        forever #50 clk = ~clk ;  //产生周期为100ns的时钟
    end
endmodule

2.5.2 repeat语句

//格式:
repeat(循环次数)   语句或语句块(循环体)   //用其产生固定次数的循环

//例:用repeat产生有4个时钟周期的信号
initial
    begin
        clk = 0;
        repeat(8)  clk = ~clk;
    end

2.5.3 while语句

//格式:
while(条件表达式) 语句或语句块  /* 为条件循环,若条件表达式为真,才重复循环执行循环体;
                               若为假,就不执行循环体 */

//例:用while产生时钟信号
initial
    begin
        clk = 0:
        while(1)  #50 clk = ~clk;
    end

2.5.4 for语句

//格式:
for(循环变量赋初值;循环结束条件;循环变量增值)
语句块     

/*先给循环变量赋初值,然后判断循环结束条件,若其为真
则执行语句块(循环体),然后进行循环变量增值操作,
循环至循环结束条件满足时,for语句结束*/

//例:用for语句实现一个8位移位寄存器
module shift_regist(q,d,rst_n,clk);
input            d,clk,rst_n;
output [7:0]    q;
reg [7:0]        q;
integer i;
always@(posedge clk)
        if(!rst_n)
            q <= 8'b00000000;
        else
            begin
                for(i=7;i>0;i=i-1)
                    q[i] <= q[i-1];
                    q[0] <= d;
            end
endmodule
/*i=7时,7>0为真,则q[6]赋值到q[7],i=6时,6>0为真
则q[5]赋值到q[6]...以此类推q[0]赋值到q[1],最后输入
d赋值到q[0];当i=0时,0>0为假,结束for循环。可以看到实现
的是一个移位寄存器功能。*/

for部分循环语句用于可综合设计是需要一定设计经验的,容易出错,不建议在可综合设计中使用。

3、结构化建模

将电路描述成一个分级子模块系统,通过逐层调用这些子模块构成所需系统的描述方法。按照调用子模块的抽象级别分为:模块级建模、门级建模、开关级建模

3.1模块级建模

模块级建模就是模块的调用,第二章已讲。

3.2 门级建模

门级开关级建模相对简单这里就不过多赘述

 3.3开关级建模

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值