主节点
仿真的内容包括读数据、写数据和比较数据 3 部分,代码如下:
- `include "timescale.v"
- //模块定义
- module wb_master_model(clk, rst, adr, din, dout, cyc, stb, we, sel, ack, err, rty);
- //参数
- parameter dwidth = 32;
- parameter awidth = 32;
- //输入、输出
- input clk, rst;
- output [awidth -1:0] adr;
- input [dwidth -1:0] din;
- output [dwidth -1:0] dout;
- output cyc, stb;
- output we;
- output [dwidth/8 -1:0] sel;
- input ack, err, rty;
- //WIRE 定义
- reg [awidth -1:0] adr;
- reg [dwidth -1:0] dout;
- reg cyc, stb;
- reg we;
- reg [dwidth/8 -1:0] sel;
- reg [dwidth -1:0] q;
- // 存储逻辑
- //初始化
- initial
- begin
- adr = {awidth{1'bx}};
- dout = {dwidth{1'bx}};
- cyc = 1'b0;
- stb = 1'bx;
- we = 1'hx;
- sel = {dwidth/8{1'bx}};
- #1;
- end
- // 写数据周期
- task wb_write;
- input delay;
- integer delay;
- input [awidth -1:0] a;
- input [dwidth -1:0] d;
- begin
- // 延迟
- repeat(delay) @(posedge clk);
- // 设置信号值
- #1;
- adr = a;
- dout = d;
- cyc = 1'b1;
- stb = 1'b1;
- we = 1'b1;
- sel = {dwidth/8{1'b1}};
- @(posedge clk);
- // 等待从节点的应答信号
- while(~ack) @(posedge clk);
- #1;
- cyc = 1'b0;
- stb = 1'bx;
- adr = {awidth{1'bx}};
- dout = {dwidth{1'bx}};
- we = 1'hx;
- sel = {dwidth/8{1'bx}};
- end
- endtask
- // 读数据周期
- task wb_read;
- input delay;
- integer delay;
- input [awidth -1:0]a;
- output [dwidth -1:0] d;
- begin
- // 延迟
- repeat(delay) @(posedge clk);
- // 设置信号值
- #1;
- adr = a;
- dout = {dwidth{1'bx}};
- cyc = 1'b1;
- stb = 1'b1;
- we = 1'b0;
- sel = {dwidth/8{1'b1}};
- @(posedge clk);
- // 等待从节点应答信号
- while(~ack) @(posedge clk);
- #1;
- cyc = 1'b0;
- stb = 1'bx;
- adr = {awidth{1'bx}};
- dout = {dwidth{1'bx}};
- we = 1'hx;
- sel = {dwidth/8{1'bx}};
- d = din;
- end
- endtask
- // 比较数据
- task wb_cmp;
- input delay;
- integer delay;
- input [awidth -1:0] a;
- input [dwidth -1:0] d_exp;
- begin
- wb_read (delay, a, q);
- if (d_exp !== q)
- $display("Data compare error. Received %h, expected %h at time %t", q, d_exp,$time);
- end
- endtask
- endmodule