0
0
VerilogHow-ToBeginner · 4 min read

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

endmodule
💻

Example

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

endmodule
⚠️

Common Pitfalls

Common mistakes when implementing a Wishbone interface include:

  • Not properly synchronizing ack signal, causing timing issues.
  • Ignoring reset conditions, which can leave the interface in an undefined state.
  • Failing to check both cyc and stb signals before processing transactions.
  • Overlooking the difference between read and write cycles using the we signal.

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:

SignalDescription
clkClock signal for synchronization
rstReset signal to initialize interface
cycIndicates a valid bus cycle
stbStrobe signal for data transfer
weWrite enable (1=write, 0=read)
adrAddress bus for selecting memory/register
dat_iData input from master
dat_oData output to master
ackAcknowledge 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.