Ana içeriğe geç

Wishbone RAM Slave - Teknik Dokümantasyon

İçindekiler

  1. Genel Bakış
  2. Modül Arayüzü
  3. Latency Pipeline
  4. Byte Enable Yazma
  5. Burst Desteği

Genel Bakış

Amaç

wb_ram_slave modülü, Wishbone bus'tan RAM modülüne arayüz sağlar. Konfigüre edilebilir gecikme (latency) ve byte-granular yazma işlemlerini destekler.

Dosya Konumu

rtl/wrapper/wb_ram_slave.sv

RAM Slave Mimarisi

┌─────────────────────────────────────────────────────────────────────────────────┐
│                          WB_RAM_SLAVE                                            │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                  │
│    Wishbone Interface              Latency Pipeline         RAM Interface       │
│                                                                                  │
│    ┌────────────┐               ┌─────────────────┐      ┌────────────────┐    │
│    │  cyc/stb   │──────────────►│                 │      │                │    │
│    │  we        │               │   Delay Shift   │─────►│   ram_we_o     │    │
│    │  addr      │──────────────►│   Register      │─────►│   ram_addr_o   │    │
│    │  wdata     │──────────────►│   (LATENCY)     │─────►│   ram_wdata_o  │    │
│    │  sel       │──────────────►│                 │─────►│   ram_wstrb_o  │    │
│    └────────────┘               └────────┬────────┘      └───────┬────────┘    │
│                                          │                       │             │
│    ┌────────────┐                        │                       │             │
│    │  ack       │◄───────────────────────┘                       │             │
│    │  rdata     │◄───────────────────────────────────────────────┘             │
│    │  err       │◄─── (1'b0)             │   ram_rdata_i                       │
│    └────────────┘                        │                                     │
│                                          │                                     │
│                     Latency: LATENCY cycles from req to ack                    │
│                                                                                  │
└─────────────────────────────────────────────────────────────────────────────────┘

Modül Arayüzü

Parametreler

module wb_ram_slave
  import ceres_param::*;
#(
    parameter int LATENCY = 1  // RAM access latency (cycles)
)

Port Tanımları

(
    input  logic clk_i,
    input  logic rst_ni,

    // Wishbone Slave Interface
    input  wb_master_t wb_m_i,    // Master request
    output wb_slave_t  wb_s_o,    // Slave response

    // RAM Interface
    output logic        ram_we_o,     // Write enable
    output logic [31:0] ram_addr_o,   // Address
    output logic [31:0] ram_wdata_o,  // Write data
    output logic [3:0]  ram_wstrb_o,  // Byte strobes
    input  logic [31:0] ram_rdata_i   // Read data
);

Latency Pipeline

Delay Shift Register

// Request tracking için shift register
logic [LATENCY-1:0] req_delay_q;
logic [LATENCY-1:0] we_delay_q;

wire wb_req = wb_m_i.cyc && wb_m_i.stb;

always_ff @(posedge clk_i or negedge rst_ni) begin
    if (!rst_ni) begin
        req_delay_q <= '0;
        we_delay_q  <= '0;
    end else begin
        // Shift request through pipeline
        req_delay_q <= {req_delay_q[LATENCY-2:0], wb_req};
        we_delay_q  <= {we_delay_q[LATENCY-2:0], wb_req && wb_m_i.we};
    end
end

ACK Generation

// ACK arrives LATENCY cycles after request
assign wb_s_o.ack = req_delay_q[LATENCY-1];

Timing Diyagramı (LATENCY=2)

              ┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐
clk_i      ───┘ └─┘ └─┘ └─┘ └─┘ └─┘ └─┘ └───

wb_req         ┌───────┐
           ────┘       └───────────────────

req_delay[0]       ┌───────┐
           ────────┘       └───────────────

req_delay[1]           ┌───────┐
(= ack)    ────────────┘       └───────────

           ├─T0─┼─T1─┼─T2─┤
           req  delay ack

Byte Enable Yazma

Write Strobe Handling

// Direct passthrough of byte enables
assign ram_we_o    = wb_req && wb_m_i.we;
assign ram_addr_o  = wb_m_i.adr;
assign ram_wdata_o = wb_m_i.dat;
assign ram_wstrb_o = wb_m_i.sel;

RAM Implementation Requirements

