zoukankan      html  css  js  c++  java
  • 4.3 Verilog练习(1)

    以后所有和FPGA相关的开发环境都为Vivado

    目录

    练习一.简单的组合逻辑设计

    练习二. 简单时序逻辑电路的设计

    练习三. 利用条件语句实现较复杂的时序逻辑电路

    练习四. 设计时序逻辑时采用阻塞赋值与非阻塞赋值的区别

     


    练习一.简单的组合逻辑设计

    这是一个可综合的数据比较器,很容易看出它的功能是比较数据a与数据b,如果两个数据相同,则给出结果1,否则给出结果0。在Verilog HDL中,描述组合逻辑时常使用assign结构。注意equal=(a==b)?1:0,这是一种在组合逻辑实现分支判断时常使用的格式。

    // compare.v
    
    `timescale 1ns / 1ns
    /*
    1. `timescale 1ns / 1ps,含义为:时延单位为1ns,时延精度为1ps。
    ​2. 在编译过程中,`timescale会影响其后面所有模块中的时延值,直至遇到另一个`timescale指令或`resetall指令。
    3. 当一个设计中的多个模块带有自身的`timescale编译指令时,模拟器将定位在所有模块的最小时延精度上,并且所有时延都相应地换算为最小时延精度。
    */
    module compare(a,b,equal);
        input a,b;
        output equal;
        
        assign equal=(a==b)?1:0;
        
    endmodule
    
    // simu_compare.v
    
    `timescale 1ns / 1ns
    module simu_compare;
        reg a,b;
        wire equal;
        initial
        begin
            a=0;
            b=0;
          #100 a=0;b=1;
          #100 a=1;b=1;
          #100 a=1;b=0;
          #100 $stop;
         end     
         compare u1(.equal(equal),.a(a),.b(b));
    endmodule
    

    练习二. 简单时序逻辑电路的设计

    在Verilog HDL中,相对于组合逻辑电路,时序逻辑电路也有规定的表述方式。在可综合的Verilog HDL模型,我们通常使用always块和 @(posedge clk)或 @(negedge clk)的结构来表述时序逻辑。下面是一个1/2分频器的可综合模型。

    //half_clk.v
    
    `timescale 1ns / 1ps
    module half_clk(reset,clk_in,clk_out);
        input reset;
        input clk_in;
        output clk_out;
        reg clk_out;
        
        always@(posedge clk_in)
        begin
            if(!reset)  clk_out = 0;
            else clk_out = ~clk_out;
        end
    endmodule
    
    //simu_half_clk.v
    
    `timescale 1ns / 1ps
    `define clk_cycle 50
    
    module simu_half_clk;
    reg clk,reset;
    wire clk_out;
    
    always #`clk_cycle clk = ~clk;
    
    initial 
        begin
                clk = 0;
                reset = 1;
           #100 reset = 0;
           #100 reset = 1;
           #1000 $stop;
        end
        half_clk  u1(.reset(reset),.clk_in(clk),.clk_out(clk_out));
    endmodule
    

    练习三. 利用条件语句实现较复杂的时序逻辑电路

    与常用的高级程序语言一样,为了描述较为复杂的时序关系,Verilog HDL提供了条件语句供分支判断时使用。在可综合风格的Verilog HDL模型中常用的条件语句有if…else和case…endcase两种结构,用法和C程序语言中类似。两者相较,if…else用于不很复杂的分支关系,实际编写可综合风格的模块、特别是用状态机构成的模块时,更常用的是case…endcase风格的代码。这一节我们给的是有关if…else的范例,有关case…endcase结构的代码已后会经常用到。

    下面给出的范例也是一个可综合风格的分频器,是将10M的时钟分频为500K的时钟。基本原理与1/2分频器是一样的,但是需要定义一个计数器,以便准确获得1/20分频

    //fdivision.v
    
    `timescale 1ns / 100ps
    module fdivision(
        input F10M,
        output F500K
        );
        reg F500K;
        reg [7:0] j;
        initial
        begin
        F500K <= 0;
        j = 0;
        end
        
        always @(posedge F10M)
          if(j != 19)
                j <= j+1;
           else
                begin
                j <= 0;
                F500K <= ~F500K; 
                end
    endmodule
    
    //fdivison_simu.v
    
    
    `timescale 1ns / 100ps
    `define clk_cycle 50
    
    module fdivison_simu;
    reg F10M_clk;
    wire F500K_clk;
    always #`clk_cycle  F10M_clk = ~F10M_clk;
    initial 
        begin
         F10M_clk = 0;
         end
         
    fdivision fdivision1(.F10M(F10M_clk),.F500K(F500K_clk));
    endmodule
    

    仿真的时候试了几次发现结果都不对,runtime总是在1000ns就停了。更改simulation setting的runtime = 10000后 结果就对了

    练习四. 设计时序逻辑时采用阻塞赋值与非阻塞赋值的区别

    目的:1.明确掌握阻塞赋值与非阻塞赋值的概念和区别;2.了解阻塞赋值的使用情况。

    阻塞赋值与非阻塞赋值,在教材中我们已经了解了它们之间在语法上的区别以及综合后所得到的电路结构上的区别。在always块中,阻塞赋值可以理解为赋值语句是顺序执行的,而非阻塞赋值可以理解为赋值语句是并发执行的。实际的时序逻辑设计中,一般的情况下非阻塞赋值语句被更多地使用,有时为了在同一周期实现相互关联的操作,也使用了阻塞赋值语句。(注意:在实现组合逻辑的assign结构中,无一例外地都必须采用阻塞赋值语句。

    下例通过分别采用阻塞赋值语句和非阻塞赋值语句的两个看上去非常相似的两个模块blocking.v和non_blocking.v来阐明两者之间的区别。

       

    // Module Name: blocking.v
    
    `timescale 1ns / 1ps
    module blocking(
        input clk,
        input [3:0] a,
        output [3:0]  b,c
         );
        
        reg  [3:0] b,c;
        always @(posedge clk)
          begin
            b = a;
            c = b;
            $display("Blocking: a = %d, b = %d, c = %d.",a,b,c);
          end
    endmodule
    
    //noblocking.v
    
    `timescale 1ns / 1ps
    module noblocking(
        input [3:0] a,
        output [3:0] b,c,
        input clk
        );
        reg  [3:0] b,c;
        
        always@(posedge clk)
        begin
            b <= a;
            c <= b;
            $display("Non_Blocking: a = %d, b = %d, c = %d.",a,b,c);
        end
    endmodule
    
    //compare_blocking.v
    
    `timescale 1ns / 1ps
    
    module compare_blocking;
        wire [3:0] b1,c1,b2,c2;
        reg [3:0] a;
        reg clk;
        initial
            begin
            clk = 0;
            forever #50 clk = ~clk;
            end
        initial
            begin
                a = 4'h3;
                $display("____________________________");
                # 100 a = 4'h7;
                $display("____________________________");
                # 100 a = 4'hf;
                $display("____________________________");
                # 100 a = 4'ha;
                $display("____________________________");
                # 100 a = 4'h2;
                $display("____________________________");
                # 100 $display("____________________________");
                $stop;
            end
        noblocking noblocking(.clk(clk),.a(a),.b(b2),.c(c2));
        blocking blocking(.clk(clk),.a(a),.b(b1),.c(c1));
    endmodule 
    
    

    从下图的结果里也验证了之前的知识点。阻塞赋值和非阻塞赋值

    a-->b1-->c1为阻塞赋值,把a的值赋给b1工作完成后,b1的值更新,再将b1的值赋给c1

    a-->b2-->c2为非阻塞赋值,a的值赋给b2的同时 b2的值赋给c2,所以b2为a的新值 c2为b2的旧值。

     

  • 相关阅读:
    混合式应用开发之AngularJS ng-repeat数组有重复值的解决方法
    混合式应用开发之串口通讯(2)
    混合式应用开发之串口通讯(1)
    第一篇博客
    win10出现"本地计算机上的MySQL57服务启动后停止"
    彻底区分html的attribute与dom的property
    Angularv4入门篇1
    node开发后将本地mysql数据导入到服务器mysql
    weex入门
    Color.js 方便修改颜色值
  • 原文地址:https://www.cnblogs.com/l20902/p/10610905.html
Copyright © 2011-2022 走看看