FPGA学习篇——Verilog学习之寄存器的实现

1 寄存器理论

这里在常见的寄存器种加了一个复位信号sys_rst_n。(_n后缀表示复位信号低电平有效,无这个后缀的则表示高电平有效)


这里规定在时钟的上升沿有效,只有当时钟的上升沿来临时,输出out 才会改变,且= 输入Key_in(上升沿前一时刻),其余时刻,输出out保持。

而复位信号什么时候有用呢,顾名思义,复位信号就是让输出清零的操作。

复位分为同步复位和异步复位:

(1)同步复位:即复位信号和时钟信号同步,只有当复位信号有效且时钟的上升沿时两个条件均满足,输出out才会清零;同步复位信号释放时,同样,只有当复位信号释放且时钟的上升沿时两个条件均满足,输出out才会不受复位信号控制。

(2)异步复位:即复位时,复位信号与时钟信号无关,只需满足复位信号有效输出out就会清零;注意异步信号释放时,采用同步释放方式,即与同步复位信号释放一样,只有当复位信号释放且时钟的上升沿时两个条件均满足,输出out才会不受复位信号控制(这是为了克服复位信号释放的随机性,可能导致时序违规,倘若复位释放时恰恰在时钟有效沿附近,就很容易使电路处于亚稳态,详细可查阅资料)。

2 代码理解:

这里跟着野火学了一下代码~

2.1 主文件

异步和同步选其中一种。

复制代码
module flip_flop
(
    input key_in, sys_rst_n, sys_clk,
    output reg Output

);

//异步
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        Output <= 1'b0;
    else
        Output <= key_in;  

endmodule

//同步
always@(posedge sys_clk)
    if(sys_rst_n == 1'b0)
        Output <= 1'b0;
    else
        Output <= key_in;  

endmodule

2.2 仿真文件

复制代码
`timescale  1ns/1ns

module tb_flip_flop();

reg t_key_in, t_sys_rst_n, t_sys_clk;
wire t_Output;

initial begin
    t_sys_clk = 1'b0;
    t_key_in = 1'b0;
    t_sys_rst_n = 1'b0;
    #20
    t_sys_rst_n = 1'b1;
    #200
    t_sys_rst_n = 1'b0;
    #40
    t_sys_rst_n = 1'b1;
    
end

always #10 t_sys_clk = ~t_sys_clk;
always #20 t_key_in <= {$random} % 2;

initial begin
    $timeformat(-9,0,"ns",10);
    $monitor("@time %t,key_in = %b,sys_clk = %b,sys_rst_n = %b,Output = %b",$time,t_key_in,t_sys_clk,t_sys_rst_n,t_Output);
end

flip_flop u_flip_flop
(
    .sys_clk(t_sys_clk),
    .sys_rst_n(t_sys_rst_n),
    .key_in(t_key_in),
    .Output(t_Output)

);

endmodule

这里解释一下:

(1)时钟周期为20ns:always #10 t_sys_clk = ~t_sys_clk;使得每10ns取反一次,故周期为20ns。

(2)初始赋值时,为什么延迟200ns后让复位信号有效,这个延迟是有讲究的,为了更好的看到同步复位和异步复位的效果,就要尽量避免复位信号有效与时钟上升沿重合。

这里时钟周期为20ns,初始时刻时钟为0开始,复位信号为0开始,20ns后,复位信号为1,此时的时钟为1,且为下降沿,再过了200ns后,复位信号为0,此时时钟为1,且为下降沿,再过40ns,复位信号为1,此时时钟为1,也刚好为下降沿。(如果把延后200ns改为延后210ns(前延后20ns不变),则在230ns处,复位信号为0,时钟信号为0,且为上升沿,则不易看实验结果了)

(20ns时 )

(220ns时)

(260ns时)

(3)野火的代码初始赋值语句中对sys_rst_n采用了非阻塞赋值,而我试了一下用阻塞赋值也完全没问题,此前说的时序逻辑用非阻塞,组合逻辑用阻塞不是所有情况,本质还是要理解阻塞和非阻塞的定义(可看FPGA学习篇------Verilog学习4(常见语句)_verilog initial-CSDN博客


**注:**以上为本人学了野火FPGA系列视频的个人经验,如有侵权,请联系我~

相关推荐
Aronup7 分钟前
NLP学习开始01-线性回归
学习·自然语言处理·线性回归
墨迹的陌离2 小时前
【Linux】重生之从零开始学习运维之Mysql
linux·运维·服务器·数据库·学习·mysql
幻风_huanfeng3 小时前
学习人工智能所需知识体系及路径详解
人工智能·学习
Runner.DUT3 小时前
基于FPGA和DDS原理的任意波形发生器(含仿真)
fpga开发
试着3 小时前
零基础学习性能测试第六章:性能难点-Jmeter文件上传场景压测
学习·jmeter·零基础·性能测试
小一亿3 小时前
【0基础PS】PS工具详解--选择工具--对象选择工具
学习·平面·adobe·信息可视化·传媒·photoshop
雾削木3 小时前
TI 2025全国电赛猜题
fpga开发
cyr___4 小时前
Unity教程(二十四)技能系统 投剑技能(中)技能变种实现
学习·游戏·unity·游戏引擎
老虎06274 小时前
JavaWeb(苍穹外卖)--学习笔记14
笔记·学习
典孝赢麻崩乐急5 小时前
Java学习-----JVM的垃圾回收算法
java·jvm·学习