Verilog进阶思想和编程练习题库

1 Verilog学习的进阶思想

1.1 初级

找到工具书后,找到最简单的基础实例(带仿真例程)开始看起,看不懂查阅工具书。看完之后用ISE或者Vivado综合,然后看RTL图,你就能看到这些代码最终翻译成了什么样的数字电路。

紧接着就是仿真或者上板实测:用仿真的信号输入到你写的模块里面,你才能清晰的知道最终电路输出是什么结果,是否和你想的一致。如果不一致,找到不一致的原因。对于简单设计,仿真和实际上板是看不出差别的。

另外:明白你写的代码是什么电路是整个FPGA设计永远的核心!如果你发现你有一天对自己写的代码非常清楚他出来是什么样子,那么恭喜你入门了!换句话说,就是要学会用机器的思维去看你的代码,只有多综合你才能懂xilinx的编译器是什么综合规律,用机器去理解机器才是最好的理解!

1.2 进阶

总的来说,进阶要掌握以下几点:

  1. 时序约束的原因和使用方法,能熟练正确的应用最基本的时钟周期约束,时序例外约束,异步时钟域约束,同步复位的约束,高扇出约束
  2. 清楚xilinx芯片内部时钟资源分布,能够知道自己的代码和约束能否让编译器用比较优化的走线布局布线。
  3. 清楚内部嵌入式硬核的分布和合理使用
  4. 懂得常见的异步时钟域正确传输的常见方法:握手信号,异步FIFO,同步器
  5. 能看懂时序报告里面基本的一些参数

1.3 高阶

高阶教程是无止境的,但是如果你学会以下几点你已经步入高手行列:

  1. 对FPGA所有常用时序约束和时序例外约束,包括逻辑锁定的方法都能正确使用
  2. 能够跟据时序报告做出合理的改进时序的方案
  3. 清楚各种时序优化方案的大概极限
  4. 能够在FPGA平台上实现一些复杂算法:比如PID调节,FFT变化,FIR滤波器,神经网络等等
  5. 对大规模,大吞吐量的逻辑设计能够在需求输入的时候有一个大概的总体方案,大致要能够一下想到时钟方案,复位方案,高速接口方案这些该怎么做,或者能不能做到

总之,高阶教程会让人离FPGA更远,把FPGA最为一个底层平台去实现一些抽象高深的理论。其实不管是CPU还是FPGA都是工具,工具里面的算法实现才是最重要的。

2 基础语法与基础编程

2.1 二分频仿真

half_clk.v源代码

module half_clk(clk_in, rst, clk_out);
input clk_in;
input rst;
output clk_out;
reg clk_out;

always @(posedge clk_in or negedge rst)
    begin
        if(!rst)
            clk_out <= 0;
        else
            clk_out <= ~clk_out;
    end
endmodule

half_clk_tb.v TestBench代码

`timescale 1ns/100ps

module half_clk_tb;
reg clk_in, rst;

initial
begin
    clk_in = 1;
    rst = 1;
    #1000 rst = 0;
    #1000 rst = 1;
end

always #200 clk_in = ~clk_in;

half_clk U(clk_in, rst,clk_out);

endmodule

仿真结果
二分频仿真

扫描二维码关注公众号,回复: 11531751 查看本文章

2.2 计数器练习

题目如图下
**加粗样式**counter.v源代码

module counter(clk,rst_n,en,dout);

input wire clk,rst_n,en;
output reg dout;
reg [4-1:0] cnt;
wire add_cnt,end_cnt;
assign add_cnt=(dout==1);
assign end_cnt=add_cnt&&(cnt==9);

always@(posedge clk or negedge rst_n)
begin 
    if(!rst_n)
        begin 
            cnt<=0;
        end
    else if(add_cnt)
        begin
            if(end_cnt)
                cnt<=0;
            else
                cnt<=cnt+1;
        end
end

always@(posedge clk or negedge rst_n)
begin
    if(!rst_n)
        dout<=0;
    else
        if(en==1)
            dout<=1;
        if(end_cnt)
            dout<=0;
end

endmodule

counter_tb.v测试代码

`timescale 1ns/100ps

module counter_tb;

reg clk,rst_n,en;
wire dout;

initial
begin
    clk=0;
    rst_n=0;
    #10 rst_n=1;
    en=0;
    #60   en=1;
    #40   en=0;
end

always #10 clk=~clk;

counter cnt(.clk(clk),.rst_n(rst_n),.en(en),.dout(dout));

endmodule 

仿真结果
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/zhanshen112/article/details/107529444