mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
Map DDR PHY controls in CSR
This commit is contained in:
parent
5d1dad583b
commit
c387ce7ce5
4 changed files with 81 additions and 8 deletions
|
@ -1,8 +1,10 @@
|
|||
from migen.fhdl.structure import *
|
||||
from migen.bus import dfi
|
||||
from migen.bank.description import *
|
||||
from migen.bank import csrgen
|
||||
|
||||
class S6DDRPHY:
|
||||
def __init__(self, a, ba, d):
|
||||
def __init__(self, csr_address, a, ba, d):
|
||||
ins = []
|
||||
outs = []
|
||||
inouts = []
|
||||
|
@ -16,8 +18,7 @@ class S6DDRPHY:
|
|||
"clk4x_rd_left",
|
||||
"clk4x_rd_strb_left",
|
||||
"clk4x_rd_right",
|
||||
"clk4x_rd_strb_right",
|
||||
"reset_n"
|
||||
"clk4x_rd_strb_right"
|
||||
]:
|
||||
s = Signal(name=name)
|
||||
setattr(self, name, s)
|
||||
|
@ -50,6 +51,8 @@ class S6DDRPHY:
|
|||
outs += self.dfi.get_standard_names(False, True)
|
||||
|
||||
ins += [
|
||||
("reset_n", BV(1)),
|
||||
|
||||
("cfg_al", BV(3)),
|
||||
("cfg_cl", BV(3)),
|
||||
("cfg_bl", BV(2)),
|
||||
|
@ -87,8 +90,23 @@ class S6DDRPHY:
|
|||
("DM_IO_LOC", Constant(2**4-1, BV(4)))
|
||||
],
|
||||
clkport="clk")
|
||||
|
||||
self._reset_n = Field("reset_n")
|
||||
self._init_done = Field("init_done")
|
||||
self._phy_cal_done = Field("phy_cal_done", 1, READ_ONLY, WRITE_ONLY)
|
||||
self._status = RegisterFields("status",
|
||||
[self._reset_n, self._init_done, self._phy_cal_done])
|
||||
self._req = RegisterRaw("req", 2)
|
||||
self._req_addr = RegisterField("req_addr", 8, READ_ONLY, WRITE_ONLY)
|
||||
|
||||
self.bank = csrgen.Bank([self._status, self._req, self._req_addr],
|
||||
address=csr_address)
|
||||
|
||||
def get_fragment(self):
|
||||
pending_r = Signal()
|
||||
pending_w = Signal()
|
||||
cpg_busy = Signal()
|
||||
|
||||
comb = [
|
||||
self._inst.ins["cfg_al"].eq(0),
|
||||
self._inst.ins["cfg_cl"].eq(3),
|
||||
|
@ -99,6 +117,22 @@ class S6DDRPHY:
|
|||
self._inst.ins["diag_io_sel"].eq(0),
|
||||
self._inst.ins["diag_disable_cal_on_startup"].eq(0),
|
||||
self._inst.ins["diag_cal_bits"].eq(0),
|
||||
self._inst.ins["diag_short_cal"].eq(0)
|
||||
self._inst.ins["diag_short_cal"].eq(0),
|
||||
|
||||
self._inst.ins["reset_n"].eq(self._reset_n.r),
|
||||
self._inst.ins["init_done"].eq(self._init_done.r),
|
||||
self._phy_cal_done.w.eq(self._inst.outs["phy_cal_done"]),
|
||||
self._req_addr.field.w.eq(self._inst.outs["cpg_addr"][2:10]),
|
||||
|
||||
self._req.w.eq(Cat(pending_r, pending_w)),
|
||||
cpg_busy.eq(pending_r | pending_w),
|
||||
self._inst.ins["cpg_busy"].eq(cpg_busy)
|
||||
]
|
||||
return Fragment(comb, instances=[self._inst], pads=set(self._sd_pins))
|
||||
sync = [
|
||||
If(self._inst.outs["cpg_r_req"], pending_r.eq(1)),
|
||||
If(self._inst.outs["cpg_w_req"], pending_w.eq(1)),
|
||||
If(self._req.re & self._req.r[0], pending_r.eq(0)),
|
||||
If(self._req.re & self._req.r[1], pending_w.eq(0))
|
||||
]
|
||||
return Fragment(comb, sync, instances=[self._inst], pads=set(self._sd_pins)) \
|
||||
+ self.bank.get_fragment()
|
||||
|
|
36
software/include/hw/s6ddrphy.h
Normal file
36
software/include/hw/s6ddrphy.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* 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_S6DDRPHY_H
|
||||
#define __HW_S6DDRPHY_H
|
||||
|
||||
#include <hw/common.h>
|
||||
|
||||
#define CSR_DDRPHY_STATUS MMPTR(0xe0000800)
|
||||
|
||||
#define DDRPHY_STATUS_RESETN (0x1)
|
||||
#define DDRPHY_STATUS_INIT_DONE (0x2)
|
||||
#define DDRPHY_STATUS_PHY_CAL_DONE (0x4)
|
||||
|
||||
#define CSR_DDRPHY_REQUESTS MMPTR(0xe0000804)
|
||||
|
||||
#define DDRPHY_REQUEST_READ (0x1)
|
||||
#define DDRPHY_REQUEST_WRITE (0x2)
|
||||
|
||||
#define CSR_DDRPHY_REQADDR MMPTR(0xe0000808)
|
||||
|
||||
#endif /* __HW_S6DDRPHY_H */
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include <hw/common.h>
|
||||
|
||||
#define CSR_UART_RXTX MMPTR(0xe0000000)
|
||||
#define CSR_UART_RXTX MMPTR(0xe0000000)
|
||||
#define CSR_UART_DIVISORH MMPTR(0xe0000004)
|
||||
#define CSR_UART_DIVISORL MMPTR(0xe0000008)
|
||||
|
||||
|
|
7
top.py
7
top.py
|
@ -31,7 +31,7 @@ def get():
|
|||
#
|
||||
# ASMI
|
||||
#
|
||||
ddrphy0 = s6ddrphy.S6DDRPHY(13, 2, 128)
|
||||
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()
|
||||
|
@ -68,7 +68,10 @@ def get():
|
|||
# CSR
|
||||
#
|
||||
uart0 = uart.UART(0, clk_freq, baud=115200)
|
||||
csrcon0 = csr.Interconnect(wishbone2csr0.csr, [uart0.bank.interface])
|
||||
csrcon0 = csr.Interconnect(wishbone2csr0.csr, [
|
||||
uart0.bank.interface,
|
||||
ddrphy0.bank.interface
|
||||
])
|
||||
|
||||
#
|
||||
# Interrupts
|
||||
|
|
Loading…
Reference in a new issue