Fix memtest tests (missing parenthesis)
[gram.git] / gram / frontend / wishbone.py
1 # This file is Copyright (c) 2020 LambdaConcept <contact@lambdaconcept.com>
2 # License: BSD
3
4 from math import log2
5
6 from nmigen import *
7 from nmigen.utils import log2_int
8
9 from nmigen_soc import wishbone
10 from nmigen_soc.memory import MemoryMap
11 from lambdasoc.periph import Peripheral
12
13
14 class gramWishbone(Peripheral, Elaboratable):
15 def __init__(self, core, data_width = 32):
16 super().__init__(name="wishbone")
17
18 self.dw = data_width
19 self._port = core.crossbar.get_native_port()
20 #self._port = core.crossbar.get_port(data_width=8, mode="read")
21
22 dram_size = core.size//4
23 dram_addr_width = log2_int(dram_size)
24 granularity = 8
25
26 self.bus = wishbone.Interface(addr_width=dram_addr_width,
27 data_width=self.dw, granularity=granularity)
28
29 map = MemoryMap(addr_width=dram_addr_width +
30 log2_int(granularity)-1, data_width=granularity)
31 self.bus.memory_map = map
32
33 def elaborate(self, platform):
34 m = Module()
35
36 # Write datapath
37 m.d.comb += [
38 self._port.wdata.valid.eq(self.bus.cyc & self.bus.stb & self.bus.we),
39 self._port.wdata.data.eq(self.bus.dat_w),
40 self._port.wdata.we.eq(self.bus.sel),
41 ]
42
43 # Read datapath
44 m.d.comb += [
45 self.bus.dat_r.eq(self._port.rdata.data),
46 self._port.rdata.ready.eq(1),
47 ]
48
49 adr_offset = 0
50 ratio = self.dw//2**int(log2(len(self._port.wdata.data)))
51 count = Signal(range(max(ratio, 2)))
52 with m.FSM():
53 with m.State("Send-Cmd"):
54 m.d.comb += [
55 self._port.cmd.valid.eq(self.bus.cyc & self.bus.stb),
56 self._port.cmd.we.eq(self.bus.we),
57 self._port.cmd.addr.eq(self.bus.adr*ratio + count - adr_offset),
58 ]
59 with m.If(self._port.cmd.valid & self._port.cmd.ready):
60 m.d.sync += count.eq(count+1)
61 with m.If(count == (max(ratio, 2)-1)):
62 m.d.sync += count.eq(0)
63 with m.If(self.bus.we):
64 m.next = "Wait-Write"
65 with m.Else():
66 m.next = "Wait-Read"
67
68 with m.State("Wait-Read"):
69 with m.If(self._port.rdata.valid):
70 m.d.comb += self.bus.ack.eq(1)
71 m.next = "Send-Cmd"
72
73 with m.State("Wait-Write"):
74 with m.If(self._port.wdata.ready):
75 m.d.comb += self.bus.ack.eq(1)
76 m.next = "Send-Cmd"
77
78 return m