diff --git a/firrtl b/firrtl index a2af16c1..6a05468e 160000 --- a/firrtl +++ b/firrtl @@ -1 +1 @@ -Subproject commit a2af16c1fb1f5166eab34188df9944012da3cbc3 +Subproject commit 6a05468ed0ece1ace3019666b16f2ae83ef76ef9 diff --git a/vsim/Makefrag b/vsim/Makefrag index af99c8d2..a2f5559d 100644 --- a/vsim/Makefrag +++ b/vsim/Makefrag @@ -10,6 +10,7 @@ bb_vsrcs = $(base_dir)/vsrc/DebugTransportModuleJtag.v \ sim_vsrcs = \ $(generated_dir)/$(MODEL).$(CONFIG).v \ + $(generated_dir)/$(MODEL).$(CONFIG).behav_srams.v \ $(generated_dir)/consts.$(CONFIG).vh \ $(base_dir)/vsrc/$(TB).v \ $(base_dir)/vsrc/SimDTM.v \ diff --git a/vsim/Makefrag-verilog b/vsim/Makefrag-verilog index 6774a309..add63f01 100644 --- a/vsim/Makefrag-verilog +++ b/vsim/Makefrag-verilog @@ -9,9 +9,13 @@ $(generated_dir)/%.$(CONFIG).fir $(generated_dir)/%.$(CONFIG).d $(generated_dir) mkdir -p $(dir $@) 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 $@) - $(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).v $(generated_dir)/$(MODEL).$(CONFIG).conf $(mem_gen) + cd $(generated_dir) && \ + $(mem_gen) $(generated_dir)/$(MODEL).$(CONFIG).conf >> $@ $(generated_dir)/consts.$(CONFIG).vh: $(generated_dir)/$(MODEL).$(CONFIG).prm echo "\`ifndef CONST_VH" > $@ diff --git a/vsim/vlsi_mem_gen b/vsim/vlsi_mem_gen index dde216bf..37829498 100755 --- a/vsim/vlsi_mem_gen +++ b/vsim/vlsi_mem_gen @@ -12,7 +12,7 @@ def parse_line(line): width = 0 depth = 0 ports = '' - mask_gran = 1 + mask_gran = 0 tokens = line.split() i = 0 for i in range(0,len(tokens),2): @@ -21,20 +21,20 @@ def parse_line(line): name = tokens[i+1] elif s == 'width': width = int(tokens[i+1]) + mask_gran = width # default setting elif s == 'depth': depth = int(tokens[i+1]) elif s == 'ports': ports = tokens[i+1].split(',') elif s == 'mask_gran': - # currently used only for fpga, but here for .conf format compatability mask_gran = int(tokens[i+1]) else: 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) - port_spec = ['input CLK', 'input RST', 'input init'] + port_spec = [] readports = [] writeports = [] latchports = [] @@ -50,28 +50,34 @@ def gen_mem(name, width, depth, ports): maskedports[pid] = pid if ptype == 'read': - port_spec.append('input [%d:0] R%dA' % (addr_width-1, pid)) - port_spec.append('input R%dE' % pid) - port_spec.append('output [%d:0] R%dO' % (width-1, pid)) + prefix = 'R%d_' % len(readports) + port_spec.append('input %sclk' % prefix) + 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) elif ptype == 'write': - port_spec.append('input [%d:0] W%dA' % (addr_width-1, pid)) - port_spec.append('input W%dE' % pid) - port_spec.append('input [%d:0] W%dI' % (width-1, pid)) + prefix = 'W%d_' % len(writeports) + port_spec.append('input %sclk' % prefix) + 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: - 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: writeports.append(pid) else: latchports.append(pid) elif ptype == 'rw': - port_spec.append('input [%d:0] RW%dA' % (addr_width-1, pid)) - port_spec.append('input RW%dE' % pid) - port_spec.append('input RW%dW' % pid) + prefix = 'RW%d_' % len(rwports) + port_spec.append('input %sclk' % prefix) + 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: - port_spec.append('input [%d:0] RW%dM' % (width-1, pid)) - port_spec.append('input [%d:0] RW%dI' % (width-1, pid)) - port_spec.append('output [%d:0] RW%dO' % (width-1, pid)) + port_spec.append('input [%d:0] %swmask' % (mask_seg-1, prefix)) + port_spec.append('input [%d:0] %swdata' % (width-1, prefix)) + port_spec.append('output [%d:0] %srdata' % (width-1, prefix)) rwports.append(pid) else: 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 tup = (depth, width, nr, nw, nrw, masked) - for pid in readports: - decl.append('reg [%d:0] reg_R%dA;' % (addr_width-1, pid)) - sequential.append('if (R%dE) reg_R%dA <= R%dA;' % (pid, pid, pid)) - combinational.append('assign R%dO = ram[reg_R%dA];' % (pid, pid)) + for idx in range(nr): + prefix = 'R%d_' % idx + decl.append('reg [%d:0] reg_%saddr;' % (addr_width-1, prefix)) + 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: - decl.append('reg [%d:0] reg_RW%dA;' % (addr_width-1, pid)) - sequential.append('if (RW%dE && !RW%dW) reg_RW%dA <= RW%dA;' % (pid, pid, pid, pid)) - combinational.append('assign RW%dO = ram[reg_RW%dA];' % (pid, pid)) + for idx in range(nrw): + prefix = 'RW%d_' % idx + decl.append('reg [%d:0] reg_%saddr;' % (addr_width-1, prefix)) + 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: - decl.append('reg [%d:0] latch_W%dA;' % (addr_width-1, pid)) - decl.append('reg [%d:0] latch_W%dI;' % (width-1, pid)) - decl.append('reg latch_W%dE;' % (pid)) + for idx in range(len(latchports)): + prefix = 'W%d_' % idx + decl.append('reg [%d:0] latch_%saddr;' % (addr_width-1, prefix)) + decl.append('reg [%d:0] latch_%sdata;' % (width-1, prefix)) + decl.append('reg latch_%sen;' % (prefix)) combinational.append('always @(*) begin') - combinational.append(' if (!CLK && W%dE) latch_W%dA <= W%dA;' % (pid, pid, pid)) - combinational.append(' if (!CLK && W%dE) latch_W%dI <= W%dI;' % (pid, pid, pid)) - combinational.append(' if (!CLK) latch_W%dE <= W%dE;' % (pid, pid)) + combinational.append(' if (!%sclk && %sen) latch_%saddr <= %saddr;' % (prefix, prefix, prefix, prefix)) + combinational.append(' if (!%sclk && %sen) latch_%sdata <= %sdata;' % (prefix, prefix, prefix, prefix)) + combinational.append(' if (!%sclk) latch_%sen <= %sen;' % (prefix, prefix, prefix)) combinational.append('end') combinational.append('always @(*)') - combinational.append(' if (CLK && latch_W%dE)' % (pid)) - combinational.append(' ram[latch_W%dA] <= latch_W%dI;' % (pid, pid)) + combinational.append(' if (%sclk && latch_%sen)' % (prefix, prefix)) + combinational.append(' ram[latch_%saddr] <= latch_%sdata;' % (prefix, prefix)) 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(' initial begin') decl.append(' #0.002;') decl.append(' for (initvar = 0; initvar < %d; initvar = initvar+1)' % depth) decl.append(' ram[initvar] = {%d {$random}};' % ((width-1)/32+1)) - for pid in readports: - decl.append(' reg_R%dA = {%d {$random}};' % (pid, ((addr_width-1)/32+1))) - for pid in rwports: - decl.append(' reg_RW%dA = {%d {$random}};' % (pid, ((addr_width-1)/32+1))) + for idx in range(nr): + prefix = 'R%d_' % idx + decl.append(' reg_%saddr = {%d {$random}};' % (prefix, ((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('`endif') decl.append("integer i;") - sequential.append("for (i = 0; i < %d; i=i+1) begin" % width) - for pid in writeports: - mask = (' && W%dM[i]' % pid) if pid in maskedports else '' - sequential.append(" if (W%dE%s) ram[W%dA][i] <= W%dI[i];" % (pid, mask, pid, pid)) - for pid in rwports: - mask = (' && RW%dM[i]' % pid) if pid in maskedports else '' - sequential.append(" if (RW%dE && RW%dW%s) ram[RW%dA][i] <= RW%dI[i];" % (pid, pid, mask, pid, pid)) - sequential.append("end") + for idx in range(nw): + prefix = 'W%d_' % idx + pid = writeports[idx] + sequential.append('always @(posedge %sclk)' % prefix) + sequential.append(" if (%sen) begin" % prefix) + for i in range(mask_seg): + mask = ('if (%smask[%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] <= %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 = "\ %s\n\ - always @(posedge CLK) begin\n\ - %s\n\ - end\n\ - %s\n" % ('\n '.join(decl), '\n '.join(sequential), '\n '.join(combinational)) + %s\n\ + %s\n" % ('\n '.join(decl), '\n '.join(sequential), '\n '.join(combinational)) - s = "module %s(\n\ + s = "\nmodule %s(\n\ %s\n\ );\n\ \n\ %s\ \n\ -endmodule\n" % (name, ',\n '.join(port_spec), body) +endmodule" % (name, ',\n '.join(port_spec), body) return s def main():