前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >FPGA系统性学习笔记连载_Day10 【时序逻辑、竞争冒险、同步复位、异步复位】

FPGA系统性学习笔记连载_Day10 【时序逻辑、竞争冒险、同步复位、异步复位】

原创
作者头像
FPGA技术江湖
修改2021-04-01 18:00:12
5610
修改2021-04-01 18:00:12
举报
文章被收录于专栏:FPGA技术江湖

FPGA系统性学习笔记连载_Day10 【时序逻辑、竞争冒险、同步复位、异步复位】之【计数器设计、verilog语法补充】

本系列为FPGA系统性学习学员学习笔记整理分享,如有学习或者购买开发板意向,可加交流群联系群主。

连载《叁芯智能fpga设计与研发-第10天》 【时序逻辑、竞争冒险、同步复位、异步复位】之【计数器设计、verilog语法补充】

原创作者:紫枫术河 转载请联系群主授权,否则追究责任

本篇文章介绍时序逻辑的设计,以设计一个计数器来讲解时序逻辑,同时扩展verilog语法知识。

一、时序逻辑

时序逻辑是Verilog HDL 设计中另一类重要应用。从电路特征上看来,其特点为任意时刻的输出不仅取决于该时刻的输入,而且还和电路原来的状态有关。

从电路行为上讲,不管输入如何变化,仅当时钟的沿(上升沿或下降沿)到达时,才有可能使输出发生变化。

1、在描述时序电路的always块中的reg型信号都会被综合成寄存器,这是和组合逻辑电路所不同的。

2、时序逻辑中推荐使用非阻塞赋值“<=”。

3、时序逻辑的敏感信号列表只需要加入所用的时钟触发沿即可,其余所有的输入和条件判断信号都不用加入,这是因为时序逻辑是通过时钟信号的跳变沿来控制的。

二、时序逻辑在FPGA里RTL实现

我们写一个简单的寄存器,看看fpga是怎样实现时序逻辑的

代码语言:javascript
复制
module  counter(
    input           a,
    input               clk,
     
    output  reg     q
);
 
    always@(posedge clk)begin
        q <= a;
    end
 
endmodule

我们看一下fpga的芯片规划器

从芯片规划器,可以看出来几个细节。

1、我们用了一个查找表、一个寄存器。对FPGA来说,这个寄存器你就算不使用他也是在那里的

2、我么的输出信号是与clk同步的,必须要等到clk的上升沿到来是,输出才会更新,因此就实现了寄存器的功能

三、同步复位、异步复位

1、同步复位:其实就是你的操作和时钟的上升沿同步

举个例子,你要将q设置为0,下面这代码就是同步复位,q <= 0,是在时钟上升沿到来时执行的,所以是同步复位

代码语言:javascript
复制
module  counter(
    input           a,
    input               clk,
     
    output  reg     q
);
 
    always@(posedge clk)begin
        q <= 0;
    end
 
endmodule

2、异步复位:其实就是你的操作和时钟没有关系

举个例子,你要将q设置为0,下面这代码就是异步复位,q <= 0,无论时钟是什么状态,只有rst_n到来就执行清零

代码语言:javascript
复制
module  counter(
    input                   a,
    input                       clk,
    input                       rst_n,
    output  reg [7:0]   q
);
 
    always@(posedge clk,negedge rst_n)begin
        if(!rst_n)
            q <= 0;
        else   
            q <= q + 1'b1;
    end
endmodule

四、竞争冒险

竞争冒险:意思是,在我时钟的上升沿进行采样时,输入信号处于不稳定状态,这个会给电路带来亚稳态的问题

为了解决竞争冒险,我们只要满足信号的建立时间和保持时间即可

五、verilog语法补充

1、parameter 定义全局变量

parameter T = 26'd49_000_000;

2、defparam 重新定义参数,这个主要是在仿真脚本修改例化的模块的内部参数

代码语言:javascript
复制
defparam counter_inst.T = 26'd49;
 
counter counter_inst(
.clk        (clk),
.rst_n  (rst_n),   
.flag       (flag)

六、计数器设计

设计一个1秒的计数器,当时间到一秒后给出一个flag信号

1、代码实现 verilog.v

代码语言:javascript
复制
module  counter(
    input               clk,
    input               rst_n,
    output  reg     flag
);
 
    reg [25:0] count;
     
    parameter   T =     26'd49_000_000;
     
    always@(posedge clk,negedge rst_n)begin
        if(!rst_n)begin
            flag <= 1'b0;
            count <= 0;
            end
        else    if(count == T)begin
                flag <= 1'b1;
                count <= 0;
            end
        else
            begin
                count <= count + 1'b1;
                flag <= 1'b0;
            end
    end
 
endmodule

2、仿真脚本

我在仿真脚本将时间参数改为T改为 T=26‘d49;方便仿真

代码语言:javascript
复制
`timescale 1ns/1ps
 
 
module counter_tb;
 
    reg             clk;
    reg             rst_n;
    wire                flag;
     
    defparam counter_inst.T = 26'd49;
     
    counter counter_inst(
    .clk        (clk),
    .rst_n  (rst_n),   
    .flag       (flag)
);
 
    always #10 clk = ~clk;
 
    initial begin
        clk = 0;
        rst_n = 0;
        #20;
        rst_n = 1;
        #5000000;
        $stop;
    end
 
endmodule

3、仿真结果

3.1、可以看出脉冲flag只持续了一个周期

3.2、可以看出脉冲的触发是50个计数值

七、计数器里隐藏的加法器问题

我们设计的这个计数器,里面其实用了一个加法器,加法器是组合逻辑(因为组合逻辑只取决于输入)

当我们给加法器一个初值0的时候,加法器的输出立即就输出1,这就是仿真的时候,开始复位拉高后,count在第一个clk上升沿就为1的原因

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • FPGA系统性学习笔记连载_Day10 【时序逻辑、竞争冒险、同步复位、异步复位】之【计数器设计、verilog语法补充】
  • 连载《叁芯智能fpga设计与研发-第10天》 【时序逻辑、竞争冒险、同步复位、异步复位】之【计数器设计、verilog语法补充】
  • 一、时序逻辑
  • 二、时序逻辑在FPGA里RTL实现
  • 三、同步复位、异步复位
  • 四、竞争冒险
  • 五、verilog语法补充
  • 六、计数器设计
  • 七、计数器里隐藏的加法器问题
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档