📄 wb_master.v
字号:
`include "timescale.v"// -*- Mode: Verilog -*-// Filename : wb_master.v// Description : Wishbone Master Behavorial// Author : Winefred Washington// Created On : 2002 12 24// Last Modified By: .// Last Modified On: .// Update Count : 0// Status : Unknown, Use with caution!// Description Specification// General Description: 8, 16, 32-bit WISHBONE Master// Supported cycles: MASTER, READ/WRITE// MASTER, BLOCK READ/WRITE// MASTER, RMW// Data port, size: 8, 16, 32-bit// Data port, granularity 8-bit// Data port, Max. operand size 32-bit// Data transfer ordering: little endian// Data transfer sequencing: undefined//module wb_master(CLK_I, RST_I, ACK_I, ADR_O, CYC_O, DAT_I, DAT_O, ERR_I, RTY_I, SEL_O, STB_O, WE_O); input CLK_I; input RST_I; input ACK_I; output [31:0] ADR_O; output CYC_O; input [31:0] DAT_I; output [31:0] DAT_O; input ERR_I; input RTY_I; output [3:0] SEL_O; output STB_O; output WE_O; reg [31:0] ADR_O; reg [3:0] SEL_O; reg CYC_O; reg STB_O; reg WE_O; reg [31:0] DAT_O; reg GO; integer cycle_end; integer address; integer data; integer selects; integer write_flag; always @(posedge CLK_I or posedge RST_I) begin if (RST_I) begin GO = 1'b0; end end // read single task rd; input [31:0] adr; output [31:0] result; begin cycle_end = 1; address = adr; selects = 255; write_flag = 0; GO <= 1; @(posedge CLK_I);// GO <= 0; // wait for cycle to start while (~CYC_O) @(posedge CLK_I); // wait for cycle to end while (CYC_O) @(posedge CLK_I); result = data;// $display(" Reading %h from address %h", result, address); end endtask // read task wr; input [31:0] adr; input [31:0] dat; input [3:0] sel; begin cycle_end = 1; address = adr; selects = sel; write_flag = 1; data = dat; GO <= 1; @(posedge CLK_I);// GO <= 0; // wait for cycle to start while (~CYC_O) @(posedge CLK_I); // wait for cycle to end while (CYC_O) @(posedge CLK_I);// $display(" Writing %h to address %h", data, address); end endtask // wr // block read task blkrd; input [31:0] adr; input end_flag; output [31:0] result; begin write_flag = 0; cycle_end = end_flag; address = adr; GO <= 1; @(posedge CLK_I);// GO <= 0; while (~(ACK_I & STB_O)) @(posedge CLK_I); result = data; end endtask // blkrd // block write task blkwr; input [31:0] adr; input [31:0] dat; input [3:0] sel; input end_flag; begin write_flag = 1; cycle_end = end_flag; address = adr; data = dat; selects = sel; GO <= 1; @(posedge CLK_I);// GO <= 0; while (~(ACK_I & STB_O)) @(posedge CLK_I); end endtask // blkwr // RMW task rmw; input [31:0] adr; input [31:0] dat; input [3:0] sel; output [31:0] result; begin // read phase write_flag = 0; cycle_end = 0; address = adr; GO <= 1; @(posedge CLK_I);// GO <= 0; while (~(ACK_I & STB_O)) @(posedge CLK_I); result = data; // write phase write_flag = 1; address = adr; selects = sel; GO <= 1; data <= dat; cycle_end <= 1; @(posedge CLK_I);// GO <= 0; while (~(ACK_I & STB_O)) @(posedge CLK_I); end endtask // rmw always @(posedge CLK_I) begin if (RST_I) ADR_O <= 32'h0000_0000; else ADR_O <= address; end always @(posedge CLK_I) begin if (RST_I | ERR_I | RTY_I) CYC_O <= 1'b0; else if ((cycle_end == 1) & ACK_I) CYC_O <= 1'b0; else if (GO | CYC_O) begin CYC_O <= 1'b1; GO <= 1'b0; end end // stb control always @(posedge CLK_I) begin if (RST_I | ERR_I | RTY_I) STB_O <= 1'b0; else if (STB_O & ACK_I) STB_O <= 1'b0; else if (GO | STB_O) STB_O <= 1'b1; end // selects & data always @(posedge CLK_I) begin if (write_flag == 0) begin SEL_O <= 4'b1111; if (STB_O & ACK_I) data <= DAT_I; end else begin SEL_O <= selects; DAT_O <= data; end end always @(posedge CLK_I) begin if (RST_I) WE_O <= 1'b0; else if (GO) WE_O <= write_flag; end endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -