verilog编写RoundRobinArbiter的一些小错误摘录
毕业设计是要做CGRA的共享存储器的仲裁和修复电路,先从仲裁入手,太久没写verilog有点生疏。
RoundRobin的代码网上有很多。这里主要是看的微信公众号"IC加油站"的老李的资源,copy了一下代码进行调试,代码如下。文章地址:仲裁器设计(二)-- Round Robin Arbiter
`timescale 1ns/1ps
// two paralleled fixed-priority arbiter using mask algorithm
module RR_Arbiter #(
parameter Req_Width = 6
)(
input clk,
input rst,
input [Req_Width-1:0] req,
output [Req_Width-1:0] gnt
);
reg [Req_Width-1:0] Pointer_Req;//denote the next priority
wire [Req_Width-1:0] req_mask;
wire [Req_Width-1:0] priority_mask;
wire [Req_Width-1:0] grant_mask;
wire [Req_Width-1:0] priority_unmask;
wire [Req_Width-1:0] grant_unmask;
wire no_req_mask_label;
//the first FP arbiter with masking
assign req_mask = req & Pointer_Req;
assign priority_mask[0] = 1'b0;
assign priority_mask[Req_Width-1:1] = req_mask[Req_Width-2:0] | priority_mask[Req_Width-2:0];
assign grant_mask[Req_Width-1:0] = req_mask[Req_Width-1:0] & (~priority_mask[Req_Width-1:0]);//the second FP arbiter without masking
assign priority_unmask[0] = 1'b0;
assign priority_unmask[Req_Width-1:1] = req[Req_Width-2:0] | priority_unmask[Req_Width-2:0];
assign grant_unmask[Req_Width-1:0] = req[Req_Width-1:0] & (~priority_unmask[Req_Width-1:0]);//Based on the value of req_mask, choose mask or unmask. (if req_mask is none, it means two conditions
//1: no req; 2: req is in the unmask part.
assign no_req_mask_label = ~(|req_mask);
assign gnt = ({Req_Width{no_req_mask_label}} & grant_unmask) | grant_mask;//Update the Pointer_Reg
always @ (posedge clk) beginif (rst) beginPointer_Req <= {Req_Width{1'b1}};// initializeendelse beginif (|req_mask) begin // still have req after maskPointer_Req <= priority_mask;endelse begin // no req after mask, so choose the req with no maskif (|req) begin //req with no mask have reqPointer_Req <= priority_unmask;endelse begin //req with no mask is none, so remain, don't changePointer_Req <= Pointer_Req;endendend
end
endmodule
其实就是一个简单的组合逻辑加上寄存器存储上一个周期的Pointer_Req用于优先级的轮换,随后编写testbench代码如下:
`timescale 1ns/1ps
module tb_RR_Arbiter #(
parameter Req_Width = 5
)(
//input [Req_Width-1:0] req,
//input clk,
//input rst,
//output reg [Req_Width-1:0] gnt
);reg [Req_Width-1:0] req;
wire [Req_Width-1:0] gnt;
reg clk;
reg rst;RR_Arbiter #(5) RRA1 (
.clk(clk),
.rst(rst),
.req(req),
.gnt(gnt)
);parameter ClockPeriod = 10 ;initialbeginclk = 1 ;repeat(20)#(ClockPeriod) clk = ~clk;endinitial beginrst = 1;req = {Req_Width{1'b0}};#20 rst = 0; req = 6'b01010;#20 req = 6'b01011;#20 req = 6'b10011;#20 req = 6'b01010;$finish;endendmodule
在Modelsim和Vivado中都跑了下代码,仿真会有问题,问题出现在always块中的pointer_req更新后直接被该周期使用了,没有存储给下一周期。因此,给输出加一拍延时缓冲即可,代码改进如下:
`timescale 1ns/1ps
// two paralleled fixed-priority arbiter using mask algorithm
module RR_Arbiter #(
parameter Req_Width = 5
)(
input clk,
input rst,
input [Req_Width-1:0] req,
output [Req_Width-1:0] gnt,
output reg [Req_Width-1:0] Pointer_Req_test, // for test
output reg [Req_Width-1:0] q_test,
output [Req_Width-1:0] req_mask,
output [Req_Width-1:0] priority_mask,
output [Req_Width-1:0] priority_unmask,
output [Req_Width-1:0] grant_unmask,
output [Req_Width-1:0] grant_mask,
output label_req_mask,
output reg [2:0] label_req
);
reg [Req_Width-1:0] Pointer_Req;//denote the next priority
//wire [Req_Width-1:0] req_mask;
//wire [Req_Width-1:0] priority_mask;
//wire [Req_Width-1:0] grant_mask;
//wire [Req_Width-1:0] priority_unmask;
//wire [Req_Width-1:0] grant_unmask;
wire no_req_mask_label;
//the first FP arbiter with masking
assign req_mask = req & Pointer_Req;
assign priority_mask[0] = 1'b0;
assign priority_mask[Req_Width-1:1] = req_mask[Req_Width-2:0] | priority_mask[Req_Width-2:0];//or operation for each bit, from small to big bit
assign grant_mask[Req_Width-1:0] = req_mask[Req_Width-1:0] & (~priority_mask[Req_Width-1:0]);//the second FP arbiter without masking
assign priority_unmask[0] = 1'b0;
assign priority_unmask[Req_Width-1:1] = req[Req_Width-2:0] | priority_unmask[Req_Width-2:0];//?????????
assign grant_unmask[Req_Width-1:0] = req[Req_Width-1:0] & (~priority_unmask[Req_Width-1:0]);//Based on the value of req_mask, choose mask or unmask. (if req_mask is none, it means two conditions
//1: no req; 2: req is in the unmask part.
assign no_req_mask_label = ~(|req_mask);
assign gnt = ({Req_Width{no_req_mask_label}} & grant_unmask) | grant_mask;//test
assign label_req_mask = |req_mask;
//assign label_req = |req;
//reg [Req_Width-1:0] q;
//Update the Pointer_Regalways @ (posedge clk) begin#1if (rst) beginq_test <= {Req_Width{1'b1}};// initialize//q_test <= q;//Pointer_Req <= q_test;//Pointer_Req_test <= q_test;label_req <= 1;//Pointer_Req_test <= {Req_Width{1'b1}};endelse beginif (label_req_mask) begin // still have req after maskq_test <= priority_mask;//Pointer_Req <= q_test;//Pointer_Req_test <= q_test;label_req <= 2;//Pointer_Req_test <= priority_mask;endelse begin // no req after mask, so choose the req with no maskif (|req) begin //req with no mask have reqq_test <= priority_unmask;//Pointer_Req <= q_test;// delay one clock, otherwise the result will be wrong, since the comb circuit will immediately use the pointer-reg//Pointer_Req_test <= q_test;label_req <= 3;//Pointer_Req_test <= priority_unmask;endelse begin //req with no mask is none, so remain, don't changeq_test <= Pointer_Req;//Pointer_Req <= q_test;//Pointer_Req_test <= q_test;label_req <= 4;//Pointer_Req_test <= Pointer_Req;endendendendalways @ (posedge clk) beginPointer_Req <= q_test;Pointer_Req_test <= q_test;
end
endmodule
同时在Always块中加入少许延时,确保每次计算该周期的gnt的时候用的是上一周期的Pointer_Req而不是本周期。随后,tb代码如下:
`timescale 1ns/1ps
module tb_RR_Arbiter #(
parameter Req_Width = 10
)(
//input [Req_Width-1:0] req,
//input clk,
//input rst,
//output reg [Req_Width-1:0] gnt
);reg [Req_Width-1:0] req;
wire [Req_Width-1:0] gnt;
reg clk;
reg rst;
wire [Req_Width-1:0] Pointer_Req_test;
wire [Req_Width-1:0] q_test;
wire [Req_Width-1:0] req_mask;
wire [Req_Width-1:0] priority_mask;
wire [Req_Width-1:0] priority_unmask;
wire [Req_Width-1:0] grant_mask;
wire [Req_Width-1:0] grant_unmask;
wire label_req_mask;
wire [2:0] label_req;
RR_Arbiter #(Req_Width) RRA1 (
.clk(clk),
.rst(rst),
.req(req),
.gnt(gnt),
.Pointer_Req_test(Pointer_Req_test),
.q_test(q_test),
.req_mask(req_mask),
.priority_mask(priority_mask),
.priority_unmask(priority_unmask),
.grant_mask(grant_mask),
.grant_unmask(grant_unmask),
.label_req_mask(label_req_mask),
.label_req(label_req)
);parameter ClockPeriod = 10 ;initialbeginclk = 1 ;repeat(40)#(ClockPeriod) clk = ~clk;endinitial beginrst = 1;req = {Req_Width{1'b0}};#40 rst = 0; req = 10'b0000000000;//0#20 req = 10'b0000001101;//2#20 req = 10'b0000001110;//cha dui#20 req = 10'b0001101101;//4#20 req = 10'b0011101001;#20 req = 10'b0011100101;#20 req = 10'b0011000110;#20 req = 10'b0010000111;//again#20 req = 10'b0000000111;#20 req = 10'b1000000110;#20 req = 10'b1000000110;#20 req = 10'b1000000011;$finish;endendmodule
得到的仿真图如下:
总结:太久没有编写verilog,过于生疏,需要熟练。时序电路的阻塞和非阻塞赋值需要注意,有时候设计时钟上升沿触发,可能输入信号的值变为了这一周期而不是上一周期的,学会用延时去卡拍。
verilog编写RoundRobinArbiter的一些小错误摘录相关推荐
- (107)FPGA面试题-Verilog编写200ns异步/同步低有效复位激励
1.1 FPGA面试题-Verilog编写200ns异步/同步低有效复位激励 1.1.1 本节目录 1)本节目录: 2)本节引言: 3)FPGA简介: 4)FPGA面试题-Verilog编写200ns ...
- (106)FPGA面试题-Verilog编写50MHz时钟激励
1.1 FPGA面试题-Verilog编写50MHz时钟激励 1.1.1 本节目录 1)本节目录: 2)本节引言: 3)FPGA简介: 4)FPGA面试题-Verilog编写50MHz时钟激励: 5) ...
- 建立强大的verilog编写环境
可能标题有点大,各位看官仔细看吧... 第一部分各个开发编写环境介绍: 转自:https://zhuanlan.zhihu.com/p/33443736 各个编辑器的肤浅体验(for Verilog) ...
- Java——编写一个算术测试小软件
问题描述: 编写一个算术测试小软件,用来训练小学生的算术能力.程序由3个类组成,其中Teacher类对象负责给出算术题目,并判断回答者的答案是否正确:ComputerFrame类对象提供的GUI界面看 ...
- java算术测试软件_Java——编写一个算术测试小软件
问题描述: 编写一个算术测试小软件,用来训练小学生的算术能力.程序由3个类组成,其中Teacher类对象负责给出算术题目,并判断回答者的答案是否正确:ComputerFrame类对象提供的GUI界面看 ...
- PCL1.8.1安装和一些小错误
PCL1.8.1安装和一些小错误 VS2017+Win10 安装 一些小错误 opencv冲突 C3861 "pop_t 找不到标识符" 安装 参考 https://blog.cs ...
- Verilog 编写规范
在学习Python时,作者有一句话对我影响很大.作者希望我们在学习编写程序的时候注意一些业内约定的规范.在内行人眼中,你的编写格式,就已经暴露了你的程度.学习verilog也是一样的道理,一段好的ve ...
- java犯的小错误_[Java教程]十个JavaScript中易犯的小错误,你中了几枪?
[Java教程]十个JavaScript中易犯的小错误,你中了几枪? 0 2015-06-01 12:00:19 序言 在今天,JavaScript已经成为了网页编辑的核心.尤其是过去的几年,互联网见 ...
- 在用c语言写代码是这么找出错误,写代码(C语言)常见粗心小错误
打码(C语言)常见粗心小错误 标签(空格分隔): 博客 自我介绍 本人学院 (http://sdcs.sysu.edu.cn/) 欢迎访问 本人学号 16340213 目录 ##1.前言 小萌新们是不 ...
最新文章
- Xamarin.android Activity动画切换效果实现
- TypeScript中的枚举类型
- SecutrCRTt 连接VirtualBox 中的Ubuntu -端口转发
- mac下webstorm 安装
- NeurIPS 2020 | 自步对比学习:充分挖掘无监督学习样本
- springboot配置定时任务及常用的cron表达式
- 【洛谷P2680】运输计划
- LED计数电路,5输入按键编码器,7段数码管显示驱动集成为LED计数测试电路
- vba 中sql like用法
- 原来“抖商大会”和抖音没有关系!抖音起诉“抖商大会”主办方 索赔300万
- FineReport的JS编辑框和URL地址栏语法简介
- 麟龙指标通达信指标公式源码_麟龙指标通达信指标公式源码
- 关键词组合工具终结版标题自由组合工具使用教程
- 简直太强,把任意图片设置为鼠标指针
- Linux安装SSH
- 文献阅读笔记【10】:基于小尺度分形维数的裂缝图像分割方法
- 2020年度十大高薪岗位出炉:程序员霸榜
- 7-7 六度空间 (30分)
- PHP如何在照片下面写一行字_怎样在手机照片下方留白加文字?
- wifi6无线网卡驱动linux,Centos6.5 WIFI无线网卡驱动BCM43142驱动安装
热门文章
- android imageview 加边框,RCImageView 自定义圆角ImageView,带边框效果
- [教程] NETGEAR R7800 路由器TFTP刷机方法(适用于.img格式固件各种刷)
- LVGL hal indev(porting evdev)
- 换个角度看HTC,或许并没有那么悲观
- 软件功能测试 pdf,大话软件测试 pdf
- 大数据可视化大屏设计经验及案例分享
- 族蚂免费建站系统,3分钟搭建官网!
- 【WIFI】WiFi驱动中的Band Steering功能
- 经典管理学定律2 - 青蛙现象
- jsp和JavaScript读取servlet数据