aboutsummaryrefslogtreecommitdiffstats
path: root/techlibs/ice40
diff options
context:
space:
mode:
Diffstat (limited to 'techlibs/ice40')
-rw-r--r--techlibs/ice40/cells_map.v2
-rw-r--r--techlibs/ice40/cells_sim.v111
-rw-r--r--techlibs/ice40/ice40_ffinit.cc4
-rw-r--r--techlibs/ice40/ice40_ffssr.cc4
-rw-r--r--techlibs/ice40/ice40_opt.cc38
-rw-r--r--techlibs/ice40/synth_ice40.cc56
6 files changed, 131 insertions, 84 deletions
diff --git a/techlibs/ice40/cells_map.v b/techlibs/ice40/cells_map.v
index 6550b75cf..d0ddfd02e 100644
--- a/techlibs/ice40/cells_map.v
+++ b/techlibs/ice40/cells_map.v
@@ -27,7 +27,7 @@ module \$__DFFE_NP1 (input D, C, E, R, output Q); SB_DFFNES _TECHMAP_REPLACE_ (
module \$__DFFE_PP0 (input D, C, E, R, output Q); SB_DFFER _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(R)); endmodule
module \$__DFFE_PP1 (input D, C, E, R, output Q); SB_DFFES _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(R)); endmodule
-`ifndef NO_SB_LUT4
+`ifndef NO_LUT
module \$lut (A, Y);
parameter WIDTH = 0;
parameter LUT = 0;
diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v
index 814895e70..e0a07af32 100644
--- a/techlibs/ice40/cells_sim.v
+++ b/techlibs/ice40/cells_sim.v
@@ -1,6 +1,6 @@
-`define SB_DFF_REG reg Q = 0;
-// `define SB_DFF_REG reg Q;
+`define SB_DFF_REG reg Q = 0
+// `define SB_DFF_REG reg Q
// SiliconBlue IO Cells
@@ -132,21 +132,18 @@ endmodule
// Positive Edge SiliconBlue FF Cells
-module SB_DFF (output Q, input C, D);
- `SB_DFF_REG
+module SB_DFF (output `SB_DFF_REG, input C, D);
always @(posedge C)
Q <= D;
endmodule
-module SB_DFFE (output Q, input C, E, D);
- `SB_DFF_REG
+module SB_DFFE (output `SB_DFF_REG, input C, E, D);
always @(posedge C)
if (E)
Q <= D;
endmodule
-module SB_DFFSR (output Q, input C, R, D);
- `SB_DFF_REG
+module SB_DFFSR (output `SB_DFF_REG, input C, R, D);
always @(posedge C)
if (R)
Q <= 0;
@@ -154,8 +151,7 @@ module SB_DFFSR (output Q, input C, R, D);
Q <= D;
endmodule
-module SB_DFFR (output Q, input C, R, D);
- `SB_DFF_REG
+module SB_DFFR (output `SB_DFF_REG, input C, R, D);
always @(posedge C, posedge R)
if (R)
Q <= 0;
@@ -163,8 +159,7 @@ module SB_DFFR (output Q, input C, R, D);
Q <= D;
endmodule
-module SB_DFFSS (output Q, input C, S, D);
- `SB_DFF_REG
+module SB_DFFSS (output `SB_DFF_REG, input C, S, D);
always @(posedge C)
if (S)
Q <= 1;
@@ -172,8 +167,7 @@ module SB_DFFSS (output Q, input C, S, D);
Q <= D;
endmodule
-module SB_DFFS (output Q, input C, S, D);
- `SB_DFF_REG
+module SB_DFFS (output `SB_DFF_REG, input C, S, D);
always @(posedge C, posedge S)
if (S)
Q <= 1;
@@ -181,8 +175,7 @@ module SB_DFFS (output Q, input C, S, D);
Q <= D;
endmodule
-module SB_DFFESR (output Q, input C, E, R, D);
- `SB_DFF_REG
+module SB_DFFESR (output `SB_DFF_REG, input C, E, R, D);
always @(posedge C)
if (E) begin
if (R)
@@ -192,8 +185,7 @@ module SB_DFFESR (output Q, input C, E, R, D);
end
endmodule
-module SB_DFFER (output Q, input C, E, R, D);
- `SB_DFF_REG
+module SB_DFFER (output `SB_DFF_REG, input C, E, R, D);
always @(posedge C, posedge R)
if (R)
Q <= 0;
@@ -201,8 +193,7 @@ module SB_DFFER (output Q, input C, E, R, D);
Q <= D;
endmodule
-module SB_DFFESS (output Q, input C, E, S, D);
- `SB_DFF_REG
+module SB_DFFESS (output `SB_DFF_REG, input C, E, S, D);
always @(posedge C)
if (E) begin
if (S)
@@ -212,8 +203,7 @@ module SB_DFFESS (output Q, input C, E, S, D);
end
endmodule
-module SB_DFFES (output Q, input C, E, S, D);
- `SB_DFF_REG
+module SB_DFFES (output `SB_DFF_REG, input C, E, S, D);
always @(posedge C, posedge S)
if (S)
Q <= 1;
@@ -223,21 +213,18 @@ endmodule
// Negative Edge SiliconBlue FF Cells
-module SB_DFFN (output Q, input C, D);
- `SB_DFF_REG
+module SB_DFFN (output `SB_DFF_REG, input C, D);
always @(negedge C)
Q <= D;
endmodule
-module SB_DFFNE (output Q, input C, E, D);
- `SB_DFF_REG
+module SB_DFFNE (output `SB_DFF_REG, input C, E, D);
always @(negedge C)
if (E)
Q <= D;
endmodule
-module SB_DFFNSR (output Q, input C, R, D);
- `SB_DFF_REG
+module SB_DFFNSR (output `SB_DFF_REG, input C, R, D);
always @(negedge C)
if (R)
Q <= 0;
@@ -245,8 +232,7 @@ module SB_DFFNSR (output Q, input C, R, D);
Q <= D;
endmodule
-module SB_DFFNR (output Q, input C, R, D);
- `SB_DFF_REG
+module SB_DFFNR (output `SB_DFF_REG, input C, R, D);
always @(negedge C, posedge R)
if (R)
Q <= 0;
@@ -254,8 +240,7 @@ module SB_DFFNR (output Q, input C, R, D);
Q <= D;
endmodule
-module SB_DFFNSS (output Q, input C, S, D);
- `SB_DFF_REG
+module SB_DFFNSS (output `SB_DFF_REG, input C, S, D);
always @(negedge C)
if (S)
Q <= 1;
@@ -263,8 +248,7 @@ module SB_DFFNSS (output Q, input C, S, D);
Q <= D;
endmodule
-module SB_DFFNS (output Q, input C, S, D);
- `SB_DFF_REG
+module SB_DFFNS (output `SB_DFF_REG, input C, S, D);
always @(negedge C, posedge S)
if (S)
Q <= 1;
@@ -272,8 +256,7 @@ module SB_DFFNS (output Q, input C, S, D);
Q <= D;
endmodule
-module SB_DFFNESR (output Q, input C, E, R, D);
- `SB_DFF_REG
+module SB_DFFNESR (output `SB_DFF_REG, input C, E, R, D);
always @(negedge C)
if (E) begin
if (R)
@@ -283,8 +266,7 @@ module SB_DFFNESR (output Q, input C, E, R, D);
end
endmodule
-module SB_DFFNER (output Q, input C, E, R, D);
- `SB_DFF_REG
+module SB_DFFNER (output `SB_DFF_REG, input C, E, R, D);
always @(negedge C, posedge R)
if (R)
Q <= 0;
@@ -292,8 +274,7 @@ module SB_DFFNER (output Q, input C, E, R, D);
Q <= D;
endmodule
-module SB_DFFNESS (output Q, input C, E, S, D);
- `SB_DFF_REG
+module SB_DFFNESS (output `SB_DFF_REG, input C, E, S, D);
always @(negedge C)
if (E) begin
if (S)
@@ -303,8 +284,7 @@ module SB_DFFNESS (output Q, input C, E, S, D);
end
endmodule
-module SB_DFFNES (output Q, input C, E, S, D);
- `SB_DFF_REG
+module SB_DFFNES (output `SB_DFF_REG, input C, E, S, D);
always @(negedge C, posedge S)
if (S)
Q <= 1;
@@ -677,7 +657,12 @@ module ICESTORM_LC (
parameter [0:0] SET_NORESET = 0;
parameter [0:0] ASYNC_SR = 0;
- wire COUT = CARRY_ENABLE ? (I1 && I2) || ((I1 || I2) && CIN) : 1'bx;
+ parameter [0:0] CIN_CONST = 0;
+ parameter [0:0] CIN_SET = 0;
+
+ wire mux_cin = CIN_CONST ? CIN_SET : CIN;
+
+ assign COUT = CARRY_ENABLE ? (I1 && I2) || ((I1 || I2) && mux_cin) : 1'bx;
wire [7:0] lut_s3 = I3 ? LUT_INIT[15:8] : LUT_INIT[7:0];
wire [3:0] lut_s2 = I2 ? lut_s3[ 7:4] : lut_s3[3:0];
@@ -935,19 +920,40 @@ parameter A_SIGNED = 1'b0;
parameter B_SIGNED = 1'b0;
endmodule
-(* blackbox *)
-module SB_SPRAM256KA(
+module SB_SPRAM256KA (
input [13:0] ADDRESS,
input [15:0] DATAIN,
input [3:0] MASKWREN,
- input WREN,
- input CHIPSELECT,
- input CLOCK,
- input STANDBY,
- input SLEEP,
- input POWEROFF,
- output [15:0] DATAOUT
+ input WREN, CHIPSELECT, CLOCK, STANDBY, SLEEP, POWEROFF,
+ output reg [15:0] DATAOUT
);
+`ifndef BLACKBOX
+ reg [15:0] mem [0:16383];
+ wire off = SLEEP || !POWEROFF;
+ integer i;
+
+ always @(negedge POWEROFF) begin
+ for (i = 0; i <= 16383; i = i+1)
+ mem[i] = 'bx;
+ end
+
+ always @(posedge CLOCK, posedge off) begin
+ if (off) begin
+ DATAOUT <= 0;
+ end else
+ if (CHIPSELECT && !STANDBY && !WREN) begin
+ DATAOUT <= mem[ADDRESS];
+ end else begin
+ if (CHIPSELECT && !STANDBY && WREN) begin
+ if (MASKWREN[0]) mem[ADDRESS][ 3: 0] = DATAIN[ 3: 0];
+ if (MASKWREN[1]) mem[ADDRESS][ 7: 4] = DATAIN[ 7: 4];
+ if (MASKWREN[2]) mem[ADDRESS][11: 8] = DATAIN[11: 8];
+ if (MASKWREN[3]) mem[ADDRESS][15:12] = DATAIN[15:12];
+ end
+ DATAOUT <= 'bx;
+ end
+ end
+`endif
endmodule
(* blackbox *)
@@ -1246,4 +1252,3 @@ module SB_IO_OD (
endgenerate
`endif
endmodule
-
diff --git a/techlibs/ice40/ice40_ffinit.cc b/techlibs/ice40/ice40_ffinit.cc
index c914b20e8..3089d8932 100644
--- a/techlibs/ice40/ice40_ffinit.cc
+++ b/techlibs/ice40/ice40_ffinit.cc
@@ -25,7 +25,7 @@ PRIVATE_NAMESPACE_BEGIN
struct Ice40FfinitPass : public Pass {
Ice40FfinitPass() : Pass("ice40_ffinit", "iCE40: handle FF init values") { }
- virtual void help()
+ void help() YS_OVERRIDE
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
@@ -35,7 +35,7 @@ struct Ice40FfinitPass : public Pass {
log("nonzero init values.\n");
log("\n");
}
- virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
+ void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
log_header(design, "Executing ICE40_FFINIT pass (implement FF init values).\n");
diff --git a/techlibs/ice40/ice40_ffssr.cc b/techlibs/ice40/ice40_ffssr.cc
index 9afbc0fce..668df09dd 100644
--- a/techlibs/ice40/ice40_ffssr.cc
+++ b/techlibs/ice40/ice40_ffssr.cc
@@ -25,7 +25,7 @@ PRIVATE_NAMESPACE_BEGIN
struct Ice40FfssrPass : public Pass {
Ice40FfssrPass() : Pass("ice40_ffssr", "iCE40: merge synchronous set/reset into FF cells") { }
- virtual void help()
+ void help() YS_OVERRIDE
{
log("\n");
log(" ice40_ffssr [options] [selection]\n");
@@ -33,7 +33,7 @@ struct Ice40FfssrPass : public Pass {
log("Merge synchronous set/reset $_MUX_ cells into iCE40 FFs.\n");
log("\n");
}
- virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
+ void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
log_header(design, "Executing ICE40_FFSSR pass (merge synchronous set/reset into FF cells).\n");
diff --git a/techlibs/ice40/ice40_opt.cc b/techlibs/ice40/ice40_opt.cc
index ae72f5d64..162740059 100644
--- a/techlibs/ice40/ice40_opt.cc
+++ b/techlibs/ice40/ice40_opt.cc
@@ -26,6 +26,13 @@
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
+static SigBit get_bit_or_zero(const SigSpec &sig)
+{
+ if (GetSize(sig) == 0)
+ return State::S0;
+ return sig[0];
+}
+
static void run_ice40_opts(Module *module, bool unlut_mode)
{
pool<SigBit> optimized_co;
@@ -45,7 +52,11 @@ static void run_ice40_opts(Module *module, bool unlut_mode)
SigSpec non_const_inputs, replacement_output;
int count_zeros = 0, count_ones = 0;
- SigBit inbit[3] = {cell->getPort("\\I0"), cell->getPort("\\I1"), cell->getPort("\\CI")};
+ SigBit inbit[3] = {
+ get_bit_or_zero(cell->getPort("\\I0")),
+ get_bit_or_zero(cell->getPort("\\I1")),
+ get_bit_or_zero(cell->getPort("\\CI"))
+ };
for (int i = 0; i < 3; i++)
if (inbit[i].wire == nullptr) {
if (inbit[i] == State::S1)
@@ -63,8 +74,8 @@ static void run_ice40_opts(Module *module, bool unlut_mode)
replacement_output = non_const_inputs;
if (GetSize(replacement_output)) {
- optimized_co.insert(sigmap(cell->getPort("\\CO")));
- module->connect(cell->getPort("\\CO"), replacement_output);
+ optimized_co.insert(sigmap(cell->getPort("\\CO")[0]));
+ module->connect(cell->getPort("\\CO")[0], replacement_output);
module->design->scratchpad_set_bool("opt.did_something", true);
log("Optimized away SB_CARRY cell %s.%s: CO=%s\n",
log_id(module), log_id(cell), log_signal(replacement_output));
@@ -78,10 +89,10 @@ static void run_ice40_opts(Module *module, bool unlut_mode)
{
SigSpec inbits;
- inbits.append(cell->getPort("\\I0"));
- inbits.append(cell->getPort("\\I1"));
- inbits.append(cell->getPort("\\I2"));
- inbits.append(cell->getPort("\\I3"));
+ inbits.append(get_bit_or_zero(cell->getPort("\\I0")));
+ inbits.append(get_bit_or_zero(cell->getPort("\\I1")));
+ inbits.append(get_bit_or_zero(cell->getPort("\\I2")));
+ inbits.append(get_bit_or_zero(cell->getPort("\\I3")));
sigmap.apply(inbits);
if (unlut_mode)
@@ -104,8 +115,13 @@ static void run_ice40_opts(Module *module, bool unlut_mode)
cell->setParam("\\LUT", cell->getParam("\\LUT_INIT"));
cell->unsetParam("\\LUT_INIT");
- cell->setPort("\\A", SigSpec({cell->getPort("\\I3"), cell->getPort("\\I2"), cell->getPort("\\I1"), cell->getPort("\\I0")}));
- cell->setPort("\\Y", cell->getPort("\\O"));
+ cell->setPort("\\A", SigSpec({
+ get_bit_or_zero(cell->getPort("\\I3")),
+ get_bit_or_zero(cell->getPort("\\I2")),
+ get_bit_or_zero(cell->getPort("\\I1")),
+ get_bit_or_zero(cell->getPort("\\I0"))
+ }));
+ cell->setPort("\\Y", cell->getPort("\\O")[0]);
cell->unsetPort("\\I0");
cell->unsetPort("\\I1");
cell->unsetPort("\\I2");
@@ -120,7 +136,7 @@ static void run_ice40_opts(Module *module, bool unlut_mode)
struct Ice40OptPass : public Pass {
Ice40OptPass() : Pass("ice40_opt", "iCE40: perform simple optimizations") { }
- virtual void help()
+ void help() YS_OVERRIDE
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
@@ -140,7 +156,7 @@ struct Ice40OptPass : public Pass {
log("mapped SB_LUT4 cells back to logic.\n");
log("\n");
}
- virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
+ void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
string opt_expr_args = "-mux_undef -undriven";
bool unlut_mode = false;
diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc
index 0bb0fb139..b0687e5e3 100644
--- a/techlibs/ice40/synth_ice40.cc
+++ b/techlibs/ice40/synth_ice40.cc
@@ -29,7 +29,7 @@ struct SynthIce40Pass : public ScriptPass
{
SynthIce40Pass() : ScriptPass("synth_ice40", "synthesis for iCE40 FPGAs") { }
- virtual void help() YS_OVERRIDE
+ void help() YS_OVERRIDE
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
@@ -45,7 +45,11 @@ struct SynthIce40Pass : public ScriptPass
log(" is omitted if this parameter is not specified.\n");
log("\n");
log(" -edif <file>\n");
- log(" write the design to the specified edif file. writing of an output file\n");
+ log(" write the design to the specified EDIF file. writing of an output file\n");
+ log(" is omitted if this parameter is not specified.\n");
+ log("\n");
+ log(" -json <file>\n");
+ log(" write the design to the specified JSON file. writing of an output file\n");
log(" is omitted if this parameter is not specified.\n");
log("\n");
log(" -run <from_label>:<to_label>\n");
@@ -62,6 +66,9 @@ struct SynthIce40Pass : public ScriptPass
log(" -nocarry\n");
log(" do not use SB_CARRY cells in output netlist\n");
log("\n");
+ log(" -nodffe\n");
+ log(" do not use SB_DFFE* cells in output netlist\n");
+ log("\n");
log(" -nobram\n");
log(" do not use SB_RAM40_4K* cells in output netlist\n");
log("\n");
@@ -78,15 +85,17 @@ struct SynthIce40Pass : public ScriptPass
log("\n");
}
- string top_opt, blif_file, edif_file;
- bool nocarry, nobram, flatten, retime, abc2, vpr;
+ string top_opt, blif_file, edif_file, json_file;
+ bool nocarry, nodffe, nobram, flatten, retime, abc2, vpr;
- virtual void clear_flags() YS_OVERRIDE
+ void clear_flags() YS_OVERRIDE
{
top_opt = "-auto-top";
blif_file = "";
edif_file = "";
+ json_file = "";
nocarry = false;
+ nodffe = false;
nobram = false;
flatten = true;
retime = false;
@@ -94,7 +103,7 @@ struct SynthIce40Pass : public ScriptPass
vpr = false;
}
- virtual void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
+ void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
string run_from, run_to;
clear_flags();
@@ -114,6 +123,10 @@ struct SynthIce40Pass : public ScriptPass
edif_file = args[++argidx];
continue;
}
+ if (args[argidx] == "-json" && argidx+1 < args.size()) {
+ json_file = args[++argidx];
+ continue;
+ }
if (args[argidx] == "-run" && argidx+1 < args.size()) {
size_t pos = args[argidx+1].find(':');
if (pos == std::string::npos)
@@ -138,6 +151,10 @@ struct SynthIce40Pass : public ScriptPass
nocarry = true;
continue;
}
+ if (args[argidx] == "-nodffe") {
+ nodffe = true;
+ continue;
+ }
if (args[argidx] == "-nobram") {
nobram = true;
continue;
@@ -165,7 +182,7 @@ struct SynthIce40Pass : public ScriptPass
log_pop();
}
- virtual void script() YS_OVERRIDE
+ void script() YS_OVERRIDE
{
if (check_label("begin"))
{
@@ -209,8 +226,9 @@ struct SynthIce40Pass : public ScriptPass
if (check_label("map_ffs"))
{
run("dffsr2dff");
- run("dff2dffe -direct-match $_DFF_*");
- run("techmap -D NO_SB_LUT4 -map +/ice40/cells_map.v");
+ if (!nodffe)
+ run("dff2dffe -direct-match $_DFF_*");
+ run("techmap -D NO_LUT -map +/ice40/cells_map.v");
run("opt_expr -mux_undef");
run("simplemap");
run("ice40_ffinit");
@@ -232,9 +250,9 @@ struct SynthIce40Pass : public ScriptPass
if (check_label("map_cells"))
{
if (vpr)
- run("techmap -D NO_SB_LUT4 -map +/ice40/cells_map.v");
+ run("techmap -D NO_LUT -map +/ice40/cells_map.v");
else
- run("techmap -map +/ice40/cells_map.v", "(with -D NO_SB_LUT4 in vpr mode)");
+ run("techmap -map +/ice40/cells_map.v", "(with -D NO_LUT in vpr mode)");
run("clean");
}
@@ -251,13 +269,15 @@ struct SynthIce40Pass : public ScriptPass
if (!blif_file.empty() || help_mode) {
if (vpr || help_mode) {
run(stringf("opt_clean -purge"),
- " (vpr mode)");
- run(stringf("write_blif %s", help_mode ? "<file-name>" : blif_file.c_str()),
- " (vpr mode)");
+ " (vpr mode)");
+ run(stringf("write_blif -attr -cname -conn -param %s",
+ help_mode ? "<file-name>" : blif_file.c_str()),
+ " (vpr mode)");
}
if (!vpr)
run(stringf("write_blif -gates -attr -param %s",
- help_mode ? "<file-name>" : blif_file.c_str()), "(non-vpr mode)");
+ help_mode ? "<file-name>" : blif_file.c_str()),
+ " (non-vpr mode)");
}
}
@@ -266,6 +286,12 @@ struct SynthIce40Pass : public ScriptPass
if (!edif_file.empty() || help_mode)
run(stringf("write_edif %s", help_mode ? "<file-name>" : edif_file.c_str()));
}
+
+ if (check_label("json"))
+ {
+ if (!json_file.empty() || help_mode)
+ run(stringf("write_json %s", help_mode ? "<file-name>" : json_file.c_str()));
+ }
}
} SynthIce40Pass;