Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Map DDR PHY controls in CSR
  • Loading branch information
Sebastien Bourdeauducq committed Feb 17, 2012
1 parent 5d1dad5 commit c387ce7
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 8 deletions.
44 changes: 39 additions & 5 deletions milkymist/s6ddrphy/__init__.py
@@ -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 = []
Expand All @@ -16,8 +18,7 @@ def __init__(self, a, ba, d):
"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)
Expand Down Expand Up @@ -50,6 +51,8 @@ def __init__(self, a, ba, d):
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)),
Expand Down Expand Up @@ -87,8 +90,23 @@ def __init__(self, a, ba, d):
("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),
Expand All @@ -99,6 +117,22 @@ def get_fragment(self):
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)
]
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, instances=[self._inst], pads=set(self._sd_pins))
return Fragment(comb, sync, instances=[self._inst], pads=set(self._sd_pins)) \
+ self.bank.get_fragment()
36 changes: 36 additions & 0 deletions software/include/hw/s6ddrphy.h
@@ -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 */
2 changes: 1 addition & 1 deletion software/include/hw/uart.h
Expand Up @@ -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)

Expand Down
7 changes: 5 additions & 2 deletions top.py
Expand Up @@ -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()
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit c387ce7

Please sign in to comment.