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,一经查实,立即删除!

相关文章

史上最烂 spring transaction 原理分析

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

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

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

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

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

06.队列介绍+实现

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

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…

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

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

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…

数字化营销助企业在生态平台实现内卷突围

在当今数字化时代&#xff0c;企业竞争激烈&#xff0c;内卷化严重。而数字化生态平台建设与数字化营销为企业带来了新机遇。 数字化生态平台意义重大。它能整合企业内外资源&#xff0c;提高运营效率。打破地域限制&#xff0c;拓展市场&#xff0c;吸引更多客户。还能为企业创…

【AI副业项目】太离谱了!爆涨粉47W+,下一个风口项目AI+大健康养S赛道,单月变现30W,教你如何用AI做爆款健康养生账号

我一直说小红薯平台是最适合新手素人做的平台&#xff0c;去中心化的平台&#xff0c;任何普通人都可以在这个平台分一杯羹的平台。 但但但是很多朋友发小红薯作品都是超低的小眼睛&#xff0c;连最基本的流量都没拿到。 从他们的经历来看就是小红薯太难做了。那是没有掌握技…

【Vue】Vue3.0 (十二)、watchEffect 和watch的区别及使用

上篇文章&#xff1a; 【Vue】Vue3.0 &#xff08;十二&#xff09;、watch对ref定义的基本类型、对象类型&#xff1b;reactive定义的对象类型的监视使用 &#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;Vue专栏&#xff1a;点击&#xff01; ⏰️创作时间&…

智慧油田智能安全管控方案-AI助力油气田安全管控升级

在科技日新月异的今天&#xff0c;万物纵横科技凭借其前沿的智慧油田智能安全管控方案&#xff0c;正引领着油气田行业向智能化、高效化转型。该方案深度融合了AI视频智能分析与AIoT&#xff08;物联网人工智能&#xff09;技术&#xff0c;为采油场、油气场的设备运维、环境监…

2024全网最详细CTF入门指南、CTF夺旗赛使用工具及刷题网站

2024年最新的CTF&#xff08;Capture The Flag&#xff0c;夺旗赛&#xff09;入门指南如下&#xff0c;涵盖了入门思路、常见题型及练习网站推荐&#xff0c;帮助你逐步了解并提升在CTF中的解题技巧。 如果你对网络安全入门感兴趣&#xff0c;我给大家整理好了相关资料&#…

Java集合剖析2】Java集合底层常用数据结构

一、数据结构与集合 接下来就要学习集合具体的实现类了&#xff0c;集合的实现类底层可能用1种或多种数据结构来存储数据。所以在学习集合的实现类前&#xff0c;我们有必要了解一下一些常见的数据结构&#xff0c;这样我们在后面查看集合实现类的底层源码时&#xff0c;才不会…

项目模块三:Socket模块

一、模块设计 1、套接字编程常用头文件展示 #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <fcntl.h> 2、成员函数设计 &#xff08;1&#xf…

题目:连续子序列

解题思路&#xff1a; 首先&#xff0c;不能使用暴力枚举&#xff0c;时间为O(n2)&#xff0c;超时。以下为正确做法&#xff1a; 假设找到一段区间&#xff08;其和>m&#xff09;&#xff0c;如上图黄色部分&#xff0c;那么该区间加上i后面的元素形成的新区间和都>m&a…

Excel中如何进行傅里叶变换(FT),几步完成

在 Excel 中&#xff0c;虽然没有像 MATLAB 那样专门的函数库来直接进行傅里叶变换&#xff0c;但可以使用 Excel 内置的分析工具库提供的傅里叶变换&#xff08;FT &#xff0c;Fourier Transform&#xff09;功能。这个工具可以对数据进行频域分析。以下是如何在 Excel 中进行…

【.net core使用minio大文件分片上传】.net core使用minio大文件分片上传以及断点续传、秒传思路

版本&#xff1a;.net core 7 需求&#xff1a;net限制了上传的大小&#xff0c;只能上传25M上下的文件&#xff0c;如果上传一个八十多兆的文件&#xff0c;swagger接口报错&#xff0c;如果前端调用上传接口&#xff0c;会报CORS跨域错误&#xff0c;这篇文章介绍怎么使用分片…

C#学习笔记(九)

C#学习笔记&#xff08;九&#xff09; 第六章 面向对象编程&#xff08;一&#xff09;类与对象、字段与属性一、类与对象正确的理解1. 什么是类&#xff1f;2.什么是对象&#xff1f;3. 类与对象的区别 二、类的基本规范和对象使用1. 类的规范 三、类的访问修饰符&#xff08…

GoFly快速开发框架的utils-plugin扩展包开发演示教程

说明 本插件是教大家如何开发框架utils->plugin下扩展插件包&#xff0c;在开发时可安装本插件&#xff0c;参考本插件代码结构写你插件&#xff0c;这样可以达到规范插件代码&#xff0c;同时也也是为了兼容你安装其他人在代码仓通过扩展插件包&#xff0c;如果不规范可能…