毕业设计是要做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的一些小错误摘录相关推荐

  1. (107)FPGA面试题-Verilog编写200ns异步/同步低有效复位激励

    1.1 FPGA面试题-Verilog编写200ns异步/同步低有效复位激励 1.1.1 本节目录 1)本节目录: 2)本节引言: 3)FPGA简介: 4)FPGA面试题-Verilog编写200ns ...

  2. (106)FPGA面试题-Verilog编写50MHz时钟激励

    1.1 FPGA面试题-Verilog编写50MHz时钟激励 1.1.1 本节目录 1)本节目录: 2)本节引言: 3)FPGA简介: 4)FPGA面试题-Verilog编写50MHz时钟激励: 5) ...

  3. 建立强大的verilog编写环境

    可能标题有点大,各位看官仔细看吧... 第一部分各个开发编写环境介绍: 转自:https://zhuanlan.zhihu.com/p/33443736 各个编辑器的肤浅体验(for Verilog) ...

  4. Java——编写一个算术测试小软件

    问题描述: 编写一个算术测试小软件,用来训练小学生的算术能力.程序由3个类组成,其中Teacher类对象负责给出算术题目,并判断回答者的答案是否正确:ComputerFrame类对象提供的GUI界面看 ...

  5. java算术测试软件_Java——编写一个算术测试小软件

    问题描述: 编写一个算术测试小软件,用来训练小学生的算术能力.程序由3个类组成,其中Teacher类对象负责给出算术题目,并判断回答者的答案是否正确:ComputerFrame类对象提供的GUI界面看 ...

  6. PCL1.8.1安装和一些小错误

    PCL1.8.1安装和一些小错误 VS2017+Win10 安装 一些小错误 opencv冲突 C3861 "pop_t 找不到标识符" 安装 参考 https://blog.cs ...

  7. Verilog 编写规范

    在学习Python时,作者有一句话对我影响很大.作者希望我们在学习编写程序的时候注意一些业内约定的规范.在内行人眼中,你的编写格式,就已经暴露了你的程度.学习verilog也是一样的道理,一段好的ve ...

  8. java犯的小错误_[Java教程]十个JavaScript中易犯的小错误,你中了几枪?

    [Java教程]十个JavaScript中易犯的小错误,你中了几枪? 0 2015-06-01 12:00:19 序言 在今天,JavaScript已经成为了网页编辑的核心.尤其是过去的几年,互联网见 ...

  9. 在用c语言写代码是这么找出错误,写代码(C语言)常见粗心小错误

    打码(C语言)常见粗心小错误 标签(空格分隔): 博客 自我介绍 本人学院 (http://sdcs.sysu.edu.cn/) 欢迎访问 本人学号 16340213 目录 ##1.前言 小萌新们是不 ...

最新文章

  1. Xamarin.android Activity动画切换效果实现
  2. TypeScript中的枚举类型
  3. SecutrCRTt 连接VirtualBox 中的Ubuntu -端口转发
  4. mac下webstorm 安装
  5. NeurIPS 2020 | 自步对比学习:充分挖掘无监督学习样本
  6. springboot配置定时任务及常用的cron表达式
  7. 【洛谷P2680】运输计划
  8. LED计数电路,5输入按键编码器,7段数码管显示驱动集成为LED计数测试电路
  9. vba 中sql like用法
  10. 原来“抖商大会”和抖音没有关系!抖音起诉“抖商大会”主办方 索赔300万
  11. FineReport的JS编辑框和URL地址栏语法简介
  12. 麟龙指标通达信指标公式源码_麟龙指标通达信指标公式源码
  13. 关键词组合工具终结版标题自由组合工具使用教程
  14. 简直太强,把任意图片设置为鼠标指针
  15. Linux安装SSH
  16. 文献阅读笔记【10】:基于小尺度分形维数的裂缝图像分割方法
  17. 2020年度十大高薪岗位出炉:程序员霸榜
  18. 7-7 六度空间 (30分)
  19. PHP如何在照片下面写一行字_怎样在手机照片下方留白加文字?
  20. wifi6无线网卡驱动linux,Centos6.5 WIFI无线网卡驱动BCM43142驱动安装

热门文章

  1. android imageview 加边框,RCImageView 自定义圆角ImageView,带边框效果
  2. [教程] NETGEAR R7800 路由器TFTP刷机方法(适用于.img格式固件各种刷)
  3. LVGL hal indev(porting evdev)
  4. 换个角度看HTC,或许并没有那么悲观
  5. 软件功能测试 pdf,大话软件测试 pdf
  6. 大数据可视化大屏设计经验及案例分享
  7. 族蚂免费建站系统,3分钟搭建官网!
  8. 【WIFI】WiFi驱动中的Band Steering功能
  9. 经典管理学定律2 - 青蛙现象
  10. jsp和JavaScript读取servlet数据