diff options
| -rw-r--r-- | gui/designwidget.cc | 11 | ||||
| -rw-r--r-- | ice40/bitstream.cc | 166 | ||||
| -rw-r--r-- | ice40/bitstream.h | 1 | ||||
| -rw-r--r-- | ice40/main.cc | 8 | 
4 files changed, 143 insertions, 43 deletions
| diff --git a/gui/designwidget.cc b/gui/designwidget.cc index 4123bf30..d28b843b 100644 --- a/gui/designwidget.cc +++ b/gui/designwidget.cc @@ -334,16 +334,7 @@ void DesignWidget::newContext(Context *ctx)      for (auto pip : nameToItem[2].toStdMap()) {
          pip_root->addChild(pip.second);
      }
 -
 -    // Add nets to tree
 -    nets_root = new QTreeWidgetItem(treeWidget);
 -    nets_root->setText(0, "Nets");
 -    treeWidget->insertTopLevelItem(0, nets_root);
 -
 -    // Add cells to tree
 -    cells_root = new QTreeWidgetItem(treeWidget);
 -    cells_root->setText(0, "Cells");
 -    treeWidget->insertTopLevelItem(0, cells_root);
 +    updateTree();
  }
  void DesignWidget::updateTree()
 diff --git a/ice40/bitstream.cc b/ice40/bitstream.cc index c12fa90e..b0f6260d 100644 --- a/ice40/bitstream.cc +++ b/ice40/bitstream.cc @@ -157,6 +157,42 @@ void configure_extra_cell(chipconfig_t &config, const Context *ctx, CellInfo *ce      }  } +std::string tagTileType(TileType &tile) +{ +    if (tile == TILE_NONE) +        return ""; +    switch (tile) { +    case TILE_LOGIC: +        return ".logic_tile"; +        break; +    case TILE_IO: +        return ".io_tile"; +        break; +    case TILE_RAMB: +        return ".ramb_tile"; +        break; +    case TILE_RAMT: +        return ".ramt_tile"; +        break; +    case TILE_DSP0: +        return ".dsp0_tile"; +        break; +    case TILE_DSP1: +        return ".dsp1_tile"; +        break; +    case TILE_DSP2: +        return ".dsp2_tile"; +        break; +    case TILE_DSP3: +        return ".dsp3_tile"; +        break; +    case TILE_IPCON: +        return ".ipcon_tile"; +        break; +    default: +        NPNR_ASSERT(false); +    } +}  void write_asc(const Context *ctx, std::ostream &out)  {      // [y][x][row][col] @@ -443,39 +479,7 @@ void write_asc(const Context *ctx, std::ostream &out)      for (int y = 0; y < ci.height; y++) {          for (int x = 0; x < ci.width; x++) {              TileType tile = tile_at(ctx, 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; -            case TILE_DSP0: -                out << ".dsp0_tile"; -                break; -            case TILE_DSP1: -                out << ".dsp1_tile"; -                break; -            case TILE_DSP2: -                out << ".dsp2_tile"; -                break; -            case TILE_DSP3: -                out << ".dsp3_tile"; -                break; -            case TILE_IPCON: -                out << ".ipcon_tile"; -                break; -            default: -                NPNR_ASSERT(false); -            } +            out << tagTileType(tile);              out << " " << x << " " << y << std::endl;              for (auto row : config.at(y).at(x)) {                  for (auto col : row) { @@ -526,4 +530,100 @@ void write_asc(const Context *ctx, std::ostream &out)      }  } +void read_config(Context *ctx, std::istream &in, chipconfig_t &config) +{ +    constexpr size_t line_buf_size = 65536; +    char buffer[line_buf_size]; +    int tile_x = -1, tile_y = -1, line_nr = -1; + +    while (1) { +        in.getline(buffer, line_buf_size); +        if (buffer[0] == '.') { +            line_nr = -1; +            const char *tok = strtok(buffer, " \t\r\n"); + +            if (!strcmp(tok, ".device")) { +                std::string config_device = strtok(nullptr, " \t\r\n"); +                std::string expected; +                switch (ctx->args.type) { +                case ArchArgs::LP384: +                    expected = "384"; +                    break; +                case ArchArgs::HX1K: +                case ArchArgs::LP1K: +                    expected = "1k"; +                    break; +                case ArchArgs::HX8K: +                case ArchArgs::LP8K: +                    expected = "8k"; +                    break; +                case ArchArgs::UP5K: +                    expected = "5k"; +                    break; +                default: +                    log_error("unsupported device type"); +                } +                if (expected != config_device) +                    log_error("device type does not match"); +            } else if (!strcmp(tok, ".io_tile") || !strcmp(tok, ".logic_tile") || !strcmp(tok, ".ramb_tile") || +                       !strcmp(tok, ".ramt_tile") || !strcmp(tok, ".ipcon_tile") || !strcmp(tok, ".dsp0_tile") || +                       !strcmp(tok, ".dsp1_tile") || !strcmp(tok, ".dsp2_tile") || !strcmp(tok, ".dsp3_tile")) { +                line_nr = 0; +                tile_x = atoi(strtok(nullptr, " \t\r\n")); +                tile_y = atoi(strtok(nullptr, " \t\r\n")); + +                TileType tile = tile_at(ctx, tile_x, tile_y); +                if (tok != tagTileType(tile)) +                    log_error("Wrong tile type for specified position"); + +            } else if (!strcmp(tok, ".extra_bit")) { +                /* +                int b = atoi(strtok(nullptr, " \t\r\n")); +                int x = atoi(strtok(nullptr, " \t\r\n")); +                int y = atoi(strtok(nullptr, " \t\r\n")); +                std::tuple<int, int, int> key(b, x, y); +                extra_bits.insert(key); +                */ +            } else if (!strcmp(tok, ".sym")) { +                int net = atoi(strtok(nullptr, " \t\r\n")); (void)net; +                const char *name = strtok(nullptr, " \t\r\n"); +                std::unique_ptr<NetInfo> created_net = std::unique_ptr<NetInfo>(new NetInfo); +                created_net->name = ctx->id(name); +                ctx->nets[created_net->name] = std::move(created_net); +            } +        } else if (line_nr >= 0 && strlen(buffer) > 0) { +            if (line_nr > int(config.at(tile_y).at(tile_x).size() - 1)) +                log_error("Invalid data in input asc file"); +            for (int i = 0; buffer[i] == '0' || buffer[i] == '1'; i++) +                config.at(tile_y).at(tile_x).at(line_nr).at(i) = (buffer[i] == '1') ? 1 : 0; +            line_nr++; +        } +        if (in.eof()) +            break; +    } +} + +bool read_asc(Context *ctx, std::istream &in) +{ +    try { +        // [y][x][row][col] +        const ChipInfoPOD &ci = *ctx->chip_info; +        const BitstreamInfoPOD &bi = *ci.bits_info; +        chipconfig_t 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(ctx, x, y); +                int rows = bi.tiles_nonrouting[tile].rows; +                int cols = bi.tiles_nonrouting[tile].cols; +                config.at(y).at(x).resize(rows, std::vector<int8_t>(cols)); +            } +        } +        read_config(ctx, in, config); +        return true; +    } catch (log_execution_error_exception) { +        return false; +    } +}  NEXTPNR_NAMESPACE_END diff --git a/ice40/bitstream.h b/ice40/bitstream.h index 2b6cda1d..41a2ae68 100644 --- a/ice40/bitstream.h +++ b/ice40/bitstream.h @@ -27,6 +27,7 @@  NEXTPNR_NAMESPACE_BEGIN  void write_asc(const Context *ctx, std::ostream &out); +bool read_asc(Context *ctx, std::istream &in);  NEXTPNR_NAMESPACE_END diff --git a/ice40/main.cc b/ice40/main.cc index e77bdd34..c14b6086 100644 --- a/ice40/main.cc +++ b/ice40/main.cc @@ -95,6 +95,7 @@ int main(int argc, char *argv[])          options.add_options()("json", po::value<std::string>(), "JSON design file to ingest");          options.add_options()("pcf", po::value<std::string>(), "PCF constraints file to ingest");          options.add_options()("asc", po::value<std::string>(), "asc bitstream file to write"); +        options.add_options()("read", po::value<std::string>(), "asc bitstream file to read");          options.add_options()("seed", po::value<int>(), "seed value for random number generator");          options.add_options()("version,V", "show version");          options.add_options()("tmfuzz", "run path delay estimate fuzzer"); @@ -353,6 +354,13 @@ int main(int argc, char *argv[])          if (vm.count("no-tmdriv"))              ctx->timing_driven = false; +        if (vm.count("read")) { +            std::string filename = vm["read"].as<std::string>(); +            std::ifstream f(filename); +            if (!read_asc(ctx.get(), f)) +                log_error("Loading ASC failed.\n"); +        } +  #ifndef NO_GUI          if (vm.count("gui")) {              Application a(argc, argv); | 
