1 from nmigen
import Elaboratable
, Cat
, Module
, Signal
, ClockSignal
, Instance
2 from nmigen
.utils
import log2_int
4 from nmigen_soc
.wishbone
.bus
import Interface
5 from nmigen
.cli
import rtlil
, verilog
7 __all__
= ["SPBlock512W64B8W"]
10 class SPBlock512W64B8W(Elaboratable
):
11 """SRAM module carrying a volatile 4k memory block (implemented with
12 Instance SPBlock512W64B8W). 512 rows, 64-bit, QTY 8 write-enable lines
15 def __init__(self
, bus
=None, features
=None, name
=None):
17 self
.idx
= int(name
.split("_")[-1])
20 self
.enable
= Signal(reset
=1) # enable signal, defaults to 1
22 features
= frozenset()
24 bus
= Interface(addr_width
=9, # 512 lines of
25 data_width
=64, # 64 bit
26 granularity
=8, # at 8-bit granularity
31 self
.granularity
= bus
.granularity
34 n_bussel
= self
.bus
.sel
.width
35 assert n_wrport
== n_bussel
, "bus enable count %d " \
36 "must match memory wen count %d" % (n_wrport
, n_bussel
)
38 assert len(self
.bus
.dat_r
) == 64, "bus width must be 64"
40 def elaborate(self
, platform
):
45 we
= Signal(8) # 8 select lines
46 q
= Signal(64) # output
47 d
= Signal(64) # input
49 # create Chips4Makers 4k SRAM cell here, mark it as "black box"
50 # for coriolis2 to pick up
52 sram
= Instance("spblock_512w64b8w", i_a
=a
, o_q
=q
,
55 m
.submodules
['spblock_512w64b8w_%s'] = sram
56 # has to be added to the actual module rather than the instance
57 # sram.attrs['blackbox'] = 1
59 with m
.If(self
.enable
): # in case of layout problems
60 # wishbone is active if cyc and stb set
62 m
.d
.comb
+= wb_active
.eq(self
.bus
.cyc
& self
.bus
.stb
)
64 # generate ack (no "pipeline" mode here)
65 m
.d
.sync
+= self
.bus
.ack
.eq(wb_active
)
70 m
.d
.comb
+= a
.eq(self
.bus
.adr
)
73 m
.d
.comb
+= self
.bus
.dat_r
.eq(q
)
76 m
.d
.comb
+= d
.eq(self
.bus
.dat_w
)
77 with m
.If(self
.bus
.we
):
78 m
.d
.comb
+= we
.eq(self
.bus
.sel
)
83 def create_ilang(dut
, ports
, test_name
):
84 vl
= rtlil
.convert(dut
, name
=test_name
, ports
=ports
)
85 with
open("%s.il" % test_name
, "w") as f
:
88 def create_verilog(dut
, ports
, test_name
):
89 vl
= verilog
.convert(dut
, name
=test_name
, ports
=ports
)
90 with
open("%s.v" % test_name
, "w") as f
:
93 if __name__
== "__main__":
94 alu
= SPBlock512W64B8W(name
="test_0")
95 create_ilang(alu
, [alu
.bus
.cyc
, alu
.bus
.stb
, alu
.bus
.ack
,
96 alu
.bus
.dat_r
, alu
.bus
.dat_w
, alu
.bus
.adr
,
97 alu
.bus
.we
, alu
.bus
.sel
], "SPBlock512W64B8W")
99 create_verilog(alu
, [alu
.bus
.cyc
, alu
.bus
.stb
, alu
.bus
.ack
,
100 alu
.bus
.dat_r
, alu
.bus
.dat_w
, alu
.bus
.adr
,
101 alu
.bus
.we
, alu
.bus
.sel
], "SPBlock512W64B8W")