码迷,mamicode.com
首页 > 其他好文 > 详细

Verilog的非阻塞语句放到顺序块中,综合出来怎样的逻辑电路?

时间:2019-10-01 14:09:06      阅读:101      评论:0      收藏:0      [点我收藏+]

标签:判断   sep   style   alt   clear   center   condition   mic   是什么   

情境:

  FPGA里面计数器需要复位(计数值置零),与计数器状态有关的行为是状态机控制的,即状态机为CLEAR_TIMER状态时,计数器才完成清零动作。

  清零有两个条件:(1)计数器值溢出(达到OVF门限);(2)清零信号有效(1有效)。这两个条件是独立的,没有先后关系的约束。

问题是:如何写Verilog语句,才使得这两个触发的优先级相同?

 

有两个思路:

一个是:

always@(posedge clk)begin
  if(!rst_n)begin
    stat_preload <= STAT_IDLE;
  end
  else begin
    //*** Combined Transition
    if
((tim_cnt >= TIIM_OVF) || (1‘b1 == tim_rst))begin // OR
      stat_preload <= STAT_CLEAR_TIMER;
    end
    else begin
      stat_preload <= stat_preload; // Status Latch
    end
  end
end

另一个:

always@(posedge clk)begin  
  if(!rst_n)begin
    stat_preload <= STAT_IDLE;
  end
  else begin
    //*** Separate Transition
    if
(tim_cnt >= TIM_OVF)begin       stat_preload <= STAT_CLEAR_TIMER;     end     else begin       stat_preload <= stat_preload; // Stay     end     if(1‘b1 == tim_rst)begin       stat_preload <= STAT_CLEAR_TIMER;     end     else begin       stat_preload <= stat_preload; // Stay     end
  end
end

 这两种写法的区别在于:第一种,状态转移语句放在两个条件参与的单个if选择结构里面;第二种,状态转移语句放在分别的两个if选择结构里面。

状态转移图中表现为这样的两种情况:

技术图片

技术图片

实现和测试:

上述两种的代码和综合结果如下:

 

module top(
    rst_n,
    clk,
    X,
    Y,
    din_A,
    dout
    );
    
    //****************************************
    //            Port Def.
    //****************************************
    input wire rst_n;
    input wire clk;
    
    input wire X;  // Conditions
    input wire Y;
    
    input wire[3:0] din_A;
    
    output wire[3:0] dout;
    
    //****************************************
    //            Variables
    //****************************************
    reg[3:0] dout_reg;
    
    //****************************************
    //            Behaviour
    //****************************************
    
    assign dout = dout_reg;
    
    always@(posedge clk)begin
        if(!rst_n)begin
            dout_reg <= 4b0;
        end
        else begin
            if((1b1 == X) || (1b1 == Y))begin
                dout_reg <= din_A;
            end
            else begin
                dout_reg <= dout_reg;
            end
        end
    end
    
endmodule

技术图片

module top(
    rst_n,
    clk,
    X,
    Y,
    din_A,
    dout
    );
    
    //****************************************
    //            Port Def.
    //****************************************
    input wire rst_n;
    input wire clk;
    
    input wire X;  // Conditions
    input wire Y;
    
    input wire[3:0] din_A;
    
    output wire[3:0] dout;
    
    //****************************************
    //            Variables
    //****************************************
    reg[3:0] dout_reg;
    
    //****************************************
    //            Behaviour
    //****************************************
    
    assign dout = dout_reg;
    
    always@(posedge clk)begin
        if(!rst_n)begin
            dout_reg <= 4b0;
        end
        else begin
            if(1b1 == X)begin
                dout_reg <= din_A;
            end
            else begin
                dout_reg <= dout_reg;
            end
            if(1b1 == Y)begin
                dout_reg <= din_A;
            end
            else begin
                dout_reg <= dout_reg;
            end
        end
    end
    
endmodule

技术图片

 

 综合器是Quartus 15.1内置的。

可以看到,第二种写法的综合结果让输入信号X没有驱动逻辑了,这样就与需求不符。

 

原因是什么?

第二种(分开if)情况下,虽然赋值语句都是非阻塞的<=,但是由于if语句放在顺序的begin::end结构内,所以判断和执行都是顺序处理的,状态转移和状态停留操作是一模一样的,所以X条件被省略了。

 

为了验证这个结论,在X,Y两个条件的基础上再加R,S两个条件,进行X,Y,R,S的顺序if,然后查看结果:

module top(
    rst_n,
    clk,
    X,
    Y,
    R,
    S,
    din_A,
    dout
    );
    
    //****************************************
    //            Port Def.
    //****************************************
    input wire rst_n;
    input wire clk;
    
    input wire X;  // Conditions
    input wire Y;
    input wire R;
    input wire S;
    
    input wire[3:0] din_A;
    
    output wire[3:0] dout;
    
    //****************************************
    //            Variables
    //****************************************
    reg[3:0] dout_reg;
    
    //****************************************
    //            Behaviour
    //****************************************
    
    assign dout = dout_reg;
    
    always@(posedge clk)begin
        if(!rst_n)begin
            dout_reg <= 4b0;
        end
        else begin
            if(1b1 == X)begin
                dout_reg <= din_A;
            end
            else begin
                dout_reg <= dout_reg;
            end
            if(1b1 == Y)begin
                dout_reg <= din_A;
            end
            else begin
                dout_reg <= dout_reg;
            end        
            if(1b1 == R)begin
                dout_reg <= din_A;
            end
            else begin
                dout_reg <= dout_reg;
            end
            if(1b1 == S)begin
                dout_reg <= din_A;
            end
            else begin
                dout_reg <= dout_reg;
            end
        end
    end
    
endmodule

技术图片

 

显然,只有S条件有效了。

结论:顺序块begin::end中的语句是顺序执行的。

 

Verilog的非阻塞语句放到顺序块中,综合出来怎样的逻辑电路?

标签:判断   sep   style   alt   clear   center   condition   mic   是什么   

原文地址:https://www.cnblogs.com/YangGuangPu/p/11613954.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!