1. 复习verilog语法

【选做题】

- reg和wire的区别


寄存器数据类型

Verilog中规定,凡是在程序块中被赋值的变量,都必须是寄存器类型的。(程序块:例如always块)

这里未免还是会让人产生疑惑?寄存器数据类型的变量最后一定会被综合成寄存器吗?

对应于实际的数字电路中,如果该程序块描述的是时序逻辑,则该寄存器变量对应为寄存器;如果该程序块描述的是组合逻辑,该寄存器变量对应为硬件逻辑;如果该程序块描述的是不完全组合逻辑,那么该寄存器变量也可以对应为锁存器。由此可见,寄存器类型的变量不一定会综合为寄存器。

线网数据类型

Verilog中规定,模块的input和inout端口必须是线网类型;连续赋值语句的被赋值对象必须是线网类型。对应于实际的数字电路,线网类型实际上就对应着硬件的连线,起到连接作用。

线网数据类型包括wire和tri等,wire最常见,不必多说,很多情况下直接声明为wire即可。

至于tri其实和wire在用法上是一模一样的,不过有时候,我们需要定义一些会被三态门驱动的硬件连线,用tri来命名会让代码更具有可读性,让人一看就知道这根连线上会出现Z状态,仅此而已!
--------------------- 
作者:李锐博恩(Reborn) 
原文:https://blog.csdn.net/Reborn_Lee/article/details/82771503 
这是我以前写过的博文:【 Verilog HDL 】寄存器数据类型(reg)与线网数据类型(wire,tri)


- 阻塞赋值与非阻塞赋值的区别


1、非阻塞(Non_Blocking)赋值方式(如 b <= a;)

块结束后才完成赋值操作;
b的值并不是立刻就改变;
这是一种比较常用的赋值方法。(特别在编写可综合模块时)
2、阻塞(Blocking)赋值方式(如: b = a;)

赋值语句执行完后,块才结束;
b的值在赋值语句执行完后立刻就改变;
可能产生意想不到的结果。
非阻塞赋值方式和阻塞赋值方式的区别常给设计人员带来问题。问题主要是给“always”块内的reg型信号的赋值方式不易把握。

如果“always”模块中的reg型信号采用非阻塞赋值方式:

b <= a;

这种方式的赋值并不是马上执行的,也就是说“always” 块内的下一条语句执行后,b并不等于a,而是保持原来的值。“always”块结束后,才进行赋值。

如果采用阻塞赋值方式:

b = a;

这种赋值方式是马上执行的。也就是说,执行下一条语句时,b已经等于a了。尽管这种方式看起来直观,但是可能引起麻烦。

下面对两种赋值方式举例分析:

例1:

非阻塞赋值

always @(posedge clk)
begin
 
    b <= a;
    c <= b;
 
end
上例中的"always"块中用了非阻塞赋值方式,定义了两个reg型信号b和c,clk信号的上升沿到来时,b就等于a,c就等于b,这里应该用到了两个触发器。请注意:赋值是在"always"块结束后执行的,c应为原来b的值,b为原来的a值。这个"always"块实际描述的电路功能如下图所示:

例2:

阻塞赋值

always @(posedge clk)
begin
 
    b = a;
    c = b;
 
end
上例中的 "always"块用了阻塞赋值方式。clk信号的上升沿到来时,将发生如下的变化:b马上取a的值,c马上取b的值(即等于a),生成的电路图如下所示只用了一个触发器来寄存器a的值,又输出给b和c。这大概不是设计者的初衷,如果采用[例1]所示的非阻塞赋值方式就可以避免这种错误。


--------------------- 
作者:李锐博恩(Reborn) 
来源:CSDN 
原文:https://blog.csdn.net/Reborn_Lee/article/details/82222665 
这也是我以前写过的博文:【Verilog HDL】赋值语句之阻塞赋值方式与非阻塞赋值方式

其他博文:【 Verilog HDL 】进一步了解 Verilog HDL 的赋值运算符


- parameter与define的区别


作用域区别:

parameter 作用于声明的那个文件;`define 从编译器读到这条指令开始到编译结束都有效,或者遇到`undef命令使之失效。

如果想让parameter或`define作用于整个项目,可以将如下声明写于单独文件,并用`include让每个文件都包含声明文件:

`ifndef data

`define data  8’d14

或者

parameter data = 8‘d14;

`endif

`define也可以写在编译器最先编译的文件顶部。通常编译器都可以定义编译顺序,或者从最底层模块开始编译。因此写在最底层就可以了。

