mirror of https://github.com/VLSIDA/OpenRAM.git
Template module done
This commit is contained in:
parent
a69a016d9f
commit
16512bc4ee
|
|
@ -10,18 +10,18 @@ module multibank # (
|
||||||
din,
|
din,
|
||||||
csb,
|
csb,
|
||||||
web,
|
web,
|
||||||
dout,
|
dout
|
||||||
#>RW_PORTS
|
#>RW_PORTS
|
||||||
#<R_PORTS
|
#<R_PORTS
|
||||||
clk,
|
clk,
|
||||||
addr,
|
addr,
|
||||||
csb,
|
csb,
|
||||||
web,
|
web,
|
||||||
dout,
|
dout
|
||||||
#>R_PORTS
|
#>R_PORTS
|
||||||
);
|
);
|
||||||
|
|
||||||
parameter RAM_DEPTH = 1 << ADRR_WIDTH;
|
parameter RAM_DEPTH = 1 << ADDR_WIDTH;
|
||||||
parameter BANK_SEL = (NUM_BANKS <= 2)? 1 :
|
parameter BANK_SEL = (NUM_BANKS <= 2)? 1 :
|
||||||
(NUM_BANKS <= 4)? 2 :
|
(NUM_BANKS <= 4)? 2 :
|
||||||
(NUM_BANKS <= 8)? 3 :
|
(NUM_BANKS <= 8)? 3 :
|
||||||
|
|
@ -32,34 +32,42 @@ module multibank # (
|
||||||
input [DATA_WIDTH - 1: 0] din;
|
input [DATA_WIDTH - 1: 0] din;
|
||||||
input csb;
|
input csb;
|
||||||
input web;
|
input web;
|
||||||
output reg [DATA_WIDTH - 1 : 0] data;
|
output reg [DATA_WIDTH - 1 : 0] dout;
|
||||||
|
|
||||||
|
#!PORT_NUM!0#
|
||||||
#<BANK_DEFS
|
#<BANK_DEFS
|
||||||
reg csb#$PORT_NUM$#;
|
reg csb#$PORT_NUM$#;
|
||||||
reg web#$PORT_NUM$#;
|
reg web#$PORT_NUM$#;
|
||||||
reg dout#$PORT_NUM$#;
|
reg [DATA_WIDTH - 1 : 0] dout#$PORT_NUM$#;
|
||||||
|
#!PORT_NUM!PORT_NUM+1#
|
||||||
#>BANK_DEFS
|
#>BANK_DEFS
|
||||||
|
|
||||||
|
#!PORT_NUM!0#
|
||||||
#<BANK_INIT
|
#<BANK_INIT
|
||||||
bank bank#$BANK_NUM$# #(DATA_WIDTH, ADDR_WIDTH) (
|
bank #(DATA_WIDTH, ADDR_WIDTH) bank#$PORT_NUM$# (
|
||||||
#<BANK_RW_PORTS
|
#<BANK_RW_PORTS
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.addr(addr),
|
.addr(addr[ADDR_WIDTH - BANK_SEL - 1 : 0]),
|
||||||
.din(din),
|
.din(din),
|
||||||
.csb(csb#$PORT_NUM$#),
|
.csb(csb#$PORT_NUM$#),
|
||||||
.web(web#$PORT_NUM$#),
|
.web(web#$PORT_NUM$#),
|
||||||
.dout(dout#$PORT_NUM$#),
|
.dout(dout#$PORT_NUM$#)
|
||||||
|
#!PORT_NUM!PORT_NUM+1#
|
||||||
#>BANK_RW_PORTS
|
#>BANK_RW_PORTS
|
||||||
)
|
);
|
||||||
#>BANK_INIT
|
#>BANK_INIT
|
||||||
|
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
case (addr[ADDR_WIDTH - 1 : ADDR_WIDTH - BANK_SEL])
|
case (addr[ADDR_WIDTH - 1 : ADDR_WIDTH - BANK_SEL])
|
||||||
|
#!PORT_NUM!0#
|
||||||
#<BANK_CASE
|
#<BANK_CASE
|
||||||
#$PORT_NUM$#: begin
|
#$PORT_NUM$#: begin
|
||||||
dout <= dout#$PORT_NUM$#;
|
dout <= dout#$PORT_NUM$#;
|
||||||
web#$PORT_NUM$# <= web;
|
web#$PORT_NUM$# <= web;
|
||||||
end
|
end
|
||||||
|
#!PORT_NUM!PORT_NUM+1#
|
||||||
#>BANK_CASE
|
#>BANK_CASE
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
|
|
||||||
|
|
||||||
class TextSection:
|
|
||||||
|
|
||||||
def __init__(self, name, parent):
|
|
||||||
self.name = name
|
|
||||||
self.parent = parent
|
|
||||||
self.lines = []
|
|
||||||
self.sections = []
|
|
||||||
self.sectionPos = []
|
|
||||||
self.lineNum = 0
|
|
||||||
self.repeat = 0
|
|
||||||
|
|
||||||
def addLine(self, line):
|
|
||||||
self.lines.append(line)
|
|
||||||
self.lineNum+= 1
|
|
||||||
|
|
||||||
def addSection(self, section):
|
|
||||||
self.sections.append(section)
|
|
||||||
self.sectionPos.append(self.lineNum)
|
|
||||||
|
|
||||||
def expand(self):
|
|
||||||
for i
|
|
||||||
|
|
||||||
class VerilogTemplate:
|
|
||||||
|
|
||||||
def __init__(self, template, output);
|
|
||||||
self.template = template
|
|
||||||
self.output = output
|
|
||||||
self.sections = []
|
|
||||||
|
|
||||||
def readTemplate(self):
|
|
||||||
lines = []
|
|
||||||
with open(self.template, 'r') as f:
|
|
||||||
lines = f.readlines()
|
|
||||||
currentSection = TextSection('base', None)
|
|
||||||
for line in lines:
|
|
||||||
if line[:2] == '#<':
|
|
||||||
section = TextSection(line[2:], currentSection)
|
|
||||||
currentSection.addSection(section)
|
|
||||||
currentSection = section
|
|
||||||
if line[:2] == '#>' and line[2:] == section.name:
|
|
||||||
currentSection = currentSection.parent
|
|
||||||
else:
|
|
||||||
currentSection.addLine(line)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
from verilog_template import verilog_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)
|
||||||
|
|
||||||
|
|
||||||
|
t.generate('test.v')
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
|
||||||
|
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
|
||||||
|
|
@ -0,0 +1,103 @@
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
def addLine(self, line):
|
||||||
|
self.lines.append(line)
|
||||||
|
self.lineNum+= 1
|
||||||
|
|
||||||
|
def addSection(self, section):
|
||||||
|
self.sections.append(section)
|
||||||
|
self.sectionPos.append(self.lineNum)
|
||||||
|
|
||||||
|
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
|
||||||
Loading…
Reference in New Issue