ice40: Add a PCF parser
Signed-off-by: David Shah <davey1576@gmail.com>
This commit is contained in:
parent
5435a97024
commit
de0918c287
@ -240,6 +240,20 @@ PipId Chip::getPipByName(IdString name) const
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
BelId Chip::getPackagePinBel(const std::string &pin) const
|
||||
{
|
||||
for (int i = 0; i < package_info->num_pins; i++) {
|
||||
if (package_info->pins[i].name == pin) {
|
||||
BelId id;
|
||||
id.index = package_info->pins[i].bel_index;
|
||||
return id;
|
||||
}
|
||||
}
|
||||
return BelId();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
void Chip::getBelPosition(BelId bel, float &x, float &y) const
|
||||
{
|
||||
assert(bel != BelId());
|
||||
|
@ -693,6 +693,8 @@ struct Chip
|
||||
return range;
|
||||
}
|
||||
|
||||
BelId getPackagePinBel(const std::string &pin) const;
|
||||
|
||||
// -------------------------------------------------
|
||||
|
||||
void getBelPosition(BelId bel, float &x, float &y) const;
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "mainwindow.h"
|
||||
#include "nextpnr.h"
|
||||
#include "pack.h"
|
||||
#include "pcf.h"
|
||||
#include "place.h"
|
||||
#include "pybindings.h"
|
||||
#include "route.h"
|
||||
@ -74,6 +75,8 @@ int main(int argc, char *argv[])
|
||||
"python file to execute");
|
||||
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()("version,v", "show version");
|
||||
@ -205,6 +208,12 @@ int main(int argc, char *argv[])
|
||||
std::istream *f = new std::ifstream(filename);
|
||||
|
||||
parse_json_file(f, filename, &design);
|
||||
|
||||
if (vm.count("pcf")) {
|
||||
std::ifstream pcf(vm["pcf"].as<std::string>());
|
||||
apply_pcf(&design, pcf);
|
||||
}
|
||||
|
||||
pack_design(&design);
|
||||
if (!vm.count("pack-only")) {
|
||||
place_design(&design);
|
||||
|
@ -1,169 +0,0 @@
|
||||
module io_wrapper(input clk_pin, cen_pin, rst_pin, ina_pin, inb_pin,
|
||||
output outa_pin, outb_pin, outc_pin, outd_pin);
|
||||
|
||||
wire clk, cen, rst, ina, inb, outa, outb, outc, outd;
|
||||
|
||||
(* BEL="0_14_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="0_14_io0" *)
|
||||
SB_IO #(
|
||||
.PIN_TYPE(6'b 0000_01),
|
||||
.PULLUP(1'b0),
|
||||
.NEG_TRIGGER(1'b0)
|
||||
) cen_iob (
|
||||
.PACKAGE_PIN(cen_pin),
|
||||
.LATCH_INPUT_VALUE(),
|
||||
.CLOCK_ENABLE(),
|
||||
.INPUT_CLK(),
|
||||
.OUTPUT_CLK(),
|
||||
.OUTPUT_ENABLE(),
|
||||
.D_OUT_0(),
|
||||
.D_OUT_1(),
|
||||
.D_IN_0(cen),
|
||||
.D_IN_1()
|
||||
);
|
||||
|
||||
(* BEL="0_13_io1" *)
|
||||
SB_IO #(
|
||||
.PIN_TYPE(6'b 0000_01),
|
||||
.PULLUP(1'b0),
|
||||
.NEG_TRIGGER(1'b0)
|
||||
) rst_iob (
|
||||
.PACKAGE_PIN(rst_pin),
|
||||
.LATCH_INPUT_VALUE(),
|
||||
.CLOCK_ENABLE(),
|
||||
.INPUT_CLK(),
|
||||
.OUTPUT_CLK(),
|
||||
.OUTPUT_ENABLE(),
|
||||
.D_OUT_0(),
|
||||
.D_OUT_1(),
|
||||
.D_IN_0(rst),
|
||||
.D_IN_1()
|
||||
);
|
||||
|
||||
(* BEL="0_13_io0" *)
|
||||
SB_IO #(
|
||||
.PIN_TYPE(6'b 0000_01),
|
||||
.PULLUP(1'b0),
|
||||
.NEG_TRIGGER(1'b0)
|
||||
) ina_iob (
|
||||
.PACKAGE_PIN(ina_pin),
|
||||
.LATCH_INPUT_VALUE(),
|
||||
.CLOCK_ENABLE(),
|
||||
.INPUT_CLK(),
|
||||
.OUTPUT_CLK(),
|
||||
.OUTPUT_ENABLE(),
|
||||
.D_OUT_0(),
|
||||
.D_OUT_1(),
|
||||
.D_IN_0(ina),
|
||||
.D_IN_1()
|
||||
);
|
||||
|
||||
(* BEL="0_12_io1" *)
|
||||
SB_IO #(
|
||||
.PIN_TYPE(6'b 0000_01),
|
||||
.PULLUP(1'b0),
|
||||
.NEG_TRIGGER(1'b0)
|
||||
) inb_iob (
|
||||
.PACKAGE_PIN(inb_pin),
|
||||
.LATCH_INPUT_VALUE(),
|
||||
.CLOCK_ENABLE(),
|
||||
.INPUT_CLK(),
|
||||
.OUTPUT_CLK(),
|
||||
.OUTPUT_ENABLE(),
|
||||
.D_OUT_0(),
|
||||
.D_OUT_1(),
|
||||
.D_IN_0(inb),
|
||||
.D_IN_1()
|
||||
);
|
||||
|
||||
(* BEL="0_12_io0" *)
|
||||
SB_IO #(
|
||||
.PIN_TYPE(6'b 0110_01),
|
||||
.PULLUP(1'b0),
|
||||
.NEG_TRIGGER(1'b0)
|
||||
) outa_iob (
|
||||
.PACKAGE_PIN(outa_pin),
|
||||
.LATCH_INPUT_VALUE(),
|
||||
.CLOCK_ENABLE(),
|
||||
.INPUT_CLK(),
|
||||
.OUTPUT_CLK(),
|
||||
.OUTPUT_ENABLE(),
|
||||
.D_OUT_0(outa),
|
||||
.D_OUT_1(),
|
||||
.D_IN_0(),
|
||||
.D_IN_1()
|
||||
);
|
||||
|
||||
(* BEL="0_11_io1" *)
|
||||
SB_IO #(
|
||||
.PIN_TYPE(6'b 0110_01),
|
||||
.PULLUP(1'b0),
|
||||
.NEG_TRIGGER(1'b0)
|
||||
) outb_iob (
|
||||
.PACKAGE_PIN(outb_pin),
|
||||
.LATCH_INPUT_VALUE(),
|
||||
.CLOCK_ENABLE(),
|
||||
.INPUT_CLK(),
|
||||
.OUTPUT_CLK(),
|
||||
.OUTPUT_ENABLE(),
|
||||
.D_OUT_0(outb),
|
||||
.D_OUT_1(),
|
||||
.D_IN_0(),
|
||||
.D_IN_1()
|
||||
);
|
||||
|
||||
(* BEL="0_11_io0" *)
|
||||
SB_IO #(
|
||||
.PIN_TYPE(6'b 0110_01),
|
||||
.PULLUP(1'b0),
|
||||
.NEG_TRIGGER(1'b0)
|
||||
) outc_iob (
|
||||
.PACKAGE_PIN(outc_pin),
|
||||
.LATCH_INPUT_VALUE(),
|
||||
.CLOCK_ENABLE(),
|
||||
.INPUT_CLK(),
|
||||
.OUTPUT_CLK(),
|
||||
.OUTPUT_ENABLE(),
|
||||
.D_OUT_0(outc),
|
||||
.D_OUT_1(),
|
||||
.D_IN_0(),
|
||||
.D_IN_1()
|
||||
);
|
||||
|
||||
(* BEL="0_10_io1" *)
|
||||
SB_IO #(
|
||||
.PIN_TYPE(6'b 0110_01),
|
||||
.PULLUP(1'b0),
|
||||
.NEG_TRIGGER(1'b0)
|
||||
) outd_iob (
|
||||
.PACKAGE_PIN(outd_pin),
|
||||
.LATCH_INPUT_VALUE(),
|
||||
.CLOCK_ENABLE(),
|
||||
.INPUT_CLK(),
|
||||
.OUTPUT_CLK(),
|
||||
.OUTPUT_ENABLE(),
|
||||
.D_OUT_0(outd),
|
||||
.D_OUT_1(),
|
||||
.D_IN_0(),
|
||||
.D_IN_1()
|
||||
);
|
||||
|
||||
top top_i(.clk(clk), .rst(rst), .cen(cen), .ina(ina), .inb(inb), .outa(outa), .outb(outb), .outc(outc), .outd(outd));
|
||||
endmodule
|
@ -1,8 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
set -ex
|
||||
NAME=${1%.v}
|
||||
yosys -p "synth_ice40 -nocarry -top io_wrapper; write_json ${NAME}.json" $1 io_wrapper.v
|
||||
../../nextpnr-ice40 --json ${NAME}.json --pack --asc ${NAME}.asc
|
||||
yosys -p "synth_ice40 -nocarry -top top; write_json ${NAME}.json" $1
|
||||
../../nextpnr-ice40 --json ${NAME}.json --pcf test.pcf --asc ${NAME}.asc
|
||||
icebox_vlog -p test.pcf ${NAME}.asc > ${NAME}_out.v
|
||||
|
||||
yosys -p "read_verilog +/ice40/cells_sim.v;\
|
||||
|
71
ice40/pcf.cc
Normal file
71
ice40/pcf.cc
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* nextpnr -- Next Generation Place and Route
|
||||
*
|
||||
* Copyright (C) 2018 Clifford Wolf <clifford@clifford.at>
|
||||
*
|
||||
* 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 "pcf.h"
|
||||
#include <sstream>
|
||||
#include "log.h"
|
||||
|
||||
NEXTPNR_NAMESPACE_BEGIN
|
||||
|
||||
// Read a w
|
||||
|
||||
// Apply PCF constraints to a pre-packing design
|
||||
void apply_pcf(Design *design, std::istream &in)
|
||||
{
|
||||
if (!in)
|
||||
log_error("failed to open PCF file");
|
||||
std::string line;
|
||||
while (std::getline(in, line)) {
|
||||
size_t cstart = line.find("#");
|
||||
if (cstart != std::string::npos)
|
||||
line = line.substr(0, cstart);
|
||||
std::stringstream ss(line);
|
||||
std::vector<std::string> words;
|
||||
std::string tmp;
|
||||
while (ss >> tmp)
|
||||
words.push_back(tmp);
|
||||
if (words.size() == 0)
|
||||
continue;
|
||||
std::string cmd = words.at(0);
|
||||
if (cmd == "set_io") {
|
||||
size_t args_end = 1;
|
||||
while (args_end < words.size() && words.at(args_end).at(0) == '-')
|
||||
args_end++;
|
||||
std::string cell = words.at(args_end);
|
||||
std::string pin = words.at(args_end + 1);
|
||||
auto fnd_cell = design->cells.find(cell);
|
||||
if (fnd_cell == design->cells.end()) {
|
||||
log_warning("unmatched pcf constraint %s\n", cell.c_str());
|
||||
} else {
|
||||
BelId pin_bel = design->chip.getPackagePinBel(pin);
|
||||
if (pin_bel == BelId())
|
||||
log_error("package does not have a pin named %s\n",
|
||||
pin.c_str());
|
||||
fnd_cell->second->attrs["BEL"] =
|
||||
design->chip.getBelName(pin_bel).str();
|
||||
log_info("constrained '%s' to bel '%s'\n", cell.c_str(),
|
||||
fnd_cell->second->attrs["BEL"].c_str());
|
||||
}
|
||||
} else {
|
||||
log_error("unsupported pcf command '%s'\n", cmd.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NEXTPNR_NAMESPACE_END
|
33
ice40/pcf.h
Normal file
33
ice40/pcf.h
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* nextpnr -- Next Generation Place and Route
|
||||
*
|
||||
* Copyright (C) 2018 Clifford Wolf <clifford@clifford.at>
|
||||
*
|
||||
* 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 PCF_H
|
||||
#define PCF_H
|
||||
|
||||
#include <iostream>
|
||||
#include "nextpnr.h"
|
||||
|
||||
NEXTPNR_NAMESPACE_BEGIN
|
||||
|
||||
// Apply PCF constraints to a pre-packing design
|
||||
void apply_pcf(Design *design, std::istream &in);
|
||||
|
||||
NEXTPNR_NAMESPACE_END
|
||||
|
||||
#endif // ROUTE_H
|
Loading…
Reference in New Issue
Block a user