Merge pull request #247 from ucb-bar/replseqmem_pr
Bump FIRRTL for Sequential Memories
This commit is contained in:
commit
7504498dff
2
firrtl
2
firrtl
@ -1 +1 @@
|
|||||||
Subproject commit a2af16c1fb1f5166eab34188df9944012da3cbc3
|
Subproject commit 6a05468ed0ece1ace3019666b16f2ae83ef76ef9
|
@ -11,7 +11,8 @@ default: all
|
|||||||
|
|
||||||
base_dir = $(abspath ..)
|
base_dir = $(abspath ..)
|
||||||
generated_dir = $(abspath ./generated-src)
|
generated_dir = $(abspath ./generated-src)
|
||||||
mem_gen = $(base_dir)/vsim/vlsi_mem_gen
|
VLSI_MEM_GEN ?= $(base_dir)/vsim/vlsi_mem_gen
|
||||||
|
mem_gen = $(VLSI_MEM_GEN)
|
||||||
sim_dir = .
|
sim_dir = .
|
||||||
output_dir = $(sim_dir)/output
|
output_dir = $(sim_dir)/output
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ bb_vsrcs = $(base_dir)/vsrc/DebugTransportModuleJtag.v \
|
|||||||
|
|
||||||
sim_vsrcs = \
|
sim_vsrcs = \
|
||||||
$(generated_dir)/$(MODEL).$(CONFIG).v \
|
$(generated_dir)/$(MODEL).$(CONFIG).v \
|
||||||
|
$(generated_dir)/$(MODEL).$(CONFIG).behav_srams.v \
|
||||||
$(generated_dir)/consts.$(CONFIG).vh \
|
$(generated_dir)/consts.$(CONFIG).vh \
|
||||||
$(base_dir)/vsrc/$(TB).v \
|
$(base_dir)/vsrc/$(TB).v \
|
||||||
$(base_dir)/vsrc/SimDTM.v \
|
$(base_dir)/vsrc/SimDTM.v \
|
||||||
|
@ -9,9 +9,15 @@ $(generated_dir)/%.$(CONFIG).fir $(generated_dir)/%.$(CONFIG).d $(generated_dir)
|
|||||||
mkdir -p $(dir $@)
|
mkdir -p $(dir $@)
|
||||||
cd $(base_dir) && $(SBT) "run $(generated_dir) $(PROJECT) $(notdir $*) $(CFG_PROJECT) $(CONFIG)"
|
cd $(base_dir) && $(SBT) "run $(generated_dir) $(PROJECT) $(notdir $*) $(CFG_PROJECT) $(CONFIG)"
|
||||||
|
|
||||||
$(generated_dir)/%.v: $(generated_dir)/%.fir $(FIRRTL_JAR)
|
$(generated_dir)/%.v $(generated_dir)/%.conf : $(generated_dir)/%.fir $(FIRRTL_JAR)
|
||||||
mkdir -p $(dir $@)
|
mkdir -p $(dir $@)
|
||||||
$(FIRRTL) -i $< -o $@ -X verilog
|
$(FIRRTL) -i $< -o $@ -X verilog --replSeqMem -c:$(MODEL):-o:$(generated_dir)/$(MODEL).$(CONFIG).conf
|
||||||
|
|
||||||
|
$(generated_dir)/$(MODEL).$(CONFIG).behav_srams.v : $(generated_dir)/$(MODEL).$(CONFIG).conf $(mem_gen)
|
||||||
|
cd $(generated_dir) && \
|
||||||
|
rm -f $@ && \
|
||||||
|
$(mem_gen) $(generated_dir)/$(MODEL).$(CONFIG).conf >> $@.tmp && \
|
||||||
|
mv $@.tmp $@
|
||||||
|
|
||||||
$(generated_dir)/consts.$(CONFIG).vh: $(generated_dir)/$(MODEL).$(CONFIG).prm
|
$(generated_dir)/consts.$(CONFIG).vh: $(generated_dir)/$(MODEL).$(CONFIG).prm
|
||||||
echo "\`ifndef CONST_VH" > $@
|
echo "\`ifndef CONST_VH" > $@
|
||||||
|
@ -12,7 +12,7 @@ def parse_line(line):
|
|||||||
width = 0
|
width = 0
|
||||||
depth = 0
|
depth = 0
|
||||||
ports = ''
|
ports = ''
|
||||||
mask_gran = 1
|
mask_gran = 0
|
||||||
tokens = line.split()
|
tokens = line.split()
|
||||||
i = 0
|
i = 0
|
||||||
for i in range(0,len(tokens),2):
|
for i in range(0,len(tokens),2):
|
||||||
@ -21,20 +21,20 @@ def parse_line(line):
|
|||||||
name = tokens[i+1]
|
name = tokens[i+1]
|
||||||
elif s == 'width':
|
elif s == 'width':
|
||||||
width = int(tokens[i+1])
|
width = int(tokens[i+1])
|
||||||
|
mask_gran = width # default setting
|
||||||
elif s == 'depth':
|
elif s == 'depth':
|
||||||
depth = int(tokens[i+1])
|
depth = int(tokens[i+1])
|
||||||
elif s == 'ports':
|
elif s == 'ports':
|
||||||
ports = tokens[i+1].split(',')
|
ports = tokens[i+1].split(',')
|
||||||
elif s == 'mask_gran':
|
elif s == 'mask_gran':
|
||||||
# currently used only for fpga, but here for .conf format compatability
|
|
||||||
mask_gran = int(tokens[i+1])
|
mask_gran = int(tokens[i+1])
|
||||||
else:
|
else:
|
||||||
sys.exit('%s: unknown argument %s' % (sys.argv[0], a))
|
sys.exit('%s: unknown argument %s' % (sys.argv[0], a))
|
||||||
return (name, width, depth, ports)
|
return (name, width, depth, mask_gran, width/mask_gran, ports)
|
||||||
|
|
||||||
def gen_mem(name, width, depth, ports):
|
def gen_mem(name, width, depth, mask_gran, mask_seg, ports):
|
||||||
addr_width = max(math.ceil(math.log(depth)/math.log(2)),1)
|
addr_width = max(math.ceil(math.log(depth)/math.log(2)),1)
|
||||||
port_spec = ['input CLK', 'input RST', 'input init']
|
port_spec = []
|
||||||
readports = []
|
readports = []
|
||||||
writeports = []
|
writeports = []
|
||||||
latchports = []
|
latchports = []
|
||||||
@ -50,28 +50,34 @@ def gen_mem(name, width, depth, ports):
|
|||||||
maskedports[pid] = pid
|
maskedports[pid] = pid
|
||||||
|
|
||||||
if ptype == 'read':
|
if ptype == 'read':
|
||||||
port_spec.append('input [%d:0] R%dA' % (addr_width-1, pid))
|
prefix = 'R%d_' % len(readports)
|
||||||
port_spec.append('input R%dE' % pid)
|
port_spec.append('input %sclk' % prefix)
|
||||||
port_spec.append('output [%d:0] R%dO' % (width-1, pid))
|
port_spec.append('input [%d:0] %saddr' % (addr_width-1, prefix))
|
||||||
|
port_spec.append('input %sen' % prefix)
|
||||||
|
port_spec.append('output [%d:0] %sdata' % (width-1, prefix))
|
||||||
readports.append(pid)
|
readports.append(pid)
|
||||||
elif ptype == 'write':
|
elif ptype == 'write':
|
||||||
port_spec.append('input [%d:0] W%dA' % (addr_width-1, pid))
|
prefix = 'W%d_' % len(writeports)
|
||||||
port_spec.append('input W%dE' % pid)
|
port_spec.append('input %sclk' % prefix)
|
||||||
port_spec.append('input [%d:0] W%dI' % (width-1, pid))
|
port_spec.append('input [%d:0] %saddr' % (addr_width-1, prefix))
|
||||||
|
port_spec.append('input %sen' % prefix)
|
||||||
|
port_spec.append('input [%d:0] %sdata' % (width-1, prefix))
|
||||||
if pid in maskedports:
|
if pid in maskedports:
|
||||||
port_spec.append('input [%d:0] W%dM' % (width-1, pid))
|
port_spec.append('input [%d:0] %smask' % (mask_seg-1, prefix))
|
||||||
if not use_latches or pid in maskedports:
|
if not use_latches or pid in maskedports:
|
||||||
writeports.append(pid)
|
writeports.append(pid)
|
||||||
else:
|
else:
|
||||||
latchports.append(pid)
|
latchports.append(pid)
|
||||||
elif ptype == 'rw':
|
elif ptype == 'rw':
|
||||||
port_spec.append('input [%d:0] RW%dA' % (addr_width-1, pid))
|
prefix = 'RW%d_' % len(rwports)
|
||||||
port_spec.append('input RW%dE' % pid)
|
port_spec.append('input %sclk' % prefix)
|
||||||
port_spec.append('input RW%dW' % pid)
|
port_spec.append('input [%d:0] %saddr' % (addr_width-1, prefix))
|
||||||
|
port_spec.append('input %sen' % prefix)
|
||||||
|
port_spec.append('input %swmode' % prefix)
|
||||||
if pid in maskedports:
|
if pid in maskedports:
|
||||||
port_spec.append('input [%d:0] RW%dM' % (width-1, pid))
|
port_spec.append('input [%d:0] %swmask' % (mask_seg-1, prefix))
|
||||||
port_spec.append('input [%d:0] RW%dI' % (width-1, pid))
|
port_spec.append('input [%d:0] %swdata' % (width-1, prefix))
|
||||||
port_spec.append('output [%d:0] RW%dO' % (width-1, pid))
|
port_spec.append('output [%d:0] %srdata' % (width-1, prefix))
|
||||||
rwports.append(pid)
|
rwports.append(pid)
|
||||||
else:
|
else:
|
||||||
sys.exit('%s: unknown port type %s' % (sys.argv[0], ptype))
|
sys.exit('%s: unknown port type %s' % (sys.argv[0], ptype))
|
||||||
@ -82,66 +88,83 @@ def gen_mem(name, width, depth, ports):
|
|||||||
masked = len(maskedports)>0
|
masked = len(maskedports)>0
|
||||||
tup = (depth, width, nr, nw, nrw, masked)
|
tup = (depth, width, nr, nw, nrw, masked)
|
||||||
|
|
||||||
for pid in readports:
|
for idx in range(nr):
|
||||||
decl.append('reg [%d:0] reg_R%dA;' % (addr_width-1, pid))
|
prefix = 'R%d_' % idx
|
||||||
sequential.append('if (R%dE) reg_R%dA <= R%dA;' % (pid, pid, pid))
|
decl.append('reg [%d:0] reg_%saddr;' % (addr_width-1, prefix))
|
||||||
combinational.append('assign R%dO = ram[reg_R%dA];' % (pid, pid))
|
sequential.append('always @(posedge %sclk)' % prefix)
|
||||||
|
sequential.append(' if (%sen) reg_%saddr <= %saddr;' % (prefix, prefix, prefix))
|
||||||
|
combinational.append('assign %sdata = ram[reg_%saddr];' % (prefix, prefix))
|
||||||
|
|
||||||
for pid in rwports:
|
for idx in range(nrw):
|
||||||
decl.append('reg [%d:0] reg_RW%dA;' % (addr_width-1, pid))
|
prefix = 'RW%d_' % idx
|
||||||
sequential.append('if (RW%dE && !RW%dW) reg_RW%dA <= RW%dA;' % (pid, pid, pid, pid))
|
decl.append('reg [%d:0] reg_%saddr;' % (addr_width-1, prefix))
|
||||||
combinational.append('assign RW%dO = ram[reg_RW%dA];' % (pid, pid))
|
sequential.append('always @(posedge %sclk)' % prefix)
|
||||||
|
sequential.append(' if (%sen && !%swmode) reg_%saddr <= %saddr;' % (prefix, prefix, prefix, prefix))
|
||||||
|
combinational.append('assign %srdata = ram[reg_%saddr];' % (prefix, prefix))
|
||||||
|
|
||||||
for pid in latchports:
|
for idx in range(len(latchports)):
|
||||||
decl.append('reg [%d:0] latch_W%dA;' % (addr_width-1, pid))
|
prefix = 'W%d_' % idx
|
||||||
decl.append('reg [%d:0] latch_W%dI;' % (width-1, pid))
|
decl.append('reg [%d:0] latch_%saddr;' % (addr_width-1, prefix))
|
||||||
decl.append('reg latch_W%dE;' % (pid))
|
decl.append('reg [%d:0] latch_%sdata;' % (width-1, prefix))
|
||||||
|
decl.append('reg latch_%sen;' % (prefix))
|
||||||
combinational.append('always @(*) begin')
|
combinational.append('always @(*) begin')
|
||||||
combinational.append(' if (!CLK && W%dE) latch_W%dA <= W%dA;' % (pid, pid, pid))
|
combinational.append(' if (!%sclk && %sen) latch_%saddr <= %saddr;' % (prefix, prefix, prefix, prefix))
|
||||||
combinational.append(' if (!CLK && W%dE) latch_W%dI <= W%dI;' % (pid, pid, pid))
|
combinational.append(' if (!%sclk && %sen) latch_%sdata <= %sdata;' % (prefix, prefix, prefix, prefix))
|
||||||
combinational.append(' if (!CLK) latch_W%dE <= W%dE;' % (pid, pid))
|
combinational.append(' if (!%sclk) latch_%sen <= %sen;' % (prefix, prefix, prefix))
|
||||||
combinational.append('end')
|
combinational.append('end')
|
||||||
combinational.append('always @(*)')
|
combinational.append('always @(*)')
|
||||||
combinational.append(' if (CLK && latch_W%dE)' % (pid))
|
combinational.append(' if (%sclk && latch_%sen)' % (prefix, prefix))
|
||||||
combinational.append(' ram[latch_W%dA] <= latch_W%dI;' % (pid, pid))
|
combinational.append(' ram[latch_%saddr] <= latch_%sdata;' % (prefix, prefix))
|
||||||
|
|
||||||
decl.append('reg [%d:0] ram [%d:0];' % (width-1, depth-1))
|
decl.append('reg [%d:0] ram [%d:0];' % (width-1, depth-1))
|
||||||
decl.append('`ifndef SYNTHESIS')
|
decl.append('`ifdef RANDOMIZE')
|
||||||
decl.append(' integer initvar;')
|
decl.append(' integer initvar;')
|
||||||
decl.append(' initial begin')
|
decl.append(' initial begin')
|
||||||
decl.append(' #0.002;')
|
decl.append(' #0.002;')
|
||||||
decl.append(' for (initvar = 0; initvar < %d; initvar = initvar+1)' % depth)
|
decl.append(' for (initvar = 0; initvar < %d; initvar = initvar+1)' % depth)
|
||||||
decl.append(' ram[initvar] = {%d {$random}};' % ((width-1)/32+1))
|
decl.append(' ram[initvar] = {%d {$random}};' % ((width-1)/32+1))
|
||||||
for pid in readports:
|
for idx in range(nr):
|
||||||
decl.append(' reg_R%dA = {%d {$random}};' % (pid, ((addr_width-1)/32+1)))
|
prefix = 'R%d_' % idx
|
||||||
for pid in rwports:
|
decl.append(' reg_%saddr = {%d {$random}};' % (prefix, ((addr_width-1)/32+1)))
|
||||||
decl.append(' reg_RW%dA = {%d {$random}};' % (pid, ((addr_width-1)/32+1)))
|
for idx in range(nrw):
|
||||||
|
prefix = 'RW%d_' % idx
|
||||||
|
decl.append(' reg_%saddr = {%d {$random}};' % (prefix, ((addr_width-1)/32+1)))
|
||||||
decl.append(' end')
|
decl.append(' end')
|
||||||
decl.append('`endif')
|
decl.append('`endif')
|
||||||
|
|
||||||
decl.append("integer i;")
|
decl.append("integer i;")
|
||||||
sequential.append("for (i = 0; i < %d; i=i+1) begin" % width)
|
for idx in range(nw):
|
||||||
for pid in writeports:
|
prefix = 'W%d_' % idx
|
||||||
mask = (' && W%dM[i]' % pid) if pid in maskedports else ''
|
pid = writeports[idx]
|
||||||
sequential.append(" if (W%dE%s) ram[W%dA][i] <= W%dI[i];" % (pid, mask, pid, pid))
|
sequential.append('always @(posedge %sclk)' % prefix)
|
||||||
for pid in rwports:
|
sequential.append(" if (%sen) begin" % prefix)
|
||||||
mask = (' && RW%dM[i]' % pid) if pid in maskedports else ''
|
for i in range(mask_seg):
|
||||||
sequential.append(" if (RW%dE && RW%dW%s) ram[RW%dA][i] <= RW%dI[i];" % (pid, pid, mask, pid, pid))
|
mask = ('if (%smask[%d]) ' % (prefix, i)) if pid in maskedports else ''
|
||||||
sequential.append("end")
|
ram_range = '%d:%d' % ((i+1)*mask_gran-1, i*mask_gran)
|
||||||
|
sequential.append(" %sram[%saddr][%s] <= %sdata[%s];" % (mask, prefix, ram_range, prefix, ram_range))
|
||||||
|
sequential.append(" end")
|
||||||
|
for idx in range(nrw):
|
||||||
|
pid = rwports[idx]
|
||||||
|
prefix = 'RW%d_' % idx
|
||||||
|
sequential.append('always @(posedge %sclk)' % prefix)
|
||||||
|
sequential.append(" if (%sen && %swmode) begin" % (prefix, prefix))
|
||||||
|
for i in range(mask_seg):
|
||||||
|
mask = ('if (%swmask[%d]) ' % (prefix, i)) if pid in maskedports else ''
|
||||||
|
ram_range = '%d:%d' % ((i+1)*mask_gran-1, i*mask_gran)
|
||||||
|
sequential.append(" %sram[%saddr][%s] <= %swdata[%s];" % (mask, prefix, ram_range, prefix, ram_range))
|
||||||
|
sequential.append(" end")
|
||||||
body = "\
|
body = "\
|
||||||
%s\n\
|
%s\n\
|
||||||
always @(posedge CLK) begin\n\
|
|
||||||
%s\n\
|
%s\n\
|
||||||
end\n\
|
|
||||||
%s\n" % ('\n '.join(decl), '\n '.join(sequential), '\n '.join(combinational))
|
%s\n" % ('\n '.join(decl), '\n '.join(sequential), '\n '.join(combinational))
|
||||||
|
|
||||||
s = "module %s(\n\
|
s = "\nmodule %s(\n\
|
||||||
%s\n\
|
%s\n\
|
||||||
);\n\
|
);\n\
|
||||||
\n\
|
\n\
|
||||||
%s\
|
%s\
|
||||||
\n\
|
\n\
|
||||||
endmodule\n" % (name, ',\n '.join(port_spec), body)
|
endmodule" % (name, ',\n '.join(port_spec), body)
|
||||||
return s
|
return s
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
Loading…
Reference in New Issue
Block a user