// RAM modülü byte-enable desteklemeli:
always_ff @(posedge clk) begin
    if (we) begin
        if (wstrb[0]) mem[addr][7:0]   <= wdata[7:0];
        if (wstrb[1]) mem[addr][15:8]  <= wdata[15:8];
        if (wstrb[2]) mem[addr][23:16] <= wdata[23:16];
        if (wstrb[3]) mem[addr][31:24] <= wdata[31:24];
    end
end

Store Instructions Mapping

Instruction sel Bytes Written
SW 4'b1111 All 4 bytes
SH (addr[1:0]=0) 4'b0011 Bytes 0,1
SH (addr[1:0]=2) 4'b1100 Bytes 2,3
SB (addr[1:0]=0) 4'b0001 Byte 0
SB (addr[1:0]=1) 4'b0010 Byte 1
SB (addr[1:0]=2) 4'b0100 Byte 2
SB (addr[1:0]=3) 4'b1000 Byte 3

Burst Desteği

Burst Detection

wire is_burst = (wb_m_i.cti == WB_CTI_INCR) ||
                (wb_m_i.cti == WB_CTI_EOB);
wire is_burst_end = (wb_m_i.cti == WB_CTI_EOB);

Burst State Machine

logic burst_active;
logic [1:0] burst_cnt;

always_ff @(posedge clk_i or negedge rst_ni) begin
    if (!rst_ni) begin
        burst_active <= 1'b0;
        burst_cnt    <= '0;
    end else begin
        if (wb_req && !burst_active && (wb_m_i.cti == WB_CTI_INCR)) begin
            // Start of burst
            burst_active <= 1'b1;
            burst_cnt    <= '0;
        end else if (burst_active && wb_req) begin
            burst_cnt <= burst_cnt + 1;
            if (is_burst_end) begin
                burst_active <= 1'b0;
            end
        end
    end
end

Burst Timing (4-beat)

              ┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐
clk_i      ───┘ └─┘ └─┘ └─┘ └─┘ └─┘ └─┘ └─┘ └───

wb_m_i.cyc     ┌───────────────────────────┐
           ────┘                           └───

wb_m_i.stb     ┌───┐   ┌───┐   ┌───┐   ┌───┐
           ────┘   └───┘   └───┘   └───┘   └───

wb_m_i.cti ────┤INCR├───┤INCR├───┤INCR├───┤EOB├───

wb_m_i.adr ────┤ A0 ├───┤ A1 ├───┤ A2 ├───┤ A3 ├───

wb_s_o.ack         ┌───┐   ┌───┐   ┌───┐   ┌───┐
           ────────┘   └───┘   └───┘   └───┘   └───

wb_s_o.dat     ────┤ D0├───┤ D1├───┤ D2├───┤ D3├───

Response Sinyalleri

// Read data from RAM (combinational or pipelined)
assign wb_s_o.dat = ram_rdata_i;

// No error or retry
assign wb_s_o.err = 1'b0;
assign wb_s_o.rty = 1'b0;

Konfigürasyon Örnekleri

Single-Cycle RAM

wb_ram_slave #(
    .LATENCY(1)
) i_ram_slave (
    .clk_i     (clk),
    .rst_ni    (rst_n),
    .wb_m_i    (wb_m),
    .wb_s_o    (wb_s),
    .ram_we_o  (ram_we),
    .ram_addr_o(ram_addr),
    .ram_wdata_o(ram_wdata),
    .ram_wstrb_o(ram_wstrb),
    .ram_rdata_i(ram_rdata)
);

Multi-Cycle RAM (External Memory)

wb_ram_slave #(
    .LATENCY(16)  // Slow external memory
) i_ext_ram_slave (
    .clk_i     (clk),
    .rst_ni    (rst_n),
    .wb_m_i    (wb_m),
    .wb_s_o    (wb_s),
    .ram_we_o  (ram_we),
    .ram_addr_o(ram_addr),
    .ram_wdata_o(ram_wdata),
    .ram_wstrb_o(ram_wstrb),
    .ram_rdata_i(ram_rdata)
);

Özet

wb_ram_slave modülü:

  1. Configurable Latency: LATENCY parametresi
  2. Byte Enable: Full sel/wstrb support
  3. Burst Support: CTI/BTE handling
  4. Simple Interface: Direct RAM connection

Bu modül, Wishbone bus'u RAM modüllerine bağlar.