Vivado Verilog 阻塞赋值与非阻塞赋值

本文详细介绍了在Vivado中使用FPGA进行计数器、可控线性序列机、参数化设计和译码器的实现,重点对比了阻塞赋值和非阻塞赋值的区别,并通过代码示例展示了它们在时序逻辑中的行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Vivado 摸鱼记录 Day_7  (ง ˙o˙)ว

1. review

         day_6  day_5的补充 Vivado 从计数器到可控线性序列机 B-优快云博客

         day_5  从计数器到可控线性序列机 A  Vivado 从计数器到可控线性序列机 A-优快云博客

         day_4  参数化设计 Vivado 时序逻辑 点灯带师 流水灯 参数化-优快云博客

         day_3  实现单个led Vivado 时序逻辑 计数器-优快云博客

         day_2  译码器 Vivado 3-8译码器 4-16译码器-优快云博客

         day_1  Vivado使用流程  Vivado 使用流程 二选一数据选择器-优快云博客

2.  阻塞赋值(=)  与  非阻塞赋值(<=)

        阻塞赋值(=):依次执行

        非阻塞赋值(<=):同时执行  //注意实例中的参数d

        //举个栗子   实现 d = a + b ;  out_1 = a + b + c ; out_2 = d + c ;

        //来see see 结果如何叭(ง ˙o˙)ว       

3.  阻塞赋值(=) 

3.1 design sources        

block_1

module block_1(input clk , input reset_n , input a , input b , input c ,
             output reg[1:0]d , output reg[1:0]out);

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

block_2
module block_2(input clk , input reset_n , input a , input b , input c ,
               output reg[1:0]d , output reg[1:0]out);
    
    always@(posedge clk or negedge reset_n)
        if(!reset_n)
           begin  out <= 0 ; d <= 0 ; end
        else  
            begin   
                out = d + c ;    
                d = a + b ;
            end
endmodule
block_3
module block_3(input clk , input reset_n , input a , input b , input c , 
               output reg[1:0]d , output reg[1:0]out);
    
    always@(posedge clk or negedge reset_n)
        if(!reset_n)
            begin  out <= 0 ; d <= 0 ; end
        else  
            begin   
                d = a + b ;
                out = d + c ;    
               
            end
endmodule
block_4

module block_4(input clk , input reset_n , input a , input b , input c ,
             output reg[1:0]d , output reg[1:0]out);

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

3.2 simulate sources      

