Wishbone RAM Slave - Teknik Dokümantasyon¶
İçindekiler¶
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¶
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¶
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ü:
- Configurable Latency: LATENCY parametresi
- Byte Enable: Full sel/wstrb support
- Burst Support: CTI/BTE handling
- Simple Interface: Direct RAM connection
Bu modül, Wishbone bus'u RAM modüllerine bağlar.