mirror of https://github.com/VLSIDA/OpenRAM.git
modified template engine & sram multibank class
This commit is contained in:
parent
bbcbddd934
commit
846dfc79dc
|
|
@ -7,7 +7,7 @@
|
|||
#
|
||||
import math
|
||||
from tech import spice
|
||||
import verilog_template
|
||||
from verilog_template import verilog_template
|
||||
|
||||
|
||||
class verilog:
|
||||
|
|
|
|||
|
|
@ -40,6 +40,14 @@ class sram():
|
|||
|
||||
self.s = sram(name, sram_config)
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
if self.num_banks != 1:
|
||||
from sram_multibank import sram_multibank
|
||||
mb = sram_multibank(s)
|
||||
mb.verilog_write()
|
||||
|
||||
>>>>>>> 3dd65b1a (modified template engine & sram multibank class)
|
||||
self.s.create_netlist()
|
||||
if not OPTS.netlist_only:
|
||||
self.s.create_layout()
|
||||
|
|
|
|||
|
|
@ -1,12 +1,16 @@
|
|||
from template import template
|
||||
from globals import OPTS
|
||||
<<<<<<< HEAD
|
||||
import os
|
||||
from math import ceil, log
|
||||
=======
|
||||
>>>>>>> 3dd65b1a (modified template engine & sram multibank class)
|
||||
|
||||
|
||||
class sram_multibank:
|
||||
|
||||
def __init__(self, sram):
|
||||
<<<<<<< HEAD
|
||||
rw_ports = [i for i in sram.all_ports if i in sram.read_ports and i in sram.write_ports]
|
||||
r_ports = [i for i in sram.all_ports if i in sram.read_ports and i not in sram.write_ports]
|
||||
w_ports = [i for i in sram.all_ports if i not in sram.read_ports and i in sram.write_ports]
|
||||
|
|
@ -30,3 +34,25 @@ class sram_multibank:
|
|||
template_filename = os.path.join(os.path.abspath(os.environ["OPENRAM_HOME"]), "sram/sram_multibank_template.v")
|
||||
t = template(template_filename, self.dict)
|
||||
t.write(name)
|
||||
=======
|
||||
dict = {
|
||||
'module_name': OPTS.output_name,
|
||||
'bank_module_name': OPTS.output_name + '_1bank',
|
||||
'vdd': 'vdd',
|
||||
'gnd': 'gnd',
|
||||
'ports': sram.all_ports,
|
||||
'rw_ports': sram.readwrite_ports,
|
||||
'r_ports': sram.read_ports,
|
||||
'w_ports': sram.write_ports,
|
||||
'banks': sram.banks,
|
||||
'data_width': sram.word_size,
|
||||
'addr_width': sram.addr_size,
|
||||
'bank_sel': list(range(sram.num_banks)),
|
||||
'num_wmask': sram.num_wmasks
|
||||
}
|
||||
|
||||
def verilog_write():
|
||||
t = template('../sram/sram_multibank_template.v', dict)
|
||||
t.write(OPTS.output_name + '.v')
|
||||
|
||||
>>>>>>> 3dd65b1a (modified template engine & sram multibank class)
|
||||
|
|
|
|||
|
|
@ -1,73 +0,0 @@
|
|||
|
||||
module multibank # (
|
||||
DATA_WIDTH = 32,
|
||||
ADDR_WIDTH= 8,
|
||||
NUM_BANKS=2
|
||||
)(
|
||||
#<RW_PORTS
|
||||
clk,
|
||||
addr,
|
||||
din,
|
||||
csb,
|
||||
web,
|
||||
dout
|
||||
#>RW_PORTS
|
||||
#<R_PORTS
|
||||
clk,
|
||||
addr,
|
||||
csb,
|
||||
web,
|
||||
dout
|
||||
#>R_PORTS
|
||||
);
|
||||
|
||||
parameter RAM_DEPTH = 1 << ADDR_WIDTH;
|
||||
parameter BANK_SEL = (NUM_BANKS <= 2)? 1 :
|
||||
(NUM_BANKS <= 4)? 2 :
|
||||
(NUM_BANKS <= 8)? 3 :
|
||||
(NUM_BANKS <= 16)? 4 : 5;
|
||||
|
||||
input clk;
|
||||
input [ADDR_WIDTH -1 : 0] addr;
|
||||
input [DATA_WIDTH - 1: 0] din;
|
||||
input csb;
|
||||
input web;
|
||||
output reg [DATA_WIDTH - 1 : 0] dout;
|
||||
|
||||
#!PORT_NUM!0#
|
||||
#<BANK_DEFS
|
||||
reg csb#$PORT_NUM$#;
|
||||
reg web#$PORT_NUM$#;
|
||||
reg [DATA_WIDTH - 1 : 0] dout#$PORT_NUM$#;
|
||||
#!PORT_NUM!PORT_NUM+1#
|
||||
#>BANK_DEFS
|
||||
|
||||
#!PORT_NUM!0#
|
||||
#<BANK_INIT
|
||||
bank #(DATA_WIDTH, ADDR_WIDTH) bank#$PORT_NUM$# (
|
||||
#<BANK_RW_PORTS
|
||||
.clk(clk),
|
||||
.addr(addr[ADDR_WIDTH - BANK_SEL - 1 : 0]),
|
||||
.din(din),
|
||||
.csb(csb#$PORT_NUM$#),
|
||||
.web(web#$PORT_NUM$#),
|
||||
.dout(dout#$PORT_NUM$#)
|
||||
#!PORT_NUM!PORT_NUM+1#
|
||||
#>BANK_RW_PORTS
|
||||
);
|
||||
#>BANK_INIT
|
||||
|
||||
always @(posedge clk) begin
|
||||
case (addr[ADDR_WIDTH - 1 : ADDR_WIDTH - BANK_SEL])
|
||||
#!PORT_NUM!0#
|
||||
#<BANK_CASE
|
||||
#$PORT_NUM$#: begin
|
||||
dout <= dout#$PORT_NUM$#;
|
||||
web#$PORT_NUM$# <= web;
|
||||
end
|
||||
#!PORT_NUM!PORT_NUM+1#
|
||||
#>BANK_CASE
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
import re
|
||||
|
||||
class baseSection:
|
||||
children = []
|
||||
|
||||
def expand(self, dict, fd):
|
||||
for c in self.children:
|
||||
c.expand(dict, fd)
|
||||
|
||||
class loopSection(baseSection):
|
||||
|
||||
def __init__(self, var, key):
|
||||
self.children = []
|
||||
self.var = var
|
||||
self.key = key
|
||||
|
||||
def expand(self, dict, fd):
|
||||
for ind in dict[self.key]:
|
||||
dict[self.var] = ind
|
||||
for c in self.children:
|
||||
c.expand(dict, fd)
|
||||
if self.var in dict:
|
||||
del dict[self.var]
|
||||
|
||||
class textSection(baseSection):
|
||||
|
||||
def __init__(self, text):
|
||||
self.text = text
|
||||
|
||||
def expand(self, dict):
|
||||
var_re = re.compile('\{\{ (\S*) \}\}')
|
||||
vars = var_re.finditer(self.text)
|
||||
newText = self.text
|
||||
for var in vars:
|
||||
newText = newText.replace('{{ ' + var.group(1) + ' }}', str(dict[var.group(1)]))
|
||||
print(newText, end='', file=fd)
|
||||
|
||||
class template:
|
||||
|
||||
def __init__(self, template, dict):
|
||||
self.template = template
|
||||
self.dict = dict
|
||||
|
||||
def readTemplate(self):
|
||||
lines = []
|
||||
with open(self.template, 'r') as f:
|
||||
lines = f.readlines()
|
||||
|
||||
self.baseSectionSection = baseSection()
|
||||
sections = []
|
||||
context = [self.baseSectionSection]
|
||||
for_re = re.compile('\{% for (\S*) in (\S*) %\}')
|
||||
end_re = re.compile('\{% endfor %\}')
|
||||
for line in lines:
|
||||
m = for_re.match(line)
|
||||
if m:
|
||||
section = loopSection(m.group(1), m.group(2))
|
||||
sections.append(section)
|
||||
context[-1].children.append(section)
|
||||
context.append(section)
|
||||
continue
|
||||
if end_re.match(line):
|
||||
context.pop()
|
||||
else:
|
||||
context[-1].children.append(textSection(line))
|
||||
|
||||
def write(self, filename):
|
||||
fd = open(filename, 'w')
|
||||
self.readTemplate()
|
||||
self.baseSectionSection.expand(self.dict, fd)
|
||||
fd.close()
|
||||
|
||||
|
|
@ -1,13 +1,20 @@
|
|||
from verilog_template import verilog_template
|
||||
from template import template
|
||||
|
||||
t = verilog_template('../sram/multibank_template.v')
|
||||
t.readTemplate()
|
||||
t.setSectionRepeat('RW_PORTS', 1)
|
||||
t.setSectionRepeat('R_PORTS', 0)
|
||||
t.setSectionRepeat('BANK_DEFS', 2)
|
||||
t.setSectionRepeat('BANK_INIT', 2)
|
||||
t.setSectionRepeat('BANK_CASE', 2)
|
||||
t.setTextDict('PORT_NUM', 0)
|
||||
dict = {
|
||||
'module_name': 'sram_1kbyte_32b_2bank',
|
||||
'bank_module_name': 'sram_1kbyte_32b_2bank_1bank',
|
||||
'vdd': 'vdd',
|
||||
'gnd': 'gnd',
|
||||
'ports': [0, 1],
|
||||
'rw_ports': [0],
|
||||
'r_ports': [1],
|
||||
'w_ports': [],
|
||||
'banks': [0, 1],
|
||||
'data_width': 32,
|
||||
'addr_width': 8,
|
||||
'bank_sel': 1,
|
||||
'num_wmask': 4
|
||||
}
|
||||
t = template('../sram/sram_multibank_template.v', dict)
|
||||
t.write(dict['module_name'] + '.v')
|
||||
|
||||
|
||||
t.generate('test.v')
|
||||
|
|
|
|||
|
|
@ -1,65 +0,0 @@
|
|||
|
||||
module multibank # (
|
||||
DATA_WIDTH = 32,
|
||||
ADDR_WIDTH= 8,
|
||||
NUM_BANKS=2
|
||||
)(
|
||||
clk,
|
||||
addr,
|
||||
din,
|
||||
csb,
|
||||
web,
|
||||
dout
|
||||
);
|
||||
|
||||
parameter RAM_DEPTH = 1 << ADDR_WIDTH;
|
||||
parameter BANK_SEL = (NUM_BANKS <= 2)? 1 :
|
||||
(NUM_BANKS <= 4)? 2 :
|
||||
(NUM_BANKS <= 8)? 3 :
|
||||
(NUM_BANKS <= 16)? 4 : 5;
|
||||
|
||||
input clk;
|
||||
input [ADDR_WIDTH -1 : 0] addr;
|
||||
input [DATA_WIDTH - 1: 0] din;
|
||||
input csb;
|
||||
input web;
|
||||
output reg [DATA_WIDTH - 1 : 0] dout;
|
||||
|
||||
reg csb0;
|
||||
reg web0;
|
||||
reg [DATA_WIDTH - 1 : 0] dout0;
|
||||
reg csb1;
|
||||
reg web1;
|
||||
reg [DATA_WIDTH - 1 : 0] dout1;
|
||||
|
||||
bank #(DATA_WIDTH, ADDR_WIDTH) bank0 (
|
||||
.clk(clk),
|
||||
.addr(addr[ADDR_WIDTH - BANK_SEL - 1 : 0]),
|
||||
.din(din),
|
||||
.csb(csb0),
|
||||
.web(web0),
|
||||
.dout(dout0)
|
||||
);
|
||||
bank #(DATA_WIDTH, ADDR_WIDTH) bank1 (
|
||||
.clk(clk),
|
||||
.addr(addr[ADDR_WIDTH - BANK_SEL - 1 : 0]),
|
||||
.din(din),
|
||||
.csb(csb1),
|
||||
.web(web1),
|
||||
.dout(dout1)
|
||||
);
|
||||
|
||||
always @(posedge clk) begin
|
||||
case (addr[ADDR_WIDTH - 1 : ADDR_WIDTH - BANK_SEL])
|
||||
0: begin
|
||||
dout <= dout0;
|
||||
web0 <= web;
|
||||
end
|
||||
1: begin
|
||||
dout <= dout1;
|
||||
web1 <= web;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -1,115 +0,0 @@
|
|||
|
||||
class text_section:
|
||||
|
||||
def __init__(self, name, parent):
|
||||
self.name = name
|
||||
self.parent = parent
|
||||
self.lines = []
|
||||
self.sections = []
|
||||
self.sectionPos = []
|
||||
self.lineNum = 0
|
||||
self.repeat = 1
|
||||
self.index = -1
|
||||
|
||||
def addLine(self, line):
|
||||
self.lines.append(line)
|
||||
self.lineNum+= 1
|
||||
|
||||
def addSection(self, section):
|
||||
self.sections.append(section)
|
||||
self.sectionPos.append(self.lineNum)
|
||||
section.index = len(self.sections) - 1
|
||||
|
||||
def clone(self, cloneName):
|
||||
other = text_section(cloneName, self.parent)
|
||||
other.sections = self.sections.copy()
|
||||
other.sectionPos = self.sectionPos.copy()
|
||||
other.repeat = self.repeat
|
||||
self.parent.sections.insert(self.index + 1, other)
|
||||
|
||||
def expand(self):
|
||||
expanded = []
|
||||
pos = 0
|
||||
if self.repeat == 0:
|
||||
return []
|
||||
if len(self.sections) == 0:
|
||||
return self.lines * self.repeat
|
||||
|
||||
for s, sPos in zip(self.sections, self.sectionPos):
|
||||
if pos < sPos:
|
||||
expanded += self.lines[pos:sPos]
|
||||
pos = sPos
|
||||
expanded += s.expand()
|
||||
|
||||
if pos < self.lineNum:
|
||||
expanded += self.lines[pos:]
|
||||
|
||||
if self.repeat > 1:
|
||||
expanded = expanded * self.repeat
|
||||
|
||||
return expanded
|
||||
|
||||
|
||||
class verilog_template:
|
||||
|
||||
def __init__(self, template):
|
||||
self.template = template
|
||||
self.sections = {}
|
||||
self.textDict = {}
|
||||
self.baseSection = None
|
||||
self.expanded = None
|
||||
|
||||
def readTemplate(self):
|
||||
lines = []
|
||||
with open(self.template, 'r') as f:
|
||||
lines = f.readlines()
|
||||
self.baseSection = text_section('base', None)
|
||||
currentSection = self.baseSection
|
||||
for line in lines:
|
||||
if line[:2] == '#<':
|
||||
section = text_section(line[2:].strip('\n'), currentSection)
|
||||
currentSection.addSection(section)
|
||||
currentSection = section
|
||||
elif line[:2] == '#>' and line[2:].strip('\n') == currentSection.name:
|
||||
self.sections[currentSection.name] = currentSection
|
||||
currentSection = currentSection.parent
|
||||
else:
|
||||
currentSection.addLine(line)
|
||||
|
||||
def expand(self):
|
||||
self.expanded = self.baseSection.expand()
|
||||
|
||||
def postProcess(self):
|
||||
text = ""
|
||||
for line in self.expanded:
|
||||
if '#$' in line:
|
||||
while True:
|
||||
indStart = line.find('#$')
|
||||
if indStart == -1:
|
||||
break
|
||||
indEnd = line.find('$#')
|
||||
line = line[:indStart] + str(self.textDict[line[indStart + 2:indEnd]]) + line[indEnd + 2:]
|
||||
text += line
|
||||
elif '#!' in line:
|
||||
indLabelStart = line.find('#!') + 2
|
||||
indLabelEnd = line.find('!', indLabelStart)
|
||||
label = line[indLabelStart:indLabelEnd]
|
||||
self.textDict[label] = eval(line[indLabelEnd + 1:-1], self.textDict)
|
||||
else:
|
||||
text += line
|
||||
return text
|
||||
|
||||
def generate(self, filename):
|
||||
self.expand()
|
||||
text = self.postProcess()
|
||||
with open(filename, 'w') as f:
|
||||
f.write(text)
|
||||
|
||||
def setSectionRepeat(self, name, repeat):
|
||||
self.sections[name].repeat = repeat
|
||||
|
||||
def setTextDict(self, label, value):
|
||||
self.textDict[label] = value
|
||||
|
||||
def cloneSection(self, name, cloneName):
|
||||
self.sections[name].clone(cloneName)
|
||||
Loading…
Reference in New Issue