Line 6... |
Line 6... |
Block RAM
|
Block RAM
|
|
|
:copyright: Copyright (c) 2010 Jian Luo
|
:copyright: Copyright (c) 2010 Jian Luo
|
:author-email: jian.luo.cn(at_)gmail.com
|
:author-email: jian.luo.cn(at_)gmail.com
|
:license: LGPL, see LICENSE for details
|
:license: LGPL, see LICENSE for details
|
:revision: $Id: bram.py 5 2010-11-21 10:59:30Z rockee $
|
:revision: $Id: bram.py 6 2010-11-21 23:18:44Z rockee $
|
"""
|
"""
|
|
|
from myhdl import *
|
from myhdl import *
|
from defines import *
|
from defines import *
|
from functions import *
|
from functions import *
|
Line 54... |
Line 54... |
"""
|
"""
|
Single Port Synchronous RAM with Old Data Read-During-Write Behavior
|
Single Port Synchronous RAM with Old Data Read-During-Write Behavior
|
"""
|
"""
|
max = 2**size
|
max = 2**size
|
ram = RAM(Signal(intbv(0)[width:]) for i in range(max))
|
ram = RAM(Signal(intbv(0)[width:]) for i in range(max))
|
#read_addr = Signal(intbv(0)[len(address):])
|
|
if filename:
|
if filename:
|
init = BRAMInitial(ram, filename, clock)
|
init = BRAMInitial(ram, filename, clock)
|
|
|
@always(clock.posedge)
|
@always(clock.posedge)
|
def logic():
|
def logic():
|
if enable:
|
if enable:
|
if write:
|
if write:
|
ram[int(address)].next = data_in
|
ram[int(address)].next = data_in
|
data_out.next = ram[int(address)%max]
|
data_out.next = ram[int(address)%max]
|
#read_addr.next = address
|
|
#@always_comb
|
|
#def output():
|
|
#data_out.next = ram[int(read_addr)]
|
|
|
|
return instances()
|
return instances()
|
|
|
def BankedBRAM(
|
def BankedBRAM(
|
data_out,
|
data_out,
|
Line 86... |
Line 81... |
to_verilog=1,
|
to_verilog=1,
|
filename_pattern='',
|
filename_pattern='',
|
):
|
):
|
# XXX: Verilog just don't allow dynamic register slicing
|
# XXX: Verilog just don't allow dynamic register slicing
|
# have to fix ram shape to 4x8bit
|
# have to fix ram shape to 4x8bit
|
if to_verilog == 1:
|
if to_verilog:
|
width=32
|
width=32
|
bank_size=2
|
bank_size=2
|
bank_count = 2 ** bank_size
|
bank_count = 2 ** bank_size
|
bank_width = width/bank_count
|
bank_width = width/bank_count
|
bank_in = [Signal(intbv(0)[bank_width:]) for i in range(bank_count)]
|
bank_in = [Signal(intbv(0)[bank_width:]) for i in range(bank_count)]
|
Line 111... |
Line 106... |
enable=enable, clock=clock,
|
enable=enable, clock=clock,
|
width=bank_width, size=size-bank_size,)
|
width=bank_width, size=size-bank_size,)
|
|
|
for i in range(bank_count)]
|
for i in range(bank_count)]
|
|
|
|
if to_verilog:
|
#@always(clock.posedge)
|
|
#def debug():
|
|
#if enable and address==0x17f4:
|
|
#print 'XXXXXX 17f4',
|
|
#if write:
|
|
#print 'WRITE %x' % int(data_in)
|
|
#else:
|
|
#print 'READ %x' % int(data_out)
|
|
|
|
if to_verilog == 1:
|
|
@always_comb
|
@always_comb
|
def dumbass_reassemble():
|
def reassemble():
|
bank_addr.next = address[:bank_size]
|
bank_addr.next = address[:bank_size]
|
for i in range(bank_count):
|
for i in range(bank_count):
|
bank_wre[i].next = write[i]
|
bank_wre[i].next = write[i]
|
#bank_in[3].next = data_in[8:]
|
|
#bank_in[2].next = data_in[16:8]
|
|
#bank_in[1].next = data_in[24:16]
|
|
#bank_in[0].next = data_in[32:24]
|
|
#data_out.next = concat(bank_out[0], bank_out[1],
|
|
#bank_out[2], bank_out[3])
|
|
bank_in[0].next = data_in[8:]
|
bank_in[0].next = data_in[8:]
|
bank_in[1].next = data_in[16:8]
|
bank_in[1].next = data_in[16:8]
|
bank_in[2].next = data_in[24:16]
|
bank_in[2].next = data_in[24:16]
|
bank_in[3].next = data_in[32:24]
|
bank_in[3].next = data_in[32:24]
|
data_out.next = concat(bank_out[3], bank_out[2],
|
data_out.next = concat(bank_out[3], bank_out[2],
|
bank_out[1], bank_out[0])
|
bank_out[1], bank_out[0])
|
|
|
#else:
|
else:
|
#@always_comb
|
@always_comb
|
#def reassemble():
|
def reassemble():
|
#bank_addr.next = address[:bank_size]
|
bank_addr.next = address[:bank_size]
|
#tmp = intbv(0)[width:]
|
tmp = intbv(0)[width:]
|
#tmp_low = intbv(0)[width-bank_width:]
|
tmp_low = intbv(0)[width-bank_width:]
|
#for i in range(bank_count):
|
for i in range(bank_count):
|
#bank_wre[i].next = write[i]
|
bank_wre[i].next = write[i]
|
#bank_in[i].next = data_in[(i+1)*bank_width:i*bank_width]
|
bank_in[i].next = data_in[(i+1)*bank_width:i*bank_width]
|
#tmp_low[:] = tmp[:bank_width]
|
tmp_low[:] = tmp[:bank_width]
|
#tmp[:] = concat(bank_out[i], tmp_low)
|
tmp[:] = concat(bank_out[i], tmp_low)
|
#data_out.next = tmp
|
data_out.next = tmp
|
|
|
return instances()
|
return bank, reassemble
|
|
|
if __name__ == '__main__':
|
if __name__ == '__main__':
|
data_out = Signal(intbv(0)[32:])
|
data_out = Signal(intbv(0)[32:])
|
data_in = Signal(intbv(0)[32:])
|
data_in = Signal(intbv(0)[32:])
|
address = Signal(intbv(0)[16:])
|
address = Signal(intbv(0)[16:])
|
Line 176... |
Line 155... |
width=32,
|
width=32,
|
size=8,
|
size=8,
|
filename='rom.vmem',
|
filename='rom.vmem',
|
)
|
)
|
kw = dict(
|
kw = dict(
|
func=BankedBRAM,
|
|
data_out=data_out,
|
data_out=data_out,
|
data_in=data_in,
|
data_in=data_in,
|
address=address,
|
address=address,
|
write=write,
|
write=write,
|
enable=enable,
|
enable=enable,
|
clock=clock,
|
clock=clock,
|
width=32,
|
width=32,
|
bank_size=2,
|
bank_size=2,
|
size=8,
|
size=8,
|
filename='rom.vmem',
|
filename_pattern='rom%d.vmem',
|
)
|
)
|
toVerilog(to_verilog=True, **kw)
|
toVerilog(BankedBRAM, to_verilog=True, **kw)
|
toVerilog(**bram_kw)
|
#toVerilog(**bram_kw)
|
toVHDL(**kw)
|
toVHDL(BankedBRAM, **kw)
|
|
|
### EOF ###
|
### EOF ###
|
# vim:smarttab:sts=4:ts=4:sw=4:et:ai:tw=80:
|
# vim:smarttab:sts=4:ts=4:sw=4:et:ai:tw=80:
|
|
|
|
|
No newline at end of file
|
No newline at end of file
|