Add support for iCE40 global buffers (currently only for 1k devices)
Signed-off-by: Clifford Wolf <clifford@clifford.at>
This commit is contained in:
parent
02b83d6db6
commit
602e6fab1e
@ -192,6 +192,8 @@ void write_asc(const Design &design, std::ostream &out)
|
|||||||
set_config(ti, config.at(iey).at(iex),
|
set_config(ti, config.at(iey).at(iex),
|
||||||
"IoCtrl.REN_" + std::to_string(iez), !pullup);
|
"IoCtrl.REN_" + std::to_string(iez), !pullup);
|
||||||
}
|
}
|
||||||
|
} else if (cell.second->type == "SB_GB") {
|
||||||
|
// no cell config bits
|
||||||
} else {
|
} else {
|
||||||
assert(false);
|
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
|
// Set other config bits
|
||||||
// crashing
|
|
||||||
// TODO: ColBufCtrl
|
|
||||||
for (int y = 0; y < ci.height; y++) {
|
for (int y = 0; y < ci.height; y++) {
|
||||||
for (int x = 0; x < ci.width; x++) {
|
for (int x = 0; x < ci.width; x++) {
|
||||||
TileType tile = tile_at(chip, x, y);
|
TileType tile = tile_at(chip, x, y);
|
||||||
TileInfoPOD &ti = bi.tiles_nonrouting[tile];
|
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)) {
|
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_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
|
// Write config out
|
||||||
for (int y = 0; y < ci.height; y++) {
|
for (int y = 0; y < ci.height; y++) {
|
||||||
for (int x = 0; x < ci.width; x++) {
|
for (int x = 0; x < ci.width; x++) {
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
set -ex
|
set -ex
|
||||||
yosys blinky.ys
|
yosys blinky.ys
|
||||||
../nextpnr-ice40 --json blinky.json --asc blinky.asc
|
../nextpnr-ice40 --json blinky.json --asc blinky.asc
|
||||||
|
icepack blinky.asc blinky.bin
|
||||||
icebox_vlog blinky.asc > blinky_chip.v
|
icebox_vlog blinky.asc > blinky_chip.v
|
||||||
iverilog -o blinky_tb blinky_chip.v blinky_tb.v
|
iverilog -o blinky_tb blinky_chip.v blinky_tb.v
|
||||||
./blinky_tb
|
vvp -N ./blinky_tb
|
||||||
|
249
ice40/blinky.v
249
ice40/blinky.v
@ -1,131 +1,144 @@
|
|||||||
module blinky (
|
module blinky (
|
||||||
input clk_pin,
|
input clk_pin,
|
||||||
output led1_pin,
|
output led1_pin,
|
||||||
output led2_pin,
|
output led2_pin,
|
||||||
output led3_pin,
|
output led3_pin,
|
||||||
output led4_pin,
|
output led4_pin,
|
||||||
output led5_pin
|
output led5_pin
|
||||||
);
|
);
|
||||||
wire clk, led1, led2, led3, led4, led5;
|
wire clk, clki;
|
||||||
|
|
||||||
(* BEL="13_12_io1" *)
|
SB_GB clk_gb (
|
||||||
SB_IO #(
|
.USER_SIGNAL_TO_GLOBAL_BUFFER(clki),
|
||||||
.PIN_TYPE(6'b 0110_01),
|
.GLOBAL_BUFFER_OUTPUT(clk)
|
||||||
.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_12_io0" *)
|
wire led1, led2, led3, led4, led5;
|
||||||
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_11_io1" *)
|
(* BEL="13_12_io1" *)
|
||||||
SB_IO #(
|
SB_IO #(
|
||||||
.PIN_TYPE(6'b 0110_01),
|
.PIN_TYPE(6'b 0110_01),
|
||||||
.PULLUP(1'b0),
|
.PULLUP(1'b0),
|
||||||
.NEG_TRIGGER(1'b0)
|
.NEG_TRIGGER(1'b0)
|
||||||
) led3_iob (
|
) led1_iob (
|
||||||
.PACKAGE_PIN(led3_pin),
|
.PACKAGE_PIN(led1_pin),
|
||||||
.LATCH_INPUT_VALUE(),
|
.LATCH_INPUT_VALUE(),
|
||||||
.CLOCK_ENABLE(),
|
.CLOCK_ENABLE(),
|
||||||
.INPUT_CLK(),
|
.INPUT_CLK(),
|
||||||
.OUTPUT_CLK(),
|
.OUTPUT_CLK(),
|
||||||
.OUTPUT_ENABLE(),
|
.OUTPUT_ENABLE(),
|
||||||
.D_OUT_0(led3),
|
.D_OUT_0(led1),
|
||||||
.D_OUT_1(),
|
.D_OUT_1(),
|
||||||
.D_IN_0(),
|
.D_IN_0(),
|
||||||
.D_IN_1()
|
.D_IN_1()
|
||||||
);
|
);
|
||||||
|
|
||||||
(* BEL="13_11_io0" *)
|
(* BEL="13_12_io0" *)
|
||||||
SB_IO #(
|
SB_IO #(
|
||||||
.PIN_TYPE(6'b 0110_01),
|
.PIN_TYPE(6'b 0110_01),
|
||||||
.PULLUP(1'b0),
|
.PULLUP(1'b0),
|
||||||
.NEG_TRIGGER(1'b0)
|
.NEG_TRIGGER(1'b0)
|
||||||
) led4_iob (
|
) led2_iob (
|
||||||
.PACKAGE_PIN(led4_pin),
|
.PACKAGE_PIN(led2_pin),
|
||||||
.LATCH_INPUT_VALUE(),
|
.LATCH_INPUT_VALUE(),
|
||||||
.CLOCK_ENABLE(),
|
.CLOCK_ENABLE(),
|
||||||
.INPUT_CLK(),
|
.INPUT_CLK(),
|
||||||
.OUTPUT_CLK(),
|
.OUTPUT_CLK(),
|
||||||
.OUTPUT_ENABLE(),
|
.OUTPUT_ENABLE(),
|
||||||
.D_OUT_0(led4),
|
.D_OUT_0(led2),
|
||||||
.D_OUT_1(),
|
.D_OUT_1(),
|
||||||
.D_IN_0(),
|
.D_IN_0(),
|
||||||
.D_IN_1()
|
.D_IN_1()
|
||||||
);
|
);
|
||||||
|
|
||||||
(* BEL="13_9_io1" *)
|
(* BEL="13_11_io1" *)
|
||||||
SB_IO #(
|
SB_IO #(
|
||||||
.PIN_TYPE(6'b 0110_01),
|
.PIN_TYPE(6'b 0110_01),
|
||||||
.PULLUP(1'b0),
|
.PULLUP(1'b0),
|
||||||
.NEG_TRIGGER(1'b0)
|
.NEG_TRIGGER(1'b0)
|
||||||
) led5_iob (
|
) led3_iob (
|
||||||
.PACKAGE_PIN(led5_pin),
|
.PACKAGE_PIN(led3_pin),
|
||||||
.LATCH_INPUT_VALUE(),
|
.LATCH_INPUT_VALUE(),
|
||||||
.CLOCK_ENABLE(),
|
.CLOCK_ENABLE(),
|
||||||
.INPUT_CLK(),
|
.INPUT_CLK(),
|
||||||
.OUTPUT_CLK(),
|
.OUTPUT_CLK(),
|
||||||
.OUTPUT_ENABLE(),
|
.OUTPUT_ENABLE(),
|
||||||
.D_OUT_0(led5),
|
.D_OUT_0(led3),
|
||||||
.D_OUT_1(),
|
.D_OUT_1(),
|
||||||
.D_IN_0(),
|
.D_IN_0(),
|
||||||
.D_IN_1()
|
.D_IN_1()
|
||||||
);
|
);
|
||||||
|
|
||||||
(* BEL="0_8_io1" *)
|
(* BEL="13_11_io0" *)
|
||||||
SB_IO #(
|
SB_IO #(
|
||||||
.PIN_TYPE(6'b 0000_01),
|
.PIN_TYPE(6'b 0110_01),
|
||||||
.PULLUP(1'b0),
|
.PULLUP(1'b0),
|
||||||
.NEG_TRIGGER(1'b0)
|
.NEG_TRIGGER(1'b0)
|
||||||
) clk_iob (
|
) led4_iob (
|
||||||
.PACKAGE_PIN(clk_pin),
|
.PACKAGE_PIN(led4_pin),
|
||||||
.LATCH_INPUT_VALUE(),
|
.LATCH_INPUT_VALUE(),
|
||||||
.CLOCK_ENABLE(),
|
.CLOCK_ENABLE(),
|
||||||
.INPUT_CLK(),
|
.INPUT_CLK(),
|
||||||
.OUTPUT_CLK(),
|
.OUTPUT_CLK(),
|
||||||
.OUTPUT_ENABLE(),
|
.OUTPUT_ENABLE(),
|
||||||
.D_OUT_0(),
|
.D_OUT_0(led4),
|
||||||
.D_OUT_1(),
|
.D_OUT_1(),
|
||||||
.D_IN_0(clk),
|
.D_IN_0(),
|
||||||
.D_IN_1()
|
.D_IN_1()
|
||||||
);
|
);
|
||||||
|
|
||||||
localparam BITS = 5;
|
(* BEL="13_9_io1" *)
|
||||||
localparam LOG2DELAY = 22;
|
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;
|
(* BEL="0_8_io1" *)
|
||||||
reg [BITS-1:0] outcnt;
|
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
|
`ifdef ALT_BLINKY
|
||||||
counter <= counter + 1;
|
reg ff = 0;
|
||||||
outcnt <= counter >> LOG2DELAY;
|
always @(posedge clk) ff <= !ff;
|
||||||
end
|
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
|
endmodule
|
||||||
|
@ -2,8 +2,15 @@ module blinky_tb;
|
|||||||
reg clk;
|
reg clk;
|
||||||
always #5 clk = (clk === 1'b0);
|
always #5 clk = (clk === 1'b0);
|
||||||
|
|
||||||
|
wire led1, led2, led3, led4, led5;
|
||||||
|
|
||||||
chip uut (
|
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
|
initial begin
|
||||||
|
@ -30,6 +30,8 @@ IdString belTypeToId(BelType type)
|
|||||||
return "ICESTORM_RAM";
|
return "ICESTORM_RAM";
|
||||||
if (type == TYPE_SB_IO)
|
if (type == TYPE_SB_IO)
|
||||||
return "SB_IO";
|
return "SB_IO";
|
||||||
|
if (type == TYPE_SB_GB)
|
||||||
|
return "SB_GB";
|
||||||
return IdString();
|
return IdString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,6 +43,8 @@ BelType belTypeFromId(IdString id)
|
|||||||
return TYPE_ICESTORM_RAM;
|
return TYPE_ICESTORM_RAM;
|
||||||
if (id == "SB_IO")
|
if (id == "SB_IO")
|
||||||
return TYPE_SB_IO;
|
return TYPE_SB_IO;
|
||||||
|
if (id == "SB_GB")
|
||||||
|
return TYPE_SB_GB;
|
||||||
return TYPE_NONE;
|
return TYPE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,8 @@ enum BelType
|
|||||||
TYPE_NONE,
|
TYPE_NONE,
|
||||||
TYPE_ICESTORM_LC,
|
TYPE_ICESTORM_LC,
|
||||||
TYPE_ICESTORM_RAM,
|
TYPE_ICESTORM_RAM,
|
||||||
TYPE_SB_IO
|
TYPE_SB_IO,
|
||||||
|
TYPE_SB_GB
|
||||||
};
|
};
|
||||||
|
|
||||||
IdString belTypeToId(BelType type);
|
IdString belTypeToId(BelType type);
|
||||||
|
@ -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/RCLKE")], "RCLKE")
|
||||||
add_bel_input(bel, wire_names[(x, y1, "ram/RE")], "RE")
|
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()):
|
for tile_xy, tile_type in sorted(tiles.items()):
|
||||||
if tile_type == "logic":
|
if tile_type == "logic":
|
||||||
for i in range(8):
|
for i in range(8):
|
||||||
@ -303,6 +313,16 @@ for tile_xy, tile_type in sorted(tiles.items()):
|
|||||||
if tile_type == "ramb":
|
if tile_type == "ramb":
|
||||||
add_bel_ram(tile_xy[0], tile_xy[1])
|
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"')
|
print('#include "chip.h"')
|
||||||
|
|
||||||
for bel in range(len(bel_name)):
|
for bel in range(len(bel_name)):
|
||||||
|
@ -103,3 +103,6 @@ X(D_OUT_0)
|
|||||||
X(D_OUT_1)
|
X(D_OUT_1)
|
||||||
X(D_IN_0)
|
X(D_IN_0)
|
||||||
X(D_IN_1)
|
X(D_IN_1)
|
||||||
|
|
||||||
|
X(USER_SIGNAL_TO_GLOBAL_BUFFER)
|
||||||
|
X(GLOBAL_BUFFER_OUTPUT)
|
||||||
|
Loading…
Reference in New Issue
Block a user