diff --git a/ice40/bitstream.cc b/ice40/bitstream.cc index 9b749717..17b1b6cf 100644 --- a/ice40/bitstream.cc +++ b/ice40/bitstream.cc @@ -192,6 +192,8 @@ void write_asc(const Design &design, std::ostream &out) set_config(ti, config.at(iey).at(iex), "IoCtrl.REN_" + std::to_string(iez), !pullup); } + } else if (cell.second->type == "SB_GB") { + // no cell config bits } else { assert(false); } @@ -216,18 +218,41 @@ void write_asc(const Design &design, std::ostream &out) } } - // Set other config bits - currently just disable RAM to stop icebox_vlog - // crashing - // TODO: ColBufCtrl + // Set other config bits for (int y = 0; y < ci.height; y++) { for (int x = 0; x < ci.width; x++) { TileType tile = tile_at(chip, x, y); TileInfoPOD &ti = bi.tiles_nonrouting[tile]; + + // disable RAM to stop icebox_vlog crashing (FIXME) if ((tile == TILE_RAMB) && (chip.args.type == ChipArgs::LP1K || chip.args.type == ChipArgs::HX1K)) { set_config(ti, config.at(y).at(x), "RamConfig.PowerUp", true); } + + // set all ColBufCtrl bits (FIXME) + bool setColBufCtrl = true; + if (chip.args.type == ChipArgs::LP1K || chip.args.type == ChipArgs::HX1K) { + if (tile == TILE_RAMB || tile == TILE_RAMT) { + setColBufCtrl = (y == 3 || y == 5 || y == 11 || y == 13); + } else { + setColBufCtrl = (y == 4 || y == 5 || y == 12 || y == 13); + } + } else if (chip.args.type == ChipArgs::LP8K || chip.args.type == ChipArgs::HX8K) { + setColBufCtrl = (y == 8 || y == 9 || y == 24 || y == 25); + } + if (setColBufCtrl) { + set_config(ti, config.at(y).at(x), "ColBufCtrl.glb_netwk_0", true); + set_config(ti, config.at(y).at(x), "ColBufCtrl.glb_netwk_1", true); + set_config(ti, config.at(y).at(x), "ColBufCtrl.glb_netwk_2", true); + set_config(ti, config.at(y).at(x), "ColBufCtrl.glb_netwk_3", true); + set_config(ti, config.at(y).at(x), "ColBufCtrl.glb_netwk_4", true); + set_config(ti, config.at(y).at(x), "ColBufCtrl.glb_netwk_5", true); + set_config(ti, config.at(y).at(x), "ColBufCtrl.glb_netwk_6", true); + set_config(ti, config.at(y).at(x), "ColBufCtrl.glb_netwk_7", true); + } } } + // Write config out for (int y = 0; y < ci.height; y++) { for (int x = 0; x < ci.width; x++) { diff --git a/ice40/blinky.sh b/ice40/blinky.sh index 8a445373..23ee2cac 100644 --- a/ice40/blinky.sh +++ b/ice40/blinky.sh @@ -2,6 +2,7 @@ set -ex yosys blinky.ys ../nextpnr-ice40 --json blinky.json --asc blinky.asc +icepack blinky.asc blinky.bin icebox_vlog blinky.asc > blinky_chip.v iverilog -o blinky_tb blinky_chip.v blinky_tb.v -./blinky_tb +vvp -N ./blinky_tb diff --git a/ice40/blinky.v b/ice40/blinky.v index 7fd3a0cf..a52a7e25 100644 --- a/ice40/blinky.v +++ b/ice40/blinky.v @@ -1,131 +1,144 @@ module blinky ( - input clk_pin, - output led1_pin, - output led2_pin, - output led3_pin, - output led4_pin, - output led5_pin + input clk_pin, + output led1_pin, + output led2_pin, + output led3_pin, + output led4_pin, + output led5_pin ); - wire clk, led1, led2, led3, led4, led5; + wire clk, clki; - (* BEL="13_12_io1" *) - SB_IO #( - .PIN_TYPE(6'b 0110_01), - .PULLUP(1'b0), - .NEG_TRIGGER(1'b0) - ) led1_iob ( - .PACKAGE_PIN(led1_pin), - .LATCH_INPUT_VALUE(), - .CLOCK_ENABLE(), - .INPUT_CLK(), - .OUTPUT_CLK(), - .OUTPUT_ENABLE(), - .D_OUT_0(led1), - .D_OUT_1(), - .D_IN_0(), - .D_IN_1() - ); + SB_GB clk_gb ( + .USER_SIGNAL_TO_GLOBAL_BUFFER(clki), + .GLOBAL_BUFFER_OUTPUT(clk) + ); - (* BEL="13_12_io0" *) - SB_IO #( - .PIN_TYPE(6'b 0110_01), - .PULLUP(1'b0), - .NEG_TRIGGER(1'b0) - ) led2_iob ( - .PACKAGE_PIN(led2_pin), - .LATCH_INPUT_VALUE(), - .CLOCK_ENABLE(), - .INPUT_CLK(), - .OUTPUT_CLK(), - .OUTPUT_ENABLE(), - .D_OUT_0(led2), - .D_OUT_1(), - .D_IN_0(), - .D_IN_1() - ); + wire led1, led2, led3, led4, led5; - (* BEL="13_11_io1" *) - SB_IO #( - .PIN_TYPE(6'b 0110_01), - .PULLUP(1'b0), - .NEG_TRIGGER(1'b0) - ) led3_iob ( - .PACKAGE_PIN(led3_pin), - .LATCH_INPUT_VALUE(), - .CLOCK_ENABLE(), - .INPUT_CLK(), - .OUTPUT_CLK(), - .OUTPUT_ENABLE(), - .D_OUT_0(led3), - .D_OUT_1(), - .D_IN_0(), - .D_IN_1() - ); + (* BEL="13_12_io1" *) + SB_IO #( + .PIN_TYPE(6'b 0110_01), + .PULLUP(1'b0), + .NEG_TRIGGER(1'b0) + ) led1_iob ( + .PACKAGE_PIN(led1_pin), + .LATCH_INPUT_VALUE(), + .CLOCK_ENABLE(), + .INPUT_CLK(), + .OUTPUT_CLK(), + .OUTPUT_ENABLE(), + .D_OUT_0(led1), + .D_OUT_1(), + .D_IN_0(), + .D_IN_1() + ); - (* BEL="13_11_io0" *) - SB_IO #( - .PIN_TYPE(6'b 0110_01), - .PULLUP(1'b0), - .NEG_TRIGGER(1'b0) - ) led4_iob ( - .PACKAGE_PIN(led4_pin), - .LATCH_INPUT_VALUE(), - .CLOCK_ENABLE(), - .INPUT_CLK(), - .OUTPUT_CLK(), - .OUTPUT_ENABLE(), - .D_OUT_0(led4), - .D_OUT_1(), - .D_IN_0(), - .D_IN_1() - ); + (* BEL="13_12_io0" *) + SB_IO #( + .PIN_TYPE(6'b 0110_01), + .PULLUP(1'b0), + .NEG_TRIGGER(1'b0) + ) led2_iob ( + .PACKAGE_PIN(led2_pin), + .LATCH_INPUT_VALUE(), + .CLOCK_ENABLE(), + .INPUT_CLK(), + .OUTPUT_CLK(), + .OUTPUT_ENABLE(), + .D_OUT_0(led2), + .D_OUT_1(), + .D_IN_0(), + .D_IN_1() + ); - (* BEL="13_9_io1" *) - SB_IO #( - .PIN_TYPE(6'b 0110_01), - .PULLUP(1'b0), - .NEG_TRIGGER(1'b0) - ) led5_iob ( - .PACKAGE_PIN(led5_pin), - .LATCH_INPUT_VALUE(), - .CLOCK_ENABLE(), - .INPUT_CLK(), - .OUTPUT_CLK(), - .OUTPUT_ENABLE(), - .D_OUT_0(led5), - .D_OUT_1(), - .D_IN_0(), - .D_IN_1() - ); + (* BEL="13_11_io1" *) + SB_IO #( + .PIN_TYPE(6'b 0110_01), + .PULLUP(1'b0), + .NEG_TRIGGER(1'b0) + ) led3_iob ( + .PACKAGE_PIN(led3_pin), + .LATCH_INPUT_VALUE(), + .CLOCK_ENABLE(), + .INPUT_CLK(), + .OUTPUT_CLK(), + .OUTPUT_ENABLE(), + .D_OUT_0(led3), + .D_OUT_1(), + .D_IN_0(), + .D_IN_1() + ); - (* BEL="0_8_io1" *) - SB_IO #( - .PIN_TYPE(6'b 0000_01), - .PULLUP(1'b0), - .NEG_TRIGGER(1'b0) - ) clk_iob ( - .PACKAGE_PIN(clk_pin), - .LATCH_INPUT_VALUE(), - .CLOCK_ENABLE(), - .INPUT_CLK(), - .OUTPUT_CLK(), - .OUTPUT_ENABLE(), - .D_OUT_0(), - .D_OUT_1(), - .D_IN_0(clk), - .D_IN_1() - ); + (* BEL="13_11_io0" *) + SB_IO #( + .PIN_TYPE(6'b 0110_01), + .PULLUP(1'b0), + .NEG_TRIGGER(1'b0) + ) led4_iob ( + .PACKAGE_PIN(led4_pin), + .LATCH_INPUT_VALUE(), + .CLOCK_ENABLE(), + .INPUT_CLK(), + .OUTPUT_CLK(), + .OUTPUT_ENABLE(), + .D_OUT_0(led4), + .D_OUT_1(), + .D_IN_0(), + .D_IN_1() + ); - localparam BITS = 5; - localparam LOG2DELAY = 22; + (* BEL="13_9_io1" *) + SB_IO #( + .PIN_TYPE(6'b 0110_01), + .PULLUP(1'b0), + .NEG_TRIGGER(1'b0) + ) led5_iob ( + .PACKAGE_PIN(led5_pin), + .LATCH_INPUT_VALUE(), + .CLOCK_ENABLE(), + .INPUT_CLK(), + .OUTPUT_CLK(), + .OUTPUT_ENABLE(), + .D_OUT_0(led5), + .D_OUT_1(), + .D_IN_0(), + .D_IN_1() + ); - reg [BITS+LOG2DELAY-1:0] counter = 0; - reg [BITS-1:0] outcnt; + (* BEL="0_8_io1" *) + SB_IO #( + .PIN_TYPE(6'b 0000_01), + .PULLUP(1'b0), + .NEG_TRIGGER(1'b0) + ) clk_iob ( + .PACKAGE_PIN(clk_pin), + .LATCH_INPUT_VALUE(), + .CLOCK_ENABLE(), + .INPUT_CLK(), + .OUTPUT_CLK(), + .OUTPUT_ENABLE(), + .D_OUT_0(), + .D_OUT_1(), + .D_IN_0(clki), + .D_IN_1() + ); - always @(posedge clk) begin - counter <= counter + 1; - outcnt <= counter >> LOG2DELAY; - end +`ifdef ALT_BLINKY + reg ff = 0; + always @(posedge clk) ff <= !ff; + assign led1 = clki, led2 = !clki, led3 = !clk, led4 = !clk, led5 = ff; +`else + localparam BITS = 5; + localparam LOG2DELAY = 22; - assign {led1, led2, led3, led4, led5} = outcnt ^ (outcnt >> 1); + reg [BITS+LOG2DELAY-1:0] counter = 0; + reg [BITS-1:0] outcnt; + + always @(posedge clk) begin + counter <= counter + 1; + outcnt <= counter >> LOG2DELAY; + end + + assign {led1, led2, led3, led4, led5} = outcnt ^ (outcnt >> 1); +`endif endmodule diff --git a/ice40/blinky_tb.v b/ice40/blinky_tb.v index 300c8a37..d5c40982 100644 --- a/ice40/blinky_tb.v +++ b/ice40/blinky_tb.v @@ -2,8 +2,15 @@ module blinky_tb; reg clk; always #5 clk = (clk === 1'b0); + wire led1, led2, led3, led4, led5; + chip uut ( - .io_0_8_1(clk) + .io_0_8_1(clk), + .io_13_12_1(led1), + .io_13_12_0(led2), + .io_13_11_1(led3), + .io_13_11_0(led4), + .io_13_9_1(led5) ); initial begin diff --git a/ice40/chip.cc b/ice40/chip.cc index 3a79d65f..b2601e2a 100644 --- a/ice40/chip.cc +++ b/ice40/chip.cc @@ -30,6 +30,8 @@ IdString belTypeToId(BelType type) return "ICESTORM_RAM"; if (type == TYPE_SB_IO) return "SB_IO"; + if (type == TYPE_SB_GB) + return "SB_GB"; return IdString(); } @@ -41,6 +43,8 @@ BelType belTypeFromId(IdString id) return TYPE_ICESTORM_RAM; if (id == "SB_IO") return TYPE_SB_IO; + if (id == "SB_GB") + return TYPE_SB_GB; return TYPE_NONE; } diff --git a/ice40/chip.h b/ice40/chip.h index 7e20a252..cedc89b6 100644 --- a/ice40/chip.h +++ b/ice40/chip.h @@ -45,7 +45,8 @@ enum BelType TYPE_NONE, TYPE_ICESTORM_LC, TYPE_ICESTORM_RAM, - TYPE_SB_IO + TYPE_SB_IO, + TYPE_SB_GB }; IdString belTypeToId(BelType type); diff --git a/ice40/chipdb.py b/ice40/chipdb.py index 1477c78a..3c3dc078 100644 --- a/ice40/chipdb.py +++ b/ice40/chipdb.py @@ -293,6 +293,16 @@ def add_bel_ram(x, y): add_bel_input(bel, wire_names[(x, y1, "ram/RCLKE")], "RCLKE") add_bel_input(bel, wire_names[(x, y1, "ram/RE")], "RE") +def add_bel_gb(x, y, g): + bel = len(bel_name) + bel_name.append("%d_%d_gb" % (x, y)) + bel_type.append("SB_GB") + bel_pos.append((x, y, 0)) + bel_wires.append(list()) + + add_bel_input(bel, wire_names[(x, y, "fabout")], "USER_SIGNAL_TO_GLOBAL_BUFFER") + add_bel_output(bel, wire_names[(x, y, "glb_netwk_%d" % g)], "GLOBAL_BUFFER_OUTPUT") + for tile_xy, tile_type in sorted(tiles.items()): if tile_type == "logic": for i in range(8): @@ -303,6 +313,16 @@ for tile_xy, tile_type in sorted(tiles.items()): if tile_type == "ramb": add_bel_ram(tile_xy[0], tile_xy[1]) +if dev_name == "1k": + add_bel_gb( 7, 0, 0) + add_bel_gb( 7, 17, 1) + add_bel_gb(13, 9, 2) + add_bel_gb( 0, 9, 3) + add_bel_gb( 6, 17, 4) + add_bel_gb( 6, 0, 5) + add_bel_gb( 0, 8, 6) + add_bel_gb(13, 8, 7) + print('#include "chip.h"') for bel in range(len(bel_name)): diff --git a/ice40/portpins.inc b/ice40/portpins.inc index 13a22bcc..c06681a7 100644 --- a/ice40/portpins.inc +++ b/ice40/portpins.inc @@ -103,3 +103,6 @@ X(D_OUT_0) X(D_OUT_1) X(D_IN_0) X(D_IN_1) + +X(USER_SIGNAL_TO_GLOBAL_BUFFER) +X(GLOBAL_BUFFER_OUTPUT)