• 《FPGA全程进阶---实战演练》第八章之程序架构格式说明


      首先在书写程序时必须有的部分,就是模块module部分,整体的架构如图8.1所示。

    wpsA3FC.tmp

    图8.1 程序整体架构

      首先要声明模块名,在module后面加上模块名,这里最好以所建立模块要实现的功能去命名此模块,因为这样在查阅时方便去寻找此模块的功能,一目了然。紧接着在方框内要列出所有的输入和输出信号,都要在方框中写出。作为一个整体的模块,凡事出现module的部分一定要加上endmodule才算完整,这是一个完整的模块。

      在输入信号中,有两个信号是一定要加上去的,就是时钟信号和复位信号,要做到对整体设计可控,全局时钟信号和复位信号必须加上。在声明括号对输入和输出信号列写完毕之后,还要在module内部再次声明到底哪个是输入信号,哪个是输出信号,这就有了124行到128行的声明。在always语句中用到的一些变量需要定义为reg类型,也就是寄存器类型,方可在always中使用,wire类型不可以在always语句中使用。

      我们在看别人写的代码时常常看到类似于130行到153行所示的结构,这是怎么回事?这是要做什么?这就要利用我们数电知识里面的组合逻辑和时序逻辑的比较了,在要求对变量存储的场合,需要时序逻辑,组合逻辑只能输出数据,但是不能存储。当然还有组合逻辑是电平触发,而时序逻辑是时钟沿触发。所以130行到153行构建了一个庞大的锁存器,构成时序逻辑电路。对于130行小括号内部的属于敏感型变量,即发生变化时,会带动整个always 语句进行更新变化。其中rst_n(这个是复位信号,可以按自己的习惯去定义。)也定义为边沿敏感型变量,但是在always语句中的内部又出现了rst_n,这是为什么呢?一个信号如果是时钟信号,那么必定不会出现在always语句中,可见rst_n不是时钟信号。那么综合器会不会认为rst_n是一个时钟信号呢?

        对于边沿触发型时序模块的verilog设计,有以下规律可循:

      (1)若敏感型变量定义为时钟信号,不要在always语句中再出现。

      (2)若某信号定义为相对于时钟的电平敏感的异步控制信号,除了在敏感型变量表中列出,还要在always语句中指出其逻辑行为。

      (3)若某信号是相对于时钟的同步控制信号,不能出现在敏感型变量表中。

      由上面的程序结构,为rst_n指定了if语句,会导致所有未能进入敏感信号的变量都必须是相对于时钟同步的。可见这是独立于主时钟的时序或组合逻辑,属于第二种情况。

      (4)敏感型变量表中不允许出现混合信号。

    always@(posedge clk or rstn) 或 always@(posedge clk or  negedge rstn or a)

    上述结构都是不允许的,在综合时会出现 双边沿敏感信号的错误。

      (5)不允许在敏感型列表中出现除时钟和异步控制信号之外的其他信号,一般的逻辑控制信号不允许出现在敏感型列表中,always@(posedge clk or negedge a)

       其中a的作用同rstn,但是a不能用于其他逻辑行为 。如q = a & b;

       可见verilog 描述敏感型时序电路较多的依赖于语法的规定和表述的规则

       If语句中对异步控制信号rst_n进行判断,然后对数据进行初始化,初始化完成之后在执行其他条件,else if......else,其中的begin....end是针对于条件语句中有多步执行程序时,构建成一个整体,隶属于else if语句或者else语句。

       155行到157行对于用户所使用的输出信号进行赋值。以上是针对单个module的建立,若是只是建立单个module,在建立工程时必须将module的名字和工程名字一致,如图8.2所示,否则会出错。对于多个模块构建,需要建议一个顶层模块,然后将各个子模块进行连接,这时用到了wire变量,如图8.3所示,注意wire类型的LED信号,起到连接各个模块的作用。图8.4是多个模块的RTL视图部分,可以看到wire的作用。

    wpsA3FD.tmp

    图8.2 单个模块命名

    wpsA40D.tmp

    图8.3 多个模块命名

    wpsA41E.tmp

    图8.4 RTL视图

    TESTBENCH格式说明

    当逻辑部分创作完成后,需要对逻辑程序进行行为仿真,那么就需要写仿真程序。

    `timescale 1 ns/ 1 ns

    module led_source_tst();

    //----------------------------------------------

    //-----------description of input signal--------

    reg clk;

    reg rst_n;

    //clk 和rst_n是全局的时钟和复位信号

    //----------------------------------------------

    //-----------description of output signal--------                                                    

    wire [3:0]  led_out;

    Wire .....

    Wire .....

    //在modelsim仿真时,.v文件中的input在modelsim中用reg类型,如clk是input,

    //上面modelsim是用reg,.v文件中的输出,即output,在modelsim中是wire,这一点要牢记

    //----------------------------------------------

    //-----------description of each module-------------------------                           

    led_source

    #(.LED_WIDTH(4))

    i1 (

    // port map - connection between master ports and signals/registers  

    .clk(clk),

    //.cnt1(cnt1),

    //.flag_cnt1(flag_cnt1),

    .led_out(led_out),

    //.led_out_cnt1(led_out_cnt1),

    .rst_n(rst_n)

    );

    //这一部分是对建立的.v文件中的模块声明部分,led_source就是.v文件中的模块名字

    //------------------------------

    //generate clock

    localparam PERIOD = 20;               //50MHz

    initial                                               

    begin                                                 

    clk = 0 ;

    forever #(PERIOD / 2) clk = ~clk;

    end   

    //上面这一段是针对clk信号做的模拟仿真;                  

    //------------------------------

    //task reset

    task task_reset;

    begin

    rst_n = 0 ;

    repeat(2) @(negedge clk);

    rst_n = 1 ;

    end

    endtask

    //上面一部分是针对复位信号,也就是rst_n。

    //一开始也是赋初值rst_n = 0 ;然后利用repeat重复执行命令;                                

    initial

    begin

    $monitor($time,"led_value = %04b ", led_out); //just test the changing of led_out  //value

    task_reset;

    end

    //上面这一部分就是对上面的task模块进行调用和对输入信号进行仿真,当然这一部分并没有用到用   //户输入信号。

    endmodule                    

    图8.5是对于按键的仿真程序,将输入也定义为一个task,然后在101行到105行进行任务的调用,清楚明了。

    wps7E44.tmp

    图8.5 输入信号的调用

  • 相关阅读:
    enmo_day_07
    enmo_day_04
    enmo_day_05
    数据仓库的模型设计
    Lucene 概念,定义应用场景
    enum 枚举的简单应用
    单例模式&synchronized
    Spark的 DAGschedule & task schedule 区别以及相互联系
    Spark的stage & job & task 到底是什么 ,以及划分原理
    Java基本数据类型&引用类型总结
  • 原文地址:https://www.cnblogs.com/raymon-tec/p/5077236.html
Copyright © 2020-2023  润新知