- 博客(28)
- 收藏
- 关注
原创 Verilog手撕代码(11)1检测(统计个数、独热码检测、1的位置检测)
那么我们就可以利用一个for循环,把每一位相加,最后再把最终的结果和1比较一下,如果是1,那就是独热码,如果不是1,那就是其他的数。对于一个4位的二进制数,我们对这4位奇偶校验,利用异或门依次进行每一位,最后的结果如果是奇数个1那么4位异或之后结果就是1,如果偶数个1那么结果就是0。独热码是一种二进制编码方式,它的特点是,用来编码这个数的N位bit中,有且只有一位是1,其余位全部为0。因为只有1位是1,所以叫做one-hot (对应的,还有一种编码方式是只有1位是0,其余位都是1,叫做one-cold)
2023-06-25 15:42:32 5920 1
原创 Verilog手撕代码(10)异步复位同步释放
但此时第二级触发器不会立刻变高,它要么复位为0,要么跟随前一级触发器的输出Q1,而前一级触发器的输出Q1为0,因此,无论如何第二级触发器的输出都为0,而触发器1的输出,若稳定后Q1为1,那么rst_sync_n在下一个周期被拉高,实现同步释放;数字电路中的寄存器和RAM上电后的默认状态和数据是不确定的,复位就是将其回到初始状态0,RAM也可由此初始化到0,也可根据设计需要复位到1,此外,当逻辑进入到错误的状态时,用复位将所有逻辑复位到初始状态,如没有复位,则将一直处于错误逻辑状态。
2023-06-24 12:52:11 1681
原创 Verilog手撕代码(8)握手机制
valid_a用来指示数据输入data_in的有效性,valid_b用来指示数据输出data_out的有效性;实现串行输入数据累加输出,输入端输入8bit数据,每当模块接收到4个输入数据后,输出端输出4个接收到数据的累加结果。实现串并转换电路,输入端输入单bit数据,每当本模块接收到6个输入数据后,输出端输出拼接后的6bit数据。valid_a用来指示数据输入data_a的有效性,valid_b用来指示数据输出data_b的有效性;握手信号,就是为了模块之间的数据交互正确才衍生出来的信号。
2023-06-21 16:23:10 2122
原创 Verilog手撕代码(7)数据位宽转换
数据位宽转换器,一般常用于模块接口处,比如一个电路模块的输出数据位宽大于另一个模块的输入数据位宽,此时就需要进行数据位宽转换。比如SATA控制器中,内部数据位宽为32bit,但外部物理收发器PHY的接口通常为16bit,或者8bit,在不使用FIFO进行缓存的情况下,可以使用数据位宽转换器,通过时钟倍频在实现数据位宽的转换。其中,先到的8bit数据应置于输出16bit的高8位。假设数据从模块A传入到模块B,模块A的输出数据为32位,模块B的输入数据位宽为16位,并把数据从A传入B而不损失数据。
2023-06-19 18:45:04 6542 1
原创 Verilog手撕代码(6)分频器
其中a计数器是由clk_flag控制的,b计数器是由clk_out控制的,而本质上clk_flag是由系统时钟clk进行控制的,因此a由系统时钟clk控制,与其他采用系统时钟clk的模块都保持着相同的时钟关系,b由clk_out控制,与系统时钟clk存在一定的偏差,因此推荐使用脉冲信号的写法。在一些低速系统或模块中,使用分频时钟出现问题的概率较低,但在高速系统和模块中,使用分频时钟就会容易出现问题,导致各模块的时钟到达时间存在较大的偏差,为解决这个问题,分频时生成脉冲时钟。Testbench与上面一样。
2023-06-13 14:56:07 6848
原创 Verilog手撕代码(5)串转并、并转串
串转并的使用环境非常多,在接口处用到最多,在某些模块的输入仅允许串行输入时,而总线上的数时并行的,那就需要通过串并转换,把并行的数据转换成串行的数据,包括在输出的时候,需要把串行的数据转换成并行的数据,才能送到总线中,使用方法都是用一个计数器来计数实现。
2023-05-29 17:17:11 4765 1
原创 Verilog手撕代码(4)序列检测
序列检测有两种写法,分别为状态机和移位寄存器,且序列检测也有很多类型,如连续和非连续检测、重叠和非重叠检测、含有无关项检测。
2023-05-15 19:25:32 696
原创 Verilog手撕代码(3)状态机
一段式:整个状态机写到一个always模块里面,在该模块中既描述状态转移,又描述状态的输入和输出。二段式:用两个always模块来描述状态机,其中一个always模块采用同步时序描述状态转移;另一个模块采用组合逻辑判断状态转移条件,描述状态转移规律以及输出。三段式:在两个always模块描述方法基础上,使用三个always模块,一个always模块采用同步时序描述状态转移,一个always采用组合逻辑判断状态转移条件,描述状态转移规律,另一个always模块描述状态输出。应该选择哪一种状态机?
2023-05-14 16:56:12 1575 1
原创 Verilog手撕代码(2)边沿检测
在使用FIFO进行数据读写的时候,我们会用到边沿检测,比如当FIFO内的数据被读空了,这样 empty 信号就会从0→1,产生一个上升沿,当这个上升沿到来的时候代表FIFO内孔,我们就可以对FIFO进行一个写操作(把写使能拉高,往FIFO写数据),所以边沿检测是十分常用的东西,下面我们来讲讲边沿检测的原理、代码以及对应仿真。比如我们要检测信号 signal 的上升沿,我们使用两个寄存器,级联记录 signal 的值,这样由于寄存器延迟一拍的特性,第二个寄存器永远会延迟第一个寄存器。
2023-05-13 19:31:06 438
原创 Verilog手撕代码(1)加法器
逻辑电路事先得出每一位全加器的进位输入信号(并行计算各个加法器的进位),而无需再从最低位开始向高位逐位传递进位信号,一种用面积换性能的方法。:N bit的加法器由N个1 bit的全加器组成。从低位开始,逐位相加, 每一bit需要等待前面计算出来得到进位,才能进行下一bit的计算。所谓半加器,就是不考虑进位的加法器,只有两个输入和两个输出;这里只做简单介绍,流水线的相关知识点在这先不详细介绍,后续将详细介绍并分析流水线相关知识点!任意位宽的超前进位加法器的代码:(以4bit为例):电路比较复杂,面积大。
2023-05-13 18:01:04 1213
原创 Verilog基础语法(18)之仿真中显示任务
请注意,monitor 就 像 一 个 在 主 线 程 后 台 生 成 运 行 的 任 务 , 它 监 视 并 显 示 其 参 数 变 量 的 值 变 化。新 的 monitor就像一个在主线程后台生成运行的任务,它监视并显示其参数变量的值变化。显示系统任务主要用于显示信息和调试信息,从日志文件中跟踪仿真的流程,也有助于更快地进行调试。仿真可不是只有波形就完事无忧的,有的时候需要一些显示任务将某些节点的数据打印出来,有利于分析。在时间10ns显示变量b的最终更新值,也就是0x2E,而。
2023-05-11 20:54:23 269
原创 Verilog基础语法(17)之延迟控制语句与赋值语句
第5ns时,q也被赋值,但是在第5ns时(起始),q经过计算为0,它经过5ns后被赋值,因此,会一直为0,好像1被吞掉了似的,其实理解了二者的含义,很好理解。还是在第5ns时候(初),a和c都已经为1了,此时,q经过计算也为1,然后延迟5ns,赋值给q,因此,q在10ns时候为1。请注意,q在时间10单位时变成了1,因为语句在10个时间单位时被计算,RHS是a、b和c的组合,计算为1。在第5ns时候,a,b,q同时被赋值,a和c在第5s被非阻塞赋值,也就是在第5ns末有效。也可以用逗号 ,代替or操作符。
2023-05-11 19:59:22 1007
原创 Verilog基础语法(16)之编译预处理
define 标识符(宏名) 字符串(宏内容) 如:`define signal string它的作用是指定用标识符signal来代替string这个字符串,在编译预处理时,把程序中在该命令以后所有的signal都替换成string。这种方法使用户能以一个简单的名字代替一个长的字符串,也可以用一个有含义的名字来代替没有含义的数字和符号,因此把这个标识符(名字)称为“宏名”,在编译预处理时将宏名替换成字符串的过程称为“宏展开”。`define是宏定义命令。//这相当于定义 reg[1:8] data。
2023-05-11 15:55:20 648
原创 Verilog基础语法(15)之参数
参数是Verilog结构,它允许一个模块以不同的规格重复使用。例如,一个4位加法器可以被参数化为接受一个位数的值,并且可以在模块实例化期间传递新的参数值。所以,一个N位加法器可以变成4位、8位或16位加法器。它们就像函数的参数一样,在函数调用过程中被传递进来。8'b3下图所示的模块使用参数来指定设计内的总线宽度、数据宽度和FIFO的深度,在模块实例化时可以用新的值覆盖,也可以使用defparam语句。input addr;input sel;
2023-05-10 21:10:20 2015
原创 Verilog基础语法(14)之function和task
注意,一个函数至少要声明一个输入,如果函数没有返回任何东西,则返回类型为void。函数的作用是对输入进行一些处理,并返回一个单一的值,而任务则更为通用,它可以计算出多个结果值,并使用output和inout类型的参数返回。如果一个任务是静态的,那么它的所有成员变量将在同一任务的不同调用中被共享,该任务已被启动为并发运行。因此,在函数的作用域内声明另一个同名的变量是非法的。关键字automatic将使函数重入,在任务中声明的项目被动态分配,而不是在任务的不同调用之间共享。有两种方式来声明函数的输入。
2023-05-10 15:10:07 484
原创 Verilog基础语法(13)之case语句
case语句的功能是:在某个信号(本例中的sel)取不同的值时,给另一个信号(本例中的q)赋不同的值。在括弧内的表达式将被精确地评估一次,并按其编写顺序与备选方案列表进行比较,与给定表达式匹配的备选方案的语句将被执行。Verilog HDL针对电路的特性提供了case语句的其它两种形式用来处理case语句比较过程中的不必考虑的情况( don’t care condition )。如果所有的case项都不符合给定的表达式,则执行缺省项内的语句,缺省语句是可选的,在case语句中只能有一条缺省语句。
2023-05-10 14:19:39 16037 2
原创 Verilog基础语法(12)之控制块
在实际设计中,一般类别少时用if_else语句,类别多用case语句,if_else语句基本上可以处理所有的复杂判断条件,但是在实际电路中占用的资源较多,所以能用case语句尽量用case语句。在Verilog程序设计中,if_else语句和case语句都是选择语句,当满足某个条件是,就选择某一样状态,当然这两个语句也是有区别的。,是顺序执行的语句,所以我们在写if_else语句时需要对优先级进行考量,不然就会产生和我们设计不符的结果,并且还不容易发现错误。这将连续执行块内的语句,不可综合。
2023-05-09 21:37:12 199
原创 Verilog基础语法(11)之阻塞与非阻塞赋值
阻塞赋值在一个always块中,后面的语句会受到前语句的影响,具体来说,在同一个always中,一条阻塞赋值语句如果没有执行结束,那么该语句后面的语句就不能被执行,即被“阻塞”。在一个过程块内多个阻塞赋值语句是顺序执行的。一条非阻塞赋值语句的执行是不会阻塞下一条语句的执行,也就是说在本条非阻塞赋值语句执行完毕前,下一条语句也可开始执行。非阻塞赋值语句在过程块结束时才完成赋值操作。在一个过程块内的多个非阻塞赋值语句是并行执行的。在Verilog HDL语言中,信号有两种赋值方式,即阻塞赋值和非阻塞赋值。
2023-05-09 15:31:17 1940
原创 Verilog基础语法(10)之赋值语句
LHS可以是网的位选择、网的部分选择、变量或网,但不能是数组的引用和变量的位/部分选择。经过10ns,a和b的值被赋值为0, o 赋值为 1,但未成功,因为强制 o = a & b = 0,RHS可以包含任何计算为最终值的表达式,而LHS表示一个线网或一个变量,RHS中的值被赋值给它。在一开始的时候,由于a和b的初始值都为1, o = a & b 因此,o的值为1;每当b或c的值发生变化时,RHS中的整个表达式将被计算,a将被更新为新的值。再过10ns后,o被赋值为1,此时成功拉高,
2023-05-08 15:51:51 1684
原创 Verilog基础语法(9)之assign语句
赋值语法以关键字assign开头,后面是信号名,可以是单个信号,也可以是不同信号网的连接。右侧的表达式或信号被分配给左侧的网或网的表达式。reg类型的变量不能使用assign进行连续赋值,这是因为reg类型的变量可以存储数据,并且不需要连续驱动。当使用assign给wire类型的网络赋值时,称为显示连续赋值,如果在定义的时候就对其连续赋值,称为隐形连续赋值,隐形连续赋值在Verilog中是被允许的。延迟值对于指定门的延迟很有用,并用于模拟实际硬件中的时序行为,因为该值决定了何时应该用评估值分配网。
2023-05-08 14:59:14 7091
原创 Verilog基础语法(8)之块语句
在这个块中的语句将被并行执行,第一个被启动的语句将是数据被赋值为8’h00的语句,因为延迟是在fork-join启动后的10个时间单位。再过10个时间单位后,第一条语句将被启动,数据将得到8’h11的值。join中的语句是并行语句块,里面的每一条语句(使用分号或者begin…并行块内的每一条语句都并行执行,我们对这里的每一条语句进行说明,使用begin…end包裹的语句块也属于一条语句,即块语句。如上例,第一条语句从begin处开始,经过10个单位的延迟,执行第一条语句;上述两个语句块是并行执行的,
2023-05-08 14:17:24 387
原创 Verilog基础语法(7)之generate块
generate if中的条件必须是参数,这是很重要的一点,初学者容易误用,例如将generate if(),括号内给一个变量,根据其值选择执行哪一块语句。(2)for只能用在always块里面,generate for可以做assign赋值,用always块话,always写在generate for里;C语言的for里面的语句是串行顺序执行,而verilog的for内的语句实际是并行的,只是为了写代码方便才用for对多个同样的结构赋值。对应的,always块内的变量要声明成reg类型。
2023-05-06 13:39:17 4033 1
原创 Verilog基础语法(6)之initial块
一旦initial块中的所有语句被执行,initial块的执行就结束了。initial块可以理解为一个初始化块,在initial的起始位置的语句在0时刻即开始执行,之后如果遇到延时,则延时之后执行接下来的语句。然而,根据每个初始块中的语句和延迟,完成该块所需的时间可能会有所不同。如果最后一个块有30个时间单位的延迟,如下图所示,仿真将在30个时间单位结束,从而杀死了当时处于活动状态的所有其他initial块。或者使用复位信号进行初始化,但这会增加综合布线的负担,可以有意识的减少,除非不得不。
2023-05-04 15:31:24 2586
原创 Verilog基础语法(4)之模块和端口及其例化和处理
Verilog进行FPGA/IC设计值,通常划分为各个子模块,木模块之间可能相互例化,并在顶层统一例化,并连接成一个顶层模块文件。
2023-05-01 17:13:42 4022 1
原创 Verilog基础语法(3)之运算符
从上面的例子可以看出这两种不同运算符的优先级别。在Verilog HDL中有两种移位运算符:<< (左移位运算符) 和 >>(右移位运算符)。其使用方法如下:a>>n或a<<n,a是操作数,n表示移动几位,这两种移位运算都用0填补移出的空位。此外,移位运算符也可理解为乘除法,<< (左移位运算符) 可以理解为乘法, >>(右移位运算符)可理解为除法,如左移一位相当于乘2,右移一位相当于除2;关系运算符的优先级别低于算术运算符的优先级别。逻辑运算符中"&&“和”||“的优先级别低于关系运算符,”!
2023-04-30 17:32:30 8408 3
原创 Verilog基础语法(2)之标量和向量、多维数组和存储器
msb以及lsb可以是任何整数值–正负或零,不允许使用变量,而且Isb的值可以大于、等于或小于msb的值。但为了保持风格统一,也就是左边的值要比右边的值大,所以不建议lsb大于或等于msb。Verilog中常用的数据类型为wire、reg,两者都可以定义为一位变量和多位变量,其中一位的称为标量,多位的称为向量。在Verilog中,多维数组对应存储器,而向量可悲认为是一个深度为0的二维数组。位宽的表达方式在上下代码中应统一风格,一般以最左边为最高位,最右边为最低位。
2023-04-29 19:59:36 4266 6
原创 Verilog基础语法(1)之变量和数据类型
字符串中每一个字符为ASCII值,需要1byte/8bite的存储空间。字符串存储在reg型变量中时,reg变量的宽度必须足够大,以容纳字符串。如果变量的大小小于字符串,那么Verilog会截断字符串的最左边的位。如果变量的大小大于字符串,那么Verilog会在字符串的左边添加0。这两种常用于仿真,time 是无符号;数据宽度为64bit,用于存储仿真时间以便调试;realtime 与 time 的最大区别为:realtime 是存储浮点型时间数据;reg型变量用于存储数据,register,即寄存器。
2023-04-28 20:20:43 1998 3
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人