diff options
Diffstat (limited to 'techlibs/ice40')
-rw-r--r-- | techlibs/ice40/Makefile.inc | 3 | ||||
-rw-r--r-- | techlibs/ice40/brams.txt | 4 | ||||
-rw-r--r-- | techlibs/ice40/brams_init.py | 5 | ||||
-rw-r--r-- | techlibs/ice40/brams_map.v | 26 | ||||
-rw-r--r-- | techlibs/ice40/cells_sim.v | 20 | ||||
-rw-r--r-- | techlibs/ice40/ice40_ffinit.cc | 142 | ||||
-rw-r--r-- | techlibs/ice40/synth_ice40.cc | 2 |
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"); } |