比尔李先森

System Verilog学习笔记

0
阅读(3633)

    之前用到是Verilog 但是写过一段时间发现同一个模块同和几次 几次结果都不一样 有时之前是好的 但是之后再次编译时发现 功能和之前的不一样  最后发现综合出来的东西和之前不一样 这是由于verilog 语法不严谨(初学者不好把握  没有几年的功底这个是写不好的 ) 为了使 写出来的代码和自己想要生成的电路是一样的  所以就想学学这个System Verilog (听说这个功能很强大)

    时序电路的关键字:

    always     熟悉Verilog的应该都知道

    always_comb    用于组合电路 自动判断敏感列表  这个只能表示没有存储功能的纯组合逻辑

    always_latch    纯锁存器

    always_ff    跳变沿触发的D触发器    

    例:

        always_comb                 //这个自动加入了敏感列表

        begin

           tmp1 = a & b;

           tmp2 = c & d;

            y = tmp1 | tmp2;

       end

    下面这样就会产生错误,因为它产生了一个锁存器

    always_comb 

         if (en)   q <= 0 ;

    所以这个要用

    always_latch  

      if (en)  q <= d;

    下面的例子又是错误的

    always_latch 

      if (en) q< = d;

      else q <= q;

    因为它产生了一个组合逻辑反馈环  不会生成锁存器

    

    

        always_ff @(posedge clk, negedge rst_n)

          if (!rst_n) q< = 0;

              else  q <= d ;

    对于这个就和原来的always块产生时序逻辑电路一样 但是当敏感列表中为电平敏感时就会出错、

         always_ff  @(clk, rst_n) 

          if (!rst_n) q< = 0;

              else q <= q;

在System V中又有一个关键字 enum    这是一个枚举类型的关键字 对于状态机这个是很有用的

例:一个三段状态机

module fsm_svla_3

(output reg rd,ds,

input      go, ws, clk,rst_n );

 enum   { IDLE  ,

              READ  ,

              DLY    ,

              DONE  ,

              XX   }   state, next;

always @(posedge clk, negedge rst_n)

    if (!rst_n) state <= IDLE;

       else      state <= next;

always @*  begin

  next = xx;

  case (state)

     IDLE:       if (go)    next = READ;

                      else     next = IDLE;

     READ:                  next = DLY;

     DLY:       if (!ws)   next = DONE;

                     else     next = READ;

     DONE:                 next = IDLE;

  end


    

always @(posedge clk, negedge rst_n)

    if (!rst_n) begin

        rd  <= 1’b0;

        ds <= 1’b0;

      end

      else  begin

         rd  <= 1’b0;

         ds <= 1’b0;

         case (next)

             READ:      rd <= 1’b1;

                DLY:      rd <= 1’b1; 

               DONE:    ds <= 1’b1;

          endcase

         end

endmodule

默认情况下 IDLE是从零递增的  这样看起来更直观