Verilog Code for Wishbone Bus Interface: Syntax and Example
A basic
wishbone bus interface in Verilog includes signals like clk, rst, cyc, stb, we, adr, dat_i, and dat_o. The interface controls data transfer by handshaking these signals between master and slave modules.Syntax
The Wishbone bus interface uses a set of standard signals to manage communication between master and slave devices. Key signals include:
- clk: Clock signal for synchronization.
- rst: Reset signal to initialize the interface.
- cyc: Indicates a valid bus cycle.
- stb: Strobe signal to indicate a valid data transfer.
- we: Write enable signal (1 for write, 0 for read).
- adr: Address bus for selecting the register or memory location.
- dat_i: Data input bus (from master to slave).
- dat_o: Data output bus (from slave to master).
- ack: Acknowledge signal from slave to master indicating completion.
This syntax forms the basis for implementing a Wishbone interface in Verilog.
verilog
module wishbone_interface(
input wire clk,
input wire rst,
input wire cyc,
input wire stb,
input wire we,
input wire [7:0] adr,
input wire [31:0] dat_i,
output reg [31:0] dat_o,
output reg ack
);
// Interface logic here
endmoduleExample
This example shows a simple Wishbone slave interface that responds to read and write requests. It uses an internal 256x32-bit memory array. When cyc and stb are high, and we is set, it writes data to memory. On read, it outputs the stored data and asserts ack to signal completion.
verilog
module wishbone_slave(
input wire clk,
input wire rst,
input wire cyc,
input wire stb,
input wire we,
input wire [7:0] adr,
input wire [31:0] dat_i,
output reg [31:0] dat_o,
output reg ack
);
reg [31:0] mem [0:255];
always @(posedge clk or posedge rst) begin
if (rst) begin
ack <= 0;
dat_o <= 32'b0;
end else begin
ack <= 0;
if (cyc && stb) begin
if (we) begin
mem[adr] <= dat_i;
ack <= 1;
end else begin
dat_o <= mem[adr];
ack <= 1;
end
end
end
end
endmoduleCommon Pitfalls
Common mistakes when implementing a Wishbone interface include:
- Not properly synchronizing
acksignal, causing timing issues. - Ignoring reset conditions, which can leave the interface in an undefined state.
- Failing to check both
cycandstbsignals before processing transactions. - Overlooking the difference between read and write cycles using the
wesignal.
Always ensure signals are handled in clocked processes and reset logic is included.
verilog
/* Wrong way: ack asserted without checking cyc and stb */ always @(posedge clk) begin if (we) begin mem[adr] <= dat_i; ack <= 1; // Incorrect: ack asserted unconditionally end end /* Right way: ack asserted only when cyc and stb are high */ always @(posedge clk or posedge rst) begin if (rst) begin ack <= 0; end else begin ack <= 0; if (cyc && stb) begin if (we) begin mem[adr] <= dat_i; ack <= 1; end end end end
Quick Reference
Remember these key points for Wishbone interface signals:
| Signal | Description |
|---|---|
| clk | Clock signal for synchronization |
| rst | Reset signal to initialize interface |
| cyc | Indicates a valid bus cycle |
| stb | Strobe signal for data transfer |
| we | Write enable (1=write, 0=read) |
| adr | Address bus for selecting memory/register |
| dat_i | Data input from master |
| dat_o | Data output to master |
| ack | Acknowledge signal from slave |
Key Takeaways
Always check both cyc and stb signals before processing Wishbone transactions.
Use the we signal to distinguish between read and write operations.
Synchronize the ack signal properly and include reset logic.
Implement address and data buses with correct widths for your design.
Test your interface with simple read/write cycles to ensure correct behavior.