FPGA学习(6)-基础语法参数化设计阻塞与非阻塞

目录

1.两种参数化不改变源文件,只改仿真文件的值

2.参数化设计实现模块的重用

2.1不用参数化方法

2.1.1源文件

 2.1.2仿真文件

2.1.3仿真波形及实验

2.2 用参数方法

2.2.1调用之前写的led灯闪烁模块,在本源函数中,例化4次调用之前的模块。

2.2.2 源文件

2.2.3仿真文件

2.2.4 电路图的理解

3阻塞与非阻塞语句 


1.两种参数化不改变源文件,只改仿真文件的值

parameter的作用:

(1)在模块被例化时,在例化它的代码中,使用一定的语句修改其值。

(2)在仿真和实际运行时,分别要取不同的常量,使用parameter进行定义。

(3)仿真时,在testbench中通过defparam语句修改其值,以新的值进行仿真。

在源文件定义好参数后,仿真文件中有两种方式:

方式1:

该语句需要放在例化后,且修改仿真文件参数时,需要使用被例化后的模块名。先定义,后使用。

defparam run_led3_inst0.MCNT=25_000-1;

方式2:

直接在例化中进行修改。

 run_led3 #(.MCNT(25_00-1))run_led3_inst0(.clk(clk),.reset(reset),.led(led)
);

2.参数化设计实现模块的重用

实现下图所示的功能

2.1不用参数化方法

2.1.1源文件

即建立4个计数器,分别计数到各自需要的次数,然后进行累加。这里将后面的会合在一起写了,犯了一个错误:不能出现与rst并行的if语句。再用begin...end相隔开。vivado综合出现ambiguous clock in event control - 知乎 (zhihu.com)

module led_four(clk,reset,led);
input clk;
input reset;
output reg [3:0]led;
reg [24:0]counter1;
reg [24:0]counter2;
reg [24:0]counter3;
reg [21:0]counter4;always@(posedge clk or negedge reset)
if(!reset)counter1<=0;
else if(counter1 == 25_000_000-1)counter1<=0;
elsecounter1<=counter1+1'd1;always@(posedge clk or negedge reset)
if(!reset)counter2<=0;
else if(counter2 == 125_000_00-1)counter2<=0;
elsecounter2<=counter2+1'd1;always@(posedge clk or negedge reset)
if(!reset)counter3<=0;
else if(counter3 == 625_000_0-1)counter3<=0;
elsecounter3<=counter3+1'd1;always@(posedge clk or negedge reset)
if(!reset)counter4<=0;
else if(counter4 == 25_000_00-1)counter4<=0;
elsecounter4<=counter4+1'd1;always@(posedge clk or negedge reset)
begin
if(!reset)led[3:0]<=1'b0;
else beginif(counter1 == 25_000_000-1)led[0]<=!led[0];if(counter2 == 125_000_00-1)led[1]<=!led[1];if(counter3 == 625_000_0-1)led[2]<=!led[2];if(counter4 == 25_000_00-1)led[3]<=!led[3];
end
end
endmodule

 2.1.2仿真文件

`timescale 1ns / 1nsmodule led_four_tb();
reg clk;
reg reset;
wire [3:0]led;led_four led_four(.clk(clk),.reset(reset),.led(led)
);initial clk=1;
always #10 clk=~clk;initial begin
reset=0;
#201;
reset=1;
#2000_000_000;
#2000_000_000;
$stop;
end
endmodule

2.1.3仿真波形及实验

仿真波形如图所示,实验现象与仿真波形一致。

2.2 用参数方法

2.2.1调用之前写的led灯闪烁模块,在本源函数中,例化4次调用之前的模块。

另一种方法是把要调用模块的.v文件先复制到本源文件工程中。

 这种方式不得勾选copy栏选项。

修改调用的源文件,设一个参数。 

module led_light(reset,clk,led);input reset;input clk;output reg led;reg [24:0]counter;parameter MCNT = 25_000_000-1;always@(posedge clk or negedge reset)if(!reset)counter<=1'b0;else if (counter == MCNT)counter<=1'b0;elsecounter<=counter+1'd1;always@(posedge clk or negedge reset)if(!reset)led<=1'b0;else if(counter == MCNT )led<=!led;
endmodule

2.2.2 源文件

分别例化这4个计数值,MCNT就好比结构体一样,MCNT1是参数。

module led_four2(clk,reset,led
);
input clk;
input reset;
output [3:0]led;
parameter MCNT1 = 25_000_000-1;
parameter MCNT2 = 125_000_00-1;
parameter MCNT3 = 625_000_0-1;
parameter MCNT4 = 25_000_00-1;led_light
#(  .MCNT(MCNT1)
)
led_light_inst0(.reset(reset),.clk(clk),.led(led[3]));led_light 
#(  .MCNT(MCNT2)
)
led_light_inst1(.reset(reset),.clk(clk),.led(led[2])
);led_light led_light_inst2(.reset(reset),.clk(clk),.led(led[1])
);
defparam led_light_inst2.MCNT=MCNT3;led_light led_light_inst3(.reset(reset),.clk(clk),.led(led[0])
);
defparam led_light_inst2.MCNT=MCNT4;
endmodule

2.2.3仿真文件

即将源文件中的参数嵌套一次,可以跟1节一样修改这个值,改变计数的时间。

`timescale 1ns / 1nsmodule led_four_tb();
reg clk;
reg reset;
wire [3:0]led;led_four2 led_four2(.clk(clk),.reset(reset),.led(led)
);
defparam led_four2.MCNT1=250_000_000-1;
defparam led_four2.MCNT2=125_000_00-1;
defparam led_four2.MCNT3=625_000_0-1;
defparam led_four2.MCNT4=25_000_00-1;initial clk=1;
always #10 clk=~clk;
initial begin
reset=0;
#201;
reset=1;
#2000_000_000;
#2000_000_000;
$stop;
end
endmodule

仿真结果,这里最开始左边端口出现空白,以为是仿真文件的模块名写错,其实这个都没什么关系,模块名最好与文件名一致。就是忘加端口了,一直改模块名可能会让软件找不到路径,导致仿真一直卡住,从而无法进行仿真。

修改每个计数时间,进行仿真验证 ,计数时间已经被修改。

2.2.4 电路图的理解

调用最开始的底层模块,然后用例化4个,分别计数至各自的时间。

3阻塞与非阻塞语句 

时序逻辑电路一般使用<=非阻塞赋值方式,确保所有相关信号在同一时刻被一致地更新,防止出现由于顺序不同导致的竞争冒险问题。组合逻辑电路一般使用=阻塞赋值方式,输出立即响应输入变化。

阻塞语句画电路图时依次往后,在out之前的一般没有触发器,在out之后的一般就需要触发器。非阻塞语句我认为只要有=号就会有触发器。

 仿真图区别在于out2的第一级加法器没有经过一拍D触发器的存储,直接和当前的c进行了运算。

 把led闪烁的例程,分别把某句变为阻塞型,查看仿真例子。左边一直为低电平,右边也是,视频说的是高电平是一个仅20ns的脉冲,这里有点理解不了电路图。

 改前:

 改后:

 

右边改后:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/56902.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ip a查看网卡接口信息

ip a命令是用于查看和管理网络接口信息的命令。通过执行ip a命令&#xff0c;可以查看当前系统上所有网络接口的配置信息&#xff0c;包括IP地址、子网掩码、网关、MAC地址等。该命令还可以用于配置网络接口的参数&#xff0c;如设置IP地址、启用或禁用接口等操作。 # ip a 1:…

史上最烂 spring transaction 原理分析

史上最烂 spring transaction 原理分析 事务定义、事务作用、事务特性、生命周期、数据库事务三种运行模式、数据库事务控制、并发事务问题、隔离级别、数据库事务实现原理、spring 事务传播行为、spring 事务核心组件、spring boot 事务相关组件、事务嵌套原理、编程式事务与声…

51单片机的万年历【proteus仿真+程序+报告+原理图+演示视频】

1、主要功能 该系统由AT89C51/STC89C52单片机LCD1602显示模块时钟模块按键蜂鸣器等模块构成。适用于电子万年历、数字时钟万年历等相似项目。 可实现功能: 1、LCD1602实时显示年月日星期和北京时间&#xff0c;具备闰年判断功能 2、按键可设置闹钟时间 3、按键可修改当前时…

MAL-PEG-SVA MW2000 丙烯酰氯基 共轭反应 靶向传递 共价结合

MAL-PEG-SVA是一种带有丙烯酰氯基和马来酰亚胺的聚乙二醇衍生物。它具有良好的溶解性、生物相容性和化学稳定性&#xff0c;因此在许多领域都有广泛的应用。 以下是MAL-PEG-SVA的一些主要应用和相应的例子&#xff1a; 1. 蛋白质修饰&#xff1a;MAL-PEG-SVA可用于蛋白质的修饰…

CVTE Android面试题及参考答案(100道题)

目录 插件化 组件化 合并相似接口 抽象通用方法 使用接口代理 引入设计模式 编写源代码 资源文件准备 编译资源文件 编译源代码 生成 dex 文件 打包 APK 文件 技术能力提升 项目经验积累 职业发展 知识分享与团队协作 建立良好的沟通机制 明确团队目标和职责…

深度学习代码学习笔记2

1、torch.max correct 0 total 0 for xb,yb in valid_dl:outputs model(xb)_,predicted torch.max(outputs.data,1)total yb.size(0) #yb.size(0) 返回的是张量 yb 在第 0 维的大小&#xff0c;也就是 yb 中的样本数量。correct (predicted yb).sum().item() print(…

[Halcon矩阵] 通过手眼标定矩阵计算相机旋转角度

&#x1f4e2;博客主页&#xff1a;https://loewen.blog.csdn.net&#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;本文由 丶布布原创&#xff0c;首发于 CSDN&#xff0c;转载注明出处&#x1f649;&#x1f4e2;现…

C++服务端的配置文件库介绍

