DFI injector (untested)
This commit is contained in:
parent
c38de34a21
commit
5bc840b9c1
|
@ -0,0 +1,112 @@
|
|||
from migen.fhdl.structure import *
|
||||
from migen.bus import dfi
|
||||
from migen.bank.description import *
|
||||
from migen.bank import csrgen
|
||||
|
||||
def _data_en(trigger, output, delay, duration):
|
||||
dcounter = Signal(BV(4))
|
||||
dce = Signal()
|
||||
return [
|
||||
If(trigger,
|
||||
dcounter.eq(delay),
|
||||
dce.eq(1)
|
||||
).Elif(dce,
|
||||
dcounter.eq(dcounter - 1),
|
||||
If(dcounter == 0,
|
||||
If(~output,
|
||||
output.eq(1),
|
||||
dcounter.eq(duration)
|
||||
).Else(
|
||||
output.eq(0),
|
||||
dce.eq(0)
|
||||
)
|
||||
)
|
||||
)
|
||||
]
|
||||
|
||||
class DFIInjector:
|
||||
def __init__(self, csr_address, a, ba, d, nphases=1):
|
||||
self._int = dfi.Interface(a, ba, d, nphases)
|
||||
self.slave = dfi.Interface(a, ba, d, nphases)
|
||||
self.master = dfi.Interface(a, ba, d, nphases)
|
||||
|
||||
self._sel = Field("sel")
|
||||
self._cke = Field("cke")
|
||||
self._control = RegisterFields("control", [self._sel, self._cke])
|
||||
|
||||
self._cs = Field("cs", 1, WRITE_ONLY, READ_ONLY)
|
||||
self._we = Field("we", 1, WRITE_ONLY, READ_ONLY)
|
||||
self._cas = Field("cas", 1, WRITE_ONLY, READ_ONLY)
|
||||
self._ras = Field("ras", 1, WRITE_ONLY, READ_ONLY)
|
||||
self._rddata = Field("rddata", 1, WRITE_ONLY, READ_ONLY)
|
||||
self._wrdata = Field("wrdata", 1, WRITE_ONLY, READ_ONLY)
|
||||
self._command = RegisterFields("command",
|
||||
[self._cs, self._we, self._cas, self._ras, self._rddata, self._wrdata])
|
||||
|
||||
self._address = RegisterField("address", a)
|
||||
self._baddress = RegisterField("baddress", ba)
|
||||
|
||||
self._rddelay = RegisterField("rddelay", 4, reset=5)
|
||||
self._rdduration = RegisterField("rdduration", 3, reset=0)
|
||||
self._wrdelay = RegisterField("wrdelay", 4, reset=3)
|
||||
self._wrduration = RegisterField("wrduration", 3, reset=0)
|
||||
|
||||
self.bank = csrgen.Bank([
|
||||
self._control, self._command,
|
||||
self._address, self._baddress,
|
||||
self._rddelay, self._rdduration,
|
||||
self._wrdelay, self._wrduration
|
||||
], address=csr_address)
|
||||
|
||||
def get_fragment(self):
|
||||
comb = []
|
||||
sync = []
|
||||
|
||||
# mux
|
||||
connect_int = dfi.interconnect_stmts(self._int, self.master)
|
||||
connect_slave = dfi.interconnect_stmts(self.slave, self.master)
|
||||
comb.append(If(self._sel.r, *connect_slave).Else(*connect_int))
|
||||
|
||||
# phases
|
||||
rddata_en = Signal()
|
||||
wrdata_en = Signal()
|
||||
for phase in self._int.phases:
|
||||
comb += [
|
||||
phase.cke.eq(self._cke.r),
|
||||
phase.rddata_en.eq(rddata_en),
|
||||
phase.wrdata_en.eq(wrdata_en)
|
||||
]
|
||||
cmdphase = self._int.phases[0]
|
||||
for phase in self._int.phases[1:]:
|
||||
comb += [
|
||||
phase.cs_n.eq(1),
|
||||
phase.we_n.eq(1),
|
||||
phase.cas_n.eq(1),
|
||||
phase.ras_n.eq(1)
|
||||
|
||||
]
|
||||
|
||||
# commands
|
||||
comb += [
|
||||
If(self._command.re,
|
||||
cmdphase.cs_n.eq(~self._cs.r),
|
||||
cmdphase.we_n.eq(~self._we.r),
|
||||
cmdphase.cas_n.eq(~self._cas.r),
|
||||
cmdphase.ras_n.eq(~self._ras.r)
|
||||
).Else(
|
||||
cmdphase.cs_n.eq(1),
|
||||
cmdphase.we_n.eq(1),
|
||||
cmdphase.cas_n.eq(1),
|
||||
cmdphase.ras_n.eq(1)
|
||||
)
|
||||
]
|
||||
|
||||
# data enables
|
||||
sync += _data_en(self._command.re & self._rddata.r,
|
||||
rddata_en,
|
||||
self._rddelay.field.r, self._rdduration.field.r)
|
||||
sync += _data_en(self._command.re & self._wrdata.r,
|
||||
wrdata_en,
|
||||
self._wrdelay.field.r, self._wrduration.field.r)
|
||||
|
||||
return Fragment(comb, sync) + self.bank.get_fragment()
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Milkymist SoC (Software)
|
||||
* Copyright (C) 2012 Sebastien Bourdeauducq
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __HW_DFII_H
|
||||
#define __HW_DFII_H
|
||||
|
||||
#include <hw/common.h>
|
||||
|
||||
#define CSR_DFII_CONTROL MMPTR(0xe0001000)
|
||||
|
||||
#define DFII_CONTROL_SEL (0x01)
|
||||
#define DFII_CONTROL_CKE (0x02)
|
||||
|
||||
#define CSR_DFII_COMMAND MMPTR(0xe0001004)
|
||||
|
||||
#define DFII_COMMAND_CS (0x01)
|
||||
#define DFII_COMMAND_WE (0x02)
|
||||
#define DFII_COMMAND_CAS (0x04)
|
||||
#define DFII_COMMAND_RAS (0x08)
|
||||
#define DFII_COMMAND_RDDATA (0x10)
|
||||
#define DFII_COMMAND_WRDATA (0x20)
|
||||
|
||||
#define CSR_DFII_AH MMPTR(0xe0001008)
|
||||
#define CSR_DFII_AL MMPTR(0xe000100C)
|
||||
#define CSR_DFII_BA MMPTR(0xe0001010)
|
||||
|
||||
#define CSR_DFII_RDDELAY MMPTR(0xe0001014)
|
||||
#define CSR_DFII_RDDURATION MMPTR(0xe0001018)
|
||||
#define CSR_DFII_WRDELAY MMPTR(0xe000101C)
|
||||
#define CSR_DFII_WRDURATION MMPTR(0xe0001020)
|
||||
|
||||
#endif /* __HW_DFII_H */
|
19
top.py
19
top.py
|
@ -2,9 +2,9 @@ from fractions import Fraction
|
|||
|
||||
from migen.fhdl.structure import *
|
||||
from migen.fhdl import verilog, autofragment
|
||||
from migen.bus import wishbone, asmibus, wishbone2asmi, csr, wishbone2csr
|
||||
from migen.bus import wishbone, asmibus, wishbone2asmi, csr, wishbone2csr, dfi
|
||||
|
||||
from milkymist import m1crg, lm32, norflash, uart, sram, s6ddrphy
|
||||
from milkymist import m1crg, lm32, norflash, uart, sram, s6ddrphy, dfii
|
||||
import constraints
|
||||
|
||||
MHz = 1000000
|
||||
|
@ -12,6 +12,10 @@ clk_freq = (83 + Fraction(1, 3))*MHz
|
|||
sram_size = 4096 # in bytes
|
||||
l2_size = 8192 # in bytes
|
||||
|
||||
dfi_a = 13
|
||||
dfi_ba = 2
|
||||
dfi_d = 128 # TODO -> 64
|
||||
|
||||
def ddrphy_clocking(crg, phy):
|
||||
names = [
|
||||
"clk2x_90",
|
||||
|
@ -31,11 +35,17 @@ def get():
|
|||
#
|
||||
# ASMI
|
||||
#
|
||||
ddrphy0 = s6ddrphy.S6DDRPHY(1, 13, 2, 128)
|
||||
asmihub0 = asmibus.Hub(23, 128, 12) # TODO: get hub from memory controller
|
||||
asmiport_wb = asmihub0.get_port()
|
||||
asmihub0.finalize()
|
||||
|
||||
#
|
||||
# DFI
|
||||
#
|
||||
ddrphy0 = s6ddrphy.S6DDRPHY(1, dfi_a, dfi_ba, dfi_d)
|
||||
dfii0 = dfii.DFIInjector(2, dfi_a, dfi_ba, dfi_d, 2)
|
||||
dficon0 = dfi.Interconnect(dfii0.master, ddrphy0.dfi)
|
||||
|
||||
#
|
||||
# WISHBONE
|
||||
#
|
||||
|
@ -70,7 +80,8 @@ def get():
|
|||
uart0 = uart.UART(0, clk_freq, baud=115200)
|
||||
csrcon0 = csr.Interconnect(wishbone2csr0.csr, [
|
||||
uart0.bank.interface,
|
||||
ddrphy0.bank.interface
|
||||
ddrphy0.bank.interface,
|
||||
dfii0.bank.interface
|
||||
])
|
||||
|
||||
#
|
||||
|
|
Loading…
Reference in New Issue