From c3fdf42825290323979730c8c3d21375853469e3 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Thu, 6 Dec 2012 17:16:17 +0100 Subject: [PATCH] bus/csr: add SRAM --- migen/bus/csr.py | 54 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/migen/bus/csr.py b/migen/bus/csr.py index df2543482..3200fb5e6 100644 --- a/migen/bus/csr.py +++ b/migen/bus/csr.py @@ -2,6 +2,7 @@ from migen.fhdl.structure import * from migen.bus.simple import * from migen.bus.transactions import * from migen.sim.generic import PureSimulable +from migen.bank.description import RegisterField data_width = 8 @@ -40,3 +41,56 @@ class Initiator(PureSimulable): if isinstance(self.transaction, TWrite): s.wr(self.bus.we, 1) s.wr(self.bus.dat_w, self.transaction.data) + +def _compute_page_bits(nwords): + npages = (nwords - 1)//512 + if npages > 0: + return bits_for(npages-1) + else: + return 0 + +class SRAM: + def __init__(self, mem_or_size, address, bus=Interface()): + if isinstance(mem_or_size, Memory): + assert(mem_or_size.width <= data_width) + self.mem = mem_or_size + else: + self.mem = Memory(data_width, mem_or_size//(data_width//8)) + self.address = address + page_bits = _compute_page_bits(self.mem.depth) + if page_bits: + self._page = RegisterField("page", page_bits) + else: + self._page = None + self.bus = bus + + def get_registers(self): + if self._page is None: + return [] + else: + return [self._page] + + def get_fragment(self): + port = self.mem.get_port(write_capable=True) + + sel = Signal() + sel_r = Signal() + sync = [sel_r.eq(sel)] + + comb = [ + sel.eq(self.bus.adr[9:] == self.address), + port.we.eq(sel & self.bus.we), + + port.dat_w.eq(self.bus.dat_w), + If(sel_r, + self.bus.dat_r.eq(port.dat_r) + ) + ] + + if self._page is None: + comb.append(port.adr.eq(self.bus.adr[:len(port.adr)])) + else: + pv = self._page.field.r + comb.append(port.adr.eq(Cat(self.bus.adr[:len(port.adr)-len(pv)], pv))) + + return Fragment(comb, sync, memories=[self.mem])