diff --git a/compiler/base/verilog.py b/compiler/base/verilog.py index 25de40d4..6711b551 100644 --- a/compiler/base/verilog.py +++ b/compiler/base/verilog.py @@ -7,7 +7,7 @@ # import math from tech import spice -import verilog_template +from verilog_template import verilog_template class verilog: diff --git a/compiler/modules/sram.py b/compiler/modules/sram.py index ac4bd304..75be6a0e 100644 --- a/compiler/modules/sram.py +++ b/compiler/modules/sram.py @@ -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() diff --git a/compiler/modules/sram_multibank.py b/compiler/modules/sram_multibank.py index 7639f87e..c48dc0ff 100644 --- a/compiler/modules/sram_multibank.py +++ b/compiler/modules/sram_multibank.py @@ -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) diff --git a/compiler/sram/multibank_template.v b/compiler/sram/multibank_template.v deleted file mode 100644 index d5724cb6..00000000 --- a/compiler/sram/multibank_template.v +++ /dev/null @@ -1,73 +0,0 @@ - -module multibank # ( - DATA_WIDTH = 32, - ADDR_WIDTH= 8, - NUM_BANKS=2 -)( -#RW_PORTS -#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 - -#!PORT_NUM!0# -#BANK_RW_PORTS - ); -#>BANK_INIT - -always @(posedge clk) begin - case (addr[ADDR_WIDTH - 1 : ADDR_WIDTH - BANK_SEL]) -#!PORT_NUM!0# -#BANK_CASE - endcase -end - -endmodule diff --git a/compiler/verilogTemplate/template.py b/compiler/verilogTemplate/template.py new file mode 100644 index 00000000..d48321b5 --- /dev/null +++ b/compiler/verilogTemplate/template.py @@ -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() + diff --git a/compiler/verilogTemplate/test.py b/compiler/verilogTemplate/test.py index 73033914..228b5042 100644 --- a/compiler/verilogTemplate/test.py +++ b/compiler/verilogTemplate/test.py @@ -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') diff --git a/compiler/verilogTemplate/test.v b/compiler/verilogTemplate/test.v deleted file mode 100644 index 390f9f47..00000000 --- a/compiler/verilogTemplate/test.v +++ /dev/null @@ -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 diff --git a/compiler/verilogTemplate/verilog_template.py b/compiler/verilogTemplate/verilog_template.py deleted file mode 100644 index f1945f54..00000000 --- a/compiler/verilogTemplate/verilog_template.py +++ /dev/null @@ -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)