From d0431225f1f7d319714301d85893ad6d20f91c93 Mon Sep 17 00:00:00 2001 From: David Shah Date: Sun, 10 Jun 2018 11:56:07 +0200 Subject: [PATCH] ice40: Writing an empty ASC file Signed-off-by: David Shah --- .gitignore | 3 ++ ice40/bitstream.cc | 99 ++++++++++++++++++++++++++++++++++++++++++++++ ice40/bitstream.h | 28 +++++++++++++ ice40/chip.cc | 2 +- ice40/chip.h | 1 + ice40/main.cc | 9 +++++ 6 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 ice40/bitstream.cc create mode 100644 ice40/bitstream.h diff --git a/.gitignore b/.gitignore index 77f1871d..a7d4313e 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,6 @@ CMakeCache.txt a.out *.json build/ +*.asc +*.bin + diff --git a/ice40/bitstream.cc b/ice40/bitstream.cc new file mode 100644 index 00000000..1ee24f42 --- /dev/null +++ b/ice40/bitstream.cc @@ -0,0 +1,99 @@ +/* + * nextpnr -- Next Generation Place and Route + * + * Copyright (C) 2018 Clifford Wolf + * Copyright (C) 2018 David Shah + * + * 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 "bitstream.h" +#include + +inline TileType tile_at(const Chip &chip, int x, int y) +{ + return chip.chip_info.tile_grid[y * chip.chip_info.width + x]; +} + +void write_asc(const Chip &chip, std::ostream &out) +{ + // [y][x][row][col] + const ChipInfoPOD &ci = chip.chip_info; + const BitstreamInfoPOD &bi = *ci.bits_info; + std::vector>>> config; + config.resize(ci.height); + for (int y = 0; y < ci.height; y++) { + config.at(y).resize(ci.width); + for (int x = 0; x < ci.width; x++) { + TileType tile = tile_at(chip, x, y); + int rows = bi.tiles_nonrouting[tile].rows; + int cols = bi.tiles_nonrouting[tile].cols; + config.at(y).at(x).resize(rows, vector(cols)); + } + } + out << ".comment from next-pnr" << std::endl; + + switch (chip.args.type) { + case ChipArgs::LP384: + out << ".device 384" << std::endl; + break; + case ChipArgs::HX1K: + case ChipArgs::LP1K: + out << ".device 1k" << std::endl; + break; + case ChipArgs::HX8K: + case ChipArgs::LP8K: + out << ".device 8k" << std::endl; + break; + case ChipArgs::UP5K: + out << ".device 5k" << std::endl; + break; + default: + assert(false); + } + // Write config out + for (int y = 0; y < ci.height; y++) { + for (int x = 0; x < ci.width; x++) { + TileType tile = tile_at(chip, x, y); + if (tile == TILE_NONE) + continue; + switch (tile) { + case TILE_LOGIC: + out << ".logic_tile"; + break; + case TILE_IO: + out << ".io_tile"; + break; + case TILE_RAMB: + out << ".ramb_tile"; + break; + case TILE_RAMT: + out << ".ramt_tile"; + break; + default: + assert(false); + } + out << " " << x << " " << y << std::endl; + for (auto row : config.at(y).at(x)) { + for (auto col : row) { + if (col == 1) + out << "1"; + else + out << "0"; + } + out << std::endl; + } + out << std::endl; + } + } +} diff --git a/ice40/bitstream.h b/ice40/bitstream.h new file mode 100644 index 00000000..6af826dc --- /dev/null +++ b/ice40/bitstream.h @@ -0,0 +1,28 @@ +/* + * nextpnr -- Next Generation Place and Route + * + * Copyright (C) 2018 Clifford Wolf + * + * 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. + * + */ + +#ifndef ICE40_BITSTREAM_H +#define ICE40_BITSTREAM_H + +#include +#include "chip.h" + +void write_asc(const Chip &chip, std::ostream &out); + +#endif diff --git a/ice40/chip.cc b/ice40/chip.cc index 26a2dc6e..c2fba89f 100644 --- a/ice40/chip.cc +++ b/ice40/chip.cc @@ -72,7 +72,7 @@ PortPin portPinFromId(IdString id) // ----------------------------------------------------------------------- -Chip::Chip(ChipArgs args) +Chip::Chip(ChipArgs args) : args(args) { #ifdef ICE40_HX1K_ONLY if (args.type == ChipArgs::HX1K) { diff --git a/ice40/chip.h b/ice40/chip.h index 1e80cc47..45987803 100644 --- a/ice40/chip.h +++ b/ice40/chip.h @@ -407,6 +407,7 @@ struct Chip Chip(ChipArgs args); + ChipArgs args; // ------------------------------------------------- BelId getBelByName(IdString name) const; diff --git a/ice40/main.cc b/ice40/main.cc index 9f909bba..a57cd0a8 100644 --- a/ice40/main.cc +++ b/ice40/main.cc @@ -23,6 +23,7 @@ #include #include #include +#include "bitstream.h" #include "design.h" #include "jsonparse.h" #include "log.h" @@ -69,6 +70,8 @@ int main(int argc, char *argv[]) "python file to execute"); options.add_options()("json", po::value(), "JSON design file to ingest"); + options.add_options()("asc", po::value(), + "asc bitstream file to write"); options.add_options()("version,v", "show version"); options.add_options()("lp384", "set device type to iCE40LP384"); options.add_options()("lp1k", "set device type to iCE40LP1K"); @@ -251,6 +254,12 @@ int main(int argc, char *argv[]) route_design(&design); } + if (vm.count("asc")) { + std::string filename = vm["asc"].as(); + std::ofstream f(filename); + write_asc(design.chip, f); + } + if (vm.count("run")) { std::vector files = vm["run"].as>();