Merge pull request #350 from pepijndevos/newslice
Dedicated output for LUT in GENERIC_SLICE
This commit is contained in:
commit
6a335411da
3
.gitignore
vendored
3
.gitignore
vendored
@ -19,6 +19,9 @@ CMakeCache.txt
|
|||||||
.*.swp
|
.*.swp
|
||||||
a.out
|
a.out
|
||||||
*.json
|
*.json
|
||||||
|
*.dot
|
||||||
|
*.il
|
||||||
|
/generic/examples/blinky.png
|
||||||
build/
|
build/
|
||||||
*.asc
|
*.asc
|
||||||
*.bin
|
*.bin
|
||||||
|
@ -42,7 +42,7 @@ std::unique_ptr<CellInfo> create_generic_cell(Context *ctx, IdString type, std::
|
|||||||
}
|
}
|
||||||
new_cell->type = type;
|
new_cell->type = type;
|
||||||
if (type == ctx->id("GENERIC_SLICE")) {
|
if (type == ctx->id("GENERIC_SLICE")) {
|
||||||
new_cell->params[ctx->id("K")] = std::to_string(ctx->args.K);
|
new_cell->params[ctx->id("K")] = ctx->args.K;
|
||||||
new_cell->params[ctx->id("INIT")] = 0;
|
new_cell->params[ctx->id("INIT")] = 0;
|
||||||
new_cell->params[ctx->id("FF_USED")] = 0;
|
new_cell->params[ctx->id("FF_USED")] = 0;
|
||||||
|
|
||||||
@ -51,6 +51,7 @@ std::unique_ptr<CellInfo> create_generic_cell(Context *ctx, IdString type, std::
|
|||||||
|
|
||||||
add_port(ctx, new_cell.get(), "CLK", PORT_IN);
|
add_port(ctx, new_cell.get(), "CLK", PORT_IN);
|
||||||
|
|
||||||
|
add_port(ctx, new_cell.get(), "F", PORT_OUT);
|
||||||
add_port(ctx, new_cell.get(), "Q", PORT_OUT);
|
add_port(ctx, new_cell.get(), "Q", PORT_OUT);
|
||||||
} else if (type == ctx->id("GENERIC_IOB")) {
|
} else if (type == ctx->id("GENERIC_IOB")) {
|
||||||
new_cell->params[ctx->id("INPUT_USED")] = 0;
|
new_cell->params[ctx->id("INPUT_USED")] = 0;
|
||||||
@ -80,8 +81,8 @@ void lut_to_lc(const Context *ctx, CellInfo *lut, CellInfo *lc, bool no_dff)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (no_dff) {
|
if (no_dff) {
|
||||||
replace_port(lut, ctx->id("Q"), lc, ctx->id("Q"));
|
|
||||||
lc->params[ctx->id("FF_USED")] = 0;
|
lc->params[ctx->id("FF_USED")] = 0;
|
||||||
|
replace_port(lut, ctx->id("Q"), lc, ctx->id("F"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,7 +92,14 @@ void dff_to_lc(const Context *ctx, CellInfo *dff, CellInfo *lc, bool pass_thru_l
|
|||||||
replace_port(dff, ctx->id("CLK"), lc, ctx->id("CLK"));
|
replace_port(dff, ctx->id("CLK"), lc, ctx->id("CLK"));
|
||||||
|
|
||||||
if (pass_thru_lut) {
|
if (pass_thru_lut) {
|
||||||
lc->params[ctx->id("INIT")] = 2;
|
// Fill LUT with alternating 10
|
||||||
|
const int init_size = 1 << lc->params[ctx->id("K")].as_int64();
|
||||||
|
std::string init;
|
||||||
|
init.reserve(init_size);
|
||||||
|
for(int i = 0; i < init_size; i+=2)
|
||||||
|
init.append("10");
|
||||||
|
lc->params[ctx->id("INIT")] = Property::from_string(init);
|
||||||
|
|
||||||
replace_port(dff, ctx->id("D"), lc, ctx->id("I[0]"));
|
replace_port(dff, ctx->id("D"), lc, ctx->id("I[0]"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,4 +14,4 @@ param_map = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
with open("blinky.fasm", "w") as f:
|
with open("blinky.fasm", "w") as f:
|
||||||
write_fasm(ctx, param_map, f)
|
write_fasm(ctx, param_map, f)
|
||||||
|
@ -9,6 +9,7 @@ for x in range(X):
|
|||||||
for z in range(N):
|
for z in range(N):
|
||||||
ctx.addWire(name="X%dY%dZ%d_CLK" % (x, y, z), type="BEL_CLK", x=x, y=y)
|
ctx.addWire(name="X%dY%dZ%d_CLK" % (x, y, z), type="BEL_CLK", x=x, y=y)
|
||||||
ctx.addWire(name="X%dY%dZ%d_Q" % (x, y, z), type="BEL_Q", x=x, y=y)
|
ctx.addWire(name="X%dY%dZ%d_Q" % (x, y, z), type="BEL_Q", x=x, y=y)
|
||||||
|
ctx.addWire(name="X%dY%dZ%d_F" % (x, y, z), type="BEL_F", x=x, y=y)
|
||||||
for i in range(K):
|
for i in range(K):
|
||||||
ctx.addWire(name="X%dY%dZ%d_I%d" % (x, y, z, i), type="BEL_I", x=x, y=y)
|
ctx.addWire(name="X%dY%dZ%d_I%d" % (x, y, z, i), type="BEL_I", x=x, y=y)
|
||||||
# Local wires
|
# Local wires
|
||||||
@ -29,6 +30,7 @@ for x in range(X):
|
|||||||
ctx.addBelInput(bel="X%dY%d_SLICE%d" % (x, y, z), name="CLK", wire="X%dY%dZ%d_CLK" % (x, y, z))
|
ctx.addBelInput(bel="X%dY%d_SLICE%d" % (x, y, z), name="CLK", wire="X%dY%dZ%d_CLK" % (x, y, z))
|
||||||
for k in range(K):
|
for k in range(K):
|
||||||
ctx.addBelInput(bel="X%dY%d_SLICE%d" % (x, y, z), name="I[%d]" % k, wire="X%dY%dZ%d_I%d" % (x, y, z, k))
|
ctx.addBelInput(bel="X%dY%d_SLICE%d" % (x, y, z), name="I[%d]" % k, wire="X%dY%dZ%d_I%d" % (x, y, z, k))
|
||||||
|
ctx.addBelOutput(bel="X%dY%d_SLICE%d" % (x, y, z), name="F", wire="X%dY%dZ%d_F" % (x, y, z))
|
||||||
ctx.addBelOutput(bel="X%dY%d_SLICE%d" % (x, y, z), name="Q", wire="X%dY%dZ%d_Q" % (x, y, z))
|
ctx.addBelOutput(bel="X%dY%d_SLICE%d" % (x, y, z), name="Q", wire="X%dY%dZ%d_Q" % (x, y, z))
|
||||||
|
|
||||||
for x in range(X):
|
for x in range(X):
|
||||||
@ -48,6 +50,9 @@ for x in range(X):
|
|||||||
# Pips from bel outputs to locals
|
# Pips from bel outputs to locals
|
||||||
def create_output_pips(dst, offset, skip):
|
def create_output_pips(dst, offset, skip):
|
||||||
for i in range(offset % skip, N, skip):
|
for i in range(offset % skip, N, skip):
|
||||||
|
src = "X%dY%dZ%d_F" % (x, y, i)
|
||||||
|
ctx.addPip(name="X%dY%d.%s.%s" % (x, y, src, dst), type="BEL_OUTPUT",
|
||||||
|
srcWire=src, dstWire=dst, delay=ctx.getDelayFromNS(0.05), loc=Loc(x, y, 0))
|
||||||
src = "X%dY%dZ%d_Q" % (x, y, i)
|
src = "X%dY%dZ%d_Q" % (x, y, i)
|
||||||
ctx.addPip(name="X%dY%d.%s.%s" % (x, y, src, dst), type="BEL_OUTPUT",
|
ctx.addPip(name="X%dY%d.%s.%s" % (x, y, src, dst), type="BEL_OUTPUT",
|
||||||
srcWire=src, dstWire=dst, delay=ctx.getDelayFromNS(0.05), loc=Loc(x, y, 0))
|
srcWire=src, dstWire=dst, delay=ctx.getDelayFromNS(0.05), loc=Loc(x, y, 0))
|
||||||
@ -69,4 +74,4 @@ for x in range(X):
|
|||||||
create_neighbour_pips(dst, x, y+1, (l + 4) % Sl, Sl)
|
create_neighbour_pips(dst, x, y+1, (l + 4) % Sl, Sl)
|
||||||
create_neighbour_pips(dst, x+1, y-1, (l + 5) % Sl, Sl)
|
create_neighbour_pips(dst, x+1, y-1, (l + 5) % Sl, Sl)
|
||||||
create_neighbour_pips(dst, x+1, y, (l + 6) % Sl, Sl)
|
create_neighbour_pips(dst, x+1, y, (l + 6) % Sl, Sl)
|
||||||
create_neighbour_pips(dst, x+1, y+1, (l + 7) % Sl, Sl)
|
create_neighbour_pips(dst, x+1, y+1, (l + 7) % Sl, Sl)
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -ex
|
set -ex
|
||||||
yosys -p "tcl ../synth/synth_generic.tcl 4 blinky.json" blinky.v
|
yosys -p "tcl ../synth/synth_generic.tcl 4 blinky.json" blinky.v
|
||||||
${NEXTPNR:-../../nextpnr-generic} --pre-pack simple.py --pre-place simple_timing.py --json blinky.json --post-route bitstream.py
|
${NEXTPNR:-../../nextpnr-generic} --pre-pack simple.py --pre-place simple_timing.py --json blinky.json --post-route bitstream.py --write pnrblinky.json
|
||||||
|
yosys -p "read_verilog -lib ../synth/prims.v; read_json pnrblinky.json; dump -o blinky.il; show -format png -prefix blinky"
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
for cname, cell in ctx.cells:
|
for cname, cell in ctx.cells:
|
||||||
if cell.type != "GENERIC_SLICE":
|
if cell.type != "GENERIC_SLICE":
|
||||||
continue
|
continue
|
||||||
if cname in ("$PACKER_GND", "$PACKER_VCC"):
|
if cname in ("$PACKER_GND", "$PACKER_VCC"):
|
||||||
continue
|
continue
|
||||||
K = int(cell.params["K"])
|
K = int(cell.params["K"])
|
||||||
if int(cell.params["FF_USED"], 2) == 1:
|
ctx.addCellTimingClock(cell=cname, port="CLK")
|
||||||
ctx.addCellTimingClock(cell=cname, port="CLK")
|
for i in range(K):
|
||||||
for i in range(K):
|
ctx.addCellTimingSetupHold(cell=cname, port="I[%d]" % i, clock="CLK",
|
||||||
ctx.addCellTimingSetupHold(cell=cname, port="I[%d]" % i, clock="CLK",
|
setup=ctx.getDelayFromNS(0.2), hold=ctx.getDelayFromNS(0))
|
||||||
setup=ctx.getDelayFromNS(0.2), hold=ctx.getDelayFromNS(0))
|
ctx.addCellTimingClockToOut(cell=cname, port="Q", clock="CLK", clktoq=ctx.getDelayFromNS(0.2))
|
||||||
ctx.addCellTimingClockToOut(cell=cname, port="Q", clock="CLK", clktoq=ctx.getDelayFromNS(0.2))
|
for i in range(K):
|
||||||
else:
|
ctx.addCellTimingDelay(cell=cname, fromPort="I[%d]" % i, toPort="F", delay=ctx.getDelayFromNS(0.2))
|
||||||
for i in range(K):
|
|
||||||
ctx.addCellTimingDelay(cell=cname, fromPort="I[%d]" % i, toPort="Q", delay=ctx.getDelayFromNS(0.2))
|
|
||||||
|
@ -25,17 +25,16 @@ module GENERIC_SLICE #(
|
|||||||
) (
|
) (
|
||||||
input CLK,
|
input CLK,
|
||||||
input [K-1:0] I,
|
input [K-1:0] I,
|
||||||
|
output F,
|
||||||
output Q
|
output Q
|
||||||
);
|
);
|
||||||
|
wire f_wire;
|
||||||
|
|
||||||
wire lut_q;
|
LUT #(.K(K), .INIT(INIT)) lut_i(.I(I), .Q(f_wire));
|
||||||
LUT #(.K(K), .INIT(INIT)) lut_i(.I(I), .Q(lut_q));
|
|
||||||
|
|
||||||
generate if (FF_USED)
|
DFF dff_i(.CLK(CLK), .D(f_wire), .Q(Q));
|
||||||
DFF dff_i(.CLK(CLK), .D(lut_q), .Q(Q));
|
|
||||||
else
|
assign F = f_wire;
|
||||||
assign Q = lut_q;
|
|
||||||
endgenerate
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
module GENERIC_IOB #(
|
module GENERIC_IOB #(
|
||||||
@ -56,4 +55,4 @@ module GENERIC_IOB #(
|
|||||||
generate if (INPUT_USED)
|
generate if (INPUT_USED)
|
||||||
assign O = PAD;
|
assign O = PAD;
|
||||||
endgenerate
|
endgenerate
|
||||||
endmodule
|
endmodule
|
||||||
|
Loading…
Reference in New Issue
Block a user