文章目录 1. inih 库原理使用方法 2. Boost.PropertyTree 库原理使用方法 3. jsoncpp 库原理使用方法 在 C 项目中&#xff0c;灵活地读取用户配置是提升软件可用性的重要部分。本文将介绍几种常见的 C 配置库&#xff0c;包括它们的原理和使用方法。 1. inih 库 原理 inih …

桥接模式、NAT模式 和 主机模式(Host-Only)区别

在虚拟化和网络配置中&#xff0c;桥接模式、NAT模式 和 主机模式&#xff08;Host-Only&#xff09;是虚拟机常用的网络连接模式。它们各自的网络特性和使用场景不同。下面详细分析它们的区别和适用场景。 1. 桥接模式 (Bridged Mode) 原理&#xff1a; 虚拟机的网卡会直接与…

06.队列介绍+实现

目录 一、队列的概念 二、队列的实现 1、头文件定义 2、功能函数实现 3、主函数测试 一、队列的概念 队列就像吃饭排队类似&#xff0c;先来先吃&#xff0c;先进先出。 队头&#xff1a;队列的头部。 队尾&#xff1a;队列的尾部。 入队&#xff1a;在队尾操作。 出队&…

根据输入的速度梯度张量A和涡量w计算得到李太克斯(Liutex)相关的量,包括r(可能是一个向量)、R和Omega

这段代码是用一种可能类似于 MATLAB 的语言编写的函数&#xff0c;其主要功能是根据输入的速度梯度张量A和涡量w计算得到李太克斯&#xff08;Liutex&#xff09;相关的量&#xff0c;包括r&#xff08;可能是一个向量&#xff09;、R和Omega。 具体步骤如下&#xff1a; 首先&…

SpringBoot实现的物流优化策略

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理智能物流管理系统的相关信息成为必然。开发…

STM32—BKP备份寄存器RTC实时时钟

1.BKP简介 BKP(Backup Registers)备份寄存器BKP可用于存储用户应用程序数据。当VDD&#xff08;2.0~3.6V&#xff09;电源被切断&#xff0c;他们仍然由VBAT(1.8~3.6V)维持供电。当系统在待机模式下被唤醒&#xff0c;或系统复位或电源复位时&#xff0c;他们也不会被复位TAMP…

如果用Java设计MySQL中表级锁、行级锁和间歇锁会是怎么的?

在 MySQL 中&#xff0c;锁机制是确保数据一致性和并发控制的重要手段。MySQL 支持多种锁类型&#xff0c;包括表级锁、行级锁等&#xff0c;每种锁的适用场景、影响范围和实现机制各不相同。我们将逐一介绍它们&#xff0c;并通过模拟代码展示不同锁的实现。 1. 锁类型及其影…

【GAMES101笔记速查——Lecture 16 Ray Tracing4】

上节课的内容&#xff1a;辐射度量学、光线传播、反射方程、渲染方程、全局光照、概率论复习 这节课要介绍一种真实的渲染方法-蒙特卡洛路径追踪 目录 1 简单回顾 1.1 渲染方程&#xff08;The Rendering Equation&#xff09; 1.2 概率 2 蒙特卡洛积分&#xff08;Monte…

ubuntu 24.04 下载安装离线包,ubuntu 24.04 配置xrdp

ubuntu 24.04 配置xrdp 1. 安装gnome-tweaks sudo apt install gnome-tweaks 2. 配置 cat <<EOF > ~/.xsessionrc export GNOME_SHELL_SESSION_MODEubuntu export XDG_CURRENT_DESKTOPubuntu:GNOME export XDG_CONFIG_DIRS/etc/xdg/xdg-ubuntu:/etc/xdg EOF 3.…

使用poi-tl动态写入目录更新问题解决

在使用poi-tl动态写完word后&#xff0c;是无法更新目录的&#xff0c;使用poi-tl提供的插件也是不行的&#xff0c;而且很多使用poi手动写入的也是不行&#xff0c;最多就是让你在打开文件时提示你更新目录/更新域&#xff0c;用户体验很差&#xff0c;要点击好几次而且wps还不…

SQL Injection | SQL 注入概述

关注这个漏洞的其他相关笔记&#xff1a;SQL 注入漏洞 - 学习手册-CSDN博客 0x01&#xff1a;SQL 注入漏洞介绍 SQL 注入就是指 Web 应用程序对用户输入数据的合法性没有判断&#xff0c;前端传入后端的参数是可控的&#xff0c;并且参数会带入到数据库中执行&#xff0c;导致…

(10) GTest c++单元测试(mac版)

文章目录 概要安装实现机制-断言&#xff08;简单、独立的测试&#xff09;实现机制-测试套件实现机制-Test Fixture和事件 概要 官方文档 https://google.github.io/googletest/ 安装 git clone https://github.com/google/googletestcd googletestmkdir build && c…

JavaScript 了解专用工作者线程

目录 一、何为专用工作者线程二、专用工作者线程的全局对象三、创建专用工作者线程的方法四、专用工作者线程特点END 一、何为专用工作者线程 最简单的WEB工作者线程,执行在页面加载外的其他任意如网络请求,繁杂计算操作并可以与页面通信. 二、专用工作者线程的全局对象 专用…