`timescale 1ns / 1ns
module block_tb();
    reg clk , reset_n , a , b , c ;
    wire [1:0]d_b1 ;
    wire [1:0]d_b2 ;
    wire [1:0]d_b3 ;
    wire [1:0]d_b4 ;
    wire [1:0]out_b1 ;
    wire [1:0]out_b2 ;
    wire [1:0]out_b3 ;
    wire [1:0]out_b4 ;
    block_1 t_1(.clk(clk) , .reset_n(reset_n) , .a(a) , .b(b) , .c(c) ,
             .d(d_b1) , .out(out_b1));
    block_2 t_2(.clk(clk) , .reset_n(reset_n) , .a(a) , .b(b) , .c(c) ,
             .d(d_b2) , .out(out_b2));
    block_3 t_3(.clk(clk) , .reset_n(reset_n) , .a(a) , .b(b) , .c(c) ,
             .d(d_b3) , .out(out_b3));         
    block_4 t_4(.clk(clk) , .reset_n(reset_n) , .a(a) , .b(b) , .c(c) ,
             .d(d_b4) , .out(out_b4));       
             
    initial  clk = 1 ;
    always #10 clk = ~clk ;
    initial
        begin
            reset_n = 0 ; 
            #21;
            reset_n = 1 ;
            a = 0 ; b = 1 ; c = 1 ;
            #219;
            a = 1 ; b = 1 ; c = 0 ;
            #200;
            a = 1 ; b = 1 ; c = 1 ;
            #200;
            $stop;
        end       

endmodule

对比结果发现:

        阻塞赋值下四种情况的d的结果是一致的

         block_1 block_2 的输出保持一致

         block_3 block_4 的输出保持一致

        其中, block_1 block_2 相对于 block_3 block_4在前两个状态下out存在一个时钟周期的延迟

        即 out = d + c ; d = a + b ;   d = a + b ; out = d + c ;      在阻塞赋值下是依次进行的

4.  非阻塞赋值(<=)

4.1 design sources

nonblock_1

module nonblock_1(input clk , input reset_n , input a , input b , input c ,
             output reg[1:0]d , output reg[1:0]out);

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

nonblock_2
module nonblock_2(input clk , input reset_n , input a , input b , input c ,
               output reg[1:0]d , output reg[1:0]out);
    
    always@(posedge clk or negedge reset_n)
        if(!reset_n)
           begin  out <= 0 ; d <= 0 ; end
        else  
            begin   
                out <= d + c ;    
                d <= a + b ;
            end
endmodule
nonblock_3
module nonblock_3(input clk , input reset_n , input a , input b , input c , 
               output reg[1:0]d , output reg[1:0]out);
    
    always@(posedge clk or negedge reset_n)
        if(!reset_n)
            begin  out <= 0 ; d <= 0 ; end
        else  
            begin   
                d <= a + b ;
                out <= d + c ;    
               
            end
endmodule
nonblock_4

module nonblock_4(input clk , input reset_n , input a , input b , input c ,
             output reg[1:0]d , output reg[1:0]out);

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

4.2 simulate sources      

`timescale 1ns / 1ns
module block_tb();
    reg clk , reset_n , a , b , c ;
    wire [1:0]d_n1 ;    wire [1:0]d_n2 ;    wire [1:0]d_n3 ;    wire [1:0]d_n4 ;    
    wire [1:0]out_n1 ;    wire [1:0]out_n2 ;    wire [1:0]out_n3 ;    wire [1:0]out_n4 ;
     nonblock_1 t_n1(.clk(clk) , .reset_n(reset_n) , .a(a) , .b(b) , .c(c) ,
             .d(d_n1) , .out(out_n1));
    nonblock_2 t_n2(.clk(clk) , .reset_n(reset_n) , .a(a) , .b(b) , .c(c) ,
             .d(d_n2) , .out(out_n2));
    nonblock_3 t_n3(.clk(clk) , .reset_n(reset_n) , .a(a) , .b(b) , .c(c) ,
             .d(d_n3) , .out(out_n3));         
    nonblock_4 t_n4(.clk(clk) , .reset_n(reset_n) , .a(a) , .b(b) , .c(c) ,
             .d(d_n4) , .out(out_n4));   
             
    initial  clk = 1 ;
    always #10 clk = ~clk ;
    initial
        begin
            reset_n = 0 ; 
            #21;
            reset_n = 1 ;
            a = 0 ; b = 1 ; c = 1 ;
            #219;
            a = 1 ; b = 1 ; c = 0 ;
            #200;
            a = 1 ; b = 1 ; c = 1 ;
            #200;
            $stop;
        end       

endmodule

对比结果发现:

        阻塞赋值下四种情况的 d 的结果是一致的 out 也是一致的

Q:为什么前两个状态下与阻塞赋值的out = d + c ; d = a + b ;结果相同呢?

A:对于非阻塞赋值,d <= a + b ; out <= d + c ;    两个语句是同时进行的,

        假设 a = 1 ; b = 0 ; c = 1 ; d = 0 ; out = 0 ;

      对于 d   : d_next <= a + b ;       d_next = 1 ;

      对于out : out_next <= d + c ;    out_next = 0 + 1 = 1 ;

      //感谢弹幕大佬解惑

【【零基础轻松学习FPGA】小梅哥Xilinx FPGA基础入门到项目应用培训教程】 【精准空降到 13:52】 https://www.bilibili.com/video/BV1va411c7Dz/?p=11&share_source=copy_web&vd_source=c913493e4c5ee20b3da6566b27024104&t=832

5. 小结

        组合逻辑电路用阻塞赋值=

        其他情况下用非阻塞赋值<=

//摸鱼结束 (ง ˙o˙)ว        

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值