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.前言 小萌新们是不 ...
最新文章
- 封装的可运行于winform与web的Log4Net的类库
- python pop check mail_python初学者,用python3实现基本的学生管理系统代码实例
- Java中转发(Forward)和重定向(Redirect)的区别
- android 从assets和res中读取文件(转)
- nc拉单查询模版_用友NC的模板管理_操作步骤
- 张小龙《微信背后的产品观》演讲文字版
- Windows10下载CUDA总是下载失败的解决方案
- 考研倒计时软件 终结版
- 移动交互设计:提示语设计总结
- 网关和路由器功能的有哪些不同
- 普通计算机电缆,计算机电缆和普通电缆有什么区别吗?
- 服务器跑项目,如何使用远程服务器跑项目
- 自定义POI的excel工具类-xls-xlsx
- 计算机网络中计算机资源管理器,资源管理器
- 从BAT到ATM,蚂蚁金服的逻辑和风险
- 基于Java实现的贪吃蛇大作战小游戏
- c语言中为什么有时候输入一个数字之后要再输入一个才输出结果
- Valgrind——memcheck内存泄漏分析
- 计算机科学艺术家,计算机科学的鼻祖,编程界的上帝,视世界的码农当作艺术家...
- CodeCombat代码全记录(Python学习利器)--SARVEN沙漠(第三章)代码6