Add support for iCE40 global buffers (currently only for 1k devices)

Signed-off-by: Clifford Wolf <clifford@clifford.at>
This commit is contained in:
Clifford Wolf 2018-06-10 16:31:06 +02:00
parent 02b83d6db6
commit 602e6fab1e
8 changed files with 198 additions and 124 deletions

View File

@ -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++) {

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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)):

View File

@ -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)