aboutsummaryrefslogtreecommitdiffstats
path: root/techlibs/ice40
diff options
context:
space:
mode:
Diffstat (limited to 'techlibs/ice40')
-rw-r--r--techlibs/ice40/Makefile.inc3
-rw-r--r--techlibs/ice40/brams.txt4
-rw-r--r--techlibs/ice40/brams_init.py5
-rw-r--r--techlibs/ice40/brams_map.v26
-rw-r--r--techlibs/ice40/cells_sim.v20
-rw-r--r--techlibs/ice40/ice40_ffinit.cc142
-rw-r--r--techlibs/ice40/synth_ice40.cc2
7 files changed, 173 insertions, 29 deletions
diff --git a/techlibs/ice40/Makefile.inc b/techlibs/ice40/Makefile.inc
index ed495519a..83009d176 100644
--- a/techlibs/ice40/Makefile.inc
+++ b/techlibs/ice40/Makefile.inc
@@ -1,6 +1,7 @@
OBJS += techlibs/ice40/synth_ice40.o
OBJS += techlibs/ice40/ice40_ffssr.o
+OBJS += techlibs/ice40/ice40_ffinit.o
OBJS += techlibs/ice40/ice40_opt.o
GENFILES += techlibs/ice40/brams_init1.vh
@@ -12,7 +13,7 @@ EXTRA_OBJS += techlibs/ice40/brams_init.mk
techlibs/ice40/brams_init.mk: techlibs/ice40/brams_init.py
$(Q) mkdir -p techlibs/ice40
- $(P) python $<
+ $(P) python3 $<
$(Q) touch techlibs/ice40/brams_init.mk
techlibs/ice40/brams_init1.vh: techlibs/ice40/brams_init.mk
diff --git a/techlibs/ice40/brams.txt b/techlibs/ice40/brams.txt
index 05131b227..03d596111 100644
--- a/techlibs/ice40/brams.txt
+++ b/techlibs/ice40/brams.txt
@@ -5,7 +5,7 @@ bram $__ICE40_RAM4K_M0
groups 2
ports 1 1
wrmode 0 1
- enable 0 16
+ enable 1 16
transp 0 0
clocks 2 3
clkpol 2 3
@@ -22,7 +22,7 @@ bram $__ICE40_RAM4K_M123
groups 2
ports 1 1
wrmode 0 1
- enable 0 1
+ enable 1 1
transp 0 0
clocks 2 3
clkpol 2 3
diff --git a/techlibs/ice40/brams_init.py b/techlibs/ice40/brams_init.py
index 93eb9846b..4a1485110 100644
--- a/techlibs/ice40/brams_init.py
+++ b/techlibs/ice40/brams_init.py
@@ -1,7 +1,4 @@
-#!/usr/bin/python
-
-from __future__ import division
-from __future__ import print_function
+#!/usr/bin/env python3
def write_init_vh(filename, initbits):
with open(filename, "w") as f:
diff --git a/techlibs/ice40/brams_map.v b/techlibs/ice40/brams_map.v
index 8c5c7e812..19a61d73b 100644
--- a/techlibs/ice40/brams_map.v
+++ b/techlibs/ice40/brams_map.v
@@ -90,7 +90,7 @@ module \$__ICE40_RAM4K (
.RCLKE(RCLKE),
.RE (RE ),
.RADDR(RADDR),
- .WCLK (WCLK ),
+ .WCLKN(WCLK ),
.WCLKE(WCLKE),
.WE (WE ),
.WADDR(WADDR),
@@ -119,7 +119,7 @@ module \$__ICE40_RAM4K (
.INIT_F(INIT_F)
) _TECHMAP_REPLACE_ (
.RDATA(RDATA),
- .RCLK (RCLK ),
+ .RCLKN(RCLK ),
.RCLKE(RCLKE),
.RE (RE ),
.RADDR(RADDR),
@@ -152,11 +152,11 @@ module \$__ICE40_RAM4K (
.INIT_F(INIT_F)
) _TECHMAP_REPLACE_ (
.RDATA(RDATA),
- .RCLK (RCLK ),
+ .RCLKN(RCLK ),
.RCLKE(RCLKE),
.RE (RE ),
.RADDR(RADDR),
- .WCLK (WCLK ),
+ .WCLKN(WCLK ),
.WCLKE(WCLKE),
.WE (WE ),
.WADDR(WADDR),
@@ -168,7 +168,7 @@ module \$__ICE40_RAM4K (
endmodule
-module \$__ICE40_RAM4K_M0 (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
+module \$__ICE40_RAM4K_M0 (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
parameter [0:0] CLKPOL2 = 1;
parameter [0:0] CLKPOL3 = 1;
@@ -179,6 +179,7 @@ module \$__ICE40_RAM4K_M0 (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
input [7:0] A1ADDR;
output [15:0] A1DATA;
+ input A1EN;
input [7:0] B1ADDR;
input [15:0] B1DATA;
@@ -212,18 +213,18 @@ module \$__ICE40_RAM4K_M0 (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
.RDATA(A1DATA),
.RADDR(A1ADDR_11),
.RCLK(CLK2),
- .RCLKE(1'b1),
+ .RCLKE(A1EN),
.RE(1'b1),
.WDATA(B1DATA),
.WADDR(B1ADDR_11),
.MASK(~B1EN),
.WCLK(CLK3),
- .WCLKE(1'b1),
- .WE(|B1EN)
+ .WCLKE(|B1EN),
+ .WE(1'b1)
);
endmodule
-module \$__ICE40_RAM4K_M123 (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
+module \$__ICE40_RAM4K_M123 (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
parameter CFG_ABITS = 9;
parameter CFG_DBITS = 8;
@@ -242,6 +243,7 @@ module \$__ICE40_RAM4K_M123 (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
input [CFG_ABITS-1:0] A1ADDR;
output [CFG_DBITS-1:0] A1DATA;
+ input A1EN;
input [CFG_ABITS-1:0] B1ADDR;
input [CFG_DBITS-1:0] B1DATA;
@@ -297,13 +299,13 @@ module \$__ICE40_RAM4K_M123 (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
.RDATA(A1DATA_16),
.RADDR(A1ADDR_11),
.RCLK(CLK2),
- .RCLKE(1'b1),
+ .RCLKE(A1EN),
.RE(1'b1),
.WDATA(B1DATA_16),
.WADDR(B1ADDR_11),
.WCLK(CLK3),
- .WCLKE(1'b1),
- .WE(|B1EN)
+ .WCLKE(|B1EN),
+ .WE(1'b1)
);
endmodule
diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v
index f94040245..f23218c00 100644
--- a/techlibs/ice40/cells_sim.v
+++ b/techlibs/ice40/cells_sim.v
@@ -58,8 +58,8 @@ module SB_IO (
generate
if (PIN_TYPE[5:4] == 2'b01) assign PACKAGE_PIN = dout;
- if (PIN_TYPE[5:4] == 2'b10) assign PACKAGE_PIN = outena_q ? dout : 1'bz;
- if (PIN_TYPE[5:4] == 2'b11) assign PACKAGE_PIN = OUTPUT_ENABLE ? dout : 1'bz;
+ if (PIN_TYPE[5:4] == 2'b10) assign PACKAGE_PIN = OUTPUT_ENABLE ? dout : 1'bz;
+ if (PIN_TYPE[5:4] == 2'b11) assign PACKAGE_PIN = outena_q ? dout : 1'bz;
endgenerate
`endif
endmodule
@@ -473,7 +473,7 @@ endmodule
module SB_RAM40_4KNR (
output [15:0] RDATA,
- input RCLK, RCLKE, RE,
+ input RCLKN, RCLKE, RE,
input [10:0] RADDR,
input WCLK, WCLKE, WE,
input [10:0] WADDR,
@@ -520,7 +520,7 @@ module SB_RAM40_4KNR (
.INIT_F (INIT_F )
) RAM (
.RDATA(RDATA),
- .RCLK (~RCLK),
+ .RCLK (~RCLKN),
.RCLKE(RCLKE),
.RE (RE ),
.RADDR(RADDR),
@@ -537,7 +537,7 @@ module SB_RAM40_4KNW (
output [15:0] RDATA,
input RCLK, RCLKE, RE,
input [10:0] RADDR,
- input WCLK, WCLKE, WE,
+ input WCLKN, WCLKE, WE,
input [10:0] WADDR,
input [15:0] MASK, WDATA
);
@@ -586,7 +586,7 @@ module SB_RAM40_4KNW (
.RCLKE(RCLKE),
.RE (RE ),
.RADDR(RADDR),
- .WCLK (~WCLK),
+ .WCLK (~WCLKN),
.WCLKE(WCLKE),
.WE (WE ),
.WADDR(WADDR),
@@ -597,9 +597,9 @@ endmodule
module SB_RAM40_4KNRNW (
output [15:0] RDATA,
- input RCLK, RCLKE, RE,
+ input RCLKN, RCLKE, RE,
input [10:0] RADDR,
- input WCLK, WCLKE, WE,
+ input WCLKN, WCLKE, WE,
input [10:0] WADDR,
input [15:0] MASK, WDATA
);
@@ -644,11 +644,11 @@ module SB_RAM40_4KNRNW (
.INIT_F (INIT_F )
) RAM (
.RDATA(RDATA),
- .RCLK (~RCLK),
+ .RCLK (~RCLKN),
.RCLKE(RCLKE),
.RE (RE ),
.RADDR(RADDR),
- .WCLK (~WCLK),
+ .WCLK (~WCLKN),
.WCLKE(WCLKE),
.WE (WE ),
.WADDR(WADDR),
diff --git a/techlibs/ice40/ice40_ffinit.cc b/techlibs/ice40/ice40_ffinit.cc
new file mode 100644
index 000000000..50400be80
--- /dev/null
+++ b/techlibs/ice40/ice40_ffinit.cc
@@ -0,0 +1,142 @@
+/*
+ * yosys -- Yosys Open SYnthesis Suite
+ *
+ * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include "kernel/yosys.h"
+#include "kernel/sigtools.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+struct Ice40FfinitPass : public Pass {
+ Ice40FfinitPass() : Pass("ice40_ffinit", "iCE40: handle FF init values") { }
+ virtual void help()
+ {
+ // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+ log("\n");
+ log(" ice40_ffinit [options] [selection]\n");
+ log("\n");
+ log("Remove zero init values for FF output signals. Add inverters to implement\n");
+ log("nonzero init values.\n");
+ log("\n");
+ }
+ virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
+ {
+ log_header("Executing ICE40_FFINIT pass (implement FF init values).\n");
+
+ size_t argidx;
+ for (argidx = 1; argidx < args.size(); argidx++)
+ {
+ // if (args[argidx] == "-singleton") {
+ // singleton_mode = true;
+ // continue;
+ // }
+ break;
+ }
+ extra_args(args, argidx, design);
+
+ for (auto module : design->selected_modules())
+ {
+ log("Handling FF init values in %s.\n", log_id(module));
+
+ SigMap sigmap(module);
+ pool<Wire*> init_wires;
+ dict<SigBit, State> initbits;
+ pool<SigBit> handled_initbits;
+
+ for (auto wire : module->selected_wires())
+ {
+ if (wire->attributes.count("\\init") == 0)
+ continue;
+
+ SigSpec wirebits = sigmap(wire);
+ Const initval = wire->attributes.at("\\init");
+ init_wires.insert(wire);
+
+ for (int i = 0; i < GetSize(wirebits) && i < GetSize(initval); i++)
+ {
+ SigBit bit = wirebits[i];
+ State val = initval[i];
+
+ if (val != State::S0 && val != State::S1)
+ continue;
+
+ if (initbits.count(bit)) {
+ if (initbits.at(bit) != val)
+ log_error("Conflicting init values for signal %s.\n", log_signal(bit));
+ continue;
+ }
+
+ initbits[bit] = val;
+ }
+ }
+
+ for (auto cell : module->selected_cells())
+ {
+ if (!cell->type.in("\\SB_DFF", "\\SB_DFFE", "\\SB_DFFN", "\\SB_DFFNE"))
+ continue;
+
+ SigBit sig_d = sigmap(cell->getPort("\\D"));
+ SigBit sig_q = sigmap(cell->getPort("\\Q"));
+
+ if (!initbits.count(sig_q))
+ continue;
+
+ State val = initbits.at(sig_q);
+ handled_initbits.insert(sig_q);
+
+ log("FF init value for cell %s (%s): %s = %c\n", log_id(cell), log_id(cell->type),
+ log_signal(sig_q), val != State::S0 ? '1' : '0');
+
+ if (val == State::S0)
+ continue;
+
+ Wire *new_sig_d = module->addWire(NEW_ID);
+ Wire *new_sig_q = module->addWire(NEW_ID);
+
+ module->addNotGate(NEW_ID, sig_d, new_sig_d);
+ module->addNotGate(NEW_ID, new_sig_q, sig_q);
+
+ cell->setPort("\\D", new_sig_d);
+ cell->setPort("\\Q", new_sig_q);
+ }
+
+ for (auto wire : init_wires)
+ {
+ if (wire->attributes.count("\\init") == 0)
+ continue;
+
+ SigSpec wirebits = sigmap(wire);
+ Const &initval = wire->attributes.at("\\init");
+ bool remove_attribute = true;
+
+ for (int i = 0; i < GetSize(wirebits) && i < GetSize(initval); i++) {
+ if (handled_initbits.count(wirebits[i]))
+ wirebits[i] = State::Sx;
+ else
+ remove_attribute = false;
+ }
+
+ if (remove_attribute)
+ wire->attributes.erase("\\init");
+ }
+ }
+ }
+} Ice40FfinitPass;
+
+PRIVATE_NAMESPACE_END
diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc
index 788835f1d..75cab7bda 100644
--- a/techlibs/ice40/synth_ice40.cc
+++ b/techlibs/ice40/synth_ice40.cc
@@ -104,6 +104,7 @@ struct SynthIce40Pass : public Pass {
log(" techmap -map +/ice40/cells_map.v\n");
log(" opt_const -mux_undef\n");
log(" simplemap\n");
+ log(" ice40_ffinit\n");
log(" ice40_ffssr\n");
log(" ice40_opt -full\n");
log("\n");
@@ -236,6 +237,7 @@ struct SynthIce40Pass : public Pass {
Pass::call(design, "techmap -map +/ice40/cells_map.v");
Pass::call(design, "opt_const -mux_undef");
Pass::call(design, "simplemap");
+ Pass::call(design, "ice40_ffinit");
Pass::call(design, "ice40_ffssr");
Pass::call(design, "ice40_opt -full");
}