小梅哥Xilinx FPGA学习笔记9——语法(阻塞与非阻塞赋值)

注意

阻塞赋值与非阻塞赋值,只有在时序逻辑中才有

//不是阻塞赋值,也不是非阻塞赋值,因为是组合电路
always@(a,b,c)begin //相当于always@(*)
        case({a,b,c})//位拼接,{a,b,c}三位信号
            3'b000:out = 8'b0000_0001;
            3'b001:out = 8'b0000_0010;
            3'b010:out = 8'b0000_0100;
            3'b011:out = 8'b0000_1000;
            3'b100:out = 8'b0001_0000;
            3'b101:out = 8'b0010_0000;//3'd5 :out = 8'b0010_0000
            3'b110:out = 8'b0100_0000;
            3'b111:out = 8'b1000_0000;           
        endcase

阻塞赋值

1.阻塞赋值属于顺序执行,即下一条语句执行前,当前语句一定会执行完毕。
2.阻塞赋值语句使用等号 = 作为赋值符。
3.前面的仿真中,initial 里面的赋值语句都是用的阻塞赋值。

1.设计文件

module block_nonblock(clk,reset_n,a,b,c,out
    );
    input clk;
    input reset_n;
    input a,b,c;
    output reg [1:0] out;
    reg [1:0] d;
//阻塞赋值
    always@(posedge clk or negedge reset_n)
    if(!reset_n)begin
        out =2'b0;
        d =0;    
    end
    else begin
        d =a+b;
        out =d+c;
    end
    
endmodule

2.激励文件

`timescale 1ns / 1ns //时间刻度 时间的单位/ 1ns精度
`define clk_period 20
module block_nonblock_tb( );

    reg clk;
    reg reset_n;
    reg a,b,c;
    wire [1:0] out;
    
    
    block_nonblock block_nonblock(
     .clk(clk),
     .reset_n(reset_n),
     .a(a),
     .b(b),
     .c(c),
     .out(out)
    );
    initial clk=1;
    always#(`clk_period/2) clk=~clk;
    
    initial begin
        reset_n=1'b0;
        a=0;b=0;c=0;
        
        #(`clk_period*200+1);
        reset_n=1'b1;
        #(`clk_period*200);
        a=0;b=0;c=0;
        #(`clk_period*200);
        a=0;b=0;c=1;
        #(`clk_period*200);
        a=0;b=1;c=0;
        #(`clk_period*200);
        a=0;b=1;c=1;
        #(`clk_period*200);
        a=1;b=0;c=0;
        #(`clk_period*200);
        a=1;b=0;c=1;
        #(`clk_period*200);
        a=1;b=1;c=0;
        #(`clk_period*200);
        a=1;b=1;c=1;
        #(`clk_period*200);
        $stop;  
    end
endmodule

3.原理图

在这里插入图片描述

4.仿真图

在这里插入图片描述

非阻塞赋值

1.非阻塞赋值属于并行执行语句,即下一条语句的执行和当前语句的执行是同时进行的,它不会阻塞位于同一个语句块中后面语句的执行。
2.非阻塞赋值语句使用小于等于号 <= 作为赋值符。

1.设计文件

第一种方法

module block_nonblock(clk,reset_n,a,b,c,out
    );
    input clk;
    input reset_n;
    input a,b,c;
    output reg [1:0] out;
    reg [1:0] d;
    
//非阻塞赋值
    always@(posedge clk or negedge reset_n)
    if(!reset_n)begin
        out <=2'd0;
        d<=0;    
    end
    else begin
        d<=a+b;
        out<=d+c;
        
//        d<= #2 a+b;//延迟2s,没有实际的电路,综合的时候会忽略,模拟传输延迟方便仿真使用,调试更加方便
//        out<= #2 d+c;
        
//        out<=a+b+c;//(数学上相等,电路上不相等)
    end
endmodule

第二种方法

module block_nonblock(clk,reset_n,a,b,c,out
    );
    input clk;
    input reset_n;
    input a,b,c;
    output reg [1:0] out;
    reg [1:0] d;
    
//两个always将out与d分开写    
    always@(posedge clk or negedge reset_n)
    if(!reset_n)begin
        out <=2'd0;  
    end
    else begin
        out<=d+c;
    end

    always@(posedge clk or negedge reset_n)
    if(!reset_n)begin
        d<=0;   
    end
    else begin
        d<=a+b;
    end

endmodule

2.激励文件

//同阻塞赋值的testbench

3.原理图

生成了d[1:0]和out[1:0]两个寄存器
在这里插入图片描述

4.仿真图

在这里插入图片描述
对上图中的红色部分放大如下
在这里插入图片描述
在非阻塞赋值的情况下,在16,020ns时刻,out[1:0]的值是计算前一个时刻16,000ns的d[1:0]和c值;
16,000ns时刻的d[1:0]等于15,980ns的a+b的值;
非阻塞赋值,均是上一时钟的赋值。

后记:事常与人违,事总在人为。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值