区别:

parameter可以用作例化时的参数传递。

在使用状态机时候区别挺大的。状态机的定义可以用parameter 定义,但是不推荐使用`define 宏定义的方式,因为'define 宏定义在编译时自动替换整个设计中所定义的宏,而parameter 仅仅定义模块内部的参数,定义的参数不会与模块外的其他状态机混淆。例如一个工程里面有两个module 各包含一个FSM,如果设计时都有IDLE 这一名称的状态,如果使用'define 宏定义就会混淆起来,如果使用parameter 则不会造成任何不良影响。

一旦`define指令被编译,其在整个编译过程中都有效。例如,通过另一个文件中的`define指令,定义的常量可以被其他文件中被调用。直到遇到`undef;parameter只在定义的文件中有效,在其它文件中无效。

这块内容参考:Verilog中parameter和define的区别


- task与function的区别


1.函数可以返回一个值而任务可以返回多个值

2.函数一经调用必须立即执行,里面不能包含任何的时序控制,而task中可以有时序控制

3.函数可以调用函数,但不可以调用任务,任务既可以调用函数也可以调用任务

4.函数必须要有一个输入参数,而任务可以没有参数输入。

4.任务输出的信号,在模块中必须定义为reg信号

参考:verilog 中任务与函数的区别


2. 用verilog实现边沿检测电路:上升沿,下降沿,双沿(上升或下降沿)。


昨天刚刚写了一篇类似的博文,里面用到了边沿检测,边沿检测应用可算是十分广泛呀, 写flash控制器时候也用到了。

使用握手协议的方式处理跨时钟域传输问题

从这篇博文中节选出边沿检测的部分吧:

