|
| 1 | +from __future__ import absolute_import |
| 2 | +from __future__ import print_function |
| 3 | + |
| 4 | +import math |
| 5 | +import veriloggen.core.vtypes as vtypes |
| 6 | +from veriloggen.core.module import Module |
| 7 | + |
| 8 | + |
| 9 | +def make_port(m, _type, *args, **kwargs): |
| 10 | + if 'initval' in kwargs and 'Reg' not in _type: |
| 11 | + del kwargs['initval'] |
| 12 | + return getattr(m, _type)(*args, **kwargs) |
| 13 | + |
| 14 | + |
| 15 | +class RAMInterface(object): |
| 16 | + _I = 'Input' |
| 17 | + _O = 'Output' |
| 18 | + |
| 19 | + def __init__(self, m, name=None, datawidth=32, addrwidth=10, itype=None, otype=None, |
| 20 | + p_addr='addr', p_rdata='rdata', p_wdata='wdata', p_wenable='wenable', |
| 21 | + index=None): |
| 22 | + |
| 23 | + if itype is None: |
| 24 | + itype = self._I |
| 25 | + if otype is None: |
| 26 | + otype = self._O |
| 27 | + |
| 28 | + self.m = m |
| 29 | + |
| 30 | + name_addr = p_addr if name is None else '_'.join([name, p_addr]) |
| 31 | + name_rdata = p_rdata if name is None else '_'.join([name, p_rdata]) |
| 32 | + name_wdata = p_wdata if name is None else '_'.join([name, p_wdata]) |
| 33 | + name_wenable = p_wenable if name is None else '_'.join( |
| 34 | + [name, p_wenable]) |
| 35 | + |
| 36 | + if index is not None: |
| 37 | + name_addr = name_addr + str(index) |
| 38 | + name_rdata = name_rdata + str(index) |
| 39 | + name_wdata = name_wdata + str(index) |
| 40 | + name_wenable = name_wenable + str(index) |
| 41 | + |
| 42 | + self.addr = make_port(m, itype, name_addr, addrwidth, initval=0) |
| 43 | + self.rdata = make_port(m, otype, name_rdata, datawidth, initval=0) |
| 44 | + self.wdata = make_port(m, itype, name_wdata, datawidth, initval=0) |
| 45 | + self.wenable = make_port(m, itype, name_wenable, initval=0) |
| 46 | + |
| 47 | + |
| 48 | +def mkRAMCore(name, datawidth=32, addrwidth=10, numports=2): |
| 49 | + m = Module(name) |
| 50 | + clk = m.Input('CLK') |
| 51 | + |
| 52 | + interfaces = [] |
| 53 | + |
| 54 | + for i in range(numports): |
| 55 | + interface = RAMInterface( |
| 56 | + m, name + '_%d' % i, datawidth, addrwidth) |
| 57 | + interface.delay_addr = m.Reg(name + '_%d_daddr' % i, addrwidth) |
| 58 | + interfaces.append(interface) |
| 59 | + |
| 60 | + mem = m.Reg('mem', datawidth, length=2**addrwidth) |
| 61 | + |
| 62 | + for interface in interfaces: |
| 63 | + m.Always(vtypes.Posedge(clk))( |
| 64 | + vtypes.If(interface.wenable)( |
| 65 | + mem[interface.addr](interface.wdata) |
| 66 | + ), |
| 67 | + interface.delay_addr(interface.addr) |
| 68 | + ) |
| 69 | + m.Assign(interface.rdata(mem[interface.delay_addr])) |
| 70 | + |
| 71 | + return m |
| 72 | + |
| 73 | + |
| 74 | +def mkRAM(name, datawidth=32, addrwidth=10, numports=2): |
| 75 | + if numports < 1: |
| 76 | + raise ValueError("numports must be greater than 0.") |
| 77 | + |
| 78 | + name = 'dataflow_ram_%d' % index |
| 79 | + m = mkRAMCore(name, datawidth, addrwidth, numports) |
| 80 | + |
| 81 | + return m |
| 82 | + |
| 83 | + |
| 84 | +# global multiplier count |
| 85 | +index_count = 0 |
| 86 | + |
| 87 | + |
| 88 | +def get_RAM(datawidth=32, length=1024, numports=1): |
| 89 | + global index_count |
| 90 | + ram = mkRAM(index_count, datawidth, length, numports) |
| 91 | + index_count += 1 |
| 92 | + return ram |
| 93 | + |
| 94 | + |
| 95 | +def reset(): |
| 96 | + global index_count |
| 97 | + index_count = 0 |
0 commit comments