repeat语句 及 赋值语句说明---verilog HDL

news2024/11/25 18:25:26

参考:verilog数字系统设计教程【第四版】夏宇闻

repeat语句用阻塞赋值语句,与用非阻塞语句产生的结果差别非常大,所以将二者放在同一篇文章中。

1、赋值语句
2、repeat 语句介绍
  2.1、用法要点
  2.2、代码举例
   代码1:always 语句实现 repeat n 次赋值
   代码2:initial 语句实现 repeat n 次赋值
   代码3:给 memory 类型数据赋值
   代码4:实现 memory 类型储值

1、赋值语句

在 verilog HDL 语言中,信号有两种赋值方式,两者的区别见下表:

非阻塞赋值方式   (non_blocking)  b<=a阻塞赋值方式  (blocking)  b=a
在语句块中,上面语句所赋值的变量值不能立即为下面语句所用。b的值在赋值语句执行完后立刻改变
块结束后才能完成这次赋值操作,而所赋值的变量值是上一次赋值得到的。赋值语句执行完毕后,块才结束
在编写可综合的时序逻辑模块时,这是最常用的赋值方法。在时序逻辑中使用时,可能会产生意想不到的结果

仿真代码如下:

`timescale 1ns / 1ps

module tb_assignment;

reg clk;
reg rst;

initial begin
    clk = 1;
    rst = 1;
    #99;
    rst = 0;
end

always #1 clk = ~clk;

reg [7:0] count;
reg [7:0] count_r1;
reg [7:0] count_r2;
reg [7:0] non_count;
reg [7:0] non_count_r1;
reg [7:0] non_count_r2;

always @(posedge clk)begin
    if(rst )begin
        non_count <= 8'd0;
        non_count_r1 <= 8'd0;
        non_count_r2 <= 8'd0;
    end else begin
        non_count <= non_count + 1'd1;
        non_count_r1 <= non_count;
        non_count_r2 <= non_count_r1;
    end
end
always @(posedge clk)begin
    if(rst )begin
        count = 8'd0;
        count_r1 = 8'd0;
        count_r2 = 8'd0;
    end else begin
        count = count + 1'd1;
        count_r1 = count;
        count_r2 = count_r1;
    end
end

endmodule

仿真结果图
在这里插入图片描述

2、repeat 语句介绍

连续执行一条语句N次。

repeat语句格式
1、单语句
	repeat(表达式)语句
2、多语句
	repeat(表达式)begin
		多条语句;
	end

2.1、用法要点

表达式通常为常量表达式。

2.2、代码举例

代码1:always语句实现 repeat n 次赋值

实现乘法器

reg i_Clk;
reg i_rst;

initial begin
    i_Clk = 1;
    i_rst = 1;
    #101;
    i_rst = 0;
end
initial begin
    forever #1 i_Clk = ~i_Clk;
end

reg [3:0] size = 4;

reg [3:0] data_a = 4'b0110;
reg [3:0] data_b = 4'b1100;

//===============================================================================
// 	 always 语句
//===============================================================================

//============================================================= =
reg [7:0] result = 0;
reg [7:0] shift_a;
reg [7:0] shift_b;

always@(posedge i_Clk)begin
if(i_rst)begin
    result = 8'd0;   
    shift_a = data_a;   
    shift_b = data_b;   
end else  
    repeat(size) begin
        if(shift_b[0])
            result = result + shift_a;
        
        shift_a = shift_a << 1;
        shift_b = shift_b >> 1;
    end  
end
//============================================================= <=
reg [7:0] non_result = 0;
reg [7:0] non_shift_a;
reg [7:0] non_shift_b;

always@(posedge i_Clk)begin
if(i_rst)begin
    non_result <= 8'd0;   
    non_shift_a <= data_a;   
    non_shift_b <= data_b;   
end else  
    repeat(size) begin
        if(non_shift_b [0])
            non_result <= non_result + non_shift_a;
        
        non_shift_a <= non_shift_a << 1;
        non_shift_b <= non_shift_b >> 1;
    end  
end

仿真结果如下:
在这里插入图片描述

代码2:inital 语句实现 repeat n 次赋值

实现乘法器

//===============================================================================
//  initial 只执行一次  同上个版本共用 i_Clk 等信号
//===============================================================================

//================================================ =
initial begin
    result = 8'd0;   
    shift_a = data_a;   
    shift_b = data_b;
    #10;
    repeat(size) @(posedge i_Clk) begin
        if(shift_b[0])
            result = result + shift_a;
    
        shift_a = shift_a << 1;
        shift_b = shift_b >> 1;
    end  
end

//================================================ <=

initial begin
    non_result <= 8'd0;   
    non_shift_a <= data_a;   
    non_shift_b <= data_b;   
    #10;
    repeat(size) @(posedge i_Clk) begin
        if(non_shift_b[0])
            non_result <= non_result + non_shift_a;
    
        non_shift_a <= non_shift_a << 1;
        non_shift_b <= non_shift_b >> 1;
    end  
end

仿真结果如下:
因为 @(posedge i_Clk) 即实现下一时钟的作用,所以此处 <= 和 = 的仿真结果一样。

在这里插入图片描述

代码3:用于给 memory 类型数据赋值

reg i_Clk;
reg i_rst;

initial begin
    i_Clk = 1;
    i_rst = 1;
    #20;
    i_rst = 0;
end

initial begin
    forever #1 i_Clk = ~i_Clk;
end

//============================================== 
//  assgn  memory
//============================================== 
reg [3:0] test_data = 0;

reg [3:0] i = 0;
reg [3:0] buffer[7:0];

reg [3:0] j = 0;
reg [3:0] non_buffer[7:0];

always @ (posedge i_Clk)begin
    if(i_rst)
        test_data <= 4'd0;
    else
        test_data <= test_data + 1'd1;
end

//================================================================= =
always @(posedge i_Clk) begin
    i = 0  ;
    if (i_rst) // repeat 8 times to assign initial value
        repeat (8) begin
            buffer[i] = 4'b0 ;
            i = i + 1 ;
        end
    else 
        repeat (5) begin
            buffer[i] = test_data ;
            i = i + 1 ;
        end
end

/*  错误写法
always @(posedge i_Clk) begin
    i = 0  ;
    if (i_rst) 
        repeat (8) //i在下一时钟上升沿即变为8
            i = i + 1 ;
    else 
        repeat (5) //i在下一时钟上升沿即变为5
            i = i + 1 ;
end

always @(posedge i_Clk) begin
    i = 0  ;
    if (i_rst) 
        repeat (8) //在下一时钟上升沿buffer[8]变为0,其他buffer[]未赋初值
            buffer[i] = 4'b0 ;
    else 
        repeat (5) //在下一时钟上升沿buffer[5]变为test_data,其他buffer[]未赋值
            buffer[i] = test_data;
end
*/

//================================================================= <=
always @(posedge i_Clk) begin
    j <= 0  ;
    if (i_rst)
        repeat (8) begin
            non_buffer[j] <= 4'b0; //此处 = 和 <= 结果都无影响
            j <= j + 1 ;
        end
    else
        repeat (5) begin
            non_buffer[j] <= test_data; //此处 = 和 <= 结果都无影响
            j <= j + 1 ;
        end
end

/* 将 j 和 buffer 分开
always @(posedge i_Clk) begin
    j <= 0  ;
    if (i_rst)
        repeat (8) 
            j <= j + 1 ;
    else
        repeat (5) 
            j <= j + 1 ;
end

always @(posedge i_Clk) begin
    if (i_rst)
        repeat (8)
            non_buffer[j] <= 4'b0 ;//此处 = 和 <= 结果都无影响
    else
        repeat (5) 
            non_buffer[j] <= test_data ; //此处 = 和 <= 结果都无影响
end
*/

在这里插入图片描述

代码4:实现 memory 类型储值

reg i_Clk;
reg i_rst;

initial begin
    i_Clk = 1;
    i_rst = 1;
    #30;
    i_rst = 0;
end

initial begin
    forever #4 i_Clk = ~i_Clk;
end

reg data_valid;
reg [3:0] data_demo;

reg [3:0] buffer_cnt;
reg [3:0] buffer_demo [7:0];

always @ (posedge i_Clk)begin
    if(i_rst) begin
        data_valid <= 1'd0;
        data_demo <= 4'd0;
    end else begin
            
        if (data_demo == 4'd15)
            data_demo <= data_demo;
        else 
            data_demo <= data_demo + 1'd1;
        
        if (data_demo == 4'd8)
            data_valid <= 1'd0;
        else if(data_demo == 4'd0)
            data_valid <= 1'd1;
    end  
end

always@(posedge i_Clk)begin
    if(i_rst)
        buffer_cnt <= 4'd0;
    else if(data_valid)
        if(buffer_cnt == 4'd7)
            buffer_cnt <= buffer_cnt;
        else 
            buffer_cnt <= buffer_cnt + 1'd1;      
    else
         buffer_cnt <= 4'd0;
end

always @(posedge i_Clk) begin
    j = 0  ;
    if (i_rst)
        repeat (8) begin
            buffer_demo[j] <= 4'b0;
            j = j + 1 ;
        end
    else if(data_valid)
        buffer_demo[buffer_cnt] <= data_demo;
end

仿真结果图:

在这里插入图片描述

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

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

相关文章

2023年北向L2接口的发展会怎么样?

众所周知北向L2接口的逐笔成交功能可以精确查看每笔成交&#xff0c;跟踪北向资金动向&#xff0c;那么由于北向资金动向是股市行情的晴雨表&#xff0c;因此股民做股票投资是要时刻关注着北向资金流动方向的&#xff0c;那么北向L2接口作为帮助头者提供跟踪资金动向的服务软件…

浅谈撮合引擎

浅谈撮合引擎设计撮合引擎简介撮合引擎的发展币安中小型交易所小型交易所业务交易流程竞价方式交易所常用指令开发简易架构设计撮数据结构设计交易委托账本限价委托单其它委托单关键代码实现1.创建一个ringbuffer2. 设置事件监听4.订单撮合主逻辑撮合分支processMath函数逻辑PS…

uniapp实现iOS支付苹果内购支付踩过的坑以及具体操作步骤

由于我们app会员属于虚拟产品&#xff0c;所以苹果商店要求我们必须选择苹果内购&#xff0c;否则就勒令下架。 无奈&#xff0c;于是就又开始了踩坑之旅~ uniapp可以直接使用uni-pay的插件去进行苹果内购。 但是&#xff0c;在对接自己的项目之前&#xff0c;建议先跑通示例项…

JavaEE-Spring(Spring中的五大类注解,@Bean注解,对象装配(@Autowired,@Resource),Bean对象在Spring中的作用域)

文章目录1. 配置扫描路径2. Spring五大类注解3. Spring Bean注解对象装配4. Bean对象在Spring中的作用域5. Bean生命周期1. 配置扫描路径 只有设置了扫描路径&#xff0c;其他的路径下注解不会被Spring扫描 这里设置路径为com.beans下 <?xml version"1.0" enc…

(七)devops持续集成开发——jenkins流水线发布一个node环境下的前端vue项目

前言 在前面的章节中已经介绍了jenkins集成前端流水化部署环境的内容&#xff0c;本节内容是关于前端项目的流水化部署发布&#xff0c;通过实操发布一个前端项目&#xff0c;从而完成前端项目的流水化发布。前端项目主要是静态资源的发布&#xff0c;这里我们以一个vue项目为…

智慧物流信息化供应链管理体系转型发展现状

现如今&#xff0c;伴随着时代的迅速发展和高新科技水准的持续提升&#xff0c;人们慢慢进入了信息时代。在其中&#xff0c;物流制造行业也从以往20年前的粗放型管理机制慢慢变化为信息化、智慧化的管理机制。 5G、云计算技术、AI、物联网等新技术的出现加快了各个领域经营方法…

k线图中的三条线是什么?

新手投资朋友可能会在行情软件中发现&#xff0c;图表中除了K线以外&#xff0c;其下方还有三条颜色不一样的曲线&#xff0c;到底这三条线有什么功能呢&#xff1f;它们的使用方法又是怎样的呢&#xff1f; 其实&#xff0c;这三条线分别是短、中、长周期移动平均线&#xff0…

界面控件DevExpress WinForm——属于WinForm组件的MVVM框架

DevExpress WinForm拥有180组件和UI库&#xff0c;能为Windows Forms平台创建具有影响力的业务解决方案。DevExpress WinForm能完美构建流畅、美观且易于使用的应用程序&#xff0c;无论是Office风格的界面&#xff0c;还是分析处理大批量的业务数据&#xff0c;它都能轻松胜任…

谷粒学院——Day17【数据同步工具、SpringCloud【GateWay网关】、权限管理功能(接口)】

❤ 作者主页&#xff1a;Java技术一点通的博客 ❀ 个人介绍&#xff1a;大家好&#xff0c;我是Java技术一点通&#xff01;(&#xffe3;▽&#xffe3;)~* &#x1f34a; 记得关注、点赞、收藏、评论⭐️⭐️⭐️ &#x1f4e3; 认真学习&#xff0c;共同进步&#xff01;&am…

sql调优

一、MySQL架构总览&#xff1a; 三、SQL解析顺序 SELECT DISTINCT< select_list > FROM< left_table > < join_type > JOIN < right_table > ON < join_condition > WHERE< where_condition > GROUP BY< group_by_list > HAVING<…

振弦采集模块的频率值与温度值的修正

振弦采集模块的频率值与温度值的修正 此功能在 SF3.51 版本时增加。 固件版本 V3.51 修改固件版本号为 V3.51_2200827。 增加了频率和温度的多项式修正参数和对应指令。 $STFP、 $GTFP、 $STTP、 $GTTP 增加了 FFT 频幅数据输出功能。设置 ATSD_SEL.[5]为 1。 修正了 VM608 采集…

java实现的非关系型数据库:nosqldb

nosqldb一、nosqldb介绍二、nosqldb功能介绍三、数据存储结构介绍1. 数据文件存储结构(data.nosqldb)2.索引文件存储结构(index.mbdb)三、优化点1. 不支持连表查询2. 不支持分片存储3. 碎片整理一、nosqldb介绍 github地址 https://github.com/MaBo2420935619/nosqldb nosqld…

2022年终总结2023年计划

目录 前言&#xff1a; 2022年总结&#xff1a; 工作上&#xff1a; 生活上&#xff1a; 2023年规划&#xff1a; 工作上&#xff1a; 生活上&#xff1a; 前言&#xff1a; 嗨&#xff0c;不知不觉一年又过去了&#xff0c;2022已经结束了&#xff0c;我们迎来了2023。…

c++ -- STL容器--list容器

7. list容器7.1 简介① 功能&#xff1a;将数据进行链式存储。② 链表(list)是一种物理存储单元上非连续的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接实现的。③ 链表的组成&#xff1a;链表由一系列结点组成。④ 结点的组成&#xff1a;一个是存储数据元素…

serverless论文总结

1.Benchmarking, Analysis, and Optimization of Serverless Function Snapshots https://zhuanlan.zhihu.com/p/572288442 这项工作引入了vHive&#xff0c;一个针对无服务器实验的开源框架&#xff0c;它使系统研究人员能够在整个无服务器堆栈中进行创新。vHive集成了来自领…

ITSM | 权威指南发布,高速IT服务管理团队是什么样子的?

当Netflix正在打造流媒体平台时&#xff0c;还有人在营业厅里为一张网卡而烦恼。当Craig Newmark创建免费分类广告网站时&#xff0c;报社的网络管理员最关心的还是重启电子邮件服务器。当数字化转型成为一道必答题&#xff0c;谁能率先给出解题之法&#xff1f; 阅读本篇文章&…

Input子系统

文章目录前言Input子系统简介Input子系统代码实现框架Linux Input子系统支持的数据类型input核心层设备驱动层input_allocate_device 与 函数input_set_capabilityinput_register_device 函数input_unregister_device 与 input_free_device 函数事件处理层input_attach_handler…

A. Divide and Conquer

An array bb is good if the sum of elements of bb is even. You are given an array aa consisting of nn positive integers. In one operation, you can select an index ii and change ai:⌊ai2⌋ai:⌊ai2⌋. †† Find the minimum number of operations (possibly 00)…

ArcGIS 切片问题小结

1. 如果发布的切片缓存服务没有自动启动怎么办&#xff1f; 在进行切片时偶然情况下可能会遇到&#xff0c;你在切片时已经设置了server自动进行切片处理&#xff0c;但是在服务发布后&#xff0c;服务发布成功&#xff0c;但是服务没有成功启动&#xff0c;导致服务器没有自动…

免费数据恢复方法有哪些?分享这几种简单又实用的恢复方法(2023年最新)

很多时候&#xff0c;我们使用电脑总是容易误删一些数据。比如使用电脑&#xff0c;误删了办公资料&#xff1b;使用SD卡&#xff0c;出现照片没有办法打开的情况&#xff1b;使用移动硬盘&#xff0c;出现文档误格式化等问题。 不必要的数据被删除那就没问题&#xff0c;如果…