//req上升沿检测
    reg reqr1, reqr2, reqr3; //定义reqrx代表延迟x拍
    //--------------------------------------------------------
    //第一种方法
    always @ (posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            reqr1 <= 1'b0;
            reqr2 <= 1'b0;
            reqr3 <= 1'b0;
        end
        else begin
            reqr1 <= req;
            reqr2 <= reqr1;
            reqr3 <= reqr2;
        end
    
    end
    
    //pos_req3比pos_req2延后一拍,确保数据被稳定锁存
    wire pos_req1, pos_req2, pos_req3;
    
    assign pos_req1 = ( { req, reqr1 } == 2'b10 ) ? 1'b1 : 1'b0;
    assign pos_req2 = ( { reqr1, reqr2 } == 2'b10 ) ? 1'b1 : 1'b0;
    assign pos_req3 = ( { reqr2, reqr3 } == 2'b10 ) ? 1'b1 : 1'b0;
    //------------------------------------------------------------------
    // 检测上升沿的第二种方法
    // assign pos_req1 = ~reqr1 & req;
    // assign pos_req2 = ~reqr2 & reqr1;
    // assign pos_req3 = ~reqr3 & reqr2;

---------------------

下面是仿真图,只看上面用到的变量部分:

更多细节,点开链接:https://blog.csdn.net/Reborn_Lee/article/details/89647526

上面的答案是昨天写的,所以优先附上,但之前也转载过类似的东西,看下之前的:

reg     [1:0]   signal_r;
//-------------------------------------------------------
//
always @(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)beginsignal_r <= 2'b00;endelse beginsignal_r <= {signal_r[0], signal_in};end
endassign  singal_posedge = ~signal_r[1] & signal_r[0];//检测上升沿
assign  singal_negedge = signal_r[1] & ~signal_r[0];//检测下降沿

其实原理都是一样的。


3. 记录一下第2题中用到的工具,包括工具版本,操作步骤或命令选项,遇到的错误,提示信息等。


工具是:Vivado 2018

操作步骤:无非是建立工程,然后编写Verilog代码,之后编写Testbench文件,然后仿真即可。

遇到的问题:仿真发现,检测到边沿有时候并不能持续一个时钟,这是由于要检测的信号与时钟上升沿之间的位置关系。在应用边沿检测的时候,如果时间不够,可以多延迟几拍,见第二题的代码吧。

【Verilog HDL 训练】第 06 天(边沿检测)相关推荐

  1. 【Verilog HDL 训练】第 11 天(分频电路)

    设计一个占空比50%的三分频电路. 针对这个分频器,博文的末尾会给出一个反面教材,这是我上次写的一个分频器,看起来很好,其实是不能综合的.针对其中的错误,我令立博文记录之:[ Verilog ]alw ...

  2. 【Verilog HDL 训练】第 05 天(序列检测)

    1. dff和latch有什么区别. 锁存器是一种对脉冲电平(也就是0或者1)敏感的存储单元电路,而触发器是一种对脉冲边沿(即上升沿或者下降沿)敏感的存储电路. "触发器" 泛指一 ...

  3. 【Verilog HDL 训练】第 09 天(按键消抖)

    5月7日 按键防抖 1. 用verilog实现按键抖动消除电路,抖动小于15ms,输入时钟12MHz. 在编写Verilog代码之前,先分析下一些前提问题,首先是几个按键(1个,多个),我们以1个和三 ...

  4. 【Verilog HDL 训练】第 07 天(串并转换)

    串并转换 1. 复习verilog语法 [选做题] - 文件操作fopen fdisplay fwrite fclose - 生成随机数 random - 初始化 readmemh readmemb ...

  5. 【Verilog HDL 训练】第 14 天(glitch-free的两个时钟切换电路)

    2019年5月13日 glitch-free的两个时钟切换电路. 可以看到这是一个星期之前的题目了,现在才抽空做,把这篇颠倒个顺序吧,也是最后一天了,以后的题目都是讨论性质的,不会以第多少天的形式来写 ...

  6. 【Verilog HDL 训练】第 13 天(存储器、SRAM)

    存储器. 1. rom,ram,flash,ddr,sram,dram,mram..列举并解释一下这些名词. 2. 用verilog实现一个深度为16,位宽8bit的单端口SRAM.搭建一个仿真环境, ...

  7. 【Verilog HDL 训练】第 10 天(PWM 呼吸灯)

    5月8日 PWM 用verilog实现PWM控制呼吸灯.呼吸周期2秒:1秒逐渐变亮,1秒逐渐变暗.系统时钟24MHz,pwm周期1ms,精度1us. 今天的题目我是第一次见,答案借鉴大神的:Veril ...

  8. 【Verilog HDL 训练】第 08 天(二进制、Johnson、环形计数器)

    5月6日 计数器 1. 用verilog实现一个4bit二进制计数器. a) 异步复位 b) 同步复位 input clk, rst_n; output [3:0] o_cnt; Verilog实现代 ...

  9. 【Verilog HDL 训练】第 04 天(竞争、冒险、译码等)

    1. 什么是竞争和冒险? 记得我刚学FPGA那会,恶补基础知识,其中之一就是竞争与冒险,我参考了<FPGA之道>,记录了几篇博客: [ FPGA ]组合逻辑中的竞争与险象问题(一) 第一篇 ...

最新文章

  1. WR:微生物污染源解析中宿主特异性标记物在中国的表现特征
  2. 05. 取SQL分组中的某几行数据
  3. 2020年联通软件研究院校招笔试第一题
  4. 后台服务出现明显“变慢”,谈谈你的诊断思路?
  5. jcmd_jcmd,大约JDK 11
  6. javascript学习系列(23):数组中的解构方法
  7. linux常用架构,Linux常用到的一些命令-Go语言中文社区
  8. 基于安全压缩感知的大数据隐私保护
  9. Python enumerate():使用计数器简化循环
  10. [ACM_NYOJ_15]括号匹配(二)
  11. PowerDesigner安装教程
  12. 微信小程序 index.js获取app.js异步请求的动态数据
  13. Python3.7中,Django配置MySql数据库
  14. 关于千牛移动端纯H5插件和QAP应用中H5页面的概念
  15. 5G科普——CU和DU分离
  16. selenium打开firefox无痕模式
  17. 微信小程序实现首页图片多种排版布局!
  18. VMTools的安装 (简单易懂)
  19. ExtJS教程(5)---Ext.data.Model之高级应用
  20. SOLIDWORKS物料编码工具SolidKits Coding

热门文章

  1. mysql自动备份与还原
  2. typedef、setw()
  3. python能够处理的最大整数是多少_python中能输出的最大整数位是多少
  4. 腾讯云视频流量服务器,腾讯云服务器有流量限制吗
  5. rust投递箱连接箱子_灭火器箱存在的必要性
  6. RabbitMQ (三)消息重试
  7. java 注解 payload_spring – 如何使用注释配置PayloadValidatingInterceptor
  8. java process started_Java HistoricProcessInstanceQuery.startedBy方法代碼示例
  9. python excel增加一列_(用Python修改excel中一列数据)python新增一列
  10. Getting Started with OpenCV