Skip to content

Commit

Permalink
update template generator
Browse files Browse the repository at this point in the history
  • Loading branch information
gadfort committed Nov 6, 2024
1 parent c0c6c85 commit 0f6b610
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 48 deletions.
2 changes: 1 addition & 1 deletion lambdalib/ramlib/rtl/la_spram.v
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ module la_spram #(
.AW (AW),
.PROP (PROP),
.CTRLW (CTRLW),
.TESTW (TESTW),
.TESTW (TESTW)
) ram (
.clk (clk),
.ce (ce),
Expand Down
10 changes: 9 additions & 1 deletion lambdalib/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from jinja2 import Template
import os
import math
from collections import OrderedDict


def write_la_spram(fout, memories, control_signals=None, la_type='ram'):
def write_la_spram(fout, memories, control_signals=None, la_type='ram', minbits=None):
template_path = os.path.abspath(os.path.join(os.path.dirname(__file__),
'templates',
'la_spmemory.v'))
Expand Down Expand Up @@ -33,6 +34,13 @@ def write_la_spram(fout, memories, control_signals=None, la_type='ram'):
selection_table = OrderedDict(sorted(selection_table.items(), reverse=True))
for aw, items in selection_table.items():
selection_table[aw] = OrderedDict(sorted(items.items(), reverse=True))

if minbits is not None:
depth = 2**aw
dw = int(math.floor(minbits / depth))
if dw > 0:
selection_table[aw][dw] = "SOFT"
selection_table[min(selection_table.keys()) - 1] = {0: "SOFT"}
widths_table.sort()
depths_table.sort()

Expand Down
116 changes: 70 additions & 46 deletions lambdalib/utils/templates/la_spmemory.v
Original file line number Diff line number Diff line change
Expand Up @@ -56,61 +56,85 @@ module la_sp{{ type }}
(MEM_PROP == "{{ memory }}") ? {{ depth }} :{% endfor %}
0;

// Create memories
localparam MEM_ADDRS = 2**(AW - MEM_DEPTH) < 1 ? 1 : 2**(AW - MEM_DEPTH);

{% if control_signals %}// Control signals{% for line in control_signals %}
{{ line }}{% endfor %}{% endif %}

generate
genvar o;
for (o = 0; o < DW; o = o + 1) begin: OUTPUTS
wire [MEM_ADDRS-1:0] mem_outputs;
assign dout[o] = |mem_outputs;
if (MEM_PROP == "SOFT") begin: isoft
la_spram_impl #(
.DW(DW),
.AW(AW),
.PROP(PROP),
.CTRLW(CTRLW),
.TESTW(TESTW)
) memory(
.clk(clk),
.ce(ce),
.we(we),
.wmask(wmask),
.addr(addr),
.din(din),
.dout(dout),
.vss(vss),
.vdd(vdd),
.vddio(vddio),
.ctrl(ctrl),
.test(test)
);
end
if (MEM_PROP != "SOFT") begin: itech
// Create memories
localparam MEM_ADDRS = 2**(AW - MEM_DEPTH) < 1 ? 1 : 2**(AW - MEM_DEPTH);

genvar a;
for (a = 0; a < MEM_ADDRS; a = a + 1) begin: ADDR
wire selected;
wire [MEM_DEPTH-1:0] mem_addr;
{% if control_signals %}// Control signals{% for line in control_signals %}
{{ line }}{% endfor %}{% endif %}

if (MEM_ADDRS == 1) begin: FITS
assign selected = 1'b1;
assign mem_addr = addr;
end else begin: NOFITS
assign selected = addr[AW-1:MEM_DEPTH] == a;
assign mem_addr = addr[MEM_DEPTH-1:0];
genvar o;
for (o = 0; o < DW; o = o + 1) begin: OUTPUTS
wire [MEM_ADDRS-1:0] mem_outputs;
assign dout[o] = |mem_outputs;
end

genvar n;
for (n = 0; n < DW; n = n + MEM_WIDTH) begin: WORD
wire [MEM_WIDTH-1:0] mem_din;
wire [MEM_WIDTH-1:0] mem_dout;
wire [MEM_WIDTH-1:0] mem_wmask;
genvar a;
for (a = 0; a < MEM_ADDRS; a = a + 1) begin: ADDR
wire selected;
wire [MEM_DEPTH-1:0] mem_addr;

genvar i;
for (i = 0; i < MEM_WIDTH; i = i + 1) begin: WORD_SELECT
if (n + i < DW) begin: ACTIVE
assign mem_din[i] = din[n + i];
assign mem_wmask[i] = wmask[n + i];
assign OUTPUTS[n + i].mem_outputs[a] = selected ? mem_dout[i] : 1'b0;
end
else begin: INACTIVE
assign mem_din[i] = 1'b0;
assign mem_wmask[i] = 1'b0;
end
if (MEM_ADDRS == 1) begin: FITS
assign selected = 1'b1;
assign mem_addr = addr;
end else begin: NOFITS
assign selected = addr[AW-1:MEM_DEPTH] == a;
assign mem_addr = addr[MEM_DEPTH-1:0];
end

wire ce_in;
wire we_in;
assign ce_in = ce && selected;
assign we_in = we && selected;
{% for memory, inst_name in inst_map.items() %}
if (MEM_PROP == "{{ memory }}") begin: i{{ memory }}
{{ inst_name }} memory ({% for port, net in port_mapping[memory] %}
.{{ port }}({{ net }}){% if loop.nextitem is defined %},{% endif %}{% endfor %}
);
end{% endfor %}
genvar n;
for (n = 0; n < DW; n = n + MEM_WIDTH) begin: WORD
wire [MEM_WIDTH-1:0] mem_din;
wire [MEM_WIDTH-1:0] mem_dout;
wire [MEM_WIDTH-1:0] mem_wmask;

genvar i;
for (i = 0; i < MEM_WIDTH; i = i + 1) begin: WORD_SELECT
if (n + i < DW) begin: ACTIVE
assign mem_din[i] = din[n + i];
assign mem_wmask[i] = wmask[n + i];
assign OUTPUTS[n + i].mem_outputs[a] = selected ? mem_dout[i] : 1'b0;
end
else begin: INACTIVE
assign mem_din[i] = 1'b0;
assign mem_wmask[i] = 1'b0;
end
end

wire ce_in;
wire we_in;
assign ce_in = ce && selected;
assign we_in = we && selected;
{% for memory, inst_name in inst_map.items() %}
if (MEM_PROP == "{{ memory }}") begin: i{{ memory }}
{{ inst_name }} memory ({% for port, net in port_mapping[memory] %}
.{{ port }}({{ net }}){% if loop.nextitem is defined %},{% endif %}{% endfor %}
);
end{% endfor %}
end
end
end
endgenerate
Expand Down

0 comments on commit 0f6b610

Please sign in to comment.