本文是记录总线仲裁器verilog实现的开发调试和测试过程;其中测试代码是我自己写的。下面描述波形是电路的理想情况,要考虑电路的延迟情况,以及保证电路的可靠性方面,实现的硬件电路会稍微复杂,不过作为程序员的角度理解硬件,verilog的路径正好合适。
1. 工程目录说明
- 根目录增加include目录,这个是后续需要的全局定义
- 在src增加include目录,这个是总线需要的定义
- bus_arbiter_tb.v是我写的,其余文件皆来自《CPU自制入门》作者
2. 测试用例注释
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| module bus_arbiter_tb; reg clk, reset,m0_req_,m1_req_,m2_req_,m3_req_; wire m0_grnt_,m1_grnt_,m2_grnt_,m3_grnt_;
bus_arbiter ba1(.clk(clk),.reset(reset) ,.m0_req_(m0_req_),.m0_grnt_(m0_grnt_) ,.m1_req_(m1_req_),.m1_grnt_(m1_grnt_) ,.m2_req_(m2_req_),.m2_grnt_(m2_grnt_) ,.m3_req_(m3_req_),.m3_grnt_(m3_grnt_) );
initial begin m0_req_ = `DISABLE_; m1_req_ = `DISABLE_; m2_req_ = `DISABLE_; m3_req_ = `DISABLE_; end initial begin clk = 0; forever #10 clk = ~clk; end initial begin reset = `RESET_ENABLE; #15 reset = `RESET_DISABLE; #20 m1_req_ = `ENABLE_; #260 m1_req_ = `DISABLE_; end initial begin #60 m2_req_ = `ENABLE_; #460 m2_req_ = `DISABLE_; #200 $finish; end
initial begin $dumpfile("bus_arbiter_tb.vcd"); $dumpvars(0, bus_arbiter_tb); end endmodule
|
3. 波形分析
结合上面的代码来看波形,在第15ns秒时reset信号变为DISABLE(高电平),接着在35ns秒时m1_req请求使用总线,直到第50ns时(也就是在35ns后clk的第一个上升沿),允许m1使用总线,m1grnt变成ENABLE_(低电平)。
上图是增加了m2请求的情况,在第60ns时m2就已经请求使用总线,但这个时候优先级最高的m1正在使用,直到m1使用完毕,也就是在第300ns的时候结束了总线的请求使用,m1grnt在稍后的下一个上升沿变成DISABLE(高电平),同时m2被允许使用总线,m2_grnt变为ENABLE_(低电平)。
项目工程文件点击下载