From a1cd9fcf73685a5b0c4e721d405550096d85d566 Mon Sep 17 00:00:00 2001 From: David Shah Date: Mon, 9 Jul 2018 14:53:20 +0200 Subject: Reduce line width, adding some switchboxes Signed-off-by: David Shah --- ice40/arch.cc | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.cc b/ice40/arch.cc index 72f9c1f3..aed99b7b 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -424,12 +424,36 @@ std::vector Arch::getBelGraphics(BelId bel) const if (bel_type == TYPE_ICESTORM_LC) { GraphicElement el; el.type = GraphicElement::G_BOX; - el.x1 = chip_info->bel_data[bel.index].x + 0.1; - el.x2 = chip_info->bel_data[bel.index].x + 0.9; - el.y1 = chip_info->bel_data[bel.index].y + 0.10 + (chip_info->bel_data[bel.index].z) * (0.8 / 8); - el.y2 = chip_info->bel_data[bel.index].y + 0.18 + (chip_info->bel_data[bel.index].z) * (0.8 / 8); + el.x1 = chip_info->bel_data[bel.index].x + 0.82; + el.x2 = chip_info->bel_data[bel.index].x + 0.92; + el.y1 = chip_info->bel_data[bel.index].y + 0.30 + (chip_info->bel_data[bel.index].z) * (0.6 / 8); + el.y2 = chip_info->bel_data[bel.index].y + 0.35 + (chip_info->bel_data[bel.index].z) * (0.6 / 8); el.z = 0; ret.push_back(el); + + if (chip_info->bel_data[bel.index].z == 0) { + int tx = chip_info->bel_data[bel.index].x; + int ty = chip_info->bel_data[bel.index].y; + // Local tracks to LUT input switchbox + GraphicElement lc_lut_sw; + lc_lut_sw.type = GraphicElement::G_BOX; + lc_lut_sw.x1 = tx + 0.75; + lc_lut_sw.x2 = tx + 0.8; + lc_lut_sw.y1 = ty + 0.30; + lc_lut_sw.y2 = ty + 0.875; + lc_lut_sw.z = 0; + ret.push_back(lc_lut_sw); + // Local tracks switchbox + GraphicElement lc_sw; + lc_sw.type = GraphicElement::G_BOX; + lc_sw.x1 = tx + 0.6; + lc_sw.x2 = tx + 0.7; + lc_sw.y1 = ty + 0.65; + lc_sw.y2 = ty + 0.75; + ret.push_back(lc_sw); + + + } } if (bel_type == TYPE_SB_IO) { -- cgit v1.2.3 From 3be10f629a7a5eb68cfca01ac8a1464585817f22 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 9 Jul 2018 15:02:29 +0200 Subject: Add ice40 wire gfx enums Signed-off-by: Clifford Wolf --- ice40/arch.cc | 6 +- ice40/gfx.cc | 28 ++++ ice40/gfx.h | 456 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 489 insertions(+), 1 deletion(-) create mode 100644 ice40/gfx.cc create mode 100644 ice40/gfx.h (limited to 'ice40') diff --git a/ice40/arch.cc b/ice40/arch.cc index aed99b7b..ecd0a411 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -22,6 +22,8 @@ #include "log.h" #include "nextpnr.h" #include "util.h" +#include "gfx.h" + NEXTPNR_NAMESPACE_BEGIN // ----------------------------------------------------------------------- @@ -452,7 +454,9 @@ std::vector Arch::getBelGraphics(BelId bel) const lc_sw.y2 = ty + 0.75; ret.push_back(lc_sw); - + // All the wires + for (int i = TILE_WIRE_GLB2LOCAL_0; i <= TILE_WIRE_SP12_H_L_23; i++) + gfxTileWire(ret, tx, ty, GfxTileWireId(i)); } } diff --git a/ice40/gfx.cc b/ice40/gfx.cc new file mode 100644 index 00000000..46824b06 --- /dev/null +++ b/ice40/gfx.cc @@ -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. + * + */ + +#include "gfx.h" + +NEXTPNR_NAMESPACE_BEGIN + +void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) +{ +} + +NEXTPNR_NAMESPACE_END diff --git a/ice40/gfx.h b/ice40/gfx.h new file mode 100644 index 00000000..e9cc0e16 --- /dev/null +++ b/ice40/gfx.h @@ -0,0 +1,456 @@ +/* + * 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 GFX_H +#define GFX_H + +#include "nextpnr.h" + +NEXTPNR_NAMESPACE_BEGIN + +enum GfxTileWireId { + TILE_WIRE_GLB2LOCAL_0, + TILE_WIRE_GLB2LOCAL_1, + TILE_WIRE_GLB2LOCAL_2, + TILE_WIRE_GLB2LOCAL_3, + + TILE_WIRE_GLB_NETWK_0, + TILE_WIRE_GLB_NETWK_1, + TILE_WIRE_GLB_NETWK_2, + TILE_WIRE_GLB_NETWK_3, + TILE_WIRE_GLB_NETWK_4, + TILE_WIRE_GLB_NETWK_5, + TILE_WIRE_GLB_NETWK_6, + TILE_WIRE_GLB_NETWK_7, + + TILE_WIRE_LOCAL_G0_0, + TILE_WIRE_LOCAL_G0_1, + TILE_WIRE_LOCAL_G0_2, + TILE_WIRE_LOCAL_G0_3, + TILE_WIRE_LOCAL_G0_4, + TILE_WIRE_LOCAL_G0_5, + TILE_WIRE_LOCAL_G0_6, + TILE_WIRE_LOCAL_G0_7, + + TILE_WIRE_LOCAL_G1_0, + TILE_WIRE_LOCAL_G1_1, + TILE_WIRE_LOCAL_G1_2, + TILE_WIRE_LOCAL_G1_3, + TILE_WIRE_LOCAL_G1_4, + TILE_WIRE_LOCAL_G1_5, + TILE_WIRE_LOCAL_G1_6, + TILE_WIRE_LOCAL_G1_7, + + TILE_WIRE_LOCAL_G2_0, + TILE_WIRE_LOCAL_G2_1, + TILE_WIRE_LOCAL_G2_2, + TILE_WIRE_LOCAL_G2_3, + TILE_WIRE_LOCAL_G2_4, + TILE_WIRE_LOCAL_G2_5, + TILE_WIRE_LOCAL_G2_6, + TILE_WIRE_LOCAL_G2_7, + + TILE_WIRE_LOCAL_G3_0, + TILE_WIRE_LOCAL_G3_1, + TILE_WIRE_LOCAL_G3_2, + TILE_WIRE_LOCAL_G3_3, + TILE_WIRE_LOCAL_G3_4, + TILE_WIRE_LOCAL_G3_5, + TILE_WIRE_LOCAL_G3_6, + TILE_WIRE_LOCAL_G3_7, + + TILE_WIRE_CARRY_IN, + TILE_WIRE_CARRY_IN_MUX, + + TILE_WIRE_LUTFF_0_COUT, + TILE_WIRE_LUTFF_0_IN_0, + TILE_WIRE_LUTFF_0_IN_1, + TILE_WIRE_LUTFF_0_IN_2, + TILE_WIRE_LUTFF_0_IN_3, + TILE_WIRE_LUTFF_0_LOUT, + TILE_WIRE_LUTFF_0_OUT, + + TILE_WIRE_LUTFF_1_COUT, + TILE_WIRE_LUTFF_1_IN_0, + TILE_WIRE_LUTFF_1_IN_1, + TILE_WIRE_LUTFF_1_IN_2, + TILE_WIRE_LUTFF_1_IN_3, + TILE_WIRE_LUTFF_1_LOUT, + TILE_WIRE_LUTFF_1_OUT, + + TILE_WIRE_LUTFF_2_COUT, + TILE_WIRE_LUTFF_2_IN_0, + TILE_WIRE_LUTFF_2_IN_1, + TILE_WIRE_LUTFF_2_IN_2, + TILE_WIRE_LUTFF_2_IN_3, + TILE_WIRE_LUTFF_2_LOUT, + TILE_WIRE_LUTFF_2_OUT, + + TILE_WIRE_LUTFF_3_COUT, + TILE_WIRE_LUTFF_3_IN_0, + TILE_WIRE_LUTFF_3_IN_1, + TILE_WIRE_LUTFF_3_IN_2, + TILE_WIRE_LUTFF_3_IN_3, + TILE_WIRE_LUTFF_3_LOUT, + TILE_WIRE_LUTFF_3_OUT, + + TILE_WIRE_LUTFF_4_COUT, + TILE_WIRE_LUTFF_4_IN_0, + TILE_WIRE_LUTFF_4_IN_1, + TILE_WIRE_LUTFF_4_IN_2, + TILE_WIRE_LUTFF_4_IN_3, + TILE_WIRE_LUTFF_4_LOUT, + TILE_WIRE_LUTFF_4_OUT, + + TILE_WIRE_LUTFF_5_COUT, + TILE_WIRE_LUTFF_5_IN_0, + TILE_WIRE_LUTFF_5_IN_1, + TILE_WIRE_LUTFF_5_IN_2, + TILE_WIRE_LUTFF_5_IN_3, + TILE_WIRE_LUTFF_5_LOUT, + TILE_WIRE_LUTFF_5_OUT, + + TILE_WIRE_LUTFF_6_COUT, + TILE_WIRE_LUTFF_6_IN_0, + TILE_WIRE_LUTFF_6_IN_1, + TILE_WIRE_LUTFF_6_IN_2, + TILE_WIRE_LUTFF_6_IN_3, + TILE_WIRE_LUTFF_6_LOUT, + TILE_WIRE_LUTFF_6_OUT, + + TILE_WIRE_LUTFF_7_COUT, + TILE_WIRE_LUTFF_7_IN_0, + TILE_WIRE_LUTFF_7_IN_1, + TILE_WIRE_LUTFF_7_IN_2, + TILE_WIRE_LUTFF_7_IN_3, + TILE_WIRE_LUTFF_7_OUT, + + TILE_WIRE_LUTFF_GLOBAL_CEN, + TILE_WIRE_LUTFF_GLOBAL_CLK, + TILE_WIRE_LUTFF_GLOBAL_S_R, + + TILE_WIRE_NEIGH_OP_BNL_0, + TILE_WIRE_NEIGH_OP_BNR_0, + TILE_WIRE_NEIGH_OP_BOT_0, + TILE_WIRE_NEIGH_OP_LFT_0, + TILE_WIRE_NEIGH_OP_RGT_0, + TILE_WIRE_NEIGH_OP_TNL_0, + TILE_WIRE_NEIGH_OP_TNR_0, + TILE_WIRE_NEIGH_OP_TOP_0, + + TILE_WIRE_NEIGH_OP_BNL_1, + TILE_WIRE_NEIGH_OP_BNR_1, + TILE_WIRE_NEIGH_OP_BOT_1, + TILE_WIRE_NEIGH_OP_LFT_1, + TILE_WIRE_NEIGH_OP_RGT_1, + TILE_WIRE_NEIGH_OP_TNL_1, + TILE_WIRE_NEIGH_OP_TNR_1, + TILE_WIRE_NEIGH_OP_TOP_1, + + TILE_WIRE_NEIGH_OP_BNL_2, + TILE_WIRE_NEIGH_OP_BNR_2, + TILE_WIRE_NEIGH_OP_BOT_2, + TILE_WIRE_NEIGH_OP_LFT_2, + TILE_WIRE_NEIGH_OP_RGT_2, + TILE_WIRE_NEIGH_OP_TNL_2, + TILE_WIRE_NEIGH_OP_TNR_2, + TILE_WIRE_NEIGH_OP_TOP_2, + + TILE_WIRE_NEIGH_OP_BNL_3, + TILE_WIRE_NEIGH_OP_BNR_3, + TILE_WIRE_NEIGH_OP_BOT_3, + TILE_WIRE_NEIGH_OP_LFT_3, + TILE_WIRE_NEIGH_OP_RGT_3, + TILE_WIRE_NEIGH_OP_TNL_3, + TILE_WIRE_NEIGH_OP_TNR_3, + TILE_WIRE_NEIGH_OP_TOP_3, + + TILE_WIRE_NEIGH_OP_BNL_4, + TILE_WIRE_NEIGH_OP_BNR_4, + TILE_WIRE_NEIGH_OP_BOT_4, + TILE_WIRE_NEIGH_OP_LFT_4, + TILE_WIRE_NEIGH_OP_RGT_4, + TILE_WIRE_NEIGH_OP_TNL_4, + TILE_WIRE_NEIGH_OP_TNR_4, + TILE_WIRE_NEIGH_OP_TOP_4, + + TILE_WIRE_NEIGH_OP_BNL_5, + TILE_WIRE_NEIGH_OP_BNR_5, + TILE_WIRE_NEIGH_OP_BOT_5, + TILE_WIRE_NEIGH_OP_LFT_5, + TILE_WIRE_NEIGH_OP_RGT_5, + TILE_WIRE_NEIGH_OP_TNL_5, + TILE_WIRE_NEIGH_OP_TNR_5, + TILE_WIRE_NEIGH_OP_TOP_5, + + TILE_WIRE_NEIGH_OP_BNL_6, + TILE_WIRE_NEIGH_OP_BNR_6, + TILE_WIRE_NEIGH_OP_BOT_6, + TILE_WIRE_NEIGH_OP_LFT_6, + TILE_WIRE_NEIGH_OP_RGT_6, + TILE_WIRE_NEIGH_OP_TNL_6, + TILE_WIRE_NEIGH_OP_TNR_6, + TILE_WIRE_NEIGH_OP_TOP_6, + + TILE_WIRE_NEIGH_OP_BNL_7, + TILE_WIRE_NEIGH_OP_BNR_7, + TILE_WIRE_NEIGH_OP_BOT_7, + TILE_WIRE_NEIGH_OP_LFT_7, + TILE_WIRE_NEIGH_OP_RGT_7, + TILE_WIRE_NEIGH_OP_TNL_7, + TILE_WIRE_NEIGH_OP_TNR_7, + TILE_WIRE_NEIGH_OP_TOP_7, + + TILE_WIRE_SP4_V_B_0, + TILE_WIRE_SP4_V_B_1, + TILE_WIRE_SP4_V_B_2, + TILE_WIRE_SP4_V_B_3, + TILE_WIRE_SP4_V_B_4, + TILE_WIRE_SP4_V_B_5, + TILE_WIRE_SP4_V_B_6, + TILE_WIRE_SP4_V_B_7, + TILE_WIRE_SP4_V_B_8, + TILE_WIRE_SP4_V_B_9, + TILE_WIRE_SP4_V_B_10, + TILE_WIRE_SP4_V_B_11, + TILE_WIRE_SP4_V_B_12, + TILE_WIRE_SP4_V_B_13, + TILE_WIRE_SP4_V_B_14, + TILE_WIRE_SP4_V_B_15, + TILE_WIRE_SP4_V_B_16, + TILE_WIRE_SP4_V_B_17, + TILE_WIRE_SP4_V_B_18, + TILE_WIRE_SP4_V_B_19, + TILE_WIRE_SP4_V_B_20, + TILE_WIRE_SP4_V_B_21, + TILE_WIRE_SP4_V_B_22, + TILE_WIRE_SP4_V_B_23, + TILE_WIRE_SP4_V_B_24, + TILE_WIRE_SP4_V_B_25, + TILE_WIRE_SP4_V_B_26, + TILE_WIRE_SP4_V_B_27, + TILE_WIRE_SP4_V_B_28, + TILE_WIRE_SP4_V_B_29, + TILE_WIRE_SP4_V_B_30, + TILE_WIRE_SP4_V_B_31, + TILE_WIRE_SP4_V_B_32, + TILE_WIRE_SP4_V_B_33, + TILE_WIRE_SP4_V_B_34, + TILE_WIRE_SP4_V_B_35, + TILE_WIRE_SP4_V_B_36, + TILE_WIRE_SP4_V_B_37, + TILE_WIRE_SP4_V_B_38, + TILE_WIRE_SP4_V_B_39, + TILE_WIRE_SP4_V_B_40, + TILE_WIRE_SP4_V_B_41, + TILE_WIRE_SP4_V_B_42, + TILE_WIRE_SP4_V_B_43, + TILE_WIRE_SP4_V_B_44, + TILE_WIRE_SP4_V_B_45, + TILE_WIRE_SP4_V_B_46, + TILE_WIRE_SP4_V_B_47, + + TILE_WIRE_SP4_V_T_36, + TILE_WIRE_SP4_V_T_37, + TILE_WIRE_SP4_V_T_38, + TILE_WIRE_SP4_V_T_39, + TILE_WIRE_SP4_V_T_40, + TILE_WIRE_SP4_V_T_41, + TILE_WIRE_SP4_V_T_42, + TILE_WIRE_SP4_V_T_43, + TILE_WIRE_SP4_V_T_44, + TILE_WIRE_SP4_V_T_45, + TILE_WIRE_SP4_V_T_46, + TILE_WIRE_SP4_V_T_47, + + TILE_WIRE_sp4_R_V_B_0, + TILE_WIRE_sp4_R_V_B_1, + TILE_WIRE_sp4_R_V_B_2, + TILE_WIRE_sp4_R_V_B_3, + TILE_WIRE_sp4_R_V_B_4, + TILE_WIRE_sp4_R_V_B_5, + TILE_WIRE_sp4_R_V_B_6, + TILE_WIRE_sp4_R_V_B_7, + TILE_WIRE_sp4_R_V_B_8, + TILE_WIRE_sp4_R_V_B_9, + TILE_WIRE_sp4_R_V_B_10, + TILE_WIRE_sp4_R_V_B_11, + TILE_WIRE_sp4_R_V_B_12, + TILE_WIRE_sp4_R_V_B_13, + TILE_WIRE_sp4_R_V_B_14, + TILE_WIRE_sp4_R_V_B_15, + TILE_WIRE_sp4_R_V_B_16, + TILE_WIRE_sp4_R_V_B_17, + TILE_WIRE_sp4_R_V_B_18, + TILE_WIRE_sp4_R_V_B_19, + TILE_WIRE_sp4_R_V_B_20, + TILE_WIRE_sp4_R_V_B_21, + TILE_WIRE_sp4_R_V_B_22, + TILE_WIRE_sp4_R_V_B_23, + TILE_WIRE_sp4_R_V_B_24, + TILE_WIRE_sp4_R_V_B_25, + TILE_WIRE_sp4_R_V_B_26, + TILE_WIRE_sp4_R_V_B_27, + TILE_WIRE_sp4_R_V_B_28, + TILE_WIRE_sp4_R_V_B_29, + TILE_WIRE_sp4_R_V_B_30, + TILE_WIRE_sp4_R_V_B_31, + TILE_WIRE_sp4_R_V_B_32, + TILE_WIRE_sp4_R_V_B_33, + TILE_WIRE_sp4_R_V_B_34, + TILE_WIRE_sp4_R_V_B_35, + TILE_WIRE_sp4_R_V_B_36, + TILE_WIRE_sp4_R_V_B_37, + TILE_WIRE_sp4_R_V_B_38, + TILE_WIRE_sp4_R_V_B_39, + TILE_WIRE_sp4_R_V_B_40, + TILE_WIRE_sp4_R_V_B_41, + TILE_WIRE_sp4_R_V_B_42, + TILE_WIRE_sp4_R_V_B_43, + TILE_WIRE_sp4_R_V_B_44, + TILE_WIRE_sp4_R_V_B_45, + TILE_WIRE_sp4_R_V_B_46, + TILE_WIRE_sp4_R_V_B_47, + + TILE_WIRE_SP4_H_L_36, + TILE_WIRE_SP4_H_L_37, + TILE_WIRE_SP4_H_L_38, + TILE_WIRE_SP4_H_L_39, + TILE_WIRE_SP4_H_L_40, + TILE_WIRE_SP4_H_L_41, + TILE_WIRE_SP4_H_L_42, + TILE_WIRE_SP4_H_L_43, + TILE_WIRE_SP4_H_L_44, + TILE_WIRE_SP4_H_L_45, + TILE_WIRE_SP4_H_L_46, + TILE_WIRE_SP4_H_L_47, + + TILE_WIRE_SP4_H_R_0, + TILE_WIRE_SP4_H_R_1, + TILE_WIRE_SP4_H_R_2, + TILE_WIRE_SP4_H_R_3, + TILE_WIRE_SP4_H_R_4, + TILE_WIRE_SP4_H_R_5, + TILE_WIRE_SP4_H_R_6, + TILE_WIRE_SP4_H_R_7, + TILE_WIRE_SP4_H_R_8, + TILE_WIRE_SP4_H_R_9, + TILE_WIRE_SP4_H_R_10, + TILE_WIRE_SP4_H_R_11, + TILE_WIRE_SP4_H_R_12, + TILE_WIRE_SP4_H_R_13, + TILE_WIRE_SP4_H_R_14, + TILE_WIRE_SP4_H_R_15, + TILE_WIRE_SP4_H_R_16, + TILE_WIRE_SP4_H_R_17, + TILE_WIRE_SP4_H_R_18, + TILE_WIRE_SP4_H_R_19, + TILE_WIRE_SP4_H_R_20, + TILE_WIRE_SP4_H_R_21, + TILE_WIRE_SP4_H_R_22, + TILE_WIRE_SP4_H_R_23, + TILE_WIRE_SP4_H_R_24, + TILE_WIRE_SP4_H_R_25, + TILE_WIRE_SP4_H_R_26, + TILE_WIRE_SP4_H_R_27, + TILE_WIRE_SP4_H_R_28, + TILE_WIRE_SP4_H_R_29, + TILE_WIRE_SP4_H_R_30, + TILE_WIRE_SP4_H_R_31, + TILE_WIRE_SP4_H_R_32, + TILE_WIRE_SP4_H_R_33, + TILE_WIRE_SP4_H_R_34, + TILE_WIRE_SP4_H_R_35, + TILE_WIRE_SP4_H_R_36, + TILE_WIRE_SP4_H_R_37, + TILE_WIRE_SP4_H_R_38, + TILE_WIRE_SP4_H_R_39, + TILE_WIRE_SP4_H_R_40, + TILE_WIRE_SP4_H_R_41, + TILE_WIRE_SP4_H_R_42, + TILE_WIRE_SP4_H_R_43, + TILE_WIRE_SP4_H_R_44, + TILE_WIRE_SP4_H_R_45, + TILE_WIRE_SP4_H_R_46, + TILE_WIRE_SP4_H_R_47, + + TILE_WIRE_SP12_V_B_0, + TILE_WIRE_SP12_V_B_1, + TILE_WIRE_SP12_V_B_2, + TILE_WIRE_SP12_V_B_3, + TILE_WIRE_SP12_V_B_4, + TILE_WIRE_SP12_V_B_5, + TILE_WIRE_SP12_V_B_6, + TILE_WIRE_SP12_V_B_7, + TILE_WIRE_SP12_V_B_8, + TILE_WIRE_SP12_V_B_9, + TILE_WIRE_SP12_V_B_10, + TILE_WIRE_SP12_V_B_11, + TILE_WIRE_SP12_V_B_12, + TILE_WIRE_SP12_V_B_13, + TILE_WIRE_SP12_V_B_14, + TILE_WIRE_SP12_V_B_15, + TILE_WIRE_SP12_V_B_16, + TILE_WIRE_SP12_V_B_17, + TILE_WIRE_SP12_V_B_18, + TILE_WIRE_SP12_V_B_19, + TILE_WIRE_SP12_V_B_20, + TILE_WIRE_SP12_V_B_21, + TILE_WIRE_SP12_V_B_22, + TILE_WIRE_SP12_V_B_23, + + TILE_WIRE_SP12_V_T_22, + TILE_WIRE_SP12_V_T_23, + + TILE_WIRE_SP12_H_R_0, + TILE_WIRE_SP12_H_R_1, + TILE_WIRE_SP12_H_R_2, + TILE_WIRE_SP12_H_R_3, + TILE_WIRE_SP12_H_R_4, + TILE_WIRE_SP12_H_R_5, + TILE_WIRE_SP12_H_R_6, + TILE_WIRE_SP12_H_R_7, + TILE_WIRE_SP12_H_R_8, + TILE_WIRE_SP12_H_R_9, + + TILE_WIRE_SP12_H_R_10, + TILE_WIRE_SP12_H_R_11, + TILE_WIRE_SP12_H_R_12, + TILE_WIRE_SP12_H_R_13, + TILE_WIRE_SP12_H_R_14, + TILE_WIRE_SP12_H_R_15, + TILE_WIRE_SP12_H_R_16, + TILE_WIRE_SP12_H_R_17, + TILE_WIRE_SP12_H_R_18, + TILE_WIRE_SP12_H_R_19, + + TILE_WIRE_SP12_H_R_20, + TILE_WIRE_SP12_H_R_21, + TILE_WIRE_SP12_H_R_22, + TILE_WIRE_SP12_H_R_23, + + TILE_WIRE_SP12_H_L_22, + TILE_WIRE_SP12_H_L_23 +}; + +void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id); + +NEXTPNR_NAMESPACE_END + +#endif // GFX_H -- cgit v1.2.3 From 1f36242d43eca636a82aa198e15cf821b59681e1 Mon Sep 17 00:00:00 2001 From: David Shah Date: Mon, 9 Jul 2018 15:09:17 +0200 Subject: Add lutff_global switchbox Signed-off-by: David Shah --- ice40/arch.cc | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'ice40') diff --git a/ice40/arch.cc b/ice40/arch.cc index ecd0a411..7016bc07 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -457,6 +457,14 @@ std::vector Arch::getBelGraphics(BelId bel) const // All the wires for (int i = TILE_WIRE_GLB2LOCAL_0; i <= TILE_WIRE_SP12_H_L_23; i++) gfxTileWire(ret, tx, ty, GfxTileWireId(i)); + // lutff_global switchbox + GraphicElement lff_glb_sw; + lff_glb_sw.type = GraphicElement::G_BOX; + lff_glb_sw.x1 = tx + 0.65; + lff_glb_sw.x2 = tx + 0.7; + lff_glb_sw.y1 = ty + 0.875; + lff_glb_sw.y2 = ty + 0.925; + ret.push_back(lff_glb_sw); } } -- cgit v1.2.3 From 6198a68968c6e8c66ad8209bf31b77b9511102d8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 9 Jul 2018 15:45:01 +0200 Subject: Add horizontal ice40 span4 wire gfx Signed-off-by: Clifford Wolf --- ice40/gfx.cc | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'ice40') diff --git a/ice40/gfx.cc b/ice40/gfx.cc index 46824b06..5a30c79d 100644 --- a/ice40/gfx.cc +++ b/ice40/gfx.cc @@ -23,6 +23,55 @@ NEXTPNR_NAMESPACE_BEGIN void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) { + if (id >= TILE_WIRE_SP4_H_L_36 && id <= TILE_WIRE_SP4_H_L_47) { + int idx = (id - TILE_WIRE_SP4_H_L_36) + 48; + GraphicElement el; + el.type = GraphicElement::G_LINE; + + float y1 = y + 0.03 + 0.0025 * (60 - idx); + + el.x1 = x + 0.0; + el.x2 = x + 0.9; + el.y1 = y1; + el.y2 = y1; + g.push_back(el); + } + + if (id >= TILE_WIRE_SP4_H_R_0 && id <= TILE_WIRE_SP4_H_R_47) { + int idx = id - TILE_WIRE_SP4_H_R_0; + GraphicElement el; + el.type = GraphicElement::G_LINE; + + float y1 = y + 0.03 + 0.0025 * (60 - idx); + float y2 = y + 0.03 + 0.0025 * (60 - (idx ^ 1)); + float y3 = y + 0.03 + 0.0025 * (60 - (idx ^ 1) - 12); + + if (idx >= 12) { + el.x1 = x; + el.x2 = x + 0.01; + el.y1 = y1; + el.y2 = y1; + g.push_back(el); + + el.x1 = x + 0.01; + el.x2 = x + 0.02; + el.y1 = y1; + el.y2 = y2; + g.push_back(el); + } + + el.x1 = x + 0.02; + el.x2 = x + 0.9; + el.y1 = y2; + el.y2 = y2; + g.push_back(el); + + el.x1 = x + 0.9; + el.x2 = x + 1.0; + el.y1 = y2; + el.y2 = y3; + g.push_back(el); + } } NEXTPNR_NAMESPACE_END -- cgit v1.2.3 From 953560ae17aa54a94c35e7475b908b628aadd647 Mon Sep 17 00:00:00 2001 From: David Shah Date: Mon, 9 Jul 2018 16:02:02 +0200 Subject: Add switchboxes Signed-off-by: David Shah --- ice40/arch.cc | 44 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.cc b/ice40/arch.cc index 7016bc07..d6947834 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -454,9 +454,6 @@ std::vector Arch::getBelGraphics(BelId bel) const lc_sw.y2 = ty + 0.75; ret.push_back(lc_sw); - // All the wires - for (int i = TILE_WIRE_GLB2LOCAL_0; i <= TILE_WIRE_SP12_H_L_23; i++) - gfxTileWire(ret, tx, ty, GfxTileWireId(i)); // lutff_global switchbox GraphicElement lff_glb_sw; lff_glb_sw.type = GraphicElement::G_BOX; @@ -465,6 +462,47 @@ std::vector Arch::getBelGraphics(BelId bel) const lff_glb_sw.y1 = ty + 0.875; lff_glb_sw.y2 = ty + 0.925; ret.push_back(lff_glb_sw); + + // glb2local switchbox + GraphicElement glb2local_sw; + glb2local_sw.type = GraphicElement::G_BOX; + glb2local_sw.x1 = tx + 0.45; + glb2local_sw.x2 = tx + 0.55; + glb2local_sw.y1 = ty + 0.80; + glb2local_sw.y2 = ty + 0.85; + ret.push_back(glb2local_sw); + + // span12 switchbox + GraphicElement sp12_sw; + sp12_sw.type = GraphicElement::G_BOX; + sp12_sw.x1 = tx + 0.500; + sp12_sw.x2 = tx + 0.575; + sp12_sw.y1 = ty + 0.525; + sp12_sw.y2 = ty + 0.625; + ret.push_back(sp12_sw); + + // span4v switchbox + GraphicElement sp4v_sw; + sp4v_sw.type = GraphicElement::G_BOX; + sp4v_sw.x1 = tx + 0.400; + sp4v_sw.x2 = tx + 0.475; + sp4v_sw.y1 = ty + 0.425; + sp4v_sw.y2 = ty + 0.525; + ret.push_back(sp4v_sw); + + // span4h switchbox + GraphicElement sp4h_sw; + sp4h_sw.type = GraphicElement::G_BOX; + sp4h_sw.x1 = tx + 0.300; + sp4h_sw.x2 = tx + 0.375; + sp4h_sw.y1 = ty + 0.3; + sp4h_sw.y2 = ty + 0.4; + ret.push_back(sp4h_sw); + + + // All the wires + for (int i = TILE_WIRE_GLB2LOCAL_0; i <= TILE_WIRE_SP12_H_L_23; i++) + gfxTileWire(ret, tx, ty, GfxTileWireId(i)); } } -- cgit v1.2.3 From 5b6fa934d87b838cef9037bf2b14465b7e5cf742 Mon Sep 17 00:00:00 2001 From: David Shah Date: Mon, 9 Jul 2018 16:07:16 +0200 Subject: Make LCs smaller and move them down Signed-off-by: David Shah --- ice40/arch.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.cc b/ice40/arch.cc index d6947834..a86d6e56 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -428,8 +428,8 @@ std::vector Arch::getBelGraphics(BelId bel) const el.type = GraphicElement::G_BOX; el.x1 = chip_info->bel_data[bel.index].x + 0.82; el.x2 = chip_info->bel_data[bel.index].x + 0.92; - el.y1 = chip_info->bel_data[bel.index].y + 0.30 + (chip_info->bel_data[bel.index].z) * (0.6 / 8); - el.y2 = chip_info->bel_data[bel.index].y + 0.35 + (chip_info->bel_data[bel.index].z) * (0.6 / 8); + el.y1 = chip_info->bel_data[bel.index].y + 0.45 + (chip_info->bel_data[bel.index].z) * (0.5 / 8); + el.y2 = chip_info->bel_data[bel.index].y + 0.5 + (chip_info->bel_data[bel.index].z) * (0.5 / 8); el.z = 0; ret.push_back(el); @@ -441,8 +441,8 @@ std::vector Arch::getBelGraphics(BelId bel) const lc_lut_sw.type = GraphicElement::G_BOX; lc_lut_sw.x1 = tx + 0.75; lc_lut_sw.x2 = tx + 0.8; - lc_lut_sw.y1 = ty + 0.30; - lc_lut_sw.y2 = ty + 0.875; + lc_lut_sw.y1 = ty + 0.45; + lc_lut_sw.y2 = ty + 0.9375; lc_lut_sw.z = 0; ret.push_back(lc_lut_sw); // Local tracks switchbox @@ -459,8 +459,8 @@ std::vector Arch::getBelGraphics(BelId bel) const lff_glb_sw.type = GraphicElement::G_BOX; lff_glb_sw.x1 = tx + 0.65; lff_glb_sw.x2 = tx + 0.7; - lff_glb_sw.y1 = ty + 0.875; - lff_glb_sw.y2 = ty + 0.925; + lff_glb_sw.y1 = ty + 0.910; + lff_glb_sw.y2 = ty + 0.960; ret.push_back(lff_glb_sw); // glb2local switchbox -- cgit v1.2.3 From 4576fc7c20c7a211556b9b160a9eb35b5f8bb5b7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 9 Jul 2018 16:12:41 +0200 Subject: Vertical wires and span-12 wires Signed-off-by: Clifford Wolf --- ice40/gfx.cc | 158 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ice40/gfx.h | 2 - 2 files changed, 158 insertions(+), 2 deletions(-) (limited to 'ice40') diff --git a/ice40/gfx.cc b/ice40/gfx.cc index 5a30c79d..613f1a31 100644 --- a/ice40/gfx.cc +++ b/ice40/gfx.cc @@ -23,6 +23,8 @@ NEXTPNR_NAMESPACE_BEGIN void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) { + // Horizontal Span-4 Wires + if (id >= TILE_WIRE_SP4_H_L_36 && id <= TILE_WIRE_SP4_H_L_47) { int idx = (id - TILE_WIRE_SP4_H_L_36) + 48; GraphicElement el; @@ -72,6 +74,162 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) el.y2 = y3; g.push_back(el); } + + // Vertical Span-4 Wires + + if (id >= TILE_WIRE_SP4_V_T_36 && id <= TILE_WIRE_SP4_V_T_47) { + int idx = (id - TILE_WIRE_SP4_V_T_36) + 48; + GraphicElement el; + el.type = GraphicElement::G_LINE; + + float x1 = x + 0.03 + 0.0025 * (60 - idx); + + el.y1 = y + 0.0; + el.y2 = y + 0.9; + el.x1 = x1; + el.x2 = x1; + g.push_back(el); + } + + if (id >= TILE_WIRE_SP4_V_B_0 && id <= TILE_WIRE_SP4_V_B_47) { + int idx = id - TILE_WIRE_SP4_V_B_0; + GraphicElement el; + el.type = GraphicElement::G_LINE; + + float x1 = x + 0.03 + 0.0025 * (60 - idx); + float x2 = x + 0.03 + 0.0025 * (60 - (idx ^ 1)); + float x3 = x + 0.03 + 0.0025 * (60 - (idx ^ 1) - 12); + + if (idx >= 12) { + el.y1 = y; + el.y2 = y + 0.01; + el.x1 = x1; + el.x2 = x1; + g.push_back(el); + + el.y1 = y + 0.01; + el.y2 = y + 0.02; + el.x1 = x1; + el.x2 = x2; + g.push_back(el); + } + + el.y1 = y + 0.02; + el.y2 = y + 0.9; + el.x1 = x2; + el.x2 = x2; + g.push_back(el); + + el.y1 = y + 0.9; + el.y2 = y + 1.0; + el.x1 = x2; + el.x2 = x3; + g.push_back(el); + } + + // Horizontal Span-12 Wires + + if (id >= TILE_WIRE_SP12_H_L_22 && id <= TILE_WIRE_SP12_H_L_23) { + int idx = (id - TILE_WIRE_SP12_H_L_22) + 24; + GraphicElement el; + el.type = GraphicElement::G_LINE; + + float y1 = y + 0.03 + 0.0025 * (90 - idx); + + el.x1 = x + 0.0; + el.x2 = x + 0.98333; + el.y1 = y1; + el.y2 = y1; + g.push_back(el); + } + + if (id >= TILE_WIRE_SP12_H_R_0 && id <= TILE_WIRE_SP12_H_R_23) { + int idx = id - TILE_WIRE_SP12_H_R_0; + GraphicElement el; + el.type = GraphicElement::G_LINE; + + float y1 = y + 0.03 + 0.0025 * (90 - idx); + float y2 = y + 0.03 + 0.0025 * (90 - (idx ^ 1)); + float y3 = y + 0.03 + 0.0025 * (90 - (idx ^ 1) - 2); + + if (idx >= 2) { + el.x1 = x; + el.x2 = x + 0.01; + el.y1 = y1; + el.y2 = y1; + g.push_back(el); + + el.x1 = x + 0.01; + el.x2 = x + 0.02; + el.y1 = y1; + el.y2 = y2; + g.push_back(el); + } + + el.x1 = x + 0.02; + el.x2 = x + 0.98333; + el.y1 = y2; + el.y2 = y2; + g.push_back(el); + + el.x1 = x + 0.98333; + el.x2 = x + 1.0; + el.y1 = y2; + el.y2 = y3; + g.push_back(el); + } + + // Vertical Span-12 Wires + + if (id >= TILE_WIRE_SP12_V_T_22 && id <= TILE_WIRE_SP12_V_T_23) { + int idx = (id - TILE_WIRE_SP12_V_T_22) + 24; + GraphicElement el; + el.type = GraphicElement::G_LINE; + + float x1 = x + 0.03 + 0.0025 * (90 - idx); + + el.y1 = y + 0.0; + el.y2 = y + 0.98333; + el.x1 = x1; + el.x2 = x1; + g.push_back(el); + } + + if (id >= TILE_WIRE_SP12_V_B_0 && id <= TILE_WIRE_SP12_V_B_23) { + int idx = id - TILE_WIRE_SP12_V_B_0; + GraphicElement el; + el.type = GraphicElement::G_LINE; + + float x1 = x + 0.03 + 0.0025 * (90 - idx); + float x2 = x + 0.03 + 0.0025 * (90 - (idx ^ 1)); + float x3 = x + 0.03 + 0.0025 * (90 - (idx ^ 1) - 2); + + if (idx >= 2) { + el.y1 = y; + el.y2 = y + 0.01; + el.x1 = x1; + el.x2 = x1; + g.push_back(el); + + el.y1 = y + 0.01; + el.y2 = y + 0.02; + el.x1 = x1; + el.x2 = x2; + g.push_back(el); + } + + el.y1 = y + 0.02; + el.y2 = y + 0.98333; + el.x1 = x2; + el.x2 = x2; + g.push_back(el); + + el.y1 = y + 0.98333; + el.y2 = y + 1.0; + el.x1 = x2; + el.x2 = x3; + g.push_back(el); + } } NEXTPNR_NAMESPACE_END diff --git a/ice40/gfx.h b/ice40/gfx.h index e9cc0e16..fa8d51eb 100644 --- a/ice40/gfx.h +++ b/ice40/gfx.h @@ -428,7 +428,6 @@ enum GfxTileWireId { TILE_WIRE_SP12_H_R_7, TILE_WIRE_SP12_H_R_8, TILE_WIRE_SP12_H_R_9, - TILE_WIRE_SP12_H_R_10, TILE_WIRE_SP12_H_R_11, TILE_WIRE_SP12_H_R_12, @@ -439,7 +438,6 @@ enum GfxTileWireId { TILE_WIRE_SP12_H_R_17, TILE_WIRE_SP12_H_R_18, TILE_WIRE_SP12_H_R_19, - TILE_WIRE_SP12_H_R_20, TILE_WIRE_SP12_H_R_21, TILE_WIRE_SP12_H_R_22, -- cgit v1.2.3 From ba6f3b45b84be2aca06d82ce5b32f68a70f05ebb Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 9 Jul 2018 16:39:18 +0200 Subject: Add ice40 gfx right vertical span-4 Signed-off-by: Clifford Wolf --- ice40/gfx.cc | 36 +++++++++++++++++++---- ice40/gfx.h | 96 ++++++++++++++++++++++++++++++------------------------------ 2 files changed, 78 insertions(+), 54 deletions(-) (limited to 'ice40') diff --git a/ice40/gfx.cc b/ice40/gfx.cc index 613f1a31..1006f7b9 100644 --- a/ice40/gfx.cc +++ b/ice40/gfx.cc @@ -96,9 +96,9 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) GraphicElement el; el.type = GraphicElement::G_LINE; - float x1 = x + 0.03 + 0.0025 * (60 - idx); - float x2 = x + 0.03 + 0.0025 * (60 - (idx ^ 1)); - float x3 = x + 0.03 + 0.0025 * (60 - (idx ^ 1) - 12); + float x1 = x + 0.03 + 0.0025 * (60 - (idx ^ 1)); + float x2 = x + 0.03 + 0.0025 * (60 - idx); + float x3 = x + 0.03 + 0.0025 * (60 - idx - 12); if (idx >= 12) { el.y1 = y; @@ -125,6 +125,14 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) el.x1 = x2; el.x2 = x3; g.push_back(el); + + float y1 = y + 0.03 + 0.0025 * (142 - idx); + + el.y1 = y1; + el.y2 = y1; + el.x1 = x; + el.x2 = x2; + g.push_back(el); } // Horizontal Span-12 Wires @@ -148,9 +156,9 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) GraphicElement el; el.type = GraphicElement::G_LINE; - float y1 = y + 0.03 + 0.0025 * (90 - idx); - float y2 = y + 0.03 + 0.0025 * (90 - (idx ^ 1)); - float y3 = y + 0.03 + 0.0025 * (90 - (idx ^ 1) - 2); + float y1 = y + 0.03 + 0.0025 * (90 - (idx ^ 1)); + float y2 = y + 0.03 + 0.0025 * (90 - idx); + float y3 = y + 0.03 + 0.0025 * (90 - idx - 2); if (idx >= 2) { el.x1 = x; @@ -179,6 +187,22 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) g.push_back(el); } + // Veritcal Right Span-4 + + if (id >= TILE_WIRE_SP4_R_V_B_0 && id <= TILE_WIRE_SP4_R_V_B_47) { + int idx = id - TILE_WIRE_SP4_R_V_B_0; + GraphicElement el; + el.type = GraphicElement::G_LINE; + + float y1 = y + 0.03 + 0.0025 * (142 - idx); + + el.y1 = y1; + el.y2 = y1; + el.x1 = x + 0.6; + el.x2 = x + 1.0; + g.push_back(el); + } + // Vertical Span-12 Wires if (id >= TILE_WIRE_SP12_V_T_22 && id <= TILE_WIRE_SP12_V_T_23) { diff --git a/ice40/gfx.h b/ice40/gfx.h index fa8d51eb..07643bca 100644 --- a/ice40/gfx.h +++ b/ice40/gfx.h @@ -279,54 +279,54 @@ enum GfxTileWireId { TILE_WIRE_SP4_V_T_46, TILE_WIRE_SP4_V_T_47, - TILE_WIRE_sp4_R_V_B_0, - TILE_WIRE_sp4_R_V_B_1, - TILE_WIRE_sp4_R_V_B_2, - TILE_WIRE_sp4_R_V_B_3, - TILE_WIRE_sp4_R_V_B_4, - TILE_WIRE_sp4_R_V_B_5, - TILE_WIRE_sp4_R_V_B_6, - TILE_WIRE_sp4_R_V_B_7, - TILE_WIRE_sp4_R_V_B_8, - TILE_WIRE_sp4_R_V_B_9, - TILE_WIRE_sp4_R_V_B_10, - TILE_WIRE_sp4_R_V_B_11, - TILE_WIRE_sp4_R_V_B_12, - TILE_WIRE_sp4_R_V_B_13, - TILE_WIRE_sp4_R_V_B_14, - TILE_WIRE_sp4_R_V_B_15, - TILE_WIRE_sp4_R_V_B_16, - TILE_WIRE_sp4_R_V_B_17, - TILE_WIRE_sp4_R_V_B_18, - TILE_WIRE_sp4_R_V_B_19, - TILE_WIRE_sp4_R_V_B_20, - TILE_WIRE_sp4_R_V_B_21, - TILE_WIRE_sp4_R_V_B_22, - TILE_WIRE_sp4_R_V_B_23, - TILE_WIRE_sp4_R_V_B_24, - TILE_WIRE_sp4_R_V_B_25, - TILE_WIRE_sp4_R_V_B_26, - TILE_WIRE_sp4_R_V_B_27, - TILE_WIRE_sp4_R_V_B_28, - TILE_WIRE_sp4_R_V_B_29, - TILE_WIRE_sp4_R_V_B_30, - TILE_WIRE_sp4_R_V_B_31, - TILE_WIRE_sp4_R_V_B_32, - TILE_WIRE_sp4_R_V_B_33, - TILE_WIRE_sp4_R_V_B_34, - TILE_WIRE_sp4_R_V_B_35, - TILE_WIRE_sp4_R_V_B_36, - TILE_WIRE_sp4_R_V_B_37, - TILE_WIRE_sp4_R_V_B_38, - TILE_WIRE_sp4_R_V_B_39, - TILE_WIRE_sp4_R_V_B_40, - TILE_WIRE_sp4_R_V_B_41, - TILE_WIRE_sp4_R_V_B_42, - TILE_WIRE_sp4_R_V_B_43, - TILE_WIRE_sp4_R_V_B_44, - TILE_WIRE_sp4_R_V_B_45, - TILE_WIRE_sp4_R_V_B_46, - TILE_WIRE_sp4_R_V_B_47, + TILE_WIRE_SP4_R_V_B_0, + TILE_WIRE_SP4_R_V_B_1, + TILE_WIRE_SP4_R_V_B_2, + TILE_WIRE_SP4_R_V_B_3, + TILE_WIRE_SP4_R_V_B_4, + TILE_WIRE_SP4_R_V_B_5, + TILE_WIRE_SP4_R_V_B_6, + TILE_WIRE_SP4_R_V_B_7, + TILE_WIRE_SP4_R_V_B_8, + TILE_WIRE_SP4_R_V_B_9, + TILE_WIRE_SP4_R_V_B_10, + TILE_WIRE_SP4_R_V_B_11, + TILE_WIRE_SP4_R_V_B_12, + TILE_WIRE_SP4_R_V_B_13, + TILE_WIRE_SP4_R_V_B_14, + TILE_WIRE_SP4_R_V_B_15, + TILE_WIRE_SP4_R_V_B_16, + TILE_WIRE_SP4_R_V_B_17, + TILE_WIRE_SP4_R_V_B_18, + TILE_WIRE_SP4_R_V_B_19, + TILE_WIRE_SP4_R_V_B_20, + TILE_WIRE_SP4_R_V_B_21, + TILE_WIRE_SP4_R_V_B_22, + TILE_WIRE_SP4_R_V_B_23, + TILE_WIRE_SP4_R_V_B_24, + TILE_WIRE_SP4_R_V_B_25, + TILE_WIRE_SP4_R_V_B_26, + TILE_WIRE_SP4_R_V_B_27, + TILE_WIRE_SP4_R_V_B_28, + TILE_WIRE_SP4_R_V_B_29, + TILE_WIRE_SP4_R_V_B_30, + TILE_WIRE_SP4_R_V_B_31, + TILE_WIRE_SP4_R_V_B_32, + TILE_WIRE_SP4_R_V_B_33, + TILE_WIRE_SP4_R_V_B_34, + TILE_WIRE_SP4_R_V_B_35, + TILE_WIRE_SP4_R_V_B_36, + TILE_WIRE_SP4_R_V_B_37, + TILE_WIRE_SP4_R_V_B_38, + TILE_WIRE_SP4_R_V_B_39, + TILE_WIRE_SP4_R_V_B_40, + TILE_WIRE_SP4_R_V_B_41, + TILE_WIRE_SP4_R_V_B_42, + TILE_WIRE_SP4_R_V_B_43, + TILE_WIRE_SP4_R_V_B_44, + TILE_WIRE_SP4_R_V_B_45, + TILE_WIRE_SP4_R_V_B_46, + TILE_WIRE_SP4_R_V_B_47, TILE_WIRE_SP4_H_L_36, TILE_WIRE_SP4_H_L_37, -- cgit v1.2.3 From c6043ed570dd90095fdbee3435b83e626b74e327 Mon Sep 17 00:00:00 2001 From: David Shah Date: Mon, 9 Jul 2018 16:42:30 +0200 Subject: Reorder gfx.h, add LUT0 inputs Signed-off-by: David Shah --- ice40/gfx.cc | 10 ++++++++++ ice40/gfx.h | 47 +++++++++++++++++++++++++---------------------- 2 files changed, 35 insertions(+), 22 deletions(-) (limited to 'ice40') diff --git a/ice40/gfx.cc b/ice40/gfx.cc index 1006f7b9..6954a9fb 100644 --- a/ice40/gfx.cc +++ b/ice40/gfx.cc @@ -254,6 +254,16 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) el.x2 = x3; g.push_back(el); } + + if (id >= TILE_WIRE_LUTFF_0_IN_0 && id <= TILE_WIRE_LUTFF_0_IN_3) { + GraphicElement el; + el.type = GraphicElement::G_LINE; + el.x1 = x + 0.8; + el.x2 = x + 0.82; + el.y1 = y + 0.4675 + (0.005 * (id - TILE_WIRE_LUTFF_0_IN_0)); + el.y2 = el.y1; + g.push_back(el); + } } NEXTPNR_NAMESPACE_END diff --git a/ice40/gfx.h b/ice40/gfx.h index 07643bca..4cd7d081 100644 --- a/ice40/gfx.h +++ b/ice40/gfx.h @@ -78,69 +78,72 @@ enum GfxTileWireId { TILE_WIRE_CARRY_IN, TILE_WIRE_CARRY_IN_MUX, - TILE_WIRE_LUTFF_0_COUT, TILE_WIRE_LUTFF_0_IN_0, TILE_WIRE_LUTFF_0_IN_1, TILE_WIRE_LUTFF_0_IN_2, TILE_WIRE_LUTFF_0_IN_3, - TILE_WIRE_LUTFF_0_LOUT, - TILE_WIRE_LUTFF_0_OUT, - TILE_WIRE_LUTFF_1_COUT, TILE_WIRE_LUTFF_1_IN_0, TILE_WIRE_LUTFF_1_IN_1, TILE_WIRE_LUTFF_1_IN_2, TILE_WIRE_LUTFF_1_IN_3, - TILE_WIRE_LUTFF_1_LOUT, - TILE_WIRE_LUTFF_1_OUT, - TILE_WIRE_LUTFF_2_COUT, TILE_WIRE_LUTFF_2_IN_0, TILE_WIRE_LUTFF_2_IN_1, TILE_WIRE_LUTFF_2_IN_2, TILE_WIRE_LUTFF_2_IN_3, - TILE_WIRE_LUTFF_2_LOUT, - TILE_WIRE_LUTFF_2_OUT, - TILE_WIRE_LUTFF_3_COUT, TILE_WIRE_LUTFF_3_IN_0, TILE_WIRE_LUTFF_3_IN_1, TILE_WIRE_LUTFF_3_IN_2, TILE_WIRE_LUTFF_3_IN_3, - TILE_WIRE_LUTFF_3_LOUT, - TILE_WIRE_LUTFF_3_OUT, - TILE_WIRE_LUTFF_4_COUT, TILE_WIRE_LUTFF_4_IN_0, TILE_WIRE_LUTFF_4_IN_1, TILE_WIRE_LUTFF_4_IN_2, TILE_WIRE_LUTFF_4_IN_3, - TILE_WIRE_LUTFF_4_LOUT, - TILE_WIRE_LUTFF_4_OUT, - TILE_WIRE_LUTFF_5_COUT, TILE_WIRE_LUTFF_5_IN_0, TILE_WIRE_LUTFF_5_IN_1, TILE_WIRE_LUTFF_5_IN_2, TILE_WIRE_LUTFF_5_IN_3, - TILE_WIRE_LUTFF_5_LOUT, - TILE_WIRE_LUTFF_5_OUT, - TILE_WIRE_LUTFF_6_COUT, TILE_WIRE_LUTFF_6_IN_0, TILE_WIRE_LUTFF_6_IN_1, TILE_WIRE_LUTFF_6_IN_2, TILE_WIRE_LUTFF_6_IN_3, - TILE_WIRE_LUTFF_6_LOUT, - TILE_WIRE_LUTFF_6_OUT, - TILE_WIRE_LUTFF_7_COUT, TILE_WIRE_LUTFF_7_IN_0, TILE_WIRE_LUTFF_7_IN_1, TILE_WIRE_LUTFF_7_IN_2, TILE_WIRE_LUTFF_7_IN_3, + + TILE_WIRE_LUTFF_0_LOUT, + TILE_WIRE_LUTFF_1_LOUT, + TILE_WIRE_LUTFF_2_LOUT, + TILE_WIRE_LUTFF_3_LOUT, + TILE_WIRE_LUTFF_4_LOUT, + TILE_WIRE_LUTFF_5_LOUT, + TILE_WIRE_LUTFF_6_LOUT, + + TILE_WIRE_LUTFF_0_OUT, + TILE_WIRE_LUTFF_1_OUT, + TILE_WIRE_LUTFF_2_OUT, + TILE_WIRE_LUTFF_3_OUT, + TILE_WIRE_LUTFF_4_OUT, + TILE_WIRE_LUTFF_5_OUT, + TILE_WIRE_LUTFF_6_OUT, TILE_WIRE_LUTFF_7_OUT, + TILE_WIRE_LUTFF_0_COUT, + TILE_WIRE_LUTFF_1_COUT, + TILE_WIRE_LUTFF_2_COUT, + TILE_WIRE_LUTFF_3_COUT, + TILE_WIRE_LUTFF_4_COUT, + TILE_WIRE_LUTFF_5_COUT, + TILE_WIRE_LUTFF_6_COUT, + TILE_WIRE_LUTFF_7_COUT, + TILE_WIRE_LUTFF_GLOBAL_CEN, TILE_WIRE_LUTFF_GLOBAL_CLK, TILE_WIRE_LUTFF_GLOBAL_S_R, -- cgit v1.2.3 From c921e4f24b24f4c14ecf3d4f8cb999cd8ead2a41 Mon Sep 17 00:00:00 2001 From: David Shah Date: Mon, 9 Jul 2018 16:50:01 +0200 Subject: Add constants for switchbox locations Signed-off-by: David Shah --- ice40/arch.cc | 56 ++++++++++++++++++++++++++++---------------------------- ice40/gfx.h | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 28 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.cc b/ice40/arch.cc index a86d6e56..a50310cf 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -439,64 +439,64 @@ std::vector Arch::getBelGraphics(BelId bel) const // Local tracks to LUT input switchbox GraphicElement lc_lut_sw; lc_lut_sw.type = GraphicElement::G_BOX; - lc_lut_sw.x1 = tx + 0.75; - lc_lut_sw.x2 = tx + 0.8; - lc_lut_sw.y1 = ty + 0.45; - lc_lut_sw.y2 = ty + 0.9375; + lc_lut_sw.x1 = tx + lc_lut_swbox_x1; + lc_lut_sw.x2 = tx + lc_lut_swbox_x2; + lc_lut_sw.y1 = ty + lc_lut_swbox_y1; + lc_lut_sw.y2 = ty + lc_lut_swbox_y2; lc_lut_sw.z = 0; ret.push_back(lc_lut_sw); // Local tracks switchbox GraphicElement lc_sw; lc_sw.type = GraphicElement::G_BOX; - lc_sw.x1 = tx + 0.6; - lc_sw.x2 = tx + 0.7; - lc_sw.y1 = ty + 0.65; - lc_sw.y2 = ty + 0.75; + lc_sw.x1 = tx + locals_swbox_x1; + lc_sw.x2 = tx + locals_swbox_x2; + lc_sw.y1 = ty + locals_swbox_y1; + lc_sw.y2 = ty + locals_swbox_y2; ret.push_back(lc_sw); // lutff_global switchbox GraphicElement lff_glb_sw; lff_glb_sw.type = GraphicElement::G_BOX; - lff_glb_sw.x1 = tx + 0.65; - lff_glb_sw.x2 = tx + 0.7; - lff_glb_sw.y1 = ty + 0.910; - lff_glb_sw.y2 = ty + 0.960; + lff_glb_sw.x1 = tx + lutff_global_swbox_x1; + lff_glb_sw.x2 = tx + lutff_global_swbox_x2; + lff_glb_sw.y1 = ty + lutff_global_swbox_y1; + lff_glb_sw.y2 = ty + lutff_global_swbox_y2; ret.push_back(lff_glb_sw); // glb2local switchbox GraphicElement glb2local_sw; glb2local_sw.type = GraphicElement::G_BOX; - glb2local_sw.x1 = tx + 0.45; - glb2local_sw.x2 = tx + 0.55; - glb2local_sw.y1 = ty + 0.80; - glb2local_sw.y2 = ty + 0.85; + glb2local_sw.x1 = tx + glb2local_swbox_x1; + glb2local_sw.x2 = tx + glb2local_swbox_x2; + glb2local_sw.y1 = ty + glb2local_swbox_y1; + glb2local_sw.y2 = ty + glb2local_swbox_y2; ret.push_back(glb2local_sw); // span12 switchbox GraphicElement sp12_sw; sp12_sw.type = GraphicElement::G_BOX; - sp12_sw.x1 = tx + 0.500; - sp12_sw.x2 = tx + 0.575; - sp12_sw.y1 = ty + 0.525; - sp12_sw.y2 = ty + 0.625; + sp12_sw.x1 = tx + span12_swbox_x1; + sp12_sw.x2 = tx + span12_swbox_x2; + sp12_sw.y1 = ty + span12_swbox_y1; + sp12_sw.y2 = ty + span12_swbox_y2; ret.push_back(sp12_sw); // span4v switchbox GraphicElement sp4v_sw; sp4v_sw.type = GraphicElement::G_BOX; - sp4v_sw.x1 = tx + 0.400; - sp4v_sw.x2 = tx + 0.475; - sp4v_sw.y1 = ty + 0.425; - sp4v_sw.y2 = ty + 0.525; + sp4v_sw.x1 = tx + span4h_swbox_x1; + sp4v_sw.x2 = tx + span4h_swbox_x2; + sp4v_sw.y1 = ty + span4h_swbox_y1; + sp4v_sw.y2 = ty + span4h_swbox_y2; ret.push_back(sp4v_sw); // span4h switchbox GraphicElement sp4h_sw; sp4h_sw.type = GraphicElement::G_BOX; - sp4h_sw.x1 = tx + 0.300; - sp4h_sw.x2 = tx + 0.375; - sp4h_sw.y1 = ty + 0.3; - sp4h_sw.y2 = ty + 0.4; + sp4h_sw.x1 = tx + span4v_swbox_x1; + sp4h_sw.x2 = tx + span4v_swbox_x2; + sp4h_sw.y1 = ty + span4v_swbox_y1; + sp4h_sw.y2 = ty + span4v_swbox_y2; ret.push_back(sp4h_sw); diff --git a/ice40/gfx.h b/ice40/gfx.h index 4cd7d081..15bb7300 100644 --- a/ice40/gfx.h +++ b/ice40/gfx.h @@ -24,6 +24,41 @@ NEXTPNR_NAMESPACE_BEGIN +const float lc_lut_swbox_x1 = 0.75; +const float lc_lut_swbox_x2 = 0.8; +const float lc_lut_swbox_y1 = 0.45; +const float lc_lut_swbox_y2 = 0.9375; + +const float locals_swbox_x1 = 0.6; +const float locals_swbox_x2 = 0.7; +const float locals_swbox_y1 = 0.65; +const float locals_swbox_y2 = 0.75; + +const float lutff_global_swbox_x1 = 0.65; +const float lutff_global_swbox_x2 = 0.7; +const float lutff_global_swbox_y1 = 0.91; +const float lutff_global_swbox_y2 = 0.96; + +const float glb2local_swbox_x1 = 0.45; +const float glb2local_swbox_x2 = 0.55; +const float glb2local_swbox_y1 = 0.80; +const float glb2local_swbox_y2 = 0.85; + +const float span12_swbox_x1 = 0.500; +const float span12_swbox_x2 = 0.575; +const float span12_swbox_y1 = 0.525; +const float span12_swbox_y2 = 0.625; + +const float span4h_swbox_x1 = 0.400; +const float span4h_swbox_x2 = 0.475; +const float span4h_swbox_y1 = 0.425; +const float span4h_swbox_y2 = 0.525; + +const float span4v_swbox_x1 = 0.300; +const float span4v_swbox_x2 = 0.375; +const float span4v_swbox_y1 = 0.300; +const float span4v_swbox_y2 = 0.400; + enum GfxTileWireId { TILE_WIRE_GLB2LOCAL_0, TILE_WIRE_GLB2LOCAL_1, -- cgit v1.2.3 From b5cf1c8257de6e6c5a6d757231879d7aba0798cb Mon Sep 17 00:00:00 2001 From: David Shah Date: Mon, 9 Jul 2018 16:52:03 +0200 Subject: Adding all LUT input wires Signed-off-by: David Shah --- ice40/gfx.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'ice40') diff --git a/ice40/gfx.cc b/ice40/gfx.cc index 6954a9fb..f29b38dc 100644 --- a/ice40/gfx.cc +++ b/ice40/gfx.cc @@ -255,12 +255,15 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) g.push_back(el); } - if (id >= TILE_WIRE_LUTFF_0_IN_0 && id <= TILE_WIRE_LUTFF_0_IN_3) { + if (id >= TILE_WIRE_LUTFF_0_IN_0 && id <= TILE_WIRE_LUTFF_7_IN_3) { + int idx = id - TILE_WIRE_LUTFF_0_IN_0; + int z = idx / 4; + int input = idx % 4; GraphicElement el; el.type = GraphicElement::G_LINE; - el.x1 = x + 0.8; + el.x1 = x + lc_lut_swbox_x2; el.x2 = x + 0.82; - el.y1 = y + 0.4675 + (0.005 * (id - TILE_WIRE_LUTFF_0_IN_0)); + el.y1 = y + 0.4675 + (0.005 * input) + z * (0.5 / 8); el.y2 = el.y1; g.push_back(el); } -- cgit v1.2.3 From 132c5b5019fa485d7e99311bb27cfdb47fc05226 Mon Sep 17 00:00:00 2001 From: David Shah Date: Mon, 9 Jul 2018 17:00:54 +0200 Subject: Make logic cell positioning a constant Signed-off-by: David Shah --- ice40/arch.cc | 8 ++++---- ice40/gfx.cc | 4 ++-- ice40/gfx.h | 6 ++++++ 3 files changed, 12 insertions(+), 6 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.cc b/ice40/arch.cc index a50310cf..2eb7d1c3 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -426,10 +426,10 @@ std::vector Arch::getBelGraphics(BelId bel) const if (bel_type == TYPE_ICESTORM_LC) { GraphicElement el; el.type = GraphicElement::G_BOX; - el.x1 = chip_info->bel_data[bel.index].x + 0.82; - el.x2 = chip_info->bel_data[bel.index].x + 0.92; - el.y1 = chip_info->bel_data[bel.index].y + 0.45 + (chip_info->bel_data[bel.index].z) * (0.5 / 8); - el.y2 = chip_info->bel_data[bel.index].y + 0.5 + (chip_info->bel_data[bel.index].z) * (0.5 / 8); + el.x1 = chip_info->bel_data[bel.index].x + logic_cell_x1; + el.x2 = chip_info->bel_data[bel.index].x + logic_cell_x2; + el.y1 = chip_info->bel_data[bel.index].y + logic_cell_y1 + (chip_info->bel_data[bel.index].z) * logic_cell_pitch; + el.y2 = chip_info->bel_data[bel.index].y + logic_cell_y2 + (chip_info->bel_data[bel.index].z) * logic_cell_pitch; el.z = 0; ret.push_back(el); diff --git a/ice40/gfx.cc b/ice40/gfx.cc index f29b38dc..d59c00aa 100644 --- a/ice40/gfx.cc +++ b/ice40/gfx.cc @@ -262,8 +262,8 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) GraphicElement el; el.type = GraphicElement::G_LINE; el.x1 = x + lc_lut_swbox_x2; - el.x2 = x + 0.82; - el.y1 = y + 0.4675 + (0.005 * input) + z * (0.5 / 8); + el.x2 = x + logic_cell_x1; + el.y1 = y + 0.4675 + (0.005 * input) + z * logic_cell_pitch; el.y2 = el.y1; g.push_back(el); } diff --git a/ice40/gfx.h b/ice40/gfx.h index 15bb7300..784ba23f 100644 --- a/ice40/gfx.h +++ b/ice40/gfx.h @@ -59,6 +59,12 @@ const float span4v_swbox_x2 = 0.375; const float span4v_swbox_y1 = 0.300; const float span4v_swbox_y2 = 0.400; +const float logic_cell_x1 = 0.82; +const float logic_cell_x2 = 0.92; +const float logic_cell_y1 = 0.45; +const float logic_cell_y2 = 0.50; +const float logic_cell_pitch = 0.0625; + enum GfxTileWireId { TILE_WIRE_GLB2LOCAL_0, TILE_WIRE_GLB2LOCAL_1, -- cgit v1.2.3 From 46d28551fca591ce6b1cd2e1de5385661077b7e3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 9 Jul 2018 17:13:26 +0200 Subject: Add ice40 LC output gfx Signed-off-by: Clifford Wolf --- ice40/gfx.cc | 31 +++++++++++++++++++++++++++++-- ice40/gfx.h | 2 +- 2 files changed, 30 insertions(+), 3 deletions(-) (limited to 'ice40') diff --git a/ice40/gfx.cc b/ice40/gfx.cc index d59c00aa..58e52d65 100644 --- a/ice40/gfx.cc +++ b/ice40/gfx.cc @@ -126,7 +126,7 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) el.x2 = x3; g.push_back(el); - float y1 = y + 0.03 + 0.0025 * (142 - idx); + float y1 = y + 0.03 + 0.0025 * (154 - idx); el.y1 = y1; el.y2 = y1; @@ -194,7 +194,7 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) GraphicElement el; el.type = GraphicElement::G_LINE; - float y1 = y + 0.03 + 0.0025 * (142 - idx); + float y1 = y + 0.03 + 0.0025 * (154 - idx); el.y1 = y1; el.y2 = y1; @@ -255,6 +255,8 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) g.push_back(el); } + // LC Inputs + if (id >= TILE_WIRE_LUTFF_0_IN_0 && id <= TILE_WIRE_LUTFF_7_IN_3) { int idx = id - TILE_WIRE_LUTFF_0_IN_0; int z = idx / 4; @@ -267,6 +269,31 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) el.y2 = el.y1; g.push_back(el); } + + // LC Outputs + + if (id >= TILE_WIRE_LUTFF_0_OUT && id <= TILE_WIRE_LUTFF_7_OUT) { + int idx = id - TILE_WIRE_LUTFF_0_OUT; + + float y1 = y + 0.03 + 0.0025 * (102 - idx); + + GraphicElement el; + el.type = GraphicElement::G_LINE; + el.y1 = y1; + el.y2 = y1; + el.x1 = x + 0.3; + el.x2 = x + 0.97 + 0.0025 * idx; + g.push_back(el); + + el.y1 = y1; + el.y2 = y + (logic_cell_y1 + logic_cell_y2) / 2 + idx * logic_cell_pitch; + el.x1 = el.x2; + g.push_back(el); + + el.y1 = el.y2; + el.x1 = x + logic_cell_x2; + g.push_back(el); + } } NEXTPNR_NAMESPACE_END diff --git a/ice40/gfx.h b/ice40/gfx.h index 784ba23f..0fdfc326 100644 --- a/ice40/gfx.h +++ b/ice40/gfx.h @@ -60,7 +60,7 @@ const float span4v_swbox_y1 = 0.300; const float span4v_swbox_y2 = 0.400; const float logic_cell_x1 = 0.82; -const float logic_cell_x2 = 0.92; +const float logic_cell_x2 = 0.95; const float logic_cell_y1 = 0.45; const float logic_cell_y2 = 0.50; const float logic_cell_pitch = 0.0625; -- cgit v1.2.3 From bfc47e9cd4512a503266c3f9cbe8841ed6136580 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 10 Jul 2018 13:58:20 +0200 Subject: Added ICE40_HX1K_ONLY check in gui and main --- ice40/main.cc | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'ice40') diff --git a/ice40/main.cc b/ice40/main.cc index 87a32ded..ff823cbe 100644 --- a/ice40/main.cc +++ b/ice40/main.cc @@ -98,12 +98,16 @@ int main(int argc, char *argv[]) options.add_options()("seed", po::value(), "seed value for random number generator"); options.add_options()("version,V", "show version"); options.add_options()("tmfuzz", "run path delay estimate fuzzer"); +#ifdef ICE40_HX1K_ONLY + options.add_options()("hx1k", "set device type to iCE40HX1K"); +#else options.add_options()("lp384", "set device type to iCE40LP384"); options.add_options()("lp1k", "set device type to iCE40LP1K"); options.add_options()("lp8k", "set device type to iCE40LP8K"); options.add_options()("hx1k", "set device type to iCE40HX1K"); options.add_options()("hx8k", "set device type to iCE40HX8K"); options.add_options()("up5k", "set device type to iCE40UP5K"); +#endif options.add_options()("freq", po::value(), "set target frequency for design in MHz"); options.add_options()("no-tmdriv", "disable timing-driven placement"); options.add_options()("package", po::value(), "set device package"); -- cgit v1.2.3 From 841714a3d6bf475586812db3ba39bbd4dd4606de Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 10 Jul 2018 15:09:11 +0200 Subject: Improve ic40 gfx Signed-off-by: Clifford Wolf --- ice40/arch.cc | 80 +++++++---------------------- ice40/gfx.cc | 141 +++++++++++++++++++++++++++++++++++++++++++++++---- ice40/gfx.h | 159 +++++++++++++++++++++++++--------------------------------- 3 files changed, 216 insertions(+), 164 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.cc b/ice40/arch.cc index 2eb7d1c3..0b82914a 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -436,69 +436,25 @@ std::vector Arch::getBelGraphics(BelId bel) const if (chip_info->bel_data[bel.index].z == 0) { int tx = chip_info->bel_data[bel.index].x; int ty = chip_info->bel_data[bel.index].y; - // Local tracks to LUT input switchbox - GraphicElement lc_lut_sw; - lc_lut_sw.type = GraphicElement::G_BOX; - lc_lut_sw.x1 = tx + lc_lut_swbox_x1; - lc_lut_sw.x2 = tx + lc_lut_swbox_x2; - lc_lut_sw.y1 = ty + lc_lut_swbox_y1; - lc_lut_sw.y2 = ty + lc_lut_swbox_y2; - lc_lut_sw.z = 0; - ret.push_back(lc_lut_sw); - // Local tracks switchbox - GraphicElement lc_sw; - lc_sw.type = GraphicElement::G_BOX; - lc_sw.x1 = tx + locals_swbox_x1; - lc_sw.x2 = tx + locals_swbox_x2; - lc_sw.y1 = ty + locals_swbox_y1; - lc_sw.y2 = ty + locals_swbox_y2; - ret.push_back(lc_sw); - - // lutff_global switchbox - GraphicElement lff_glb_sw; - lff_glb_sw.type = GraphicElement::G_BOX; - lff_glb_sw.x1 = tx + lutff_global_swbox_x1; - lff_glb_sw.x2 = tx + lutff_global_swbox_x2; - lff_glb_sw.y1 = ty + lutff_global_swbox_y1; - lff_glb_sw.y2 = ty + lutff_global_swbox_y2; - ret.push_back(lff_glb_sw); - - // glb2local switchbox - GraphicElement glb2local_sw; - glb2local_sw.type = GraphicElement::G_BOX; - glb2local_sw.x1 = tx + glb2local_swbox_x1; - glb2local_sw.x2 = tx + glb2local_swbox_x2; - glb2local_sw.y1 = ty + glb2local_swbox_y1; - glb2local_sw.y2 = ty + glb2local_swbox_y2; - ret.push_back(glb2local_sw); - - // span12 switchbox - GraphicElement sp12_sw; - sp12_sw.type = GraphicElement::G_BOX; - sp12_sw.x1 = tx + span12_swbox_x1; - sp12_sw.x2 = tx + span12_swbox_x2; - sp12_sw.y1 = ty + span12_swbox_y1; - sp12_sw.y2 = ty + span12_swbox_y2; - ret.push_back(sp12_sw); - - // span4v switchbox - GraphicElement sp4v_sw; - sp4v_sw.type = GraphicElement::G_BOX; - sp4v_sw.x1 = tx + span4h_swbox_x1; - sp4v_sw.x2 = tx + span4h_swbox_x2; - sp4v_sw.y1 = ty + span4h_swbox_y1; - sp4v_sw.y2 = ty + span4h_swbox_y2; - ret.push_back(sp4v_sw); - - // span4h switchbox - GraphicElement sp4h_sw; - sp4h_sw.type = GraphicElement::G_BOX; - sp4h_sw.x1 = tx + span4v_swbox_x1; - sp4h_sw.x2 = tx + span4v_swbox_x2; - sp4h_sw.y1 = ty + span4v_swbox_y1; - sp4h_sw.y2 = ty + span4v_swbox_y2; - ret.push_back(sp4h_sw); + // Main switchbox + GraphicElement main_sw; + main_sw.type = GraphicElement::G_BOX; + main_sw.x1 = tx + main_swbox_x1; + main_sw.x2 = tx + main_swbox_x2; + main_sw.y1 = ty + main_swbox_y1; + main_sw.y2 = ty + main_swbox_y2; + ret.push_back(main_sw); + + // Local tracks to LUT input switchbox + GraphicElement local_sw; + local_sw.type = GraphicElement::G_BOX; + local_sw.x1 = tx + local_swbox_x1; + local_sw.x2 = tx + local_swbox_x2; + local_sw.y1 = ty + local_swbox_y1; + local_sw.y2 = ty + local_swbox_y2; + local_sw.z = 0; + ret.push_back(local_sw); // All the wires for (int i = TILE_WIRE_GLB2LOCAL_0; i <= TILE_WIRE_SP12_H_L_23; i++) diff --git a/ice40/gfx.cc b/ice40/gfx.cc index 58e52d65..e72b2515 100644 --- a/ice40/gfx.cc +++ b/ice40/gfx.cc @@ -37,6 +37,12 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) el.y1 = y1; el.y2 = y1; g.push_back(el); + + el.x1 = x + main_swbox_x1 + 0.0025 * (idx + 35); + el.x2 = el.x1; + el.y1 = y1; + el.y2 = y + main_swbox_y1; + g.push_back(el); } if (id >= TILE_WIRE_SP4_H_R_0 && id <= TILE_WIRE_SP4_H_R_47) { @@ -73,6 +79,12 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) el.y1 = y2; el.y2 = y3; g.push_back(el); + + el.x1 = x + main_swbox_x1 + 0.0025 * ((idx ^ 1) + 35); + el.x2 = el.x1; + el.y1 = y2; + el.y2 = y + main_swbox_y1; + g.push_back(el); } // Vertical Span-4 Wires @@ -89,6 +101,12 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) el.x1 = x1; el.x2 = x1; g.push_back(el); + + el.y1 = y + 0.03 + 0.0025 * (270 - idx); + el.y2 = el.y1; + el.x1 = x1; + el.x2 = x + main_swbox_x1; + g.push_back(el); } if (id >= TILE_WIRE_SP4_V_B_0 && id <= TILE_WIRE_SP4_V_B_47) { @@ -126,13 +144,17 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) el.x2 = x3; g.push_back(el); - float y1 = y + 0.03 + 0.0025 * (154 - idx); - - el.y1 = y1; - el.y2 = y1; + el.y1 = y + 0.03 + 0.0025 * (145 - idx); + el.y2 = el.y1; el.x1 = x; el.x2 = x2; g.push_back(el); + + el.y1 = y + 0.03 + 0.0025 * (270 - idx); + el.y2 = el.y1; + el.x1 = x2; + el.x2 = x + main_swbox_x1; + g.push_back(el); } // Horizontal Span-12 Wires @@ -149,6 +171,12 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) el.y1 = y1; el.y2 = y1; g.push_back(el); + + el.x1 = x + main_swbox_x1 + 0.0025 * (idx + 5); + el.x2 = el.x1; + el.y1 = y1; + el.y2 = y + main_swbox_y1; + g.push_back(el); } if (id >= TILE_WIRE_SP12_H_R_0 && id <= TILE_WIRE_SP12_H_R_23) { @@ -185,20 +213,26 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) el.y1 = y2; el.y2 = y3; g.push_back(el); + + el.x1 = x + main_swbox_x1 + 0.0025 * (idx + 5); + el.x2 = el.x1; + el.y1 = y2; + el.y2 = y + main_swbox_y1; + g.push_back(el); } - // Veritcal Right Span-4 + // Vertical Right Span-4 if (id >= TILE_WIRE_SP4_R_V_B_0 && id <= TILE_WIRE_SP4_R_V_B_47) { int idx = id - TILE_WIRE_SP4_R_V_B_0; GraphicElement el; el.type = GraphicElement::G_LINE; - float y1 = y + 0.03 + 0.0025 * (154 - idx); + float y1 = y + 0.03 + 0.0025 * (145 - idx); el.y1 = y1; el.y2 = y1; - el.x1 = x + 0.6; + el.x1 = x + main_swbox_x2; el.x2 = x + 1.0; g.push_back(el); } @@ -217,6 +251,12 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) el.x1 = x1; el.x2 = x1; g.push_back(el); + + el.y1 = y + 0.03 + 0.0025 * (300 - idx); + el.y2 = el.y1; + el.x1 = x1; + el.x2 = x + main_swbox_x1; + g.push_back(el); } if (id >= TILE_WIRE_SP12_V_B_0 && id <= TILE_WIRE_SP12_V_B_23) { @@ -253,6 +293,65 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) el.x1 = x2; el.x2 = x3; g.push_back(el); + + el.y1 = y + 0.03 + 0.0025 * (300 - (idx ^ 1)); + el.y2 = el.y1; + el.x1 = x2; + el.x2 = x + main_swbox_x1; + g.push_back(el); + } + + // Global2Local + + if (id >= TILE_WIRE_GLB2LOCAL_0 && id <= TILE_WIRE_GLB2LOCAL_3) { + int idx = id - TILE_WIRE_GLB2LOCAL_0; + GraphicElement el; + el.type = GraphicElement::G_LINE; + el.x1 = x + main_swbox_x1 + 0.005 * (idx + 5); + el.x2 = el.x1; + el.y1 = y + main_swbox_y2; + el.y2 = el.y1 + 0.02; + g.push_back(el); + } + + // GlobalNets + + if (id >= TILE_WIRE_GLB_NETWK_0 && id <= TILE_WIRE_GLB_NETWK_7) { + int idx = id - TILE_WIRE_GLB_NETWK_0; + GraphicElement el; + el.type = GraphicElement::G_LINE; + el.x1 = x + main_swbox_x1 - 0.05; + el.x2 = x + main_swbox_x1; + el.y1 = y + main_swbox_y2 - 0.005 * (13 - idx); + el.y2 = el.y1; + g.push_back(el); + } + + // Neighbours + + if (id >= TILE_WIRE_NEIGH_OP_BNL_0 && id <= TILE_WIRE_NEIGH_OP_TOP_7) { + int idx = id - TILE_WIRE_NEIGH_OP_BNL_0; + GraphicElement el; + el.type = GraphicElement::G_LINE; + el.y1 = y + main_swbox_y1 + 0.0025 * (idx + 10) + 0.01 * (idx / 8); + el.y2 = el.y1; + el.x1 = x + main_swbox_x1 - 0.05; + el.x2 = x + main_swbox_x1; + g.push_back(el); + } + + // Local Tracks + + if (id >= TILE_WIRE_LOCAL_G0_0 && id <= TILE_WIRE_LOCAL_G3_7) { + int idx = id - TILE_WIRE_LOCAL_G0_0; + GraphicElement el; + el.type = GraphicElement::G_LINE; + el.x1 = x + main_swbox_x2; + el.x2 = x + local_swbox_x1; + float yoff = y + (local_swbox_y1 + local_swbox_y2) / 2 - 0.005 * 16 - 0.075; + el.y1 = yoff + 0.005 * idx + 0.05 * (idx / 8); + el.y2 = el.y1; + g.push_back(el); } // LC Inputs @@ -263,7 +362,7 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) int input = idx % 4; GraphicElement el; el.type = GraphicElement::G_LINE; - el.x1 = x + lc_lut_swbox_x2; + el.x1 = x + local_swbox_x2; el.x2 = x + logic_cell_x1; el.y1 = y + 0.4675 + (0.005 * input) + z * logic_cell_pitch; el.y2 = el.y1; @@ -275,13 +374,13 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) if (id >= TILE_WIRE_LUTFF_0_OUT && id <= TILE_WIRE_LUTFF_7_OUT) { int idx = id - TILE_WIRE_LUTFF_0_OUT; - float y1 = y + 0.03 + 0.0025 * (102 - idx); + float y1 = y + 0.03 + 0.0025 * (159 - idx); GraphicElement el; el.type = GraphicElement::G_LINE; el.y1 = y1; el.y2 = y1; - el.x1 = x + 0.3; + el.x1 = x + main_swbox_x2; el.x2 = x + 0.97 + 0.0025 * idx; g.push_back(el); @@ -294,6 +393,28 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) el.x1 = x + logic_cell_x2; g.push_back(el); } + + // LC Control + + if (id >= TILE_WIRE_LUTFF_GLOBAL_CEN && id <= TILE_WIRE_LUTFF_GLOBAL_S_R) { + int idx = id - TILE_WIRE_LUTFF_GLOBAL_CEN; + GraphicElement el; + el.type = GraphicElement::G_LINE; + + el.x1 = x + main_swbox_x2 - 0.005 * (idx + 5); + el.x2 = el.x1; + el.y1 = y + main_swbox_y2; + el.y2 = el.y1 + 0.005 * (idx + 3); + g.push_back(el); + + el.y1 = el.y2; + el.x2 = x + logic_cell_x2 - 0.005 * (2 - idx + 5); + g.push_back(el); + + el.y2 = y + logic_cell_y2 + 7*logic_cell_pitch; + el.x1 = el.x2; + g.push_back(el); + } } NEXTPNR_NAMESPACE_END diff --git a/ice40/gfx.h b/ice40/gfx.h index 0fdfc326..9fce27e8 100644 --- a/ice40/gfx.h +++ b/ice40/gfx.h @@ -24,42 +24,17 @@ NEXTPNR_NAMESPACE_BEGIN -const float lc_lut_swbox_x1 = 0.75; -const float lc_lut_swbox_x2 = 0.8; -const float lc_lut_swbox_y1 = 0.45; -const float lc_lut_swbox_y2 = 0.9375; - -const float locals_swbox_x1 = 0.6; -const float locals_swbox_x2 = 0.7; -const float locals_swbox_y1 = 0.65; -const float locals_swbox_y2 = 0.75; - -const float lutff_global_swbox_x1 = 0.65; -const float lutff_global_swbox_x2 = 0.7; -const float lutff_global_swbox_y1 = 0.91; -const float lutff_global_swbox_y2 = 0.96; - -const float glb2local_swbox_x1 = 0.45; -const float glb2local_swbox_x2 = 0.55; -const float glb2local_swbox_y1 = 0.80; -const float glb2local_swbox_y2 = 0.85; - -const float span12_swbox_x1 = 0.500; -const float span12_swbox_x2 = 0.575; -const float span12_swbox_y1 = 0.525; -const float span12_swbox_y2 = 0.625; - -const float span4h_swbox_x1 = 0.400; -const float span4h_swbox_x2 = 0.475; -const float span4h_swbox_y1 = 0.425; -const float span4h_swbox_y2 = 0.525; - -const float span4v_swbox_x1 = 0.300; -const float span4v_swbox_x2 = 0.375; -const float span4v_swbox_y1 = 0.300; -const float span4v_swbox_y2 = 0.400; - -const float logic_cell_x1 = 0.82; +const float main_swbox_x1 = 0.35; +const float main_swbox_x2 = 0.60; +const float main_swbox_y1 = 0.27; +const float main_swbox_y2 = 0.95; + +const float local_swbox_x1 = 0.63; +const float local_swbox_x2 = 0.73; +const float local_swbox_y1 = 0.45; +const float local_swbox_y2 = 0.9375; + +const float logic_cell_x1 = 0.76; const float logic_cell_x2 = 0.95; const float logic_cell_y1 = 0.45; const float logic_cell_y2 = 0.50; @@ -190,75 +165,75 @@ enum GfxTileWireId { TILE_WIRE_LUTFF_GLOBAL_S_R, TILE_WIRE_NEIGH_OP_BNL_0, - TILE_WIRE_NEIGH_OP_BNR_0, - TILE_WIRE_NEIGH_OP_BOT_0, - TILE_WIRE_NEIGH_OP_LFT_0, - TILE_WIRE_NEIGH_OP_RGT_0, - TILE_WIRE_NEIGH_OP_TNL_0, - TILE_WIRE_NEIGH_OP_TNR_0, - TILE_WIRE_NEIGH_OP_TOP_0, - TILE_WIRE_NEIGH_OP_BNL_1, - TILE_WIRE_NEIGH_OP_BNR_1, - TILE_WIRE_NEIGH_OP_BOT_1, - TILE_WIRE_NEIGH_OP_LFT_1, - TILE_WIRE_NEIGH_OP_RGT_1, - TILE_WIRE_NEIGH_OP_TNL_1, - TILE_WIRE_NEIGH_OP_TNR_1, - TILE_WIRE_NEIGH_OP_TOP_1, - TILE_WIRE_NEIGH_OP_BNL_2, - TILE_WIRE_NEIGH_OP_BNR_2, - TILE_WIRE_NEIGH_OP_BOT_2, - TILE_WIRE_NEIGH_OP_LFT_2, - TILE_WIRE_NEIGH_OP_RGT_2, - TILE_WIRE_NEIGH_OP_TNL_2, - TILE_WIRE_NEIGH_OP_TNR_2, - TILE_WIRE_NEIGH_OP_TOP_2, - TILE_WIRE_NEIGH_OP_BNL_3, - TILE_WIRE_NEIGH_OP_BNR_3, - TILE_WIRE_NEIGH_OP_BOT_3, - TILE_WIRE_NEIGH_OP_LFT_3, - TILE_WIRE_NEIGH_OP_RGT_3, - TILE_WIRE_NEIGH_OP_TNL_3, - TILE_WIRE_NEIGH_OP_TNR_3, - TILE_WIRE_NEIGH_OP_TOP_3, - TILE_WIRE_NEIGH_OP_BNL_4, - TILE_WIRE_NEIGH_OP_BNR_4, - TILE_WIRE_NEIGH_OP_BOT_4, - TILE_WIRE_NEIGH_OP_LFT_4, - TILE_WIRE_NEIGH_OP_RGT_4, - TILE_WIRE_NEIGH_OP_TNL_4, - TILE_WIRE_NEIGH_OP_TNR_4, - TILE_WIRE_NEIGH_OP_TOP_4, - TILE_WIRE_NEIGH_OP_BNL_5, - TILE_WIRE_NEIGH_OP_BNR_5, - TILE_WIRE_NEIGH_OP_BOT_5, - TILE_WIRE_NEIGH_OP_LFT_5, - TILE_WIRE_NEIGH_OP_RGT_5, - TILE_WIRE_NEIGH_OP_TNL_5, - TILE_WIRE_NEIGH_OP_TNR_5, - TILE_WIRE_NEIGH_OP_TOP_5, - TILE_WIRE_NEIGH_OP_BNL_6, - TILE_WIRE_NEIGH_OP_BNR_6, - TILE_WIRE_NEIGH_OP_BOT_6, - TILE_WIRE_NEIGH_OP_LFT_6, - TILE_WIRE_NEIGH_OP_RGT_6, - TILE_WIRE_NEIGH_OP_TNL_6, - TILE_WIRE_NEIGH_OP_TNR_6, - TILE_WIRE_NEIGH_OP_TOP_6, - TILE_WIRE_NEIGH_OP_BNL_7, + + TILE_WIRE_NEIGH_OP_BNR_0, + TILE_WIRE_NEIGH_OP_BNR_1, + TILE_WIRE_NEIGH_OP_BNR_2, + TILE_WIRE_NEIGH_OP_BNR_3, + TILE_WIRE_NEIGH_OP_BNR_4, + TILE_WIRE_NEIGH_OP_BNR_5, + TILE_WIRE_NEIGH_OP_BNR_6, TILE_WIRE_NEIGH_OP_BNR_7, + + TILE_WIRE_NEIGH_OP_BOT_0, + TILE_WIRE_NEIGH_OP_BOT_1, + TILE_WIRE_NEIGH_OP_BOT_2, + TILE_WIRE_NEIGH_OP_BOT_3, + TILE_WIRE_NEIGH_OP_BOT_4, + TILE_WIRE_NEIGH_OP_BOT_5, + TILE_WIRE_NEIGH_OP_BOT_6, TILE_WIRE_NEIGH_OP_BOT_7, + + TILE_WIRE_NEIGH_OP_LFT_0, + TILE_WIRE_NEIGH_OP_LFT_1, + TILE_WIRE_NEIGH_OP_LFT_2, + TILE_WIRE_NEIGH_OP_LFT_3, + TILE_WIRE_NEIGH_OP_LFT_4, + TILE_WIRE_NEIGH_OP_LFT_5, + TILE_WIRE_NEIGH_OP_LFT_6, TILE_WIRE_NEIGH_OP_LFT_7, + + TILE_WIRE_NEIGH_OP_RGT_0, + TILE_WIRE_NEIGH_OP_RGT_1, + TILE_WIRE_NEIGH_OP_RGT_2, + TILE_WIRE_NEIGH_OP_RGT_3, + TILE_WIRE_NEIGH_OP_RGT_4, + TILE_WIRE_NEIGH_OP_RGT_5, + TILE_WIRE_NEIGH_OP_RGT_6, TILE_WIRE_NEIGH_OP_RGT_7, + + TILE_WIRE_NEIGH_OP_TNL_0, + TILE_WIRE_NEIGH_OP_TNL_1, + TILE_WIRE_NEIGH_OP_TNL_2, + TILE_WIRE_NEIGH_OP_TNL_3, + TILE_WIRE_NEIGH_OP_TNL_4, + TILE_WIRE_NEIGH_OP_TNL_5, + TILE_WIRE_NEIGH_OP_TNL_6, TILE_WIRE_NEIGH_OP_TNL_7, + + TILE_WIRE_NEIGH_OP_TNR_0, + TILE_WIRE_NEIGH_OP_TNR_1, + TILE_WIRE_NEIGH_OP_TNR_2, + TILE_WIRE_NEIGH_OP_TNR_3, + TILE_WIRE_NEIGH_OP_TNR_4, + TILE_WIRE_NEIGH_OP_TNR_5, + TILE_WIRE_NEIGH_OP_TNR_6, TILE_WIRE_NEIGH_OP_TNR_7, + + TILE_WIRE_NEIGH_OP_TOP_0, + TILE_WIRE_NEIGH_OP_TOP_1, + TILE_WIRE_NEIGH_OP_TOP_2, + TILE_WIRE_NEIGH_OP_TOP_3, + TILE_WIRE_NEIGH_OP_TOP_4, + TILE_WIRE_NEIGH_OP_TOP_5, + TILE_WIRE_NEIGH_OP_TOP_6, TILE_WIRE_NEIGH_OP_TOP_7, TILE_WIRE_SP4_V_B_0, -- cgit v1.2.3 From c4af52dd5b3830905e2b9e8f7135f886882841ba Mon Sep 17 00:00:00 2001 From: David Shah Date: Thu, 5 Jul 2018 20:59:11 +0200 Subject: ecp5: Working on arch implementation Signed-off-by: David Shah --- ice40/arch_pybindings.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'ice40') diff --git a/ice40/arch_pybindings.cc b/ice40/arch_pybindings.cc index 67a37983..ac8c189a 100644 --- a/ice40/arch_pybindings.cc +++ b/ice40/arch_pybindings.cc @@ -75,7 +75,7 @@ void arch_wrap_python() fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getConflictingBelCell"); fn_wrapper_0a>::def_wrap(ctx_cls, - "getBels"); + "getBels"); fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getBelsAtSameTile"); @@ -139,15 +139,15 @@ void arch_wrap_python() fn_wrapper_0a>::def_wrap( ctx_cls, "getChipName"); fn_wrapper_0a>::def_wrap(ctx_cls, - "archId"); + "archId"); typedef std::unordered_map> CellMap; typedef std::unordered_map> NetMap; readonly_wrapper>::def_wrap(ctx_cls, - "cells"); + "cells"); readonly_wrapper>::def_wrap(ctx_cls, - "nets"); + "nets"); WRAP_RANGE(Bel, conv_to_str); WRAP_RANGE(Wire, conv_to_str); WRAP_RANGE(AllPip, conv_to_str); -- cgit v1.2.3 From 7081cca01654030f9a3b731cebf36e68590e3ed1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 11 Jul 2018 14:03:23 +0200 Subject: Add GUI Decals API Signed-off-by: Clifford Wolf --- ice40/arch.cc | 207 +++++++++++++++++++++++++++++-------------------------- ice40/arch.h | 10 +-- ice40/archdefs.h | 22 ++++++ 3 files changed, 139 insertions(+), 100 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.cc b/ice40/arch.cc index 0b82914a..a25c3d87 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -400,128 +400,143 @@ delay_t Arch::estimateDelay(WireId src, WireId dst) const // ----------------------------------------------------------------------- -std::vector Arch::getFrameGraphics() const +DecalXY Arch::getFrameDecal() const { - std::vector ret; + DecalXY decalxy; + decalxy.decal.type = 'f'; + return decalxy; +} - for (int x = 0; x <= chip_info->width; x++) - for (int y = 0; y <= chip_info->height; y++) { - GraphicElement el; - el.type = GraphicElement::G_LINE; - el.x1 = x - 0.05, el.x2 = x + 0.05, el.y1 = y, el.y2 = y, el.z = 0; - ret.push_back(el); - el.x1 = x, el.x2 = x, el.y1 = y - 0.05, el.y2 = y + 0.05, el.z = 0; - ret.push_back(el); - } +DecalXY Arch::getBelDecal(BelId bel) const +{ + DecalXY decalxy; + decalxy.decal.type = 'b'; + decalxy.decal.z = bel.index; + return decalxy; +} - return ret; +DecalXY Arch::getWireDecal(WireId wire) const +{ + DecalXY decalxy; + return decalxy; } -std::vector Arch::getBelGraphics(BelId bel) const +DecalXY Arch::getPipDecal(PipId pip) const +{ + DecalXY decalxy; + return decalxy; +}; + +std::vector Arch::getDecalGraphics(DecalId decal) const { std::vector ret; - auto bel_type = getBelType(bel); - - if (bel_type == TYPE_ICESTORM_LC) { - GraphicElement el; - el.type = GraphicElement::G_BOX; - el.x1 = chip_info->bel_data[bel.index].x + logic_cell_x1; - el.x2 = chip_info->bel_data[bel.index].x + logic_cell_x2; - el.y1 = chip_info->bel_data[bel.index].y + logic_cell_y1 + (chip_info->bel_data[bel.index].z) * logic_cell_pitch; - el.y2 = chip_info->bel_data[bel.index].y + logic_cell_y2 + (chip_info->bel_data[bel.index].z) * logic_cell_pitch; - el.z = 0; - ret.push_back(el); - - if (chip_info->bel_data[bel.index].z == 0) { - int tx = chip_info->bel_data[bel.index].x; - int ty = chip_info->bel_data[bel.index].y; - - // Main switchbox - GraphicElement main_sw; - main_sw.type = GraphicElement::G_BOX; - main_sw.x1 = tx + main_swbox_x1; - main_sw.x2 = tx + main_swbox_x2; - main_sw.y1 = ty + main_swbox_y1; - main_sw.y2 = ty + main_swbox_y2; - ret.push_back(main_sw); - - // Local tracks to LUT input switchbox - GraphicElement local_sw; - local_sw.type = GraphicElement::G_BOX; - local_sw.x1 = tx + local_swbox_x1; - local_sw.x2 = tx + local_swbox_x2; - local_sw.y1 = ty + local_swbox_y1; - local_sw.y2 = ty + local_swbox_y2; - local_sw.z = 0; - ret.push_back(local_sw); - - // All the wires - for (int i = TILE_WIRE_GLB2LOCAL_0; i <= TILE_WIRE_SP12_H_L_23; i++) - gfxTileWire(ret, tx, ty, GfxTileWireId(i)); - } + if (decal.type == 'f') + { + for (int x = 0; x <= chip_info->width; x++) + for (int y = 0; y <= chip_info->height; y++) { + GraphicElement el; + el.type = GraphicElement::G_LINE; + el.x1 = x - 0.05, el.x2 = x + 0.05, el.y1 = y, el.y2 = y, el.z = 0; + ret.push_back(el); + el.x1 = x, el.x2 = x, el.y1 = y - 0.05, el.y2 = y + 0.05, el.z = 0; + ret.push_back(el); + } } - if (bel_type == TYPE_SB_IO) { - if (chip_info->bel_data[bel.index].x == 0 || chip_info->bel_data[bel.index].x == chip_info->width - 1) { + if (decal.type == 'b') + { + BelId bel; + bel.index = decal.z; + + auto bel_type = getBelType(bel); + + if (bel_type == TYPE_ICESTORM_LC) { GraphicElement el; el.type = GraphicElement::G_BOX; - el.x1 = chip_info->bel_data[bel.index].x + 0.1; - el.x2 = chip_info->bel_data[bel.index].x + 0.9; - if (chip_info->bel_data[bel.index].z == 0) { - el.y1 = chip_info->bel_data[bel.index].y + 0.10; - el.y2 = chip_info->bel_data[bel.index].y + 0.45; - } else { - el.y1 = chip_info->bel_data[bel.index].y + 0.55; - el.y2 = chip_info->bel_data[bel.index].y + 0.90; - } + el.x1 = chip_info->bel_data[bel.index].x + logic_cell_x1; + el.x2 = chip_info->bel_data[bel.index].x + logic_cell_x2; + el.y1 = chip_info->bel_data[bel.index].y + logic_cell_y1 + (chip_info->bel_data[bel.index].z) * logic_cell_pitch; + el.y2 = chip_info->bel_data[bel.index].y + logic_cell_y2 + (chip_info->bel_data[bel.index].z) * logic_cell_pitch; el.z = 0; ret.push_back(el); - } else { - GraphicElement el; - el.type = GraphicElement::G_BOX; + if (chip_info->bel_data[bel.index].z == 0) { - el.x1 = chip_info->bel_data[bel.index].x + 0.10; - el.x2 = chip_info->bel_data[bel.index].x + 0.45; + int tx = chip_info->bel_data[bel.index].x; + int ty = chip_info->bel_data[bel.index].y; + + // Main switchbox + GraphicElement main_sw; + main_sw.type = GraphicElement::G_BOX; + main_sw.x1 = tx + main_swbox_x1; + main_sw.x2 = tx + main_swbox_x2; + main_sw.y1 = ty + main_swbox_y1; + main_sw.y2 = ty + main_swbox_y2; + ret.push_back(main_sw); + + // Local tracks to LUT input switchbox + GraphicElement local_sw; + local_sw.type = GraphicElement::G_BOX; + local_sw.x1 = tx + local_swbox_x1; + local_sw.x2 = tx + local_swbox_x2; + local_sw.y1 = ty + local_swbox_y1; + local_sw.y2 = ty + local_swbox_y2; + local_sw.z = 0; + ret.push_back(local_sw); + + // All the wires + for (int i = TILE_WIRE_GLB2LOCAL_0; i <= TILE_WIRE_SP12_H_L_23; i++) + gfxTileWire(ret, tx, ty, GfxTileWireId(i)); + } + } + + if (bel_type == TYPE_SB_IO) { + if (chip_info->bel_data[bel.index].x == 0 || chip_info->bel_data[bel.index].x == chip_info->width - 1) { + GraphicElement el; + el.type = GraphicElement::G_BOX; + el.x1 = chip_info->bel_data[bel.index].x + 0.1; + el.x2 = chip_info->bel_data[bel.index].x + 0.9; + if (chip_info->bel_data[bel.index].z == 0) { + el.y1 = chip_info->bel_data[bel.index].y + 0.10; + el.y2 = chip_info->bel_data[bel.index].y + 0.45; + } else { + el.y1 = chip_info->bel_data[bel.index].y + 0.55; + el.y2 = chip_info->bel_data[bel.index].y + 0.90; + } + el.z = 0; + ret.push_back(el); } else { - el.x1 = chip_info->bel_data[bel.index].x + 0.55; - el.x2 = chip_info->bel_data[bel.index].x + 0.90; + GraphicElement el; + el.type = GraphicElement::G_BOX; + if (chip_info->bel_data[bel.index].z == 0) { + el.x1 = chip_info->bel_data[bel.index].x + 0.10; + el.x2 = chip_info->bel_data[bel.index].x + 0.45; + } else { + el.x1 = chip_info->bel_data[bel.index].x + 0.55; + el.x2 = chip_info->bel_data[bel.index].x + 0.90; + } + el.y1 = chip_info->bel_data[bel.index].y + 0.1; + el.y2 = chip_info->bel_data[bel.index].y + 0.9; + el.z = 0; + ret.push_back(el); } + } + + if (bel_type == TYPE_ICESTORM_RAM) { + GraphicElement el; + el.type = GraphicElement::G_BOX; + el.x1 = chip_info->bel_data[bel.index].x + 0.1; + el.x2 = chip_info->bel_data[bel.index].x + 0.9; el.y1 = chip_info->bel_data[bel.index].y + 0.1; - el.y2 = chip_info->bel_data[bel.index].y + 0.9; + el.y2 = chip_info->bel_data[bel.index].y + 1.9; el.z = 0; ret.push_back(el); } } - if (bel_type == TYPE_ICESTORM_RAM) { - GraphicElement el; - el.type = GraphicElement::G_BOX; - el.x1 = chip_info->bel_data[bel.index].x + 0.1; - el.x2 = chip_info->bel_data[bel.index].x + 0.9; - el.y1 = chip_info->bel_data[bel.index].y + 0.1; - el.y2 = chip_info->bel_data[bel.index].y + 1.9; - el.z = 0; - ret.push_back(el); - } - - return ret; -} - -std::vector Arch::getWireGraphics(WireId wire) const -{ - std::vector ret; - // FIXME return ret; } -std::vector Arch::getPipGraphics(PipId pip) const -{ - std::vector ret; - // FIXME - return ret; -}; - // ----------------------------------------------------------------------- bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, delay_t &delay) const diff --git a/ice40/arch.h b/ice40/arch.h index 43aa0829..03685152 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -643,10 +643,12 @@ struct Arch : BaseCtx // ------------------------------------------------- - std::vector getFrameGraphics() const; - std::vector getBelGraphics(BelId bel) const; - std::vector getWireGraphics(WireId wire) const; - std::vector getPipGraphics(PipId pip) const; + std::vector getDecalGraphics(DecalId decal) const; + + DecalXY getFrameDecal() const; + DecalXY getBelDecal(BelId bel) const; + DecalXY getWireDecal(WireId wire) const; + DecalXY getPipDecal(PipId pip) const; bool allGraphicsReload = false; bool frameGraphicsReload = false; diff --git a/ice40/archdefs.h b/ice40/archdefs.h index be2e406d..061e9b44 100644 --- a/ice40/archdefs.h +++ b/ice40/archdefs.h @@ -21,6 +21,8 @@ #error Include "archdefs.h" via "nextpnr.h" only. #endif +#include + NEXTPNR_NAMESPACE_BEGIN typedef int delay_t; @@ -107,6 +109,13 @@ struct PipId bool operator!=(const PipId &other) const { return index != other.index; } }; +struct DecalId +{ + char type = 0; // Bel/Wire/Pip/Frame (b/w/p/f) + uint8_t x = 0, y = 0; + uint32_t z = 0; +}; + NEXTPNR_NAMESPACE_END namespace std { @@ -135,4 +144,17 @@ template <> struct hash : hash template <> struct hash : hash { }; + +template <> struct hash +{ + std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX DecalId &decal) const noexcept { + std::size_t seed = 0; + boost::hash_combine(seed, hash()(decal.type)); + boost::hash_combine(seed, hash()(decal.x)); + boost::hash_combine(seed, hash()(decal.y)); + boost::hash_combine(seed, hash()(decal.z)); + return seed; + } +}; + } // namespace std -- cgit v1.2.3 From 2a01b5e4d326f697636c592b7589080f88d5fa2c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 11 Jul 2018 17:02:13 +0200 Subject: New refreshUi API Signed-off-by: Clifford Wolf --- ice40/arch.h | 6 ------ 1 file changed, 6 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.h b/ice40/arch.h index 03685152..28e913e4 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -650,12 +650,6 @@ struct Arch : BaseCtx DecalXY getWireDecal(WireId wire) const; DecalXY getPipDecal(PipId pip) const; - bool allGraphicsReload = false; - bool frameGraphicsReload = false; - std::unordered_set belGraphicsReload; - std::unordered_set wireGraphicsReload; - std::unordered_set pipGraphicsReload; - // ------------------------------------------------- // Get the delay through a cell from one port to another, returning false -- cgit v1.2.3 From e9b27860daa97eb66c3268be247c28d15d33db1e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 11 Jul 2018 17:40:02 +0200 Subject: Unflip iCE40 tile graphics Signed-off-by: Clifford Wolf --- ice40/gfx.cc | 96 ++++++++++++++++++++++++++++++------------------------------ ice40/gfx.h | 12 ++++---- 2 files changed, 54 insertions(+), 54 deletions(-) (limited to 'ice40') diff --git a/ice40/gfx.cc b/ice40/gfx.cc index e72b2515..2d6b048b 100644 --- a/ice40/gfx.cc +++ b/ice40/gfx.cc @@ -30,7 +30,7 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) GraphicElement el; el.type = GraphicElement::G_LINE; - float y1 = y + 0.03 + 0.0025 * (60 - idx); + float y1 = y + 1.0 - (0.03 + 0.0025 * (60 - idx)); el.x1 = x + 0.0; el.x2 = x + 0.9; @@ -41,7 +41,7 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) el.x1 = x + main_swbox_x1 + 0.0025 * (idx + 35); el.x2 = el.x1; el.y1 = y1; - el.y2 = y + main_swbox_y1; + el.y2 = y + main_swbox_y2; g.push_back(el); } @@ -50,9 +50,9 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) GraphicElement el; el.type = GraphicElement::G_LINE; - float y1 = y + 0.03 + 0.0025 * (60 - idx); - float y2 = y + 0.03 + 0.0025 * (60 - (idx ^ 1)); - float y3 = y + 0.03 + 0.0025 * (60 - (idx ^ 1) - 12); + float y1 = y + 1.0 - (0.03 + 0.0025 * (60 - idx)); + float y2 = y + 1.0 - (0.03 + 0.0025 * (60 - (idx ^ 1))); + float y3 = y + 1.0 - (0.03 + 0.0025 * (60 - (idx ^ 1) - 12)); if (idx >= 12) { el.x1 = x; @@ -83,7 +83,7 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) el.x1 = x + main_swbox_x1 + 0.0025 * ((idx ^ 1) + 35); el.x2 = el.x1; el.y1 = y2; - el.y2 = y + main_swbox_y1; + el.y2 = y + main_swbox_y2; g.push_back(el); } @@ -96,13 +96,13 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) float x1 = x + 0.03 + 0.0025 * (60 - idx); - el.y1 = y + 0.0; - el.y2 = y + 0.9; + el.y1 = y + 1.0; + el.y2 = y + 0.1; el.x1 = x1; el.x2 = x1; g.push_back(el); - el.y1 = y + 0.03 + 0.0025 * (270 - idx); + el.y1 = y + 1.0 - (0.03 + 0.0025 * (270 - idx)); el.y2 = el.y1; el.x1 = x1; el.x2 = x + main_swbox_x1; @@ -119,38 +119,38 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) float x3 = x + 0.03 + 0.0025 * (60 - idx - 12); if (idx >= 12) { - el.y1 = y; - el.y2 = y + 0.01; + el.y1 = y + 1.00; + el.y2 = y + 0.99; el.x1 = x1; el.x2 = x1; g.push_back(el); - el.y1 = y + 0.01; - el.y2 = y + 0.02; + el.y1 = y + 0.99; + el.y2 = y + 0.98; el.x1 = x1; el.x2 = x2; g.push_back(el); } - el.y1 = y + 0.02; - el.y2 = y + 0.9; + el.y1 = y + 0.98; + el.y2 = y + 0.10; el.x1 = x2; el.x2 = x2; g.push_back(el); - el.y1 = y + 0.9; - el.y2 = y + 1.0; + el.y1 = y + 0.10; + el.y2 = y; el.x1 = x2; el.x2 = x3; g.push_back(el); - el.y1 = y + 0.03 + 0.0025 * (145 - idx); + el.y1 = y + 1.0 - (0.03 + 0.0025 * (145 - idx)); el.y2 = el.y1; el.x1 = x; el.x2 = x2; g.push_back(el); - el.y1 = y + 0.03 + 0.0025 * (270 - idx); + el.y1 = y + 1.0 - (0.03 + 0.0025 * (270 - idx)); el.y2 = el.y1; el.x1 = x2; el.x2 = x + main_swbox_x1; @@ -164,7 +164,7 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) GraphicElement el; el.type = GraphicElement::G_LINE; - float y1 = y + 0.03 + 0.0025 * (90 - idx); + float y1 = y + 1.0 - (0.03 + 0.0025 * (90 - idx)); el.x1 = x + 0.0; el.x2 = x + 0.98333; @@ -175,7 +175,7 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) el.x1 = x + main_swbox_x1 + 0.0025 * (idx + 5); el.x2 = el.x1; el.y1 = y1; - el.y2 = y + main_swbox_y1; + el.y2 = y + main_swbox_y2; g.push_back(el); } @@ -184,9 +184,9 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) GraphicElement el; el.type = GraphicElement::G_LINE; - float y1 = y + 0.03 + 0.0025 * (90 - (idx ^ 1)); - float y2 = y + 0.03 + 0.0025 * (90 - idx); - float y3 = y + 0.03 + 0.0025 * (90 - idx - 2); + float y1 = y + 1.0 - (0.03 + 0.0025 * (90 - (idx ^ 1))); + float y2 = y + 1.0 - (0.03 + 0.0025 * (90 - idx)); + float y3 = y + 1.0 - (0.03 + 0.0025 * (90 - idx - 2)); if (idx >= 2) { el.x1 = x; @@ -217,7 +217,7 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) el.x1 = x + main_swbox_x1 + 0.0025 * (idx + 5); el.x2 = el.x1; el.y1 = y2; - el.y2 = y + main_swbox_y1; + el.y2 = y + main_swbox_y2; g.push_back(el); } @@ -228,7 +228,7 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) GraphicElement el; el.type = GraphicElement::G_LINE; - float y1 = y + 0.03 + 0.0025 * (145 - idx); + float y1 = y + 1.0 - (0.03 + 0.0025 * (145 - idx)); el.y1 = y1; el.y2 = y1; @@ -246,13 +246,13 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) float x1 = x + 0.03 + 0.0025 * (90 - idx); - el.y1 = y + 0.0; - el.y2 = y + 0.98333; + el.y1 = y + 1.00; + el.y2 = y + 0.01667; el.x1 = x1; el.x2 = x1; g.push_back(el); - el.y1 = y + 0.03 + 0.0025 * (300 - idx); + el.y1 = y + 1.0 - (0.03 + 0.0025 * (300 - idx)); el.y2 = el.y1; el.x1 = x1; el.x2 = x + main_swbox_x1; @@ -269,32 +269,32 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) float x3 = x + 0.03 + 0.0025 * (90 - (idx ^ 1) - 2); if (idx >= 2) { - el.y1 = y; - el.y2 = y + 0.01; + el.y1 = y + 1.00; + el.y2 = y + 0.99; el.x1 = x1; el.x2 = x1; g.push_back(el); - el.y1 = y + 0.01; - el.y2 = y + 0.02; + el.y1 = y + 0.99; + el.y2 = y + 0.98; el.x1 = x1; el.x2 = x2; g.push_back(el); } - el.y1 = y + 0.02; - el.y2 = y + 0.98333; + el.y1 = y + 0.98; + el.y2 = y + 0.01667; el.x1 = x2; el.x2 = x2; g.push_back(el); - el.y1 = y + 0.98333; - el.y2 = y + 1.0; + el.y1 = y + 0.01667; + el.y2 = y; el.x1 = x2; el.x2 = x3; g.push_back(el); - el.y1 = y + 0.03 + 0.0025 * (300 - (idx ^ 1)); + el.y1 = y + 1.0 - (0.03 + 0.0025 * (300 - (idx ^ 1))); el.y2 = el.y1; el.x1 = x2; el.x2 = x + main_swbox_x1; @@ -309,8 +309,8 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) el.type = GraphicElement::G_LINE; el.x1 = x + main_swbox_x1 + 0.005 * (idx + 5); el.x2 = el.x1; - el.y1 = y + main_swbox_y2; - el.y2 = el.y1 + 0.02; + el.y1 = y + main_swbox_y1; + el.y2 = el.y1 - 0.02; g.push_back(el); } @@ -322,7 +322,7 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) el.type = GraphicElement::G_LINE; el.x1 = x + main_swbox_x1 - 0.05; el.x2 = x + main_swbox_x1; - el.y1 = y + main_swbox_y2 - 0.005 * (13 - idx); + el.y1 = y + main_swbox_y1 + 0.005 * (13 - idx); el.y2 = el.y1; g.push_back(el); } @@ -333,7 +333,7 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) int idx = id - TILE_WIRE_NEIGH_OP_BNL_0; GraphicElement el; el.type = GraphicElement::G_LINE; - el.y1 = y + main_swbox_y1 + 0.0025 * (idx + 10) + 0.01 * (idx / 8); + el.y1 = y + main_swbox_y2 - (0.0025 * (idx + 10) + 0.01 * (idx / 8)); el.y2 = el.y1; el.x1 = x + main_swbox_x1 - 0.05; el.x2 = x + main_swbox_x1; @@ -364,7 +364,7 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) el.type = GraphicElement::G_LINE; el.x1 = x + local_swbox_x2; el.x2 = x + logic_cell_x1; - el.y1 = y + 0.4675 + (0.005 * input) + z * logic_cell_pitch; + el.y1 = y + (logic_cell_y1 + logic_cell_y2) / 2 - 0.0125 + (0.005 * input) + z * logic_cell_pitch; el.y2 = el.y1; g.push_back(el); } @@ -374,14 +374,14 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) if (id >= TILE_WIRE_LUTFF_0_OUT && id <= TILE_WIRE_LUTFF_7_OUT) { int idx = id - TILE_WIRE_LUTFF_0_OUT; - float y1 = y + 0.03 + 0.0025 * (159 - idx); + float y1 = y + 1.0 - (0.03 + 0.0025 * (152 + idx)); GraphicElement el; el.type = GraphicElement::G_LINE; el.y1 = y1; el.y2 = y1; el.x1 = x + main_swbox_x2; - el.x2 = x + 0.97 + 0.0025 * idx; + el.x2 = x + 0.97 + 0.0025 * (7-idx); g.push_back(el); el.y1 = y1; @@ -403,15 +403,15 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) el.x1 = x + main_swbox_x2 - 0.005 * (idx + 5); el.x2 = el.x1; - el.y1 = y + main_swbox_y2; - el.y2 = el.y1 + 0.005 * (idx + 3); + el.y1 = y + main_swbox_y1; + el.y2 = el.y1 - 0.005 * (idx + 3); g.push_back(el); el.y1 = el.y2; el.x2 = x + logic_cell_x2 - 0.005 * (2 - idx + 5); g.push_back(el); - el.y2 = y + logic_cell_y2 + 7*logic_cell_pitch; + el.y2 = y + logic_cell_y1; el.x1 = el.x2; g.push_back(el); } diff --git a/ice40/gfx.h b/ice40/gfx.h index 9fce27e8..b0009b59 100644 --- a/ice40/gfx.h +++ b/ice40/gfx.h @@ -26,18 +26,18 @@ NEXTPNR_NAMESPACE_BEGIN const float main_swbox_x1 = 0.35; const float main_swbox_x2 = 0.60; -const float main_swbox_y1 = 0.27; -const float main_swbox_y2 = 0.95; +const float main_swbox_y1 = 0.05; +const float main_swbox_y2 = 0.73; const float local_swbox_x1 = 0.63; const float local_swbox_x2 = 0.73; -const float local_swbox_y1 = 0.45; -const float local_swbox_y2 = 0.9375; +const float local_swbox_y1 = 0.05; +const float local_swbox_y2 = 0.55; const float logic_cell_x1 = 0.76; const float logic_cell_x2 = 0.95; -const float logic_cell_y1 = 0.45; -const float logic_cell_y2 = 0.50; +const float logic_cell_y1 = 0.05; +const float logic_cell_y2 = 0.10; const float logic_cell_pitch = 0.0625; enum GfxTileWireId { -- cgit v1.2.3 From 7df67c91b38433e8a1002f8e9f53926aafaa4d1b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 11 Jul 2018 18:04:09 +0200 Subject: Add ctx->route() API Signed-off-by: Clifford Wolf --- ice40/arch.cc | 8 ++++++++ ice40/arch.h | 4 ++++ ice40/main.cc | 5 ++--- 3 files changed, 14 insertions(+), 3 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.cc b/ice40/arch.cc index a25c3d87..0bb27d38 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -21,6 +21,7 @@ #include #include "log.h" #include "nextpnr.h" +#include "router1.h" #include "util.h" #include "gfx.h" @@ -400,6 +401,13 @@ delay_t Arch::estimateDelay(WireId src, WireId dst) const // ----------------------------------------------------------------------- +bool Arch::route() +{ + return router1(getCtx()); +} + +// ----------------------------------------------------------------------- + DecalXY Arch::getFrameDecal() const { DecalXY decalxy; diff --git a/ice40/arch.h b/ice40/arch.h index 28e913e4..02c37fae 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -643,6 +643,10 @@ struct Arch : BaseCtx // ------------------------------------------------- + bool route(); + + // ------------------------------------------------- + std::vector getDecalGraphics(DecalId decal) const; DecalXY getFrameDecal() const; diff --git a/ice40/main.cc b/ice40/main.cc index ff823cbe..f586a079 100644 --- a/ice40/main.cc +++ b/ice40/main.cc @@ -43,7 +43,6 @@ #include "pcf.h" #include "place_legaliser.h" #include "place_sa.h" -#include "route.h" #include "timing.h" #include "version.h" @@ -339,7 +338,7 @@ int main(int argc, char *argv[]) for (int i = 0; i < int(src_wires.size()) && i < int(dst_wires.size()); i++) { delay_t actual_delay; WireId src = src_wires[i], dst = dst_wires[i]; - if (!get_actual_route_delay(&ctx, src, dst, actual_delay)) + if (!ctx.getActualRouteDelay(src, dst, actual_delay)) continue; printf("%s %s %.3f %.3f %d %d %d %d %d %d\n", ctx.getWireName(src).c_str(&ctx), ctx.getWireName(dst).c_str(&ctx), ctx.getDelayNS(actual_delay), @@ -376,7 +375,7 @@ int main(int argc, char *argv[]) if (!place_design_sa(&ctx) && !ctx.force) log_error("Placing design failed.\n"); ctx.check(); - if (!route_design(&ctx) && !ctx.force) + if (!ctx.route() && !ctx.force) log_error("Routing design failed.\n"); } } -- cgit v1.2.3 From 7daa8524c8ab8c9ff5400d5074b80573b0d39a14 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 11 Jul 2018 18:15:08 +0200 Subject: Add ctx->place() API Signed-off-by: Clifford Wolf --- ice40/arch.cc | 6 ++++++ ice40/arch.h | 1 + ice40/main.cc | 3 +-- 3 files changed, 8 insertions(+), 2 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.cc b/ice40/arch.cc index 0bb27d38..1e6b4569 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -21,6 +21,7 @@ #include #include "log.h" #include "nextpnr.h" +#include "placer1.h" #include "router1.h" #include "util.h" #include "gfx.h" @@ -401,6 +402,11 @@ delay_t Arch::estimateDelay(WireId src, WireId dst) const // ----------------------------------------------------------------------- +bool Arch::place() +{ + return placer1(getCtx()); +} + bool Arch::route() { return router1(getCtx()); diff --git a/ice40/arch.h b/ice40/arch.h index 02c37fae..659139a6 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -643,6 +643,7 @@ struct Arch : BaseCtx // ------------------------------------------------- + bool place(); bool route(); // ------------------------------------------------- diff --git a/ice40/main.cc b/ice40/main.cc index f586a079..2427ea6c 100644 --- a/ice40/main.cc +++ b/ice40/main.cc @@ -42,7 +42,6 @@ #include "pack.h" #include "pcf.h" #include "place_legaliser.h" -#include "place_sa.h" #include "timing.h" #include "version.h" @@ -372,7 +371,7 @@ int main(int argc, char *argv[]) if (vm.count("no-tmdriv")) ctx.timing_driven = false; if (!vm.count("pack-only")) { - if (!place_design_sa(&ctx) && !ctx.force) + if (!ctx.place() && !ctx.force) log_error("Placing design failed.\n"); ctx.check(); if (!ctx.route() && !ctx.force) -- cgit v1.2.3 From 6ffae27aa14ee48ebd5713e540bfc53568e56fd6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 11 Jul 2018 18:36:15 +0200 Subject: Deterministic chipdb blobs Signed-off-by: Clifford Wolf --- ice40/chipdb.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ice40') diff --git a/ice40/chipdb.py b/ice40/chipdb.py index 931c73d1..2a918ed9 100644 --- a/ice40/chipdb.py +++ b/ice40/chipdb.py @@ -712,7 +712,7 @@ class BinaryBlobAssembler: def finalize(self): assert not self.finalized - for s, index in self.strings.items(): + for s, index in sorted(self.strings.items()): self.l("str%d" % index, "char") for c in s: self.data.append(ord(c)) @@ -947,7 +947,7 @@ for wire in range(num_wires): if wire in wire_downhill_belports: num_bels_downhill = len(wire_downhill_belports[wire]) bba.l("wire%d_downbels" % wire, "BelPortPOD") - for belport in wire_downhill_belports[wire]: + for belport in sorted(wire_downhill_belports[wire]): bba.u32(belport[0], "bel_index") bba.u32(portpins[belport[1]], "port") else: -- cgit v1.2.3 From 33e592e55e30e097db08218d4dc0888c6058f5f2 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 11 Jul 2018 19:02:30 +0200 Subject: Add missing wires to ice40 gfx Signed-off-by: Clifford Wolf --- ice40/gfx.cc | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-) (limited to 'ice40') diff --git a/ice40/gfx.cc b/ice40/gfx.cc index 2d6b048b..64bb66ec 100644 --- a/ice40/gfx.cc +++ b/ice40/gfx.cc @@ -364,7 +364,7 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) el.type = GraphicElement::G_LINE; el.x1 = x + local_swbox_x2; el.x2 = x + logic_cell_x1; - el.y1 = y + (logic_cell_y1 + logic_cell_y2) / 2 - 0.0125 + (0.005 * input) + z * logic_cell_pitch; + el.y1 = y + (logic_cell_y1 + logic_cell_y2) / 2 - 0.0075 + (0.005 * input) + z * logic_cell_pitch; el.y2 = el.y1; g.push_back(el); } @@ -404,7 +404,7 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) el.x1 = x + main_swbox_x2 - 0.005 * (idx + 5); el.x2 = el.x1; el.y1 = y + main_swbox_y1; - el.y2 = el.y1 - 0.005 * (idx + 3); + el.y2 = el.y1 - 0.005 * (idx + 2); g.push_back(el); el.y1 = el.y2; @@ -414,6 +414,58 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) el.y2 = y + logic_cell_y1; el.x1 = el.x2; g.push_back(el); + + for (int i = 0; i < 7; i ++) { + el.y1 = y + logic_cell_y2 + i * logic_cell_pitch; + el.y2 = y + logic_cell_y1 + (i + 1) * logic_cell_pitch; + g.push_back(el); + } + } + + // LC Cascade + + if (id >= TILE_WIRE_LUTFF_0_LOUT && id <= TILE_WIRE_LUTFF_6_LOUT) { + int idx = id - TILE_WIRE_LUTFF_0_LOUT; + GraphicElement el; + el.type = GraphicElement::G_LINE; + el.x1 = x + logic_cell_x1 + 0.005 * 5; + el.x2 = el.x1; + el.y1 = y + logic_cell_y2 + idx * logic_cell_pitch; + el.y2 = y + logic_cell_y1 + (idx + 1) * logic_cell_pitch; + g.push_back(el); + } + + // Carry Chain + + if (id >= TILE_WIRE_LUTFF_0_COUT && id <= TILE_WIRE_LUTFF_7_COUT) { + int idx = id - TILE_WIRE_LUTFF_0_COUT; + GraphicElement el; + el.type = GraphicElement::G_LINE; + el.x1 = x + logic_cell_x1 + 0.005 * 3; + el.x2 = el.x1; + el.y1 = y + logic_cell_y2 + idx * logic_cell_pitch; + el.y2 = y + (idx < 7 ? logic_cell_y1 + (idx + 1) * logic_cell_pitch : 1.0); + g.push_back(el); + } + + if (id == TILE_WIRE_CARRY_IN) { + GraphicElement el; + el.type = GraphicElement::G_LINE; + el.x1 = x + logic_cell_x1 + 0.005 * 3; + el.x2 = el.x1; + el.y1 = y; + el.y2 = y + 0.01; + g.push_back(el); + } + + if (id == TILE_WIRE_CARRY_IN_MUX) { + GraphicElement el; + el.type = GraphicElement::G_LINE; + el.x1 = x + logic_cell_x1 + 0.005 * 3; + el.x2 = el.x1; + el.y1 = y + 0.02; + el.y2 = y + logic_cell_y1; + g.push_back(el); } } -- cgit v1.2.3 From a436035424368b3d424822c7b72f99044c93dafd Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 12 Jul 2018 17:22:29 +0200 Subject: Add Groups API Signed-off-by: Clifford Wolf --- ice40/arch.cc | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++------ ice40/arch.h | 11 ++++++++++ ice40/archdefs.h | 52 +++++++++++++++++++++++++++++++++++++++------ 3 files changed, 115 insertions(+), 12 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.cc b/ice40/arch.cc index 1e6b4569..26c3b003 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -369,6 +369,52 @@ std::string Arch::getBelPackagePin(BelId bel) const } return ""; } + +// ----------------------------------------------------------------------- + +GroupId Arch::getGroupByName(IdString name) const +{ + for (auto g : getGroups()) + if (getGroupName(g) == name) + return g; + return GroupId(); +} + +IdString Arch::getGroupName(GroupId group) const +{ + return IdString(); +} + +std::vector Arch::getGroups() const +{ + std::vector ret; + return ret; +} + +std::vector Arch::getGroupBels(GroupId group) const +{ + std::vector ret; + return ret; +} + +std::vector Arch::getGroupWires(GroupId group) const +{ + std::vector ret; + return ret; +} + +std::vector Arch::getGroupPips(GroupId group) const +{ + std::vector ret; + return ret; +} + +std::vector Arch::getGroupGroups(GroupId group) const +{ + std::vector ret; + return ret; +} + // ----------------------------------------------------------------------- void Arch::estimatePosition(BelId bel, int &x, int &y, bool &gb) const @@ -417,15 +463,15 @@ bool Arch::route() DecalXY Arch::getFrameDecal() const { DecalXY decalxy; - decalxy.decal.type = 'f'; + decalxy.decal.type = DecalId::TYPE_FRAME; return decalxy; } DecalXY Arch::getBelDecal(BelId bel) const { DecalXY decalxy; - decalxy.decal.type = 'b'; - decalxy.decal.z = bel.index; + decalxy.decal.type = DecalId::TYPE_BEL; + decalxy.decal.index = bel.index; return decalxy; } @@ -441,11 +487,17 @@ DecalXY Arch::getPipDecal(PipId pip) const return decalxy; }; +DecalXY Arch::getGroupDecal(GroupId group) const +{ + DecalXY decalxy; + return decalxy; +}; + std::vector Arch::getDecalGraphics(DecalId decal) const { std::vector ret; - if (decal.type == 'f') + if (decal.type == DecalId::TYPE_FRAME) { for (int x = 0; x <= chip_info->width; x++) for (int y = 0; y <= chip_info->height; y++) { @@ -458,10 +510,10 @@ std::vector Arch::getDecalGraphics(DecalId decal) const } } - if (decal.type == 'b') + if (decal.type == DecalId::TYPE_BEL) { BelId bel; - bel.index = decal.z; + bel.index = decal.index; auto bel_type = getBelType(bel); diff --git a/ice40/arch.h b/ice40/arch.h index 659139a6..96d0d209 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -634,6 +634,16 @@ struct Arch : BaseCtx // ------------------------------------------------- + GroupId getGroupByName(IdString name) const; + IdString getGroupName(GroupId group) const; + std::vector getGroups() const; + std::vector getGroupBels(GroupId group) const; + std::vector getGroupWires(GroupId group) const; + std::vector getGroupPips(GroupId group) const; + std::vector getGroupGroups(GroupId group) const; + + // ------------------------------------------------- + void estimatePosition(BelId bel, int &x, int &y, bool &gb) const; delay_t estimateDelay(WireId src, WireId dst) const; delay_t getDelayEpsilon() const { return 20; } @@ -654,6 +664,7 @@ struct Arch : BaseCtx DecalXY getBelDecal(BelId bel) const; DecalXY getWireDecal(WireId wire) const; DecalXY getPipDecal(PipId pip) const; + DecalXY getGroupDecal(GroupId group) const; // ------------------------------------------------- diff --git a/ice40/archdefs.h b/ice40/archdefs.h index 061e9b44..62c248c7 100644 --- a/ice40/archdefs.h +++ b/ice40/archdefs.h @@ -109,11 +109,42 @@ struct PipId bool operator!=(const PipId &other) const { return index != other.index; } }; +struct GroupId +{ + enum : int8_t { + TYPE_NONE, + TYPE_FRAME, + TYPE_MAIN_SW, + TYPE_LOCAL_SW, + TYPE_LC0_SW, + TYPE_LC1_SW, + TYPE_LC2_SW, + TYPE_LC3_SW, + TYPE_LC4_SW, + TYPE_LC5_SW, + TYPE_LC6_SW, + TYPE_LC7_SW + } type = TYPE_NONE; + int8_t x = 0, y = 0; + + bool operator==(const GroupId &other) const { return (type == other.type) && (x == other.x) && (y == other.y); } + bool operator!=(const GroupId &other) const { return (type != other.type) || (x != other.x) || (y == other.y); } +}; + struct DecalId { - char type = 0; // Bel/Wire/Pip/Frame (b/w/p/f) - uint8_t x = 0, y = 0; - uint32_t z = 0; + enum : int8_t { + TYPE_NONE, + TYPE_FRAME, + TYPE_BEL, + TYPE_WIRE, + TYPE_PIP, + TYPE_GROUP + } type = TYPE_NONE; + int32_t index = -1; + + bool operator==(const DecalId &other) const { return (type == other.type) && (index == other.index); } + bool operator!=(const DecalId &other) const { return (type != other.type) || (index != other.index); } }; NEXTPNR_NAMESPACE_END @@ -145,14 +176,23 @@ template <> struct hash : hash { }; +template <> struct hash +{ + std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX GroupId &group) const noexcept { + std::size_t seed = 0; + boost::hash_combine(seed, hash()(group.type)); + boost::hash_combine(seed, hash()(group.x)); + boost::hash_combine(seed, hash()(group.y)); + return seed; + } +}; + template <> struct hash { std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX DecalId &decal) const noexcept { std::size_t seed = 0; boost::hash_combine(seed, hash()(decal.type)); - boost::hash_combine(seed, hash()(decal.x)); - boost::hash_combine(seed, hash()(decal.y)); - boost::hash_combine(seed, hash()(decal.z)); + boost::hash_combine(seed, hash()(decal.index)); return seed; } }; -- cgit v1.2.3 From 4f87ea0eb6ae8a4f8fbf9890c8101cd530d4c5da Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 12 Jul 2018 21:05:09 +0200 Subject: Improve iCE40 wire database and gfx Signed-off-by: Clifford Wolf --- ice40/arch.cc | 24 ++++++++++++++++++++---- ice40/arch.h | 8 ++++++++ ice40/chipdb.py | 35 ++++++++++++++++++++++++++++++++++- ice40/family.cmake | 6 ++++-- ice40/gfx.cc | 47 +++++------------------------------------------ ice40/gfx.h | 2 +- 6 files changed, 72 insertions(+), 50 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.cc b/ice40/arch.cc index 26c3b003..8650aeff 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -478,6 +478,8 @@ DecalXY Arch::getBelDecal(BelId bel) const DecalXY Arch::getWireDecal(WireId wire) const { DecalXY decalxy; + decalxy.decal.type = DecalId::TYPE_WIRE; + decalxy.decal.index = wire.index; return decalxy; } @@ -510,6 +512,21 @@ std::vector Arch::getDecalGraphics(DecalId decal) const } } + if (decal.type == DecalId::TYPE_WIRE) + { + WireId wire; + wire.index = decal.index; + + int n = chip_info->wire_data[wire.index].num_segments; + const WireSegmentPOD *p = chip_info->wire_data[wire.index].segments.get(); + + GraphicElement::style_t style = wire_to_net.at(wire.index) != IdString() ? + GraphicElement::G_ACTIVE : GraphicElement::G_INACTIVE; + + for (int i = 0; i < n; i++) + gfxTileWire(ret, p[i].x, p[i].y, GfxTileWireId(p[i].index), style); + } + if (decal.type == DecalId::TYPE_BEL) { BelId bel; @@ -520,6 +537,7 @@ std::vector Arch::getDecalGraphics(DecalId decal) const if (bel_type == TYPE_ICESTORM_LC) { GraphicElement el; el.type = GraphicElement::G_BOX; + el.style = bel_to_cell.at(bel.index) != IdString() ? GraphicElement::G_ACTIVE : GraphicElement::G_INACTIVE; el.x1 = chip_info->bel_data[bel.index].x + logic_cell_x1; el.x2 = chip_info->bel_data[bel.index].x + logic_cell_x2; el.y1 = chip_info->bel_data[bel.index].y + logic_cell_y1 + (chip_info->bel_data[bel.index].z) * logic_cell_pitch; @@ -534,6 +552,7 @@ std::vector Arch::getDecalGraphics(DecalId decal) const // Main switchbox GraphicElement main_sw; main_sw.type = GraphicElement::G_BOX; + main_sw.style = GraphicElement::G_FRAME; main_sw.x1 = tx + main_swbox_x1; main_sw.x2 = tx + main_swbox_x2; main_sw.y1 = ty + main_swbox_y1; @@ -543,16 +562,13 @@ std::vector Arch::getDecalGraphics(DecalId decal) const // Local tracks to LUT input switchbox GraphicElement local_sw; local_sw.type = GraphicElement::G_BOX; + local_sw.style = GraphicElement::G_FRAME; local_sw.x1 = tx + local_swbox_x1; local_sw.x2 = tx + local_swbox_x2; local_sw.y1 = ty + local_swbox_y1; local_sw.y2 = ty + local_swbox_y2; local_sw.z = 0; ret.push_back(local_sw); - - // All the wires - for (int i = TILE_WIRE_GLB2LOCAL_0; i <= TILE_WIRE_SP12_H_L_23; i++) - gfxTileWire(ret, tx, ty, GfxTileWireId(i)); } } diff --git a/ice40/arch.h b/ice40/arch.h index 96d0d209..04de5178 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -70,6 +70,11 @@ NPNR_PACKED_STRUCT(struct PipInfoPOD { int32_t switch_index; }); +NPNR_PACKED_STRUCT(struct WireSegmentPOD { + int8_t x, y; + int16_t index; +}); + NPNR_PACKED_STRUCT(struct WireInfoPOD { RelPtr name; int32_t num_uphill, num_downhill; @@ -79,6 +84,9 @@ NPNR_PACKED_STRUCT(struct WireInfoPOD { BelPortPOD bel_uphill; RelPtr bels_downhill; + int32_t num_segments; + RelPtr segments; + int8_t x, y; WireType type; int8_t padding_0; diff --git a/ice40/chipdb.py b/ice40/chipdb.py index 2a918ed9..00194deb 100644 --- a/ice40/chipdb.py +++ b/ice40/chipdb.py @@ -11,6 +11,7 @@ group.add_argument("-b", "--binary", action="store_true") group.add_argument("-c", "--c_file", action="store_true") parser.add_argument("filename", type=str, help="chipdb input filename") parser.add_argument("-p", "--portspins", type=str, help="path to portpins.inc") +parser.add_argument("-g", "--gfxh", type=str, help="path to gfx.h") args = parser.parse_args() endianness = "le" @@ -54,6 +55,9 @@ beltypes = dict() tiletypes = dict() wiretypes = dict() +gfx_wire_ids = dict() +wire_segments = dict() + with open(args.portspins) as f: for line in f: line = line.replace("(", " ") @@ -66,6 +70,18 @@ with open(args.portspins) as f: idx = len(portpins) + 1 portpins[line[1]] = idx +with open(args.gfxh) as f: + state = 0 + for line in f: + if state == 0 and line.startswith("enum GfxTileWireId "): + state = 1 + elif state == 1 and line.startswith("};"): + state = 0 + elif state == 1: + idx = len(gfx_wire_ids) + name = line.strip().rstrip(",") + gfx_wire_ids[name] = idx + beltypes["ICESTORM_LC"] = 1 beltypes["ICESTORM_RAM"] = 2 beltypes["SB_IO"] = 3 @@ -371,6 +387,10 @@ with open(args.filename, "r") as f: if mode[1] not in wire_xy: wire_xy[mode[1]] = list() wire_xy[mode[1]].append((int(line[0]), int(line[1]))) + if mode[1] not in wire_segments: + wire_segments[mode[1]] = set() + if ("TILE_WIRE_" + wname[2].upper()) in gfx_wire_ids: + wire_segments[mode[1]].add((wname[0], wname[1], gfx_wire_ids["TILE_WIRE_" + wname[2].upper()])) continue if mode[0] in ("buffer", "routing"): @@ -1040,7 +1060,7 @@ for t in range(num_tile_types): tileinfo.append(ti) bba.l("wire_data_%s" % dev_name, "WireInfoPOD") -for info in wireinfo: +for wire, info in enumerate(wireinfo): bba.s(info["name"], "name") bba.u32(info["num_uphill"], "num_uphill") bba.u32(info["num_downhill"], "num_downhill") @@ -1050,11 +1070,24 @@ for info in wireinfo: bba.u32(info["uphill_bel"], "bel_uphill.bel_index") bba.u32(info["uphill_pin"], "bel_uphill.port") bba.r(info["list_bels_downhill"], "bels_downhill") + bba.u32(len(wire_segments[wire]), "num_segments") + if len(wire_segments[wire]): + bba.r("wire_segments_%d" % wire, "segments") + else: + bba.u32(0, "segments") bba.u8(info["x"], "x") bba.u8(info["y"], "y") bba.u8(wiretypes[wire_type(info["name"])], "type") bba.u8(0, "padding") +for wire in range(num_wires): + if len(wire_segments[wire]): + bba.l("wire_segments_%d" % wire, "WireSegmentPOD") + for seg in sorted(wire_segments[wire]): + bba.u8(seg[0], "x") + bba.u8(seg[1], "y") + bba.u16(seg[2], "index") + bba.l("pip_data_%s" % dev_name, "PipInfoPOD") for info in pipinfo: bba.u32(info["src"], "src") diff --git a/ice40/family.cmake b/ice40/family.cmake index e6cefecb..9af06f82 100644 --- a/ice40/family.cmake +++ b/ice40/family.cmake @@ -21,8 +21,9 @@ if (MSVC) set(DEV_TXT_DB ${ICEBOX_ROOT}/chipdb-${dev}.txt) set(DEV_CC_DB ${CMAKE_CURRENT_SOURCE_DIR}/ice40/chipdbs/chipdb-${dev}.bin) set(DEV_PORTS_INC ${CMAKE_CURRENT_SOURCE_DIR}/ice40/portpins.inc) + set(DEV_GFXH ${CMAKE_CURRENT_SOURCE_DIR}/ice40/gfx.h) add_custom_command(OUTPUT ${DEV_CC_DB} - COMMAND ${PYTHON_EXECUTABLE} ${DB_PY} -b -p ${DEV_PORTS_INC} ${DEV_TXT_DB} > ${DEV_CC_DB} + COMMAND ${PYTHON_EXECUTABLE} ${DB_PY} -b -p ${DEV_PORTS_INC} -g ${DEV_GFXH} ${DEV_TXT_DB} > ${DEV_CC_DB} DEPENDS ${DEV_TXT_DB} ${DB_PY} ) target_sources(ice40_chipdb PRIVATE ${DEV_CC_DB}) @@ -37,8 +38,9 @@ else() set(DEV_TXT_DB ${ICEBOX_ROOT}/chipdb-${dev}.txt) set(DEV_CC_DB ${CMAKE_CURRENT_SOURCE_DIR}/ice40/chipdbs/chipdb-${dev}.cc) set(DEV_PORTS_INC ${CMAKE_CURRENT_SOURCE_DIR}/ice40/portpins.inc) + set(DEV_GFXH ${CMAKE_CURRENT_SOURCE_DIR}/ice40/gfx.h) add_custom_command(OUTPUT ${DEV_CC_DB} - COMMAND ${PYTHON_EXECUTABLE} ${DB_PY} -c -p ${DEV_PORTS_INC} ${DEV_TXT_DB} > ${DEV_CC_DB}.new + COMMAND ${PYTHON_EXECUTABLE} ${DB_PY} -c -p ${DEV_PORTS_INC} -g ${DEV_GFXH} ${DEV_TXT_DB} > ${DEV_CC_DB}.new COMMAND mv ${DEV_CC_DB}.new ${DEV_CC_DB} DEPENDS ${DEV_TXT_DB} ${DB_PY} ) diff --git a/ice40/gfx.cc b/ice40/gfx.cc index 64bb66ec..d6935b7d 100644 --- a/ice40/gfx.cc +++ b/ice40/gfx.cc @@ -21,15 +21,16 @@ NEXTPNR_NAMESPACE_BEGIN -void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) +void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id, GraphicElement::style_t style) { + GraphicElement el; + el.type = GraphicElement::G_LINE; + el.style = style; + // Horizontal Span-4 Wires if (id >= TILE_WIRE_SP4_H_L_36 && id <= TILE_WIRE_SP4_H_L_47) { int idx = (id - TILE_WIRE_SP4_H_L_36) + 48; - GraphicElement el; - el.type = GraphicElement::G_LINE; - float y1 = y + 1.0 - (0.03 + 0.0025 * (60 - idx)); el.x1 = x + 0.0; @@ -47,8 +48,6 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) if (id >= TILE_WIRE_SP4_H_R_0 && id <= TILE_WIRE_SP4_H_R_47) { int idx = id - TILE_WIRE_SP4_H_R_0; - GraphicElement el; - el.type = GraphicElement::G_LINE; float y1 = y + 1.0 - (0.03 + 0.0025 * (60 - idx)); float y2 = y + 1.0 - (0.03 + 0.0025 * (60 - (idx ^ 1))); @@ -91,8 +90,6 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) if (id >= TILE_WIRE_SP4_V_T_36 && id <= TILE_WIRE_SP4_V_T_47) { int idx = (id - TILE_WIRE_SP4_V_T_36) + 48; - GraphicElement el; - el.type = GraphicElement::G_LINE; float x1 = x + 0.03 + 0.0025 * (60 - idx); @@ -111,8 +108,6 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) if (id >= TILE_WIRE_SP4_V_B_0 && id <= TILE_WIRE_SP4_V_B_47) { int idx = id - TILE_WIRE_SP4_V_B_0; - GraphicElement el; - el.type = GraphicElement::G_LINE; float x1 = x + 0.03 + 0.0025 * (60 - (idx ^ 1)); float x2 = x + 0.03 + 0.0025 * (60 - idx); @@ -161,8 +156,6 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) if (id >= TILE_WIRE_SP12_H_L_22 && id <= TILE_WIRE_SP12_H_L_23) { int idx = (id - TILE_WIRE_SP12_H_L_22) + 24; - GraphicElement el; - el.type = GraphicElement::G_LINE; float y1 = y + 1.0 - (0.03 + 0.0025 * (90 - idx)); @@ -181,8 +174,6 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) if (id >= TILE_WIRE_SP12_H_R_0 && id <= TILE_WIRE_SP12_H_R_23) { int idx = id - TILE_WIRE_SP12_H_R_0; - GraphicElement el; - el.type = GraphicElement::G_LINE; float y1 = y + 1.0 - (0.03 + 0.0025 * (90 - (idx ^ 1))); float y2 = y + 1.0 - (0.03 + 0.0025 * (90 - idx)); @@ -225,8 +216,6 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) if (id >= TILE_WIRE_SP4_R_V_B_0 && id <= TILE_WIRE_SP4_R_V_B_47) { int idx = id - TILE_WIRE_SP4_R_V_B_0; - GraphicElement el; - el.type = GraphicElement::G_LINE; float y1 = y + 1.0 - (0.03 + 0.0025 * (145 - idx)); @@ -241,8 +230,6 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) if (id >= TILE_WIRE_SP12_V_T_22 && id <= TILE_WIRE_SP12_V_T_23) { int idx = (id - TILE_WIRE_SP12_V_T_22) + 24; - GraphicElement el; - el.type = GraphicElement::G_LINE; float x1 = x + 0.03 + 0.0025 * (90 - idx); @@ -261,8 +248,6 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) if (id >= TILE_WIRE_SP12_V_B_0 && id <= TILE_WIRE_SP12_V_B_23) { int idx = id - TILE_WIRE_SP12_V_B_0; - GraphicElement el; - el.type = GraphicElement::G_LINE; float x1 = x + 0.03 + 0.0025 * (90 - idx); float x2 = x + 0.03 + 0.0025 * (90 - (idx ^ 1)); @@ -305,8 +290,6 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) if (id >= TILE_WIRE_GLB2LOCAL_0 && id <= TILE_WIRE_GLB2LOCAL_3) { int idx = id - TILE_WIRE_GLB2LOCAL_0; - GraphicElement el; - el.type = GraphicElement::G_LINE; el.x1 = x + main_swbox_x1 + 0.005 * (idx + 5); el.x2 = el.x1; el.y1 = y + main_swbox_y1; @@ -318,8 +301,6 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) if (id >= TILE_WIRE_GLB_NETWK_0 && id <= TILE_WIRE_GLB_NETWK_7) { int idx = id - TILE_WIRE_GLB_NETWK_0; - GraphicElement el; - el.type = GraphicElement::G_LINE; el.x1 = x + main_swbox_x1 - 0.05; el.x2 = x + main_swbox_x1; el.y1 = y + main_swbox_y1 + 0.005 * (13 - idx); @@ -331,8 +312,6 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) if (id >= TILE_WIRE_NEIGH_OP_BNL_0 && id <= TILE_WIRE_NEIGH_OP_TOP_7) { int idx = id - TILE_WIRE_NEIGH_OP_BNL_0; - GraphicElement el; - el.type = GraphicElement::G_LINE; el.y1 = y + main_swbox_y2 - (0.0025 * (idx + 10) + 0.01 * (idx / 8)); el.y2 = el.y1; el.x1 = x + main_swbox_x1 - 0.05; @@ -344,8 +323,6 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) if (id >= TILE_WIRE_LOCAL_G0_0 && id <= TILE_WIRE_LOCAL_G3_7) { int idx = id - TILE_WIRE_LOCAL_G0_0; - GraphicElement el; - el.type = GraphicElement::G_LINE; el.x1 = x + main_swbox_x2; el.x2 = x + local_swbox_x1; float yoff = y + (local_swbox_y1 + local_swbox_y2) / 2 - 0.005 * 16 - 0.075; @@ -360,8 +337,6 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) int idx = id - TILE_WIRE_LUTFF_0_IN_0; int z = idx / 4; int input = idx % 4; - GraphicElement el; - el.type = GraphicElement::G_LINE; el.x1 = x + local_swbox_x2; el.x2 = x + logic_cell_x1; el.y1 = y + (logic_cell_y1 + logic_cell_y2) / 2 - 0.0075 + (0.005 * input) + z * logic_cell_pitch; @@ -376,8 +351,6 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) float y1 = y + 1.0 - (0.03 + 0.0025 * (152 + idx)); - GraphicElement el; - el.type = GraphicElement::G_LINE; el.y1 = y1; el.y2 = y1; el.x1 = x + main_swbox_x2; @@ -398,8 +371,6 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) if (id >= TILE_WIRE_LUTFF_GLOBAL_CEN && id <= TILE_WIRE_LUTFF_GLOBAL_S_R) { int idx = id - TILE_WIRE_LUTFF_GLOBAL_CEN; - GraphicElement el; - el.type = GraphicElement::G_LINE; el.x1 = x + main_swbox_x2 - 0.005 * (idx + 5); el.x2 = el.x1; @@ -426,8 +397,6 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) if (id >= TILE_WIRE_LUTFF_0_LOUT && id <= TILE_WIRE_LUTFF_6_LOUT) { int idx = id - TILE_WIRE_LUTFF_0_LOUT; - GraphicElement el; - el.type = GraphicElement::G_LINE; el.x1 = x + logic_cell_x1 + 0.005 * 5; el.x2 = el.x1; el.y1 = y + logic_cell_y2 + idx * logic_cell_pitch; @@ -439,8 +408,6 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) if (id >= TILE_WIRE_LUTFF_0_COUT && id <= TILE_WIRE_LUTFF_7_COUT) { int idx = id - TILE_WIRE_LUTFF_0_COUT; - GraphicElement el; - el.type = GraphicElement::G_LINE; el.x1 = x + logic_cell_x1 + 0.005 * 3; el.x2 = el.x1; el.y1 = y + logic_cell_y2 + idx * logic_cell_pitch; @@ -449,8 +416,6 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) } if (id == TILE_WIRE_CARRY_IN) { - GraphicElement el; - el.type = GraphicElement::G_LINE; el.x1 = x + logic_cell_x1 + 0.005 * 3; el.x2 = el.x1; el.y1 = y; @@ -459,8 +424,6 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id) } if (id == TILE_WIRE_CARRY_IN_MUX) { - GraphicElement el; - el.type = GraphicElement::G_LINE; el.x1 = x + logic_cell_x1 + 0.005 * 3; el.x2 = el.x1; el.y1 = y + 0.02; diff --git a/ice40/gfx.h b/ice40/gfx.h index b0009b59..aa07c2fa 100644 --- a/ice40/gfx.h +++ b/ice40/gfx.h @@ -466,7 +466,7 @@ enum GfxTileWireId { TILE_WIRE_SP12_H_L_23 }; -void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id); +void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id, GraphicElement::style_t style); NEXTPNR_NAMESPACE_END -- cgit v1.2.3 From ad60ab2ef164678cdde4410906cea674d122bf13 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 12 Jul 2018 21:46:16 +0200 Subject: Fix ice40 wire segments in lutff complex Signed-off-by: Clifford Wolf --- ice40/chipdb.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ice40') diff --git a/ice40/chipdb.py b/ice40/chipdb.py index 00194deb..97bc3183 100644 --- a/ice40/chipdb.py +++ b/ice40/chipdb.py @@ -389,8 +389,8 @@ with open(args.filename, "r") as f: wire_xy[mode[1]].append((int(line[0]), int(line[1]))) if mode[1] not in wire_segments: wire_segments[mode[1]] = set() - if ("TILE_WIRE_" + wname[2].upper()) in gfx_wire_ids: - wire_segments[mode[1]].add((wname[0], wname[1], gfx_wire_ids["TILE_WIRE_" + wname[2].upper()])) + if ("TILE_WIRE_" + wname[2].upper().replace("/", "_")) in gfx_wire_ids: + wire_segments[mode[1]].add((wname[0], wname[1], gfx_wire_ids["TILE_WIRE_" + wname[2].upper().replace("/", "_")])) continue if mode[0] in ("buffer", "routing"): -- cgit v1.2.3 From b8a42ff53b1fbb6e03d169d14e58180a750f4cad Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 12 Jul 2018 22:04:13 +0200 Subject: Updates from clang-format Signed-off-by: Clifford Wolf --- ice40/arch.cc | 36 +++++++++++++----------------------- ice40/archdefs.h | 12 ++++++++---- ice40/bitstream.cc | 5 ++--- ice40/chipdb.py | 4 +++- ice40/gfx.cc | 6 +++--- ice40/gfx.h | 3 ++- ice40/main.cc | 10 ++++------ 7 files changed, 35 insertions(+), 41 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.cc b/ice40/arch.cc index 8650aeff..786bf686 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -19,12 +19,12 @@ #include #include +#include "gfx.h" #include "log.h" #include "nextpnr.h" #include "placer1.h" #include "router1.h" #include "util.h" -#include "gfx.h" NEXTPNR_NAMESPACE_BEGIN @@ -380,10 +380,7 @@ GroupId Arch::getGroupByName(IdString name) const return GroupId(); } -IdString Arch::getGroupName(GroupId group) const -{ - return IdString(); -} +IdString Arch::getGroupName(GroupId group) const { return IdString(); } std::vector Arch::getGroups() const { @@ -448,15 +445,9 @@ delay_t Arch::estimateDelay(WireId src, WireId dst) const // ----------------------------------------------------------------------- -bool Arch::place() -{ - return placer1(getCtx()); -} +bool Arch::place() { return placer1(getCtx()); } -bool Arch::route() -{ - return router1(getCtx()); -} +bool Arch::route() { return router1(getCtx()); } // ----------------------------------------------------------------------- @@ -499,8 +490,7 @@ std::vector Arch::getDecalGraphics(DecalId decal) const { std::vector ret; - if (decal.type == DecalId::TYPE_FRAME) - { + if (decal.type == DecalId::TYPE_FRAME) { for (int x = 0; x <= chip_info->width; x++) for (int y = 0; y <= chip_info->height; y++) { GraphicElement el; @@ -512,23 +502,21 @@ std::vector Arch::getDecalGraphics(DecalId decal) const } } - if (decal.type == DecalId::TYPE_WIRE) - { + if (decal.type == DecalId::TYPE_WIRE) { WireId wire; wire.index = decal.index; int n = chip_info->wire_data[wire.index].num_segments; const WireSegmentPOD *p = chip_info->wire_data[wire.index].segments.get(); - GraphicElement::style_t style = wire_to_net.at(wire.index) != IdString() ? - GraphicElement::G_ACTIVE : GraphicElement::G_INACTIVE; + GraphicElement::style_t style = + wire_to_net.at(wire.index) != IdString() ? GraphicElement::G_ACTIVE : GraphicElement::G_INACTIVE; for (int i = 0; i < n; i++) gfxTileWire(ret, p[i].x, p[i].y, GfxTileWireId(p[i].index), style); } - if (decal.type == DecalId::TYPE_BEL) - { + if (decal.type == DecalId::TYPE_BEL) { BelId bel; bel.index = decal.index; @@ -540,8 +528,10 @@ std::vector Arch::getDecalGraphics(DecalId decal) const el.style = bel_to_cell.at(bel.index) != IdString() ? GraphicElement::G_ACTIVE : GraphicElement::G_INACTIVE; el.x1 = chip_info->bel_data[bel.index].x + logic_cell_x1; el.x2 = chip_info->bel_data[bel.index].x + logic_cell_x2; - el.y1 = chip_info->bel_data[bel.index].y + logic_cell_y1 + (chip_info->bel_data[bel.index].z) * logic_cell_pitch; - el.y2 = chip_info->bel_data[bel.index].y + logic_cell_y2 + (chip_info->bel_data[bel.index].z) * logic_cell_pitch; + el.y1 = chip_info->bel_data[bel.index].y + logic_cell_y1 + + (chip_info->bel_data[bel.index].z) * logic_cell_pitch; + el.y2 = chip_info->bel_data[bel.index].y + logic_cell_y2 + + (chip_info->bel_data[bel.index].z) * logic_cell_pitch; el.z = 0; ret.push_back(el); diff --git a/ice40/archdefs.h b/ice40/archdefs.h index 62c248c7..3252dabf 100644 --- a/ice40/archdefs.h +++ b/ice40/archdefs.h @@ -111,7 +111,8 @@ struct PipId struct GroupId { - enum : int8_t { + enum : int8_t + { TYPE_NONE, TYPE_FRAME, TYPE_MAIN_SW, @@ -133,7 +134,8 @@ struct GroupId struct DecalId { - enum : int8_t { + enum : int8_t + { TYPE_NONE, TYPE_FRAME, TYPE_BEL, @@ -178,7 +180,8 @@ template <> struct hash : hash template <> struct hash { - std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX GroupId &group) const noexcept { + std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX GroupId &group) const noexcept + { std::size_t seed = 0; boost::hash_combine(seed, hash()(group.type)); boost::hash_combine(seed, hash()(group.x)); @@ -189,7 +192,8 @@ template <> struct hash template <> struct hash { - std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX DecalId &decal) const noexcept { + std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX DecalId &decal) const noexcept + { std::size_t seed = 0; boost::hash_combine(seed, hash()(decal.type)); boost::hash_combine(seed, hash()(decal.index)); diff --git a/ice40/bitstream.cc b/ice40/bitstream.cc index 98a7a0e4..a62c6c09 100644 --- a/ice40/bitstream.cc +++ b/ice40/bitstream.cc @@ -341,9 +341,8 @@ void write_asc(const Context *ctx, std::ostream &out) set_config(ti, config.at(y).at(x), "Cascade.IPCON_LC0" + std::to_string(lc_idx) + "_inmux02_5", true); else - set_config(ti, config.at(y).at(x), - "Cascade.MULT" + std::to_string(int(tile - TILE_DSP0)) + "_LC0" + - std::to_string(lc_idx) + "_inmux02_5", + set_config(ti, config.at(y).at(x), "Cascade.MULT" + std::to_string(int(tile - TILE_DSP0)) + + "_LC0" + std::to_string(lc_idx) + "_inmux02_5", true); } } diff --git a/ice40/chipdb.py b/ice40/chipdb.py index 97bc3183..f52a2283 100644 --- a/ice40/chipdb.py +++ b/ice40/chipdb.py @@ -73,10 +73,12 @@ with open(args.portspins) as f: with open(args.gfxh) as f: state = 0 for line in f: - if state == 0 and line.startswith("enum GfxTileWireId "): + if state == 0 and line.startswith("enum GfxTileWireId"): state = 1 elif state == 1 and line.startswith("};"): state = 0 + elif state == 1 and line.startswith("{"): + pass elif state == 1: idx = len(gfx_wire_ids) name = line.strip().rstrip(",") diff --git a/ice40/gfx.cc b/ice40/gfx.cc index d6935b7d..f4941750 100644 --- a/ice40/gfx.cc +++ b/ice40/gfx.cc @@ -333,7 +333,7 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id, // LC Inputs - if (id >= TILE_WIRE_LUTFF_0_IN_0 && id <= TILE_WIRE_LUTFF_7_IN_3) { + if (id >= TILE_WIRE_LUTFF_0_IN_0 && id <= TILE_WIRE_LUTFF_7_IN_3) { int idx = id - TILE_WIRE_LUTFF_0_IN_0; int z = idx / 4; int input = idx % 4; @@ -354,7 +354,7 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id, el.y1 = y1; el.y2 = y1; el.x1 = x + main_swbox_x2; - el.x2 = x + 0.97 + 0.0025 * (7-idx); + el.x2 = x + 0.97 + 0.0025 * (7 - idx); g.push_back(el); el.y1 = y1; @@ -386,7 +386,7 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id, el.x1 = el.x2; g.push_back(el); - for (int i = 0; i < 7; i ++) { + for (int i = 0; i < 7; i++) { el.y1 = y + logic_cell_y2 + i * logic_cell_pitch; el.y2 = y + logic_cell_y1 + (i + 1) * logic_cell_pitch; g.push_back(el); diff --git a/ice40/gfx.h b/ice40/gfx.h index aa07c2fa..a65f7683 100644 --- a/ice40/gfx.h +++ b/ice40/gfx.h @@ -40,7 +40,8 @@ const float logic_cell_y1 = 0.05; const float logic_cell_y2 = 0.10; const float logic_cell_pitch = 0.0625; -enum GfxTileWireId { +enum GfxTileWireId +{ TILE_WIRE_GLB2LOCAL_0, TILE_WIRE_GLB2LOCAL_1, TILE_WIRE_GLB2LOCAL_2, diff --git a/ice40/main.cc b/ice40/main.cc index 2427ea6c..5fa58921 100644 --- a/ice40/main.cc +++ b/ice40/main.cc @@ -128,18 +128,16 @@ int main(int argc, char *argv[]) if (vm.count("help") || argc == 1) { help: - std::cout << boost::filesystem::basename(argv[0]) - << " -- Next Generation Place and Route (git " - "sha1 " GIT_COMMIT_HASH_STR ")\n"; + std::cout << boost::filesystem::basename(argv[0]) << " -- Next Generation Place and Route (git " + "sha1 " GIT_COMMIT_HASH_STR ")\n"; std::cout << "\n"; std::cout << options << "\n"; return argc != 1; } if (vm.count("version")) { - std::cout << boost::filesystem::basename(argv[0]) - << " -- Next Generation Place and Route (git " - "sha1 " GIT_COMMIT_HASH_STR ")\n"; + std::cout << boost::filesystem::basename(argv[0]) << " -- Next Generation Place and Route (git " + "sha1 " GIT_COMMIT_HASH_STR ")\n"; return 1; } -- cgit v1.2.3 From 499951cb65ff31fe15aa360a6b44371b13815d66 Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Thu, 12 Jul 2018 21:30:36 +0100 Subject: Remove legacy graphics API For now we do not optimize the OpenGL renderer against the new decal API, but this can be done in the future. --- ice40/main.cc | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'ice40') diff --git a/ice40/main.cc b/ice40/main.cc index 5fa58921..32864703 100644 --- a/ice40/main.cc +++ b/ice40/main.cc @@ -47,20 +47,22 @@ USING_NEXTPNR_NAMESPACE -void svg_dump_el(const GraphicElement &el) +void svg_dump_decal(const Context &ctx, const DecalXY &decal) { - float scale = 10.0, offset = 10.0; - std::string style = "stroke=\"black\" stroke-width=\"0.1\" fill=\"none\""; - - if (el.type == GraphicElement::G_BOX) { - std::cout << "\n"; - } + const float scale = 10.0, offset = 10.0; + const std::string style = "stroke=\"black\" stroke-width=\"0.1\" fill=\"none\""; + + for (auto &el : ctx.getDecalGraphics(decal.decal)) { + if (el.type == GraphicElement::G_BOX) { + std::cout << "\n"; + } - if (el.type == GraphicElement::G_LINE) { - std::cout << "\n"; + if (el.type == GraphicElement::G_LINE) { + std::cout << "\n"; + } } } @@ -291,12 +293,10 @@ int main(int argc, char *argv[]) "xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n"; for (auto bel : ctx.getBels()) { std::cout << "\n"; - for (auto &el : ctx.getBelGraphics(bel)) - svg_dump_el(el); + svg_dump_decal(ctx, ctx.getBelDecal(bel)); } std::cout << "\n"; - for (auto &el : ctx.getFrameGraphics()) - svg_dump_el(el); + svg_dump_decal(ctx, ctx.getFrameDecal()); std::cout << "\n"; } -- cgit v1.2.3 From 8e54ac15421be441ece2a85ff0d61e850a99b2e9 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 13 Jul 2018 09:14:48 +0200 Subject: Use command line parameters settings for GUI as well. --- ice40/main.cc | 155 +++++++++++++++++++++++++++++++--------------------------- 1 file changed, 82 insertions(+), 73 deletions(-) (limited to 'ice40') diff --git a/ice40/main.cc b/ice40/main.cc index 32864703..ae988da9 100644 --- a/ice40/main.cc +++ b/ice40/main.cc @@ -47,21 +47,22 @@ USING_NEXTPNR_NAMESPACE -void svg_dump_decal(const Context &ctx, const DecalXY &decal) +void svg_dump_decal(const Context *ctx, const DecalXY &decal) { const float scale = 10.0, offset = 10.0; const std::string style = "stroke=\"black\" stroke-width=\"0.1\" fill=\"none\""; - for (auto &el : ctx.getDecalGraphics(decal.decal)) { + for (auto &el : ctx->getDecalGraphics(decal.decal)) { if (el.type == GraphicElement::G_BOX) { - std::cout << "\n"; + std::cout << "\n"; } if (el.type == GraphicElement::G_LINE) { - std::cout << "\n"; + std::cout << "\n"; } } } @@ -130,16 +131,18 @@ int main(int argc, char *argv[]) if (vm.count("help") || argc == 1) { help: - std::cout << boost::filesystem::basename(argv[0]) << " -- Next Generation Place and Route (git " - "sha1 " GIT_COMMIT_HASH_STR ")\n"; + std::cout << boost::filesystem::basename(argv[0]) + << " -- Next Generation Place and Route (git " + "sha1 " GIT_COMMIT_HASH_STR ")\n"; std::cout << "\n"; std::cout << options << "\n"; return argc != 1; } if (vm.count("version")) { - std::cout << boost::filesystem::basename(argv[0]) << " -- Next Generation Place and Route (git " - "sha1 " GIT_COMMIT_HASH_STR ")\n"; + std::cout << boost::filesystem::basename(argv[0]) + << " -- Next Generation Place and Route (git " + "sha1 " GIT_COMMIT_HASH_STR ")\n"; return 1; } @@ -269,110 +272,126 @@ int main(int argc, char *argv[]) return 1; } - Context ctx(chipArgs); + std::unique_ptr ctx = std::unique_ptr(new Context(chipArgs)); if (vm.count("verbose")) { - ctx.verbose = true; + ctx->verbose = true; } if (vm.count("debug")) { - ctx.verbose = true; - ctx.debug = true; + ctx->verbose = true; + ctx->debug = true; } if (vm.count("force")) { - ctx.force = true; + ctx->force = true; } if (vm.count("seed")) { - ctx.rngseed(vm["seed"].as()); + ctx->rngseed(vm["seed"].as()); } if (vm.count("svg")) { std::cout << "\n"; - for (auto bel : ctx.getBels()) { - std::cout << "\n"; - svg_dump_decal(ctx, ctx.getBelDecal(bel)); + for (auto bel : ctx->getBels()) { + std::cout << "\n"; + svg_dump_decal(ctx.get(), ctx->getBelDecal(bel)); } std::cout << "\n"; - svg_dump_decal(ctx, ctx.getFrameDecal()); + svg_dump_decal(ctx.get(), ctx->getFrameDecal()); std::cout << "\n"; } if (vm.count("tmfuzz")) { std::vector src_wires, dst_wires; - /*for (auto w : ctx.getWires()) + /*for (auto w : ctx->getWires()) src_wires.push_back(w);*/ - for (auto b : ctx.getBels()) { - if (ctx.getBelType(b) == TYPE_ICESTORM_LC) { - src_wires.push_back(ctx.getWireBelPin(b, PIN_O)); + for (auto b : ctx->getBels()) { + if (ctx->getBelType(b) == TYPE_ICESTORM_LC) { + src_wires.push_back(ctx->getWireBelPin(b, PIN_O)); } - if (ctx.getBelType(b) == TYPE_SB_IO) { - src_wires.push_back(ctx.getWireBelPin(b, PIN_D_IN_0)); + if (ctx->getBelType(b) == TYPE_SB_IO) { + src_wires.push_back(ctx->getWireBelPin(b, PIN_D_IN_0)); } } - for (auto b : ctx.getBels()) { - if (ctx.getBelType(b) == TYPE_ICESTORM_LC) { - dst_wires.push_back(ctx.getWireBelPin(b, PIN_I0)); - dst_wires.push_back(ctx.getWireBelPin(b, PIN_I1)); - dst_wires.push_back(ctx.getWireBelPin(b, PIN_I2)); - dst_wires.push_back(ctx.getWireBelPin(b, PIN_I3)); - dst_wires.push_back(ctx.getWireBelPin(b, PIN_CEN)); - dst_wires.push_back(ctx.getWireBelPin(b, PIN_CIN)); + for (auto b : ctx->getBels()) { + if (ctx->getBelType(b) == TYPE_ICESTORM_LC) { + dst_wires.push_back(ctx->getWireBelPin(b, PIN_I0)); + dst_wires.push_back(ctx->getWireBelPin(b, PIN_I1)); + dst_wires.push_back(ctx->getWireBelPin(b, PIN_I2)); + dst_wires.push_back(ctx->getWireBelPin(b, PIN_I3)); + dst_wires.push_back(ctx->getWireBelPin(b, PIN_CEN)); + dst_wires.push_back(ctx->getWireBelPin(b, PIN_CIN)); } - if (ctx.getBelType(b) == TYPE_SB_IO) { - dst_wires.push_back(ctx.getWireBelPin(b, PIN_D_OUT_0)); - dst_wires.push_back(ctx.getWireBelPin(b, PIN_OUTPUT_ENABLE)); + if (ctx->getBelType(b) == TYPE_SB_IO) { + dst_wires.push_back(ctx->getWireBelPin(b, PIN_D_OUT_0)); + dst_wires.push_back(ctx->getWireBelPin(b, PIN_OUTPUT_ENABLE)); } } - ctx.shuffle(src_wires); - ctx.shuffle(dst_wires); + ctx->shuffle(src_wires); + ctx->shuffle(dst_wires); for (int i = 0; i < int(src_wires.size()) && i < int(dst_wires.size()); i++) { delay_t actual_delay; WireId src = src_wires[i], dst = dst_wires[i]; - if (!ctx.getActualRouteDelay(src, dst, actual_delay)) + if (!ctx->getActualRouteDelay(src, dst, actual_delay)) continue; - printf("%s %s %.3f %.3f %d %d %d %d %d %d\n", ctx.getWireName(src).c_str(&ctx), - ctx.getWireName(dst).c_str(&ctx), ctx.getDelayNS(actual_delay), - ctx.getDelayNS(ctx.estimateDelay(src, dst)), ctx.chip_info->wire_data[src.index].x, - ctx.chip_info->wire_data[src.index].y, ctx.chip_info->wire_data[src.index].type, - ctx.chip_info->wire_data[dst.index].x, ctx.chip_info->wire_data[dst.index].y, - ctx.chip_info->wire_data[dst.index].type); + printf("%s %s %.3f %.3f %d %d %d %d %d %d\n", ctx->getWireName(src).c_str(ctx.get()), + ctx->getWireName(dst).c_str(ctx.get()), ctx->getDelayNS(actual_delay), + ctx->getDelayNS(ctx->estimateDelay(src, dst)), ctx->chip_info->wire_data[src.index].x, + ctx->chip_info->wire_data[src.index].y, ctx->chip_info->wire_data[src.index].type, + ctx->chip_info->wire_data[dst.index].x, ctx->chip_info->wire_data[dst.index].y, + ctx->chip_info->wire_data[dst.index].type); } } + if (vm.count("freq")) + ctx->target_freq = vm["freq"].as() * 1e6; + ctx->timing_driven = true; + if (vm.count("no-tmdriv")) + ctx->timing_driven = false; +#ifndef NO_GUI + if (vm.count("gui")) { + Application a(argc, argv); + MainWindow w(std::move(ctx)); + if (vm.count("json")) { + std::string filename = vm["json"].as(); + std::string pcf = ""; + if (vm.count("pcf")) + pcf = vm["pcf"].as(); + w.load_json(filename, pcf); + } + w.show(); + + return a.exec(); + } +#endif if (vm.count("json")) { std::string filename = vm["json"].as(); std::ifstream f(filename); - if (!parse_json_file(f, filename, &ctx)) + if (!parse_json_file(f, filename, ctx.get())) log_error("Loading design failed.\n"); if (vm.count("pcf")) { std::ifstream pcf(vm["pcf"].as()); - if (!apply_pcf(&ctx, pcf)) + if (!apply_pcf(ctx.get(), pcf)) log_error("Loading PCF failed.\n"); } - if (!pack_design(&ctx) && !ctx.force) + if (!pack_design(ctx.get()) && !ctx->force) log_error("Packing design failed.\n"); - if (vm.count("freq")) - ctx.target_freq = vm["freq"].as() * 1e6; - assign_budget(&ctx); - ctx.check(); - print_utilisation(&ctx); - ctx.timing_driven = true; - if (vm.count("no-tmdriv")) - ctx.timing_driven = false; + assign_budget(ctx.get()); + ctx->check(); + print_utilisation(ctx.get()); if (!vm.count("pack-only")) { - if (!ctx.place() && !ctx.force) + if (!ctx->place() && !ctx->force) log_error("Placing design failed.\n"); - ctx.check(); - if (!ctx.route() && !ctx.force) + ctx->check(); + if (!ctx->route() && !ctx->force) log_error("Routing design failed.\n"); } } @@ -380,13 +399,13 @@ int main(int argc, char *argv[]) if (vm.count("asc")) { std::string filename = vm["asc"].as(); std::ofstream f(filename); - write_asc(&ctx, f); + write_asc(ctx.get(), f); } #ifndef NO_PYTHON if (vm.count("run")) { init_python(argv[0], true); - python_export_global("ctx", ctx); + python_export_global("ctx", *ctx.get()); std::vector files = vm["run"].as>(); for (auto filename : files) @@ -395,16 +414,6 @@ int main(int argc, char *argv[]) deinit_python(); } #endif - -#ifndef NO_GUI - if (vm.count("gui")) { - Application a(argc, argv); - MainWindow w; - w.show(); - - rc = a.exec(); - } -#endif return rc; } catch (log_execution_error_exception) { #if defined(_MSC_VER) -- cgit v1.2.3 From b5498c8a5366f8ae6c1e6e850a55b49753b0d6a6 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 13 Jul 2018 12:02:49 +0200 Subject: Fixed initial title and actions after new --- ice40/main.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ice40') diff --git a/ice40/main.cc b/ice40/main.cc index ae988da9..53cd7164 100644 --- a/ice40/main.cc +++ b/ice40/main.cc @@ -357,7 +357,7 @@ int main(int argc, char *argv[]) #ifndef NO_GUI if (vm.count("gui")) { Application a(argc, argv); - MainWindow w(std::move(ctx)); + MainWindow w(std::move(ctx), chipArgs); if (vm.count("json")) { std::string filename = vm["json"].as(); std::string pcf = ""; -- cgit v1.2.3 From e9668ed618b054d323fe848fce2bf1e78840316e Mon Sep 17 00:00:00 2001 From: David Shah Date: Fri, 13 Jul 2018 12:42:04 +0200 Subject: Fixing hash link problem Signed-off-by: David Shah --- ice40/archdefs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ice40') diff --git a/ice40/archdefs.h b/ice40/archdefs.h index 3252dabf..2bb718f1 100644 --- a/ice40/archdefs.h +++ b/ice40/archdefs.h @@ -21,7 +21,7 @@ #error Include "archdefs.h" via "nextpnr.h" only. #endif -#include +#include NEXTPNR_NAMESPACE_BEGIN -- cgit v1.2.3 From 0816f447b768ebe0632f419e9b696714dda4e860 Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Fri, 13 Jul 2018 12:35:39 +0100 Subject: Make ice40::Arch thread-safe We move all non-chip data to be private and guard them with an R/W mutex. We then modify all calls that access these fields to lock/shared_lock the mutex as required. Profiling the code before and after is an exercise left to the reader :). --- ice40/arch.cc | 7 +++++++ ice40/arch.h | 38 ++++++++++++++++++++++++++++++++------ ice40/bitstream.cc | 10 +++++----- 3 files changed, 44 insertions(+), 11 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.cc b/ice40/arch.cc index 786bf686..88a900d8 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -241,6 +241,7 @@ IdString Arch::archArgsToId(ArchArgs args) const BelId Arch::getBelByName(IdString name) const { + boost::lock_guard lock(mtx_); BelId ret; if (bel_by_name.empty()) { @@ -276,6 +277,7 @@ BelRange Arch::getBelsAtSameTile(BelId bel) const WireId Arch::getWireBelPin(BelId bel, PortPin pin) const { WireId ret; + boost::shared_lock_guard lock(mtx_); NPNR_ASSERT(bel != BelId()); @@ -296,6 +298,7 @@ WireId Arch::getWireBelPin(BelId bel, PortPin pin) const WireId Arch::getWireByName(IdString name) const { WireId ret; + boost::shared_lock_guard lock(mtx_); if (wire_by_name.empty()) { for (int i = 0; i < chip_info->num_wires; i++) @@ -314,6 +317,7 @@ WireId Arch::getWireByName(IdString name) const PipId Arch::getPipByName(IdString name) const { PipId ret; + boost::shared_lock_guard lock(mtx_); if (pip_by_name.empty()) { for (int i = 0; i < chip_info->num_pips; i++) { @@ -372,6 +376,8 @@ std::string Arch::getBelPackagePin(BelId bel) const // ----------------------------------------------------------------------- +// TODO(cliffordvienna): lock all of this + GroupId Arch::getGroupByName(IdString name) const { for (auto g : getGroups()) @@ -488,6 +494,7 @@ DecalXY Arch::getGroupDecal(GroupId group) const std::vector Arch::getDecalGraphics(DecalId decal) const { + boost::shared_lock_guard lock(mtx_); std::vector ret; if (decal.type == DecalId::TYPE_FRAME) { diff --git a/ice40/arch.h b/ice40/arch.h index 04de5178..410df48b 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -21,6 +21,9 @@ #error Include "arch.h" via "nextpnr.h" only. #endif +#include +#include + NEXTPNR_NAMESPACE_BEGIN /**** Everything in this section must be kept in sync with chipdb.py ****/ @@ -324,8 +327,17 @@ struct ArchArgs std::string package; }; -struct Arch : BaseCtx +class Arch : public BaseCtx { +private: + // All of the following... + std::vector bel_to_cell; + std::vector wire_to_net; + std::vector pip_to_net; + std::vector switches_locked; + // ... are guarded by the following lock: + mutable boost::shared_mutex mtx_; +public: const ChipInfoPOD *chip_info; const PackageInfoPOD *package_info; @@ -333,11 +345,6 @@ struct Arch : BaseCtx mutable std::unordered_map wire_by_name; mutable std::unordered_map pip_by_name; - std::vector bel_to_cell; - std::vector wire_to_net; - std::vector pip_to_net; - std::vector switches_locked; - ArchArgs args; Arch(ArchArgs args); @@ -368,6 +375,7 @@ struct Arch : BaseCtx { NPNR_ASSERT(bel != BelId()); NPNR_ASSERT(bel_to_cell[bel.index] == IdString()); + boost::lock_guard lock(mtx_); bel_to_cell[bel.index] = cell; cells[cell]->bel = bel; cells[cell]->belStrength = strength; @@ -377,6 +385,7 @@ struct Arch : BaseCtx { NPNR_ASSERT(bel != BelId()); NPNR_ASSERT(bel_to_cell[bel.index] != IdString()); + boost::lock_guard lock(mtx_); cells[bel_to_cell[bel.index]]->bel = BelId(); cells[bel_to_cell[bel.index]]->belStrength = STRENGTH_NONE; bel_to_cell[bel.index] = IdString(); @@ -385,18 +394,21 @@ struct Arch : BaseCtx bool checkBelAvail(BelId bel) const { NPNR_ASSERT(bel != BelId()); + boost::shared_lock_guard lock(mtx_); return bel_to_cell[bel.index] == IdString(); } IdString getBoundBelCell(BelId bel) const { NPNR_ASSERT(bel != BelId()); + boost::shared_lock_guard lock(mtx_); return bel_to_cell[bel.index]; } IdString getConflictingBelCell(BelId bel) const { NPNR_ASSERT(bel != BelId()); + boost::shared_lock_guard lock(mtx_); return bel_to_cell[bel.index]; } @@ -470,6 +482,8 @@ struct Arch : BaseCtx { NPNR_ASSERT(wire != WireId()); NPNR_ASSERT(wire_to_net[wire.index] == IdString()); + boost::lock_guard lock(mtx_); + wire_to_net[wire.index] = net; nets[net]->wires[wire].pip = PipId(); nets[net]->wires[wire].strength = strength; @@ -479,6 +493,7 @@ struct Arch : BaseCtx { NPNR_ASSERT(wire != WireId()); NPNR_ASSERT(wire_to_net[wire.index] != IdString()); + boost::lock_guard lock(mtx_); auto &net_wires = nets[wire_to_net[wire.index]]->wires; auto it = net_wires.find(wire); @@ -497,18 +512,24 @@ struct Arch : BaseCtx bool checkWireAvail(WireId wire) const { NPNR_ASSERT(wire != WireId()); + boost::shared_lock_guard lock(mtx_); + return wire_to_net[wire.index] == IdString(); } IdString getBoundWireNet(WireId wire) const { NPNR_ASSERT(wire != WireId()); + boost::shared_lock_guard lock(mtx_); + return wire_to_net[wire.index]; } IdString getConflictingWireNet(WireId wire) const { NPNR_ASSERT(wire != WireId()); + boost::shared_lock_guard lock(mtx_); + return wire_to_net[wire.index]; } @@ -532,6 +553,7 @@ struct Arch : BaseCtx NPNR_ASSERT(pip != PipId()); NPNR_ASSERT(pip_to_net[pip.index] == IdString()); NPNR_ASSERT(switches_locked[chip_info->pip_data[pip.index].switch_index] == IdString()); + boost::lock_guard lock(mtx_); pip_to_net[pip.index] = net; switches_locked[chip_info->pip_data[pip.index].switch_index] = net; @@ -549,6 +571,7 @@ struct Arch : BaseCtx NPNR_ASSERT(pip != PipId()); NPNR_ASSERT(pip_to_net[pip.index] != IdString()); NPNR_ASSERT(switches_locked[chip_info->pip_data[pip.index].switch_index] != IdString()); + boost::lock_guard lock(mtx_); WireId dst; dst.index = chip_info->pip_data[pip.index].dst; @@ -563,18 +586,21 @@ struct Arch : BaseCtx bool checkPipAvail(PipId pip) const { NPNR_ASSERT(pip != PipId()); + boost::shared_lock_guard lock(mtx_); return switches_locked[chip_info->pip_data[pip.index].switch_index] == IdString(); } IdString getBoundPipNet(PipId pip) const { NPNR_ASSERT(pip != PipId()); + boost::shared_lock_guard lock(mtx_); return pip_to_net[pip.index]; } IdString getConflictingPipNet(PipId pip) const { NPNR_ASSERT(pip != PipId()); + boost::shared_lock_guard lock(mtx_); return switches_locked[chip_info->pip_data[pip.index].switch_index]; } diff --git a/ice40/bitstream.cc b/ice40/bitstream.cc index a62c6c09..58a59366 100644 --- a/ice40/bitstream.cc +++ b/ice40/bitstream.cc @@ -128,7 +128,7 @@ void write_asc(const Context *ctx, std::ostream &out) } // Set pips for (auto pip : ctx->getPips()) { - if (ctx->pip_to_net[pip.index] != IdString()) { + if (ctx->getBoundPipNet(pip) != IdString()) { const PipInfoPOD &pi = ci.pip_data[pip.index]; const SwitchInfoPOD &swi = bi.switches[pi.switch_index]; for (int i = 0; i < swi.num_bits; i++) { @@ -199,8 +199,8 @@ void write_asc(const Context *ctx, std::ostream &out) NPNR_ASSERT(iez != -1); bool input_en = false; - if ((ctx->wire_to_net[ctx->getWireBelPin(bel, PIN_D_IN_0).index] != IdString()) || - (ctx->wire_to_net[ctx->getWireBelPin(bel, PIN_D_IN_1).index] != IdString())) { + if (!ctx->checkWireAvail(ctx->getWireBelPin(bel, PIN_D_IN_0)) || + !ctx->checkWireAvail(ctx->getWireBelPin(bel, PIN_D_IN_1))) { input_en = true; } @@ -271,7 +271,7 @@ void write_asc(const Context *ctx, std::ostream &out) } // Set config bits in unused IO and RAM for (auto bel : ctx->getBels()) { - if (ctx->bel_to_cell[bel.index] == IdString() && ctx->getBelType(bel) == TYPE_SB_IO) { + if (ctx->checkBelAvail(bel) && ctx->getBelType(bel) == TYPE_SB_IO) { const TileInfoPOD &ti = bi.tiles_nonrouting[TILE_IO]; const BelInfoPOD &beli = ci.bel_data[bel.index]; int x = beli.x, y = beli.y, z = beli.z; @@ -284,7 +284,7 @@ void write_asc(const Context *ctx, std::ostream &out) set_config(ti, config.at(iey).at(iex), "IoCtrl.REN_" + std::to_string(iez), false); } } - } else if (ctx->bel_to_cell[bel.index] == IdString() && ctx->getBelType(bel) == TYPE_ICESTORM_RAM) { + } else if (ctx->checkBelAvail(bel) && ctx->getBelType(bel) == TYPE_ICESTORM_RAM) { const BelInfoPOD &beli = ci.bel_data[bel.index]; int x = beli.x, y = beli.y; const TileInfoPOD &ti = bi.tiles_nonrouting[TILE_RAMB]; -- cgit v1.2.3 From 45462ef3a714c0d98fe570d96e6761e2b298c7d0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 13 Jul 2018 14:29:03 +0200 Subject: Fix Ui/Decal handling of active/inactive arch objects Signed-off-by: Clifford Wolf --- ice40/arch.cc | 14 +++++++++++--- ice40/arch.h | 11 +++++++++++ ice40/archdefs.h | 1 + 3 files changed, 23 insertions(+), 3 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.cc b/ice40/arch.cc index 786bf686..9b058aa0 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -455,6 +455,7 @@ DecalXY Arch::getFrameDecal() const { DecalXY decalxy; decalxy.decal.type = DecalId::TYPE_FRAME; + decalxy.decal.active = true; return decalxy; } @@ -463,6 +464,7 @@ DecalXY Arch::getBelDecal(BelId bel) const DecalXY decalxy; decalxy.decal.type = DecalId::TYPE_BEL; decalxy.decal.index = bel.index; + decalxy.decal.active = bel_to_cell.at(bel.index) != IdString(); return decalxy; } @@ -471,18 +473,25 @@ DecalXY Arch::getWireDecal(WireId wire) const DecalXY decalxy; decalxy.decal.type = DecalId::TYPE_WIRE; decalxy.decal.index = wire.index; + decalxy.decal.active = wire_to_net.at(wire.index) != IdString(); return decalxy; } DecalXY Arch::getPipDecal(PipId pip) const { DecalXY decalxy; + decalxy.decal.type = DecalId::TYPE_PIP; + decalxy.decal.index = pip.index; + decalxy.decal.active = pip_to_net.at(pip.index) != IdString(); return decalxy; }; DecalXY Arch::getGroupDecal(GroupId group) const { DecalXY decalxy; + decalxy.decal.type = DecalId::TYPE_GROUP; + decalxy.decal.index = (group.type << 16) | (group.x << 8) | (group.y); + decalxy.decal.active = true; return decalxy; }; @@ -509,8 +518,7 @@ std::vector Arch::getDecalGraphics(DecalId decal) const int n = chip_info->wire_data[wire.index].num_segments; const WireSegmentPOD *p = chip_info->wire_data[wire.index].segments.get(); - GraphicElement::style_t style = - wire_to_net.at(wire.index) != IdString() ? GraphicElement::G_ACTIVE : GraphicElement::G_INACTIVE; + GraphicElement::style_t style = decal.active ? GraphicElement::G_ACTIVE : GraphicElement::G_INACTIVE; for (int i = 0; i < n; i++) gfxTileWire(ret, p[i].x, p[i].y, GfxTileWireId(p[i].index), style); @@ -525,7 +533,7 @@ std::vector Arch::getDecalGraphics(DecalId decal) const if (bel_type == TYPE_ICESTORM_LC) { GraphicElement el; el.type = GraphicElement::G_BOX; - el.style = bel_to_cell.at(bel.index) != IdString() ? GraphicElement::G_ACTIVE : GraphicElement::G_INACTIVE; + el.style = decal.active ? GraphicElement::G_ACTIVE : GraphicElement::G_INACTIVE; el.x1 = chip_info->bel_data[bel.index].x + logic_cell_x1; el.x2 = chip_info->bel_data[bel.index].x + logic_cell_x2; el.y1 = chip_info->bel_data[bel.index].y + logic_cell_y1 + diff --git a/ice40/arch.h b/ice40/arch.h index 04de5178..b6c64de4 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -371,6 +371,7 @@ struct Arch : BaseCtx bel_to_cell[bel.index] = cell; cells[cell]->bel = bel; cells[cell]->belStrength = strength; + refreshUiBel(bel); } void unbindBel(BelId bel) @@ -380,6 +381,7 @@ struct Arch : BaseCtx cells[bel_to_cell[bel.index]]->bel = BelId(); cells[bel_to_cell[bel.index]]->belStrength = STRENGTH_NONE; bel_to_cell[bel.index] = IdString(); + refreshUiBel(bel); } bool checkBelAvail(BelId bel) const @@ -473,6 +475,7 @@ struct Arch : BaseCtx wire_to_net[wire.index] = net; nets[net]->wires[wire].pip = PipId(); nets[net]->wires[wire].strength = strength; + refreshUiWire(wire); } void unbindWire(WireId wire) @@ -488,10 +491,12 @@ struct Arch : BaseCtx if (pip != PipId()) { pip_to_net[pip.index] = IdString(); switches_locked[chip_info->pip_data[pip.index].switch_index] = IdString(); + refreshUiPip(pip); } net_wires.erase(it); wire_to_net[wire.index] = IdString(); + refreshUiWire(wire); } bool checkWireAvail(WireId wire) const @@ -542,6 +547,9 @@ struct Arch : BaseCtx wire_to_net[dst.index] = net; nets[net]->wires[dst].pip = pip; nets[net]->wires[dst].strength = strength; + + refreshUiPip(pip); + refreshUiWire(dst); } void unbindPip(PipId pip) @@ -558,6 +566,9 @@ struct Arch : BaseCtx pip_to_net[pip.index] = IdString(); switches_locked[chip_info->pip_data[pip.index].switch_index] = IdString(); + + refreshUiPip(pip); + refreshUiWire(dst); } bool checkPipAvail(PipId pip) const diff --git a/ice40/archdefs.h b/ice40/archdefs.h index 2bb718f1..75df678a 100644 --- a/ice40/archdefs.h +++ b/ice40/archdefs.h @@ -144,6 +144,7 @@ struct DecalId TYPE_GROUP } type = TYPE_NONE; int32_t index = -1; + bool active = false; bool operator==(const DecalId &other) const { return (type == other.type) && (index == other.index); } bool operator!=(const DecalId &other) const { return (type != other.type) || (index != other.index); } -- cgit v1.2.3 From c05bea12e0af7ec847043c832133cbfddfb278b1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 13 Jul 2018 15:16:44 +0200 Subject: Add ctx->pack() API Signed-off-by: Clifford Wolf --- ice40/arch.h | 1 + ice40/arch_pybindings.cc | 5 ++++- ice40/main.cc | 3 +-- ice40/pack.cc | 4 ++-- ice40/pack.h | 32 -------------------------------- 5 files changed, 8 insertions(+), 37 deletions(-) delete mode 100644 ice40/pack.h (limited to 'ice40') diff --git a/ice40/arch.h b/ice40/arch.h index b6c64de4..34797442 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -672,6 +672,7 @@ struct Arch : BaseCtx // ------------------------------------------------- + bool pack(); bool place(); bool route(); diff --git a/ice40/arch_pybindings.cc b/ice40/arch_pybindings.cc index ac8c189a..fd5109b4 100644 --- a/ice40/arch_pybindings.cc +++ b/ice40/arch_pybindings.cc @@ -58,7 +58,10 @@ void arch_wrap_python() auto arch_cls = class_, boost::noncopyable>("Arch", init()); auto ctx_cls = class_, boost::noncopyable>("Context", no_init) - .def("checksum", &Context::checksum); + .def("checksum", &Context::checksum) + .def("pack", &Context::pack) + .def("place", &Context::place) + .def("route", &Context::route); fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getBelType"); diff --git a/ice40/main.cc b/ice40/main.cc index 53cd7164..e77bdd34 100644 --- a/ice40/main.cc +++ b/ice40/main.cc @@ -39,7 +39,6 @@ #include "jsonparse.h" #include "log.h" #include "nextpnr.h" -#include "pack.h" #include "pcf.h" #include "place_legaliser.h" #include "timing.h" @@ -382,7 +381,7 @@ int main(int argc, char *argv[]) log_error("Loading PCF failed.\n"); } - if (!pack_design(ctx.get()) && !ctx->force) + if (!ctx->pack() && !ctx->force) log_error("Packing design failed.\n"); assign_budget(ctx.get()); ctx->check(); diff --git a/ice40/pack.cc b/ice40/pack.cc index d1be4a29..76a52be0 100644 --- a/ice40/pack.cc +++ b/ice40/pack.cc @@ -18,7 +18,6 @@ * */ -#include "pack.h" #include #include #include @@ -577,8 +576,9 @@ static void pack_special(Context *ctx) } // Main pack function -bool pack_design(Context *ctx) +bool Arch::pack() { + Context *ctx = getCtx(); try { log_break(); pack_constants(ctx); diff --git a/ice40/pack.h b/ice40/pack.h deleted file mode 100644 index cdebdd79..00000000 --- a/ice40/pack.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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. - * - */ - -#ifndef PACK_H -#define PACK_H - -#include "nextpnr.h" - -NEXTPNR_NAMESPACE_BEGIN - -bool pack_design(Context *ctx); - -NEXTPNR_NAMESPACE_END - -#endif // ROUTE_H -- cgit v1.2.3 From 44663fa5898ad84ac1e04c597b5037aa41697b94 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 13 Jul 2018 15:44:39 +0200 Subject: Fix ice40 gfx wire indices Signed-off-by: Clifford Wolf --- ice40/chipdb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ice40') diff --git a/ice40/chipdb.py b/ice40/chipdb.py index f52a2283..51fe169c 100644 --- a/ice40/chipdb.py +++ b/ice40/chipdb.py @@ -77,7 +77,7 @@ with open(args.gfxh) as f: state = 1 elif state == 1 and line.startswith("};"): state = 0 - elif state == 1 and line.startswith("{"): + elif state == 1 and (line.startswith("{") or line.strip() == ""): pass elif state == 1: idx = len(gfx_wire_ids) -- cgit v1.2.3 From 9e4f97290a50fc5d9dc0cbe6ead945840b9811b1 Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Fri, 13 Jul 2018 14:50:58 +0100 Subject: Make PnR use Unlocked methods --- ice40/arch.cc | 26 +++++++++-- ice40/arch.h | 117 ++++++++++++++++++++++++++++++++++++++--------- ice40/arch_place.cc | 6 +-- ice40/place_legaliser.cc | 14 +++--- 4 files changed, 129 insertions(+), 34 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.cc b/ice40/arch.cc index 88a900d8..6c00f0d2 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -242,6 +242,11 @@ IdString Arch::archArgsToId(ArchArgs args) const BelId Arch::getBelByName(IdString name) const { boost::lock_guard lock(mtx_); + return getBelByNameUnlocked(name); +} + +BelId Arch::getBelByNameUnlocked(IdString name) const +{ BelId ret; if (bel_by_name.empty()) { @@ -276,8 +281,13 @@ BelRange Arch::getBelsAtSameTile(BelId bel) const WireId Arch::getWireBelPin(BelId bel, PortPin pin) const { - WireId ret; boost::shared_lock_guard lock(mtx_); + return getWireBelPinUnlocked(bel, pin); +} + +WireId Arch::getWireBelPinUnlocked(BelId bel, PortPin pin) const +{ + WireId ret; NPNR_ASSERT(bel != BelId()); @@ -297,8 +307,13 @@ WireId Arch::getWireBelPin(BelId bel, PortPin pin) const WireId Arch::getWireByName(IdString name) const { - WireId ret; boost::shared_lock_guard lock(mtx_); + return getWireByNameUnlocked(name); +} + +WireId Arch::getWireByNameUnlocked(IdString name) const +{ + WireId ret; if (wire_by_name.empty()) { for (int i = 0; i < chip_info->num_wires; i++) @@ -316,8 +331,13 @@ WireId Arch::getWireByName(IdString name) const PipId Arch::getPipByName(IdString name) const { - PipId ret; boost::shared_lock_guard lock(mtx_); + return getPipByNameUnlocked(name); +} + +PipId Arch::getPipByNameUnlocked(IdString name) const +{ + PipId ret; if (pip_by_name.empty()) { for (int i = 0; i < chip_info->num_pips; i++) { diff --git a/ice40/arch.h b/ice40/arch.h index 410df48b..ab66e7d8 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -362,6 +362,7 @@ public: // ------------------------------------------------- BelId getBelByName(IdString name) const; + BelId getBelByNameUnlocked(IdString name) const; IdString getBelName(BelId bel) const { @@ -371,21 +372,30 @@ public: uint32_t getBelChecksum(BelId bel) const { return bel.index; } - void bindBel(BelId bel, IdString cell, PlaceStrength strength) + void bindBel(BelId bel, IdString cell, PlaceStrength strength) { + boost::lock_guard lock(mtx_); + bindBelUnlocked(bel, cell, strength); + } + + void bindBelUnlocked(BelId bel, IdString cell, PlaceStrength strength) { NPNR_ASSERT(bel != BelId()); NPNR_ASSERT(bel_to_cell[bel.index] == IdString()); - boost::lock_guard lock(mtx_); bel_to_cell[bel.index] = cell; cells[cell]->bel = bel; cells[cell]->belStrength = strength; } void unbindBel(BelId bel) + { + boost::lock_guard lock(mtx_); + unbindBelUnlocked(bel); + } + + void unbindBelUnlocked(BelId bel) { NPNR_ASSERT(bel != BelId()); NPNR_ASSERT(bel_to_cell[bel.index] != IdString()); - boost::lock_guard lock(mtx_); cells[bel_to_cell[bel.index]]->bel = BelId(); cells[bel_to_cell[bel.index]]->belStrength = STRENGTH_NONE; bel_to_cell[bel.index] = IdString(); @@ -393,22 +403,37 @@ public: bool checkBelAvail(BelId bel) const { - NPNR_ASSERT(bel != BelId()); boost::shared_lock_guard lock(mtx_); + return checkBelAvailUnlocked(bel); + } + + bool checkBelAvailUnlocked(BelId bel) const + { + NPNR_ASSERT(bel != BelId()); return bel_to_cell[bel.index] == IdString(); } IdString getBoundBelCell(BelId bel) const { - NPNR_ASSERT(bel != BelId()); boost::shared_lock_guard lock(mtx_); + return getBoundBelCellUnlocked(bel); + } + + IdString getBoundBelCellUnlocked(BelId bel) const + { + NPNR_ASSERT(bel != BelId()); return bel_to_cell[bel.index]; } IdString getConflictingBelCell(BelId bel) const { - NPNR_ASSERT(bel != BelId()); boost::shared_lock_guard lock(mtx_); + return getConflictingBelCellUnlocked(bel); + } + + IdString getConflictingBelCellUnlocked(BelId bel) const + { + NPNR_ASSERT(bel != BelId()); return bel_to_cell[bel.index]; } @@ -425,11 +450,11 @@ public: BelRange range; // FIXME #if 0 - if (type == "TYPE_A") { - range.b.cursor = bels_type_a_begin; - range.e.cursor = bels_type_a_end; - } - ... + if (type == "TYPE_A") { + range.b.cursor = bels_type_a_begin; + range.e.cursor = bels_type_a_end; + } + ... #endif return range; } @@ -443,6 +468,7 @@ public: } WireId getWireBelPin(BelId bel, PortPin pin) const; + WireId getWireBelPinUnlocked(BelId bel, PortPin pin) const; BelPin getBelPinUphill(WireId wire) const { @@ -469,6 +495,7 @@ public: // ------------------------------------------------- WireId getWireByName(IdString name) const; + WireId getWireByNameUnlocked(IdString name) const; IdString getWireName(WireId wire) const { @@ -479,10 +506,15 @@ public: uint32_t getWireChecksum(WireId wire) const { return wire.index; } void bindWire(WireId wire, IdString net, PlaceStrength strength) + { + boost::lock_guard lock(mtx_); + bindWireUnlocked(wire, net, strength); + } + + void bindWireUnlocked(WireId wire, IdString net, PlaceStrength strength) { NPNR_ASSERT(wire != WireId()); NPNR_ASSERT(wire_to_net[wire.index] == IdString()); - boost::lock_guard lock(mtx_); wire_to_net[wire.index] = net; nets[net]->wires[wire].pip = PipId(); @@ -490,10 +522,15 @@ public: } void unbindWire(WireId wire) + { + boost::lock_guard lock(mtx_); + unbindWireUnlocked(wire); + } + + void unbindWireUnlocked(WireId wire) { NPNR_ASSERT(wire != WireId()); NPNR_ASSERT(wire_to_net[wire.index] != IdString()); - boost::lock_guard lock(mtx_); auto &net_wires = nets[wire_to_net[wire.index]]->wires; auto it = net_wires.find(wire); @@ -511,25 +548,37 @@ public: bool checkWireAvail(WireId wire) const { - NPNR_ASSERT(wire != WireId()); boost::shared_lock_guard lock(mtx_); + return checkWireAvailUnlocked(wire); + } + bool checkWireAvailUnlocked(WireId wire) const + { + NPNR_ASSERT(wire != WireId()); return wire_to_net[wire.index] == IdString(); } IdString getBoundWireNet(WireId wire) const { - NPNR_ASSERT(wire != WireId()); boost::shared_lock_guard lock(mtx_); + return getBoundWireNetUnlocked(wire); + } + IdString getBoundWireNetUnlocked(WireId wire) const + { + NPNR_ASSERT(wire != WireId()); return wire_to_net[wire.index]; } IdString getConflictingWireNet(WireId wire) const { - NPNR_ASSERT(wire != WireId()); boost::shared_lock_guard lock(mtx_); + return getConflictingWireNetUnlocked(wire); + } + IdString getConflictingWireNetUnlocked(WireId wire) const + { + NPNR_ASSERT(wire != WireId()); return wire_to_net[wire.index]; } @@ -544,16 +593,22 @@ public: // ------------------------------------------------- PipId getPipByName(IdString name) const; + PipId getPipByNameUnlocked(IdString name) const; IdString getPipName(PipId pip) const; uint32_t getPipChecksum(PipId pip) const { return pip.index; } void bindPip(PipId pip, IdString net, PlaceStrength strength) + { + boost::lock_guard lock(mtx_); + bindPipUnlocked(pip, net, strength); + } + + void bindPipUnlocked(PipId pip, IdString net, PlaceStrength strength) { NPNR_ASSERT(pip != PipId()); NPNR_ASSERT(pip_to_net[pip.index] == IdString()); NPNR_ASSERT(switches_locked[chip_info->pip_data[pip.index].switch_index] == IdString()); - boost::lock_guard lock(mtx_); pip_to_net[pip.index] = net; switches_locked[chip_info->pip_data[pip.index].switch_index] = net; @@ -567,11 +622,16 @@ public: } void unbindPip(PipId pip) + { + boost::lock_guard lock(mtx_); + unbindPipUnlocked(pip); + } + + void unbindPipUnlocked(PipId pip) { NPNR_ASSERT(pip != PipId()); NPNR_ASSERT(pip_to_net[pip.index] != IdString()); NPNR_ASSERT(switches_locked[chip_info->pip_data[pip.index].switch_index] != IdString()); - boost::lock_guard lock(mtx_); WireId dst; dst.index = chip_info->pip_data[pip.index].dst; @@ -585,22 +645,37 @@ public: bool checkPipAvail(PipId pip) const { - NPNR_ASSERT(pip != PipId()); boost::shared_lock_guard lock(mtx_); + return checkPipAvailUnlocked(pip); + } + + bool checkPipAvailUnlocked(PipId pip) const + { + NPNR_ASSERT(pip != PipId()); return switches_locked[chip_info->pip_data[pip.index].switch_index] == IdString(); } IdString getBoundPipNet(PipId pip) const { - NPNR_ASSERT(pip != PipId()); boost::shared_lock_guard lock(mtx_); + return getBoundPipNetUnlocked(pip); + } + + IdString getBoundPipNetUnlocked(PipId pip) const + { + NPNR_ASSERT(pip != PipId()); return pip_to_net[pip.index]; } IdString getConflictingPipNet(PipId pip) const { - NPNR_ASSERT(pip != PipId()); boost::shared_lock_guard lock(mtx_); + return getConflictingPipNetUnlocked(pip); + } + + IdString getConflictingPipNetUnlocked(PipId pip) const + { + NPNR_ASSERT(pip != PipId()); return switches_locked[chip_info->pip_data[pip.index].switch_index]; } diff --git a/ice40/arch_place.cc b/ice40/arch_place.cc index dc1bc3eb..c9dd26c5 100644 --- a/ice40/arch_place.cc +++ b/ice40/arch_place.cc @@ -80,7 +80,7 @@ bool Arch::isBelLocationValid(BelId bel) const if (getBelType(bel) == TYPE_ICESTORM_LC) { std::vector bel_cells; for (auto bel_other : getBelsAtSameTile(bel)) { - IdString cell_other = getBoundBelCell(bel_other); + IdString cell_other = getBoundBelCellUnlocked(bel_other); if (cell_other != IdString()) { const CellInfo *ci_other = cells.at(cell_other).get(); bel_cells.push_back(ci_other); @@ -88,7 +88,7 @@ bool Arch::isBelLocationValid(BelId bel) const } return logicCellsCompatible(bel_cells); } else { - IdString cellId = getBoundBelCell(bel); + IdString cellId = getBoundBelCellUnlocked(bel); if (cellId == IdString()) return true; else @@ -104,7 +104,7 @@ bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const std::vector bel_cells; for (auto bel_other : getBelsAtSameTile(bel)) { - IdString cell_other = getBoundBelCell(bel_other); + IdString cell_other = getBoundBelCellUnlocked(bel_other); if (cell_other != IdString() && bel_other != bel) { const CellInfo *ci_other = cells.at(cell_other).get(); bel_cells.push_back(ci_other); diff --git a/ice40/place_legaliser.cc b/ice40/place_legaliser.cc index 559358c7..d42188f0 100644 --- a/ice40/place_legaliser.cc +++ b/ice40/place_legaliser.cc @@ -143,7 +143,7 @@ class PlacementLegaliser // Using the non-standard API here to get (x, y, z) rather than just (x, y) auto bi = ctx->chip_info->bel_data[bel.index]; int x = bi.x, y = bi.y, z = bi.z; - IdString cell = ctx->getBoundBelCell(bel); + IdString cell = ctx->getBoundBelCellUnlocked(bel); if (cell != IdString() && ctx->cells.at(cell)->belStrength >= STRENGTH_FIXED) logic_bels.at(x).at(y).at(z) = std::make_pair(bel, true); // locked out of use else @@ -331,16 +331,16 @@ class PlacementLegaliser NPNR_ASSERT(!loc.second); BelId bel = loc.first; // Check if there is a cell presently at the location, which we will need to rip up - IdString existing = ctx->getBoundBelCell(bel); + IdString existing = ctx->getBoundBelCellUnlocked(bel); if (existing != IdString()) { // TODO: keep track of the previous position of the ripped up cell, as a hint rippedCells.insert(existing); - ctx->unbindBel(bel); + ctx->unbindBelUnlocked(bel); } if (cell->bel != BelId()) { - ctx->unbindBel(cell->bel); + ctx->unbindBelUnlocked(cell->bel); } - ctx->bindBel(bel, cell->name, STRENGTH_LOCKED); + ctx->bindBelUnlocked(bel, cell->name, STRENGTH_LOCKED); rippedCells.erase(cell->name); // If cell was ripped up previously, no need to re-place loc.second = true; // Bel is now unavailable for further use } @@ -435,7 +435,7 @@ class PlacementLegaliser CellInfo *target = nullptr; for (int z = 0; z < 8; z++) { BelId bel = logic_bels.at(x).at(y).at(z).first; - IdString cell = ctx->getBoundBelCell(bel); + IdString cell = ctx->getBoundBelCellUnlocked(bel); if (cell != IdString()) { CellInfo *ci = ctx->cells.at(cell).get(); if (ci->belStrength >= STRENGTH_STRONG) @@ -448,7 +448,7 @@ class PlacementLegaliser } } if (target != nullptr) { - ctx->unbindBel(target->bel); + ctx->unbindBelUnlocked(target->bel); rippedCells.insert(target->name); changed = true; } -- cgit v1.2.3 From 0f736f551c30b7689b72b10d1a21ceca58657f23 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 13 Jul 2018 16:15:15 +0200 Subject: Fix iCE40 wire gfx decals Signed-off-by: Clifford Wolf --- ice40/gfx.cc | 103 ++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 78 insertions(+), 25 deletions(-) (limited to 'ice40') diff --git a/ice40/gfx.cc b/ice40/gfx.cc index f4941750..19aaed13 100644 --- a/ice40/gfx.cc +++ b/ice40/gfx.cc @@ -31,17 +31,31 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id, if (id >= TILE_WIRE_SP4_H_L_36 && id <= TILE_WIRE_SP4_H_L_47) { int idx = (id - TILE_WIRE_SP4_H_L_36) + 48; - float y1 = y + 1.0 - (0.03 + 0.0025 * (60 - idx)); - el.x1 = x + 0.0; - el.x2 = x + 0.9; + float y1 = y + 1.0 - (0.03 + 0.0025 * (60 - (idx ^ 1))); + float y2 = y + 1.0 - (0.03 + 0.0025 * (60 - idx)); + + el.x1 = x; + el.x2 = x + 0.01; el.y1 = y1; el.y2 = y1; g.push_back(el); + el.x1 = x + 0.01; + el.x2 = x + 0.02; + el.y1 = y1; + el.y2 = y2; + g.push_back(el); + + el.x1 = x + 0.02; + el.x2 = x + 0.9; + el.y1 = y2; + el.y2 = y2; + g.push_back(el); + el.x1 = x + main_swbox_x1 + 0.0025 * (idx + 35); el.x2 = el.x1; - el.y1 = y1; + el.y1 = y2; el.y2 = y + main_swbox_y2; g.push_back(el); } @@ -91,17 +105,30 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id, if (id >= TILE_WIRE_SP4_V_T_36 && id <= TILE_WIRE_SP4_V_T_47) { int idx = (id - TILE_WIRE_SP4_V_T_36) + 48; - float x1 = x + 0.03 + 0.0025 * (60 - idx); + float x1 = x + 0.03 + 0.0025 * (60 - (idx ^ 1)); + float x2 = x + 0.03 + 0.0025 * (60 - idx); - el.y1 = y + 1.0; - el.y2 = y + 0.1; + el.y1 = y + 1.00; + el.y2 = y + 0.99; el.x1 = x1; el.x2 = x1; g.push_back(el); + el.y1 = y + 0.99; + el.y2 = y + 0.98; + el.x1 = x1; + el.x2 = x2; + g.push_back(el); + + el.y1 = y + 0.98; + el.y2 = y + 0.10; + el.x1 = x2; + el.x2 = x2; + g.push_back(el); + el.y1 = y + 1.0 - (0.03 + 0.0025 * (270 - idx)); el.y2 = el.y1; - el.x1 = x1; + el.x1 = x2; el.x2 = x + main_swbox_x1; g.push_back(el); } @@ -109,9 +136,9 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id, if (id >= TILE_WIRE_SP4_V_B_0 && id <= TILE_WIRE_SP4_V_B_47) { int idx = id - TILE_WIRE_SP4_V_B_0; - float x1 = x + 0.03 + 0.0025 * (60 - (idx ^ 1)); - float x2 = x + 0.03 + 0.0025 * (60 - idx); - float x3 = x + 0.03 + 0.0025 * (60 - idx - 12); + float x1 = x + 0.03 + 0.0025 * (60 - idx); + float x2 = x + 0.03 + 0.0025 * (60 - (idx ^ 1)); + float x3 = x + 0.03 + 0.0025 * (60 - (idx ^ 1) - 12); if (idx >= 12) { el.y1 = y + 1.00; @@ -139,13 +166,13 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id, el.x2 = x3; g.push_back(el); - el.y1 = y + 1.0 - (0.03 + 0.0025 * (145 - idx)); + el.y1 = y + 1.0 - (0.03 + 0.0025 * (145 - (idx ^ 1))); el.y2 = el.y1; el.x1 = x; el.x2 = x2; g.push_back(el); - el.y1 = y + 1.0 - (0.03 + 0.0025 * (270 - idx)); + el.y1 = y + 1.0 - (0.03 + 0.0025 * (270 - (idx ^ 1))); el.y2 = el.y1; el.x1 = x2; el.x2 = x + main_swbox_x1; @@ -157,17 +184,30 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id, if (id >= TILE_WIRE_SP12_H_L_22 && id <= TILE_WIRE_SP12_H_L_23) { int idx = (id - TILE_WIRE_SP12_H_L_22) + 24; - float y1 = y + 1.0 - (0.03 + 0.0025 * (90 - idx)); + float y1 = y + 1.0 - (0.03 + 0.0025 * (90 - (idx ^ 1))); + float y2 = y + 1.0 - (0.03 + 0.0025 * (90 - idx)); - el.x1 = x + 0.0; - el.x2 = x + 0.98333; + el.x1 = x; + el.x2 = x + 0.01; el.y1 = y1; el.y2 = y1; g.push_back(el); + el.x1 = x + 0.01; + el.x2 = x + 0.02; + el.y1 = y1; + el.y2 = y2; + g.push_back(el); + + el.x1 = x + 0.02; + el.x2 = x + 0.98333; + el.y1 = y2; + el.y2 = y2; + g.push_back(el); + el.x1 = x + main_swbox_x1 + 0.0025 * (idx + 5); el.x2 = el.x1; - el.y1 = y1; + el.y1 = y2; el.y2 = y + main_swbox_y2; g.push_back(el); } @@ -175,9 +215,9 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id, if (id >= TILE_WIRE_SP12_H_R_0 && id <= TILE_WIRE_SP12_H_R_23) { int idx = id - TILE_WIRE_SP12_H_R_0; - float y1 = y + 1.0 - (0.03 + 0.0025 * (90 - (idx ^ 1))); - float y2 = y + 1.0 - (0.03 + 0.0025 * (90 - idx)); - float y3 = y + 1.0 - (0.03 + 0.0025 * (90 - idx - 2)); + float y1 = y + 1.0 - (0.03 + 0.0025 * (90 - idx)); + float y2 = y + 1.0 - (0.03 + 0.0025 * (90 - (idx ^ 1))); + float y3 = y + 1.0 - (0.03 + 0.0025 * (90 - (idx ^ 1) - 2)); if (idx >= 2) { el.x1 = x; @@ -205,7 +245,7 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id, el.y2 = y3; g.push_back(el); - el.x1 = x + main_swbox_x1 + 0.0025 * (idx + 5); + el.x1 = x + main_swbox_x1 + 0.0025 * ((idx ^ 1) + 5); el.x2 = el.x1; el.y1 = y2; el.y2 = y + main_swbox_y2; @@ -217,7 +257,7 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id, if (id >= TILE_WIRE_SP4_R_V_B_0 && id <= TILE_WIRE_SP4_R_V_B_47) { int idx = id - TILE_WIRE_SP4_R_V_B_0; - float y1 = y + 1.0 - (0.03 + 0.0025 * (145 - idx)); + float y1 = y + 1.0 - (0.03 + 0.0025 * (145 - (idx ^ 1))); el.y1 = y1; el.y2 = y1; @@ -231,17 +271,30 @@ void gfxTileWire(std::vector &g, int x, int y, GfxTileWireId id, if (id >= TILE_WIRE_SP12_V_T_22 && id <= TILE_WIRE_SP12_V_T_23) { int idx = (id - TILE_WIRE_SP12_V_T_22) + 24; - float x1 = x + 0.03 + 0.0025 * (90 - idx); + float x1 = x + 0.03 + 0.0025 * (90 - (idx ^ 1)); + float x2 = x + 0.03 + 0.0025 * (90 - idx); el.y1 = y + 1.00; - el.y2 = y + 0.01667; + el.y2 = y + 0.99; el.x1 = x1; el.x2 = x1; g.push_back(el); + el.y1 = y + 0.99; + el.y2 = y + 0.98; + el.x1 = x1; + el.x2 = x2; + g.push_back(el); + + el.y1 = y + 0.98; + el.y2 = y + 0.01667; + el.x1 = x2; + el.x2 = x2; + g.push_back(el); + el.y1 = y + 1.0 - (0.03 + 0.0025 * (300 - idx)); el.y2 = el.y1; - el.x1 = x1; + el.x1 = x2; el.x2 = x + main_swbox_x1; g.push_back(el); } -- cgit v1.2.3 From 013cfebcc5ccdf0fda9cedddd94e5b70ec20a029 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 13 Jul 2018 16:22:28 +0200 Subject: Improve handling of iCE40 BRAM bels Signed-off-by: Clifford Wolf --- ice40/arch.cc | 44 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 8 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.cc b/ice40/arch.cc index 9b058aa0..adc37dbd 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -603,14 +603,42 @@ std::vector Arch::getDecalGraphics(DecalId decal) const } if (bel_type == TYPE_ICESTORM_RAM) { - GraphicElement el; - el.type = GraphicElement::G_BOX; - el.x1 = chip_info->bel_data[bel.index].x + 0.1; - el.x2 = chip_info->bel_data[bel.index].x + 0.9; - el.y1 = chip_info->bel_data[bel.index].y + 0.1; - el.y2 = chip_info->bel_data[bel.index].y + 1.9; - el.z = 0; - ret.push_back(el); + for (int i = 0; i < 2; i++) + { + int tx = chip_info->bel_data[bel.index].x; + int ty = chip_info->bel_data[bel.index].y + i; + + GraphicElement el; + el.type = GraphicElement::G_BOX; + el.style = decal.active ? GraphicElement::G_ACTIVE : GraphicElement::G_INACTIVE; + el.x1 = chip_info->bel_data[bel.index].x + logic_cell_x1; + el.x2 = chip_info->bel_data[bel.index].x + logic_cell_x2; + el.y1 = chip_info->bel_data[bel.index].y + logic_cell_y1; + el.y2 = chip_info->bel_data[bel.index].y + logic_cell_y2 + 7*logic_cell_pitch; + el.z = 0; + ret.push_back(el); + + // Main switchbox + GraphicElement main_sw; + main_sw.type = GraphicElement::G_BOX; + main_sw.style = GraphicElement::G_FRAME; + main_sw.x1 = tx + main_swbox_x1; + main_sw.x2 = tx + main_swbox_x2; + main_sw.y1 = ty + main_swbox_y1; + main_sw.y2 = ty + main_swbox_y2; + ret.push_back(main_sw); + + // Local tracks to LUT input switchbox + GraphicElement local_sw; + local_sw.type = GraphicElement::G_BOX; + local_sw.style = GraphicElement::G_FRAME; + local_sw.x1 = tx + local_swbox_x1; + local_sw.x2 = tx + local_swbox_x2; + local_sw.y1 = ty + local_swbox_y1; + local_sw.y2 = ty + local_swbox_y2; + local_sw.z = 0; + ret.push_back(local_sw); + } } } -- cgit v1.2.3 From 89809a8b810dd57f50f365d70a0ce547705f8dbb Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Fri, 13 Jul 2018 18:57:55 +0100 Subject: Introduce proxies for locked access to ctx --- ice40/arch.cc | 357 +++++++++++++++++++++++++++++++++++-------- ice40/arch.h | 387 ++++++++++++++++++----------------------------- ice40/arch_place.cc | 75 ++++----- ice40/place_legaliser.cc | 73 +++++---- 4 files changed, 520 insertions(+), 372 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.cc b/ice40/arch.cc index 6c00f0d2..7c6af263 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -2,6 +2,7 @@ * nextpnr -- Next Generation Place and Route * * Copyright (C) 2018 Clifford Wolf + * Copyright (C) 2018 Serge Bazanski * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -28,6 +29,16 @@ NEXTPNR_NAMESPACE_BEGIN +ArchRWProxy Arch::rwproxy(void) { + ArchRWProxy res(this); + return res; +} + +ArchRProxy Arch::rproxy(void) const { + ArchRProxy res(this); + return res; +} + // ----------------------------------------------------------------------- IdString Arch::belTypeToId(BelType type) const @@ -239,28 +250,6 @@ IdString Arch::archArgsToId(ArchArgs args) const // ----------------------------------------------------------------------- -BelId Arch::getBelByName(IdString name) const -{ - boost::lock_guard lock(mtx_); - return getBelByNameUnlocked(name); -} - -BelId Arch::getBelByNameUnlocked(IdString name) const -{ - BelId ret; - - if (bel_by_name.empty()) { - for (int i = 0; i < chip_info->num_bels; i++) - bel_by_name[id(chip_info->bel_data[i].name.get())] = i; - } - - auto it = bel_by_name.find(name); - if (it != bel_by_name.end()) - ret.index = it->second; - - return ret; -} - BelRange Arch::getBelsAtSameTile(BelId bel) const { BelRange br; @@ -279,81 +268,105 @@ BelRange Arch::getBelsAtSameTile(BelId bel) const return br; } -WireId Arch::getWireBelPin(BelId bel, PortPin pin) const +// ----------------------------------------------------------------------- +// Shorthands to ArchProxy + +BelId Arch::getBelByName(IdString name) const { - boost::shared_lock_guard lock(mtx_); - return getWireBelPinUnlocked(bel, pin); + return rproxy().getBelByName(name); } -WireId Arch::getWireBelPinUnlocked(BelId bel, PortPin pin) const +void Arch::bindWire(WireId wire, IdString net, PlaceStrength strength) { - WireId ret; + rwproxy().bindWire(wire, net, strength); +} - NPNR_ASSERT(bel != BelId()); +void Arch::unbindWire(WireId wire) +{ + rwproxy().unbindWire(wire); +} - int num_bel_wires = chip_info->bel_data[bel.index].num_bel_wires; - const BelWirePOD *bel_wires = chip_info->bel_data[bel.index].bel_wires.get(); +void Arch::bindBel(BelId bel, IdString cell, PlaceStrength strength) { + rwproxy().bindBel(bel, cell, strength); +} - for (int i = 0; i < num_bel_wires; i++) - if (bel_wires[i].port == pin) { - ret.index = bel_wires[i].wire_index; - break; - } +void Arch::unbindBel(BelId bel) +{ + rwproxy().unbindBel(bel); +} - return ret; +bool Arch::checkBelAvail(BelId bel) const +{ + return rproxy().checkBelAvail(bel); } -// ----------------------------------------------------------------------- +IdString Arch::getBoundBelCell(BelId bel) const +{ + return rproxy().getBoundBelCell(bel); +} -WireId Arch::getWireByName(IdString name) const +IdString Arch::getConflictingBelCell(BelId bel) const { - boost::shared_lock_guard lock(mtx_); - return getWireByNameUnlocked(name); + return rproxy().getConflictingBelCell(bel); } -WireId Arch::getWireByNameUnlocked(IdString name) const +WireId Arch::getWireByName(IdString name) const { - WireId ret; + return rproxy().getWireByName(name); +} - if (wire_by_name.empty()) { - for (int i = 0; i < chip_info->num_wires; i++) - wire_by_name[id(chip_info->wire_data[i].name.get())] = i; - } +WireId Arch::getWireBelPin(BelId bel, PortPin pin) const +{ + return rproxy().getWireBelPin(bel, pin); +} - auto it = wire_by_name.find(name); - if (it != wire_by_name.end()) - ret.index = it->second; +bool Arch::checkWireAvail(WireId wire) const +{ + return rproxy().checkWireAvail(wire); +} - return ret; +IdString Arch::getBoundWireNet(WireId wire) const +{ + return rproxy().getBoundWireNet(wire); } -// ----------------------------------------------------------------------- +IdString Arch::getConflictingWireNet(WireId wire) const +{ + return rproxy().getConflictingWireNet(wire); +} PipId Arch::getPipByName(IdString name) const { - boost::shared_lock_guard lock(mtx_); - return getPipByNameUnlocked(name); + return rproxy().getPipByName(name); } -PipId Arch::getPipByNameUnlocked(IdString name) const +void Arch::bindPip(PipId pip, IdString net, PlaceStrength strength) { - PipId ret; + return rwproxy().bindPip(pip, net, strength); +} - if (pip_by_name.empty()) { - for (int i = 0; i < chip_info->num_pips; i++) { - PipId pip; - pip.index = i; - pip_by_name[getPipName(pip)] = i; - } - } +void Arch::unbindPip(PipId pip) +{ + return rwproxy().unbindPip(pip); +} - auto it = pip_by_name.find(name); - if (it != pip_by_name.end()) - ret.index = it->second; +bool Arch::checkPipAvail(PipId pip) const +{ + return rproxy().checkPipAvail(pip); +} - return ret; +IdString Arch::getBoundPipNet(PipId pip) const +{ + return rproxy().getBoundPipNet(pip); } +IdString Arch::getConflictingPipNet(PipId pip) const +{ + return rproxy().getConflictingPipNet(pip); +} + +// ----------------------------------------------------------------------- + IdString Arch::getPipName(PipId pip) const { NPNR_ASSERT(pip != PipId()); @@ -682,4 +695,216 @@ bool Arch::isGlobalNet(const NetInfo *net) const return net->driver.cell != nullptr && net->driver.port == id_glb_buf_out; } +// ----------------------------------------------------------------------- + +bool ArchRProxyMethods::checkBelAvail(BelId bel) const +{ + NPNR_ASSERT(bel != BelId()); + return parent_->bel_to_cell[bel.index] == IdString(); +} + +IdString ArchRProxyMethods::getBoundBelCell(BelId bel) const +{ + NPNR_ASSERT(bel != BelId()); + return parent_->bel_to_cell[bel.index]; +} + +IdString ArchRProxyMethods::getConflictingBelCell(BelId bel) const +{ + NPNR_ASSERT(bel != BelId()); + return parent_->bel_to_cell[bel.index]; +} + +WireId ArchRProxyMethods::getWireBelPin(BelId bel, PortPin pin) const +{ + WireId ret; + + NPNR_ASSERT(bel != BelId()); + + int num_bel_wires = parent_->chip_info->bel_data[bel.index].num_bel_wires; + const BelWirePOD *bel_wires = parent_->chip_info->bel_data[bel.index].bel_wires.get(); + + for (int i = 0; i < num_bel_wires; i++) + if (bel_wires[i].port == pin) { + ret.index = bel_wires[i].wire_index; + break; + } + + return ret; +} + +WireId ArchRProxyMethods::getWireByName(IdString name) const +{ + WireId ret; + + if (parent_->wire_by_name.empty()) { + for (int i = 0; i < parent_->chip_info->num_wires; i++) + parent_->wire_by_name[parent_->id(parent_->chip_info->wire_data[i].name.get())] = i; + } + + auto it = parent_->wire_by_name.find(name); + if (it != parent_->wire_by_name.end()) + ret.index = it->second; + + return ret; +} + +bool ArchRProxyMethods::checkWireAvail(WireId wire) const +{ + NPNR_ASSERT(wire != WireId()); + return parent_->wire_to_net[wire.index] == IdString(); +} + +IdString ArchRProxyMethods::getBoundWireNet(WireId wire) const +{ + NPNR_ASSERT(wire != WireId()); + return parent_->wire_to_net[wire.index]; +} + +IdString ArchRProxyMethods::getConflictingWireNet(WireId wire) const +{ + NPNR_ASSERT(wire != WireId()); + return parent_->wire_to_net[wire.index]; +} + +PipId ArchRProxyMethods::getPipByName(IdString name) const +{ + PipId ret; + + if (parent_->pip_by_name.empty()) { + for (int i = 0; i < parent_->chip_info->num_pips; i++) { + PipId pip; + pip.index = i; + parent_->pip_by_name[parent_->getPipName(pip)] = i; + } + } + + auto it = parent_->pip_by_name.find(name); + if (it != parent_->pip_by_name.end()) + ret.index = it->second; + + return ret; +} + +bool ArchRProxyMethods::checkPipAvail(PipId pip) const +{ + NPNR_ASSERT(pip != PipId()); + return parent_->switches_locked[parent_->chip_info->pip_data[pip.index].switch_index] == IdString(); +} + +IdString ArchRProxyMethods::getBoundPipNet(PipId pip) const +{ + NPNR_ASSERT(pip != PipId()); + return parent_->pip_to_net[pip.index]; +} + +IdString ArchRProxyMethods::getConflictingPipNet(PipId pip) const +{ + NPNR_ASSERT(pip != PipId()); + return parent_->switches_locked[parent_->chip_info->pip_data[pip.index].switch_index]; +} + +BelId ArchRProxyMethods::getBelByName(IdString name) const +{ + BelId ret; + + if (parent_->bel_by_name.empty()) { + for (int i = 0; i < parent_->chip_info->num_bels; i++) + parent_->bel_by_name[parent_->id(parent_->chip_info->bel_data[i].name.get())] = i; + } + + auto it = parent_->bel_by_name.find(name); + if (it != parent_->bel_by_name.end()) + ret.index = it->second; + + return ret; +} + +// ----------------------------------------------------------------------- + +void ArchRWProxyMethods::bindWire(WireId wire, IdString net, PlaceStrength strength) +{ + NPNR_ASSERT(wire != WireId()); + NPNR_ASSERT(parent_->wire_to_net[wire.index] == IdString()); + + parent_->wire_to_net[wire.index] = net; + parent_->nets[net]->wires[wire].pip = PipId(); + parent_->nets[net]->wires[wire].strength = strength; +} + +void ArchRWProxyMethods::bindBel(BelId bel, IdString cell, PlaceStrength strength) +{ + NPNR_ASSERT(bel != BelId()); + NPNR_ASSERT(parent_->bel_to_cell[bel.index] == IdString()); + parent_->bel_to_cell[bel.index] = cell; + parent_->cells[cell]->bel = bel; + parent_->cells[cell]->belStrength = strength; +} + +void ArchRWProxyMethods::unbindBel(BelId bel) +{ + NPNR_ASSERT(bel != BelId()); + NPNR_ASSERT(parent_->bel_to_cell[bel.index] != IdString()); + parent_->cells[parent_->bel_to_cell[bel.index]]->bel = BelId(); + parent_->cells[parent_->bel_to_cell[bel.index]]->belStrength = STRENGTH_NONE; + parent_->bel_to_cell[bel.index] = IdString(); +} + +void ArchRWProxyMethods::unbindWire(WireId wire) +{ + NPNR_ASSERT(wire != WireId()); + NPNR_ASSERT(parent_->wire_to_net[wire.index] != IdString()); + + auto &net_wires = parent_->nets[parent_->wire_to_net[wire.index]]->wires; + auto it = net_wires.find(wire); + NPNR_ASSERT(it != net_wires.end()); + + auto pip = it->second.pip; + if (pip != PipId()) { + parent_->pip_to_net[pip.index] = IdString(); + parent_->switches_locked[parent_->chip_info->pip_data[pip.index].switch_index] = IdString(); + } + + net_wires.erase(it); + parent_->wire_to_net[wire.index] = IdString(); +} + +void ArchRWProxyMethods::bindPip(PipId pip, IdString net, PlaceStrength strength) +{ + NPNR_ASSERT(pip != PipId()); + NPNR_ASSERT(parent_->pip_to_net[pip.index] == IdString()); + NPNR_ASSERT(parent_->switches_locked[parent_->chip_info->pip_data[pip.index].switch_index] == IdString()); + + parent_->pip_to_net[pip.index] = net; + parent_->switches_locked[parent_->chip_info->pip_data[pip.index].switch_index] = net; + + WireId dst; + dst.index = parent_->chip_info->pip_data[pip.index].dst; + NPNR_ASSERT(parent_->wire_to_net[dst.index] == IdString()); + parent_->wire_to_net[dst.index] = net; + parent_->nets[net]->wires[dst].pip = pip; + parent_->nets[net]->wires[dst].strength = strength; +} + +void ArchRWProxyMethods::unbindPip(PipId pip) +{ + NPNR_ASSERT(pip != PipId()); + NPNR_ASSERT(parent_->pip_to_net[pip.index] != IdString()); + NPNR_ASSERT(parent_->switches_locked[parent_->chip_info->pip_data[pip.index].switch_index] != IdString()); + + WireId dst; + dst.index = parent_->chip_info->pip_data[pip.index].dst; + NPNR_ASSERT(parent_->wire_to_net[dst.index] != IdString()); + parent_->wire_to_net[dst.index] = IdString(); + parent_->nets[parent_->pip_to_net[pip.index]]->wires.erase(dst); + + parent_->pip_to_net[pip.index] = IdString(); + parent_->switches_locked[parent_->chip_info->pip_data[pip.index].switch_index] = IdString(); +} + +CellInfo *ArchRWProxyMethods::getCell(IdString cell) +{ + return parent_->cells.at(cell).get(); +} + NEXTPNR_NAMESPACE_END diff --git a/ice40/arch.h b/ice40/arch.h index ab66e7d8..4462ce9e 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -2,6 +2,7 @@ * nextpnr -- Next Generation Place and Route * * Copyright (C) 2018 Clifford Wolf + * Copyright (C) 2018 Serge Bazanski * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -327,27 +328,40 @@ struct ArchArgs std::string package; }; +class ArchRWProxyMethods; +class ArchRProxyMethods; +class ArchRWProxy; +class ArchRProxy; + class Arch : public BaseCtx { + friend class ArchRWProxyMethods; + friend class ArchRProxyMethods; + friend class ArchRWProxy; + friend class ArchRProxy; private: // All of the following... std::vector bel_to_cell; std::vector wire_to_net; std::vector pip_to_net; std::vector switches_locked; + mutable std::unordered_map bel_by_name; + mutable std::unordered_map wire_by_name; + mutable std::unordered_map pip_by_name; + // ... are guarded by the following lock: mutable boost::shared_mutex mtx_; + public: const ChipInfoPOD *chip_info; const PackageInfoPOD *package_info; - mutable std::unordered_map bel_by_name; - mutable std::unordered_map wire_by_name; - mutable std::unordered_map pip_by_name; - ArchArgs args; Arch(ArchArgs args); + ArchRWProxy rwproxy(void); + ArchRProxy rproxy(void) const; + std::string getChipName(); IdString archId() const { return id("ice40"); } @@ -361,8 +375,33 @@ public: // ------------------------------------------------- + /// Wrappers around getting a r(w)proxy and calling a single method. + // Deprecated: please acquire a proxy yourself and call the methods + // you want on it. + void unbindWire(WireId wire); + void unbindPip(PipId pip); + void unbindBel(BelId bel); + void bindWire(WireId wire, IdString net, PlaceStrength strength); + void bindPip(PipId pip, IdString net, PlaceStrength strength); + void bindBel(BelId bel, IdString cell, PlaceStrength strength); + bool checkWireAvail(WireId wire) const; + bool checkPipAvail(PipId pip) const; + bool checkBelAvail(BelId bel) const; + WireId getWireByName(IdString name) const; + WireId getWireBelPin(BelId bel, PortPin pin) const; + PipId getPipByName(IdString name) const; + IdString getConflictingWireNet(WireId wire) const; + IdString getConflictingPipNet(PipId pip) const; + IdString getConflictingBelCell(BelId bel) const; + IdString getBoundWireNet(WireId wire) const; + IdString getBoundPipNet(PipId pip) const; + IdString getBoundBelCell(BelId bel) const; BelId getBelByName(IdString name) const; - BelId getBelByNameUnlocked(IdString name) const; + + // ------------------------------------------------- + + /// Methods to get chip info - don't need to use a wrapper, as these are + /// static per lifetime of object. IdString getBelName(BelId bel) const { @@ -370,71 +409,9 @@ public: return id(chip_info->bel_data[bel.index].name.get()); } - uint32_t getBelChecksum(BelId bel) const { return bel.index; } - - void bindBel(BelId bel, IdString cell, PlaceStrength strength) { - boost::lock_guard lock(mtx_); - bindBelUnlocked(bel, cell, strength); - } - - void bindBelUnlocked(BelId bel, IdString cell, PlaceStrength strength) - { - NPNR_ASSERT(bel != BelId()); - NPNR_ASSERT(bel_to_cell[bel.index] == IdString()); - bel_to_cell[bel.index] = cell; - cells[cell]->bel = bel; - cells[cell]->belStrength = strength; - } - - void unbindBel(BelId bel) + uint32_t getBelChecksum(BelId bel) const { - boost::lock_guard lock(mtx_); - unbindBelUnlocked(bel); - } - - void unbindBelUnlocked(BelId bel) - { - NPNR_ASSERT(bel != BelId()); - NPNR_ASSERT(bel_to_cell[bel.index] != IdString()); - cells[bel_to_cell[bel.index]]->bel = BelId(); - cells[bel_to_cell[bel.index]]->belStrength = STRENGTH_NONE; - bel_to_cell[bel.index] = IdString(); - } - - bool checkBelAvail(BelId bel) const - { - boost::shared_lock_guard lock(mtx_); - return checkBelAvailUnlocked(bel); - } - - bool checkBelAvailUnlocked(BelId bel) const - { - NPNR_ASSERT(bel != BelId()); - return bel_to_cell[bel.index] == IdString(); - } - - IdString getBoundBelCell(BelId bel) const - { - boost::shared_lock_guard lock(mtx_); - return getBoundBelCellUnlocked(bel); - } - - IdString getBoundBelCellUnlocked(BelId bel) const - { - NPNR_ASSERT(bel != BelId()); - return bel_to_cell[bel.index]; - } - - IdString getConflictingBelCell(BelId bel) const - { - boost::shared_lock_guard lock(mtx_); - return getConflictingBelCellUnlocked(bel); - } - - IdString getConflictingBelCellUnlocked(BelId bel) const - { - NPNR_ASSERT(bel != BelId()); - return bel_to_cell[bel.index]; + return bel.index; } BelRange getBels() const @@ -467,8 +444,6 @@ public: return chip_info->bel_data[bel.index].type; } - WireId getWireBelPin(BelId bel, PortPin pin) const; - WireId getWireBelPinUnlocked(BelId bel, PortPin pin) const; BelPin getBelPinUphill(WireId wire) const { @@ -494,9 +469,6 @@ public: // ------------------------------------------------- - WireId getWireByName(IdString name) const; - WireId getWireByNameUnlocked(IdString name) const; - IdString getWireName(WireId wire) const { NPNR_ASSERT(wire != WireId()); @@ -505,82 +477,6 @@ public: uint32_t getWireChecksum(WireId wire) const { return wire.index; } - void bindWire(WireId wire, IdString net, PlaceStrength strength) - { - boost::lock_guard lock(mtx_); - bindWireUnlocked(wire, net, strength); - } - - void bindWireUnlocked(WireId wire, IdString net, PlaceStrength strength) - { - NPNR_ASSERT(wire != WireId()); - NPNR_ASSERT(wire_to_net[wire.index] == IdString()); - - wire_to_net[wire.index] = net; - nets[net]->wires[wire].pip = PipId(); - nets[net]->wires[wire].strength = strength; - } - - void unbindWire(WireId wire) - { - boost::lock_guard lock(mtx_); - unbindWireUnlocked(wire); - } - - void unbindWireUnlocked(WireId wire) - { - NPNR_ASSERT(wire != WireId()); - NPNR_ASSERT(wire_to_net[wire.index] != IdString()); - - auto &net_wires = nets[wire_to_net[wire.index]]->wires; - auto it = net_wires.find(wire); - NPNR_ASSERT(it != net_wires.end()); - - auto pip = it->second.pip; - if (pip != PipId()) { - pip_to_net[pip.index] = IdString(); - switches_locked[chip_info->pip_data[pip.index].switch_index] = IdString(); - } - - net_wires.erase(it); - wire_to_net[wire.index] = IdString(); - } - - bool checkWireAvail(WireId wire) const - { - boost::shared_lock_guard lock(mtx_); - return checkWireAvailUnlocked(wire); - } - - bool checkWireAvailUnlocked(WireId wire) const - { - NPNR_ASSERT(wire != WireId()); - return wire_to_net[wire.index] == IdString(); - } - - IdString getBoundWireNet(WireId wire) const - { - boost::shared_lock_guard lock(mtx_); - return getBoundWireNetUnlocked(wire); - } - - IdString getBoundWireNetUnlocked(WireId wire) const - { - NPNR_ASSERT(wire != WireId()); - return wire_to_net[wire.index]; - } - - IdString getConflictingWireNet(WireId wire) const - { - boost::shared_lock_guard lock(mtx_); - return getConflictingWireNetUnlocked(wire); - } - - IdString getConflictingWireNetUnlocked(WireId wire) const - { - NPNR_ASSERT(wire != WireId()); - return wire_to_net[wire.index]; - } WireRange getWires() const { @@ -592,93 +488,10 @@ public: // ------------------------------------------------- - PipId getPipByName(IdString name) const; - PipId getPipByNameUnlocked(IdString name) const; IdString getPipName(PipId pip) const; uint32_t getPipChecksum(PipId pip) const { return pip.index; } - void bindPip(PipId pip, IdString net, PlaceStrength strength) - { - boost::lock_guard lock(mtx_); - bindPipUnlocked(pip, net, strength); - } - - void bindPipUnlocked(PipId pip, IdString net, PlaceStrength strength) - { - NPNR_ASSERT(pip != PipId()); - NPNR_ASSERT(pip_to_net[pip.index] == IdString()); - NPNR_ASSERT(switches_locked[chip_info->pip_data[pip.index].switch_index] == IdString()); - - pip_to_net[pip.index] = net; - switches_locked[chip_info->pip_data[pip.index].switch_index] = net; - - WireId dst; - dst.index = chip_info->pip_data[pip.index].dst; - NPNR_ASSERT(wire_to_net[dst.index] == IdString()); - wire_to_net[dst.index] = net; - nets[net]->wires[dst].pip = pip; - nets[net]->wires[dst].strength = strength; - } - - void unbindPip(PipId pip) - { - boost::lock_guard lock(mtx_); - unbindPipUnlocked(pip); - } - - void unbindPipUnlocked(PipId pip) - { - NPNR_ASSERT(pip != PipId()); - NPNR_ASSERT(pip_to_net[pip.index] != IdString()); - NPNR_ASSERT(switches_locked[chip_info->pip_data[pip.index].switch_index] != IdString()); - - WireId dst; - dst.index = chip_info->pip_data[pip.index].dst; - NPNR_ASSERT(wire_to_net[dst.index] != IdString()); - wire_to_net[dst.index] = IdString(); - nets[pip_to_net[pip.index]]->wires.erase(dst); - - pip_to_net[pip.index] = IdString(); - switches_locked[chip_info->pip_data[pip.index].switch_index] = IdString(); - } - - bool checkPipAvail(PipId pip) const - { - boost::shared_lock_guard lock(mtx_); - return checkPipAvailUnlocked(pip); - } - - bool checkPipAvailUnlocked(PipId pip) const - { - NPNR_ASSERT(pip != PipId()); - return switches_locked[chip_info->pip_data[pip.index].switch_index] == IdString(); - } - - IdString getBoundPipNet(PipId pip) const - { - boost::shared_lock_guard lock(mtx_); - return getBoundPipNetUnlocked(pip); - } - - IdString getBoundPipNetUnlocked(PipId pip) const - { - NPNR_ASSERT(pip != PipId()); - return pip_to_net[pip.index]; - } - - IdString getConflictingPipNet(PipId pip) const - { - boost::shared_lock_guard lock(mtx_); - return getConflictingPipNetUnlocked(pip); - } - - IdString getConflictingPipNetUnlocked(PipId pip) const - { - NPNR_ASSERT(pip != PipId()); - return switches_locked[chip_info->pip_data[pip.index].switch_index]; - } - AllPipRange getPips() const { AllPipRange range; @@ -789,7 +602,26 @@ public: // ------------------------------------------------- - // Perform placement validity checks, returning false on failure (all implemented in arch_place.cc) + IdString id_glb_buf_out; + IdString id_icestorm_lc, id_sb_io, id_sb_gb; + IdString id_cen, id_clk, id_sr; + IdString id_i0, id_i1, id_i2, id_i3; + IdString id_dff_en, id_neg_clk; +}; + +class ArchRProxyMethods { + friend class ArchRProxy; + friend class ArchRWProxy; +private: + const Arch *parent_; + ArchRProxyMethods(const Arch *parent) : parent_(parent) {} + ArchRProxyMethods(ArchRProxyMethods &&other) noexcept : parent_(other.parent_) {} + ArchRProxyMethods(const ArchRProxyMethods &other) : parent_(other.parent_) {} + +public: + ~ArchRProxyMethods() noexcept { } + + /// Perform placement validity checks, returning false on failure (all implemented in arch_place.cc) // Whether or not a given cell can be placed at a given Bel // This is not intended for Bel type checks, but finer-grained constraints @@ -802,11 +634,88 @@ public: // Helper function for above bool logicCellsCompatible(const std::vector &cells) const; - IdString id_glb_buf_out; - IdString id_icestorm_lc, id_sb_io, id_sb_gb; - IdString id_cen, id_clk, id_sr; - IdString id_i0, id_i1, id_i2, id_i3; - IdString id_dff_en, id_neg_clk; + bool checkWireAvail(WireId wire) const; + bool checkPipAvail(PipId pip) const; + bool checkBelAvail(BelId bel) const; + + WireId getWireByName(IdString name) const; + WireId getWireBelPin(BelId bel, PortPin pin) const; + PipId getPipByName(IdString name) const; + + + IdString getConflictingWireNet(WireId wire) const; + IdString getConflictingPipNet(PipId pip) const; + IdString getConflictingBelCell(BelId bel) const; + + IdString getBoundWireNet(WireId wire) const; + IdString getBoundPipNet(PipId pip) const; + IdString getBoundBelCell(BelId bel) const; + + BelId getBelByName(IdString name) const; +}; + +class ArchRProxy : public ArchRProxyMethods { + friend class Arch; + friend class ArchRWProxy; +private: + boost::shared_mutex *lock_; + ArchRProxy(const Arch *parent) : ArchRProxyMethods(parent), lock_(&parent->mtx_) + { + lock_->lock_shared(); + } + +public: + ~ArchRProxy() { + if (lock_ != nullptr) { + lock_->unlock_shared(); + } + } + ArchRProxy(ArchRProxy &&other) : ArchRProxyMethods(other), lock_(other.lock_) + { + other.lock_ = nullptr; + } +}; + +class ArchRWProxyMethods { + friend class ArchRWProxy; +private: + Arch *parent_; + ArchRWProxyMethods(Arch *parent) : parent_(parent) {} + ArchRWProxyMethods(ArchRWProxyMethods &&other) : parent_(other.parent_) {} + ArchRWProxyMethods(const ArchRWProxyMethods &other) : parent_(other.parent_) {} +public: + ~ArchRWProxyMethods() {} + + void unbindWire(WireId wire); + void unbindPip(PipId pip); + void unbindBel(BelId bel); + void bindWire(WireId wire, IdString net, PlaceStrength strength); + void bindPip(PipId pip, IdString net, PlaceStrength strength); + void bindBel(BelId bel, IdString cell, PlaceStrength strength); + CellInfo *getCell(IdString cell); +}; + +class ArchRWProxy : public ArchRProxyMethods, public ArchRWProxyMethods { + friend class Arch; +private: + boost::shared_mutex *lock_; + ArchRWProxy(Arch *parent) : ArchRProxyMethods(parent), ArchRWProxyMethods(parent), lock_(&parent->mtx_) { + lock_->lock(); + } + +public: + ArchRWProxy(ArchRWProxy &&other) : ArchRProxyMethods(other), ArchRWProxyMethods(other), lock_(other.lock_) + { + other.lock_ = nullptr; + } + ~ArchRWProxy() + { + if (lock_ != nullptr) { + lock_->unlock(); + } + } + + }; NEXTPNR_NAMESPACE_END diff --git a/ice40/arch_place.cc b/ice40/arch_place.cc index c9dd26c5..cb7c44b8 100644 --- a/ice40/arch_place.cc +++ b/ice40/arch_place.cc @@ -3,6 +3,7 @@ * * Copyright (C) 2018 Clifford Wolf * Copyright (C) 2018 David Shah + * Copyright (C) 2018 Serge Bazanski * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -24,44 +25,44 @@ NEXTPNR_NAMESPACE_BEGIN -bool Arch::logicCellsCompatible(const std::vector &cells) const +bool ArchRProxyMethods::logicCellsCompatible(const std::vector &cells) const { bool dffs_exist = false, dffs_neg = false; const NetInfo *cen = nullptr, *clk = nullptr, *sr = nullptr; int locals_count = 0; for (auto cell : cells) { - if (bool_or_default(cell->params, id_dff_en)) { + if (bool_or_default(cell->params, parent_->id_dff_en)) { if (!dffs_exist) { dffs_exist = true; - cen = get_net_or_empty(cell, id_cen); - clk = get_net_or_empty(cell, id_clk); - sr = get_net_or_empty(cell, id_sr); + cen = get_net_or_empty(cell, parent_->id_cen); + clk = get_net_or_empty(cell, parent_->id_clk); + sr = get_net_or_empty(cell, parent_->id_sr); - if (!isGlobalNet(cen) && cen != nullptr) + if (!parent_->isGlobalNet(cen) && cen != nullptr) locals_count++; - if (!isGlobalNet(clk) && clk != nullptr) + if (!parent_->isGlobalNet(clk) && clk != nullptr) locals_count++; - if (!isGlobalNet(sr) && sr != nullptr) + if (!parent_->isGlobalNet(sr) && sr != nullptr) locals_count++; - if (bool_or_default(cell->params, id_neg_clk)) { + if (bool_or_default(cell->params, parent_->id_neg_clk)) { dffs_neg = true; } } else { - if (cen != get_net_or_empty(cell, id_cen)) + if (cen != get_net_or_empty(cell, parent_->id_cen)) return false; - if (clk != get_net_or_empty(cell, id_clk)) + if (clk != get_net_or_empty(cell, parent_->id_clk)) return false; - if (sr != get_net_or_empty(cell, id_sr)) + if (sr != get_net_or_empty(cell, parent_->id_sr)) return false; - if (dffs_neg != bool_or_default(cell->params, id_neg_clk)) + if (dffs_neg != bool_or_default(cell->params, parent_->id_neg_clk)) return false; } } - const NetInfo *i0 = get_net_or_empty(cell, id_i0), *i1 = get_net_or_empty(cell, id_i1), - *i2 = get_net_or_empty(cell, id_i2), *i3 = get_net_or_empty(cell, id_i3); + const NetInfo *i0 = get_net_or_empty(cell, parent_->id_i0), *i1 = get_net_or_empty(cell, parent_->id_i1), + *i2 = get_net_or_empty(cell, parent_->id_i2), *i3 = get_net_or_empty(cell, parent_->id_i3); if (i0 != nullptr) locals_count++; if (i1 != nullptr) @@ -75,57 +76,57 @@ bool Arch::logicCellsCompatible(const std::vector &cells) cons return locals_count <= 32; } -bool Arch::isBelLocationValid(BelId bel) const +bool ArchRProxyMethods::isBelLocationValid(BelId bel) const { - if (getBelType(bel) == TYPE_ICESTORM_LC) { + if (parent_->getBelType(bel) == TYPE_ICESTORM_LC) { std::vector bel_cells; - for (auto bel_other : getBelsAtSameTile(bel)) { - IdString cell_other = getBoundBelCellUnlocked(bel_other); + for (auto bel_other : parent_->getBelsAtSameTile(bel)) { + IdString cell_other = getBoundBelCell(bel_other); if (cell_other != IdString()) { - const CellInfo *ci_other = cells.at(cell_other).get(); + const CellInfo *ci_other = parent_->cells.at(cell_other).get(); bel_cells.push_back(ci_other); } } return logicCellsCompatible(bel_cells); } else { - IdString cellId = getBoundBelCellUnlocked(bel); + IdString cellId = getBoundBelCell(bel); if (cellId == IdString()) return true; else - return isValidBelForCell(cells.at(cellId).get(), bel); + return isValidBelForCell(parent_->cells.at(cellId).get(), bel); } } -bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const +bool ArchRProxyMethods::isValidBelForCell(CellInfo *cell, BelId bel) const { - if (cell->type == id_icestorm_lc) { - NPNR_ASSERT(getBelType(bel) == TYPE_ICESTORM_LC); + if (cell->type == parent_->id_icestorm_lc) { + NPNR_ASSERT(parent_->getBelType(bel) == TYPE_ICESTORM_LC); std::vector bel_cells; - for (auto bel_other : getBelsAtSameTile(bel)) { - IdString cell_other = getBoundBelCellUnlocked(bel_other); + for (auto bel_other : parent_->getBelsAtSameTile(bel)) { + IdString cell_other = getBoundBelCell(bel_other); if (cell_other != IdString() && bel_other != bel) { - const CellInfo *ci_other = cells.at(cell_other).get(); + const CellInfo *ci_other = parent_->cells.at(cell_other).get(); bel_cells.push_back(ci_other); } } bel_cells.push_back(cell); return logicCellsCompatible(bel_cells); - } else if (cell->type == id_sb_io) { - return getBelPackagePin(bel) != ""; - } else if (cell->type == id_sb_gb) { + } else if (cell->type == parent_->id_sb_io) { + return parent_->getBelPackagePin(bel) != ""; + } else if (cell->type == parent_->id_sb_gb) { bool is_reset = false, is_cen = false; - NPNR_ASSERT(cell->ports.at(id_glb_buf_out).net != nullptr); - for (auto user : cell->ports.at(id_glb_buf_out).net->users) { - if (is_reset_port(this, user)) + NPNR_ASSERT(cell->ports.at(parent_->id_glb_buf_out).net != nullptr); + for (auto user : cell->ports.at(parent_->id_glb_buf_out).net->users) { + if (is_reset_port(parent_, user)) is_reset = true; - if (is_enable_port(this, user)) + if (is_enable_port(parent_, user)) is_cen = true; } - IdString glb_net = getWireName(getWireBelPin(bel, PIN_GLOBAL_BUFFER_OUTPUT)); - int glb_id = std::stoi(std::string("") + glb_net.str(this).back()); + IdString glb_net = parent_->getWireName(getWireBelPin(bel, PIN_GLOBAL_BUFFER_OUTPUT)); + int glb_id = std::stoi(std::string("") + glb_net.str(parent_).back()); if (is_reset && is_cen) return false; else if (is_reset) diff --git a/ice40/place_legaliser.cc b/ice40/place_legaliser.cc index d42188f0..10a6f3ff 100644 --- a/ice40/place_legaliser.cc +++ b/ice40/place_legaliser.cc @@ -119,13 +119,17 @@ class PlacementLegaliser bool legalise() { - log_info("Legalising design..\n"); + log_info("Legalising logic cells...\n"); init_logic_cells(); + log_info("Legalising carries...\n"); bool legalised_carries = legalise_carries(); if (!legalised_carries && !ctx->force) return false; + log_info("Legalising others...\n"); legalise_others(); + log_info("Legalising logic tiles...\n"); legalise_logic_tiles(); + log_info("Replacing cells...\n"); bool replaced_cells = replace_cells(); return legalised_carries && replaced_cells; } @@ -133,6 +137,7 @@ class PlacementLegaliser private: void init_logic_cells() { + auto &&proxy = ctx->rproxy(); for (auto bel : ctx->getBels()) { // Initialise the logic bels vector with unavailable invalid bels, dimensions [0..width][0..height[0..7] logic_bels.resize(ctx->chip_info->width + 1, @@ -143,7 +148,7 @@ class PlacementLegaliser // Using the non-standard API here to get (x, y, z) rather than just (x, y) auto bi = ctx->chip_info->bel_data[bel.index]; int x = bi.x, y = bi.y, z = bi.z; - IdString cell = ctx->getBoundBelCellUnlocked(bel); + IdString cell = proxy.getBoundBelCell(bel); if (cell != IdString() && ctx->cells.at(cell)->belStrength >= STRENGTH_FIXED) logic_bels.at(x).at(y).at(z) = std::make_pair(bel, true); // locked out of use else @@ -195,28 +200,33 @@ class PlacementLegaliser } } bool success = true; + // Find midpoints for all chains, before we start tearing them up std::vector all_chains; - for (auto &base_chain : carry_chains) { - if (ctx->verbose) { - log_info("Found carry chain: \n"); - for (auto entry : base_chain.cells) - log_info(" %s\n", entry->name.c_str(ctx)); - log_info("\n"); - } - std::vector split_chains = split_carry_chain(base_chain); - for (auto &chain : split_chains) { - get_chain_midpoint(ctx, chain, chain.mid_x, chain.mid_y); - all_chains.push_back(chain); + { + auto &&proxy = ctx->rproxy(); + for (auto &base_chain : carry_chains) { + if (ctx->verbose) { + log_info("Found carry chain: \n"); + for (auto entry : base_chain.cells) + log_info(" %s\n", entry->name.c_str(ctx)); + log_info("\n"); + } + std::vector split_chains = split_carry_chain(proxy, base_chain); + for (auto &chain : split_chains) { + get_chain_midpoint(ctx, chain, chain.mid_x, chain.mid_y); + all_chains.push_back(chain); + } } } // Actual chain placement + auto &&proxy = ctx->rwproxy(); for (auto &chain : all_chains) { if (ctx->verbose) log_info("Placing carry chain starting at '%s'\n", chain.cells.front()->name.c_str(ctx)); float base_x = chain.mid_x, base_y = chain.mid_y - (chain.cells.size() / 16.0f); // Find Bel meeting requirements closest to the target base, returning location as - auto chain_origin_bel = find_closest_bel(base_x, base_y, chain); + auto chain_origin_bel = find_closest_bel(proxy, base_x, base_y, chain); int place_x = std::get<0>(chain_origin_bel), place_y = std::get<1>(chain_origin_bel), place_z = std::get<2>(chain_origin_bel); if (place_x == -1) { @@ -233,7 +243,7 @@ class PlacementLegaliser // Place carry chain for (int i = 0; i < int(chain.cells.size()); i++) { int target_z = place_y * 8 + place_z + i; - place_lc(chain.cells.at(i), place_x, target_z / 8, target_z % 8); + place_lc(proxy, chain.cells.at(i), place_x, target_z / 8, target_z % 8); if (ctx->verbose) log_info(" Cell '%s' placed at (%d, %d, %d)\n", chain.cells.at(i)->name.c_str(ctx), place_x, target_z / 8, target_z % 8); @@ -243,7 +253,7 @@ class PlacementLegaliser } // Find Bel closest to a location, meeting chain requirements - std::tuple find_closest_bel(float target_x, float target_y, CellChain &chain) + std::tuple find_closest_bel(ArchRWProxy &proxy, float target_x, float target_y, CellChain &chain) { std::tuple best_origin = std::make_tuple(-1, -1, -1); wirelen_t best_wirelength = std::numeric_limits::max(); @@ -260,7 +270,7 @@ class PlacementLegaliser valid = false; break; } else { - wirelen += get_cell_wirelength_at_bel(ctx, chain.cells.at(k), lb.first); + wirelen += get_cell_wirelength_at_bel(proxy, ctx, chain.cells.at(k), lb.first); } } if (valid && wirelen < best_wirelength) { @@ -273,7 +283,7 @@ class PlacementLegaliser } // Split a carry chain into multiple legal chains - std::vector split_carry_chain(CellChain &carryc) + std::vector split_carry_chain(const ArchRProxy &proxy, CellChain &carryc) { bool start_of_chain = true; std::vector chains; @@ -298,7 +308,7 @@ class PlacementLegaliser } tile.push_back(cell); chains.back().cells.push_back(cell); - bool split_chain = (!ctx->logicCellsCompatible(tile)) || (int(chains.back().cells.size()) > max_length); + bool split_chain = (!proxy.logicCellsCompatible(tile)) || (int(chains.back().cells.size()) > max_length); if (split_chain) { CellInfo *passout = make_carry_pass_out(cell->ports.at(ctx->id("COUT"))); tile.pop_back(); @@ -325,22 +335,22 @@ class PlacementLegaliser } // Place a logic cell at a given grid location, handling rip-up etc - void place_lc(CellInfo *cell, int x, int y, int z) + void place_lc(ArchRWProxy &proxy, CellInfo *cell, int x, int y, int z) { auto &loc = logic_bels.at(x).at(y).at(z); NPNR_ASSERT(!loc.second); BelId bel = loc.first; // Check if there is a cell presently at the location, which we will need to rip up - IdString existing = ctx->getBoundBelCellUnlocked(bel); + IdString existing = proxy.getBoundBelCell(bel); if (existing != IdString()) { // TODO: keep track of the previous position of the ripped up cell, as a hint rippedCells.insert(existing); - ctx->unbindBelUnlocked(bel); + proxy.unbindBel(bel); } if (cell->bel != BelId()) { - ctx->unbindBelUnlocked(cell->bel); + proxy.unbindBel(cell->bel); } - ctx->bindBelUnlocked(bel, cell->name, STRENGTH_LOCKED); + proxy.bindBel(bel, cell->name, STRENGTH_LOCKED); rippedCells.erase(cell->name); // If cell was ripped up previously, no need to re-place loc.second = true; // Bel is now unavailable for further use } @@ -423,19 +433,20 @@ class PlacementLegaliser // Legalise logic tiles void legalise_logic_tiles() { + auto &&proxy = ctx->rwproxy(); int width = ctx->chip_info->width, height = ctx->chip_info->height; for (int x = 1; x < width; x++) { for (int y = 1; y < height; y++) { BelId tileBel = logic_bels.at(x).at(y).at(0).first; if (tileBel != BelId()) { bool changed = true; - while (!ctx->isBelLocationValid(tileBel) && changed) { + while (!proxy.isBelLocationValid(tileBel) && changed) { changed = false; int max_score = 0; CellInfo *target = nullptr; for (int z = 0; z < 8; z++) { BelId bel = logic_bels.at(x).at(y).at(z).first; - IdString cell = ctx->getBoundBelCellUnlocked(bel); + IdString cell = proxy.getBoundBelCell(bel); if (cell != IdString()) { CellInfo *ci = ctx->cells.at(cell).get(); if (ci->belStrength >= STRENGTH_STRONG) @@ -448,7 +459,7 @@ class PlacementLegaliser } } if (target != nullptr) { - ctx->unbindBelUnlocked(target->bel); + proxy.unbindBel(target->bel); rippedCells.insert(target->name); changed = true; } @@ -461,13 +472,14 @@ class PlacementLegaliser // Legalise other tiles void legalise_others() { + auto &&proxy = ctx->rwproxy(); std::vector legalised_others; for (auto cell : sorted(ctx->cells)) { CellInfo *ci = cell.second; if (!is_lc(ctx, ci)) { if (ci->belStrength < STRENGTH_STRONG && ci->bel != BelId()) { - if (!ctx->isValidBelForCell(ci, ci->bel)) { - place_single_cell(ctx, ci, true); + if (!proxy.isValidBelForCell(ci, ci->bel)) { + place_single_cell(proxy, ctx, ci, true); } legalised_others.push_back(ci); } @@ -482,10 +494,11 @@ class PlacementLegaliser // Replace ripped-up cells bool replace_cells() { + auto &&proxy = ctx->rwproxy(); bool success = true; for (auto cell : sorted(rippedCells)) { CellInfo *ci = ctx->cells.at(cell).get(); - bool placed = place_single_cell(ctx, ci, true); + bool placed = place_single_cell(proxy, ctx, ci, true); if (!placed) { if (ctx->force) { log_warning("failed to place cell '%s' of type '%s'\n", cell.c_str(ctx), ci->type.c_str(ctx)); -- cgit v1.2.3 From dc3256e62fce923a3dc703c521bea5a13cef4443 Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Fri, 13 Jul 2018 19:20:54 +0100 Subject: Comment arch.h --- ice40/arch.h | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) (limited to 'ice40') diff --git a/ice40/arch.h b/ice40/arch.h index 36e34d7b..8428dc29 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -328,15 +328,28 @@ struct ArchArgs std::string package; }; +/// Forward declare proxy classes for Arch. + class ArchRWProxyMethods; class ArchRProxyMethods; class ArchRWProxy; class ArchRProxy; + +/// Arch/Context +// Arch is the main state class of the PnR algorithms. It keeps note of mapped +// cells/nets, locked switches, etc. +// +// In order to mutate state in Arch, you can do one of two things: +// - directly call one of the wrapper methods to mutate state +// - get a read or readwrite proxy to the Arch, and call methods on it + class Arch : public BaseCtx { + // We let proxy methods access our state. friend class ArchRWProxyMethods; friend class ArchRProxyMethods; + // We let proxy objects access our mutex. friend class ArchRWProxy; friend class ArchRProxy; private: @@ -359,7 +372,13 @@ public: ArchArgs args; Arch(ArchArgs args); + // Get a readwrite proxy to arch - this will keep a readwrite lock on the + // entire architecture until the proxy object goes out of scope. ArchRWProxy rwproxy(void); + // Get a read-only proxy to arch - this will keep a read lock on the + // entire architecture until the proxy object goes out of scope. Other read + // locks can be taken while this one still exists. Ie., the UI can draw + // elements while the PnR is going a RO operation. ArchRProxy rproxy(void) const; std::string getChipName(); @@ -378,6 +397,9 @@ public: /// Wrappers around getting a r(w)proxy and calling a single method. // Deprecated: please acquire a proxy yourself and call the methods // you want on it. + // Warning: these will content with locks taken by the r(w)proxies, and + // thus can cause difficult to debug deadlocks - we'll be getting rid of + // them because of that. void unbindWire(WireId wire); void unbindPip(PipId pip); void unbindBel(BelId bel); @@ -554,6 +576,7 @@ public: // ------------------------------------------------- + // TODO(q3k) move this to archproxies? GroupId getGroupByName(IdString name) const; IdString getGroupName(GroupId group) const; std::vector getGroups() const; @@ -564,6 +587,8 @@ public: // ------------------------------------------------- + // These are also specific to the chip and not state, so they're available + // on arch directly. void estimatePosition(BelId bel, int &x, int &y, bool &gb) const; delay_t estimateDelay(WireId src, WireId dst) const; delay_t getDelayEpsilon() const { return 20; } @@ -608,7 +633,9 @@ public: IdString id_dff_en, id_neg_clk; }; +// Read-only methods on Arch that require state access. class ArchRProxyMethods { + // We let proxy objects access our private constructors. friend class ArchRProxy; friend class ArchRWProxy; private: @@ -641,7 +668,6 @@ public: WireId getWireBelPin(BelId bel, PortPin pin) const; PipId getPipByName(IdString name) const; - IdString getConflictingWireNet(WireId wire) const; IdString getConflictingPipNet(PipId pip) const; IdString getConflictingBelCell(BelId bel) const; @@ -653,6 +679,8 @@ public: BelId getBelByName(IdString name) const; }; +// A proxy object that keeps an Arch shared/readonly lock until it goes out +// of scope. All const/read-only ArchRProxyMethods are available on it. class ArchRProxy : public ArchRProxyMethods { friend class Arch; friend class ArchRWProxy; @@ -675,7 +703,9 @@ public: } }; +// State mutating methods on Arch. class ArchRWProxyMethods { + // We let proxy objects access our private constructors. friend class ArchRWProxy; private: Arch *parent_; @@ -691,9 +721,12 @@ public: void bindWire(WireId wire, IdString net, PlaceStrength strength); void bindPip(PipId pip, IdString net, PlaceStrength strength); void bindBel(BelId bel, IdString cell, PlaceStrength strength); + // Returned pointer is valid as long as Proxy object exists. CellInfo *getCell(IdString cell); }; +// A proxy object that keeps an Arch readwrite lock until it goes out of scope. +// All ArchRProxyMethods and ArchRWProxyMethods are available on it. class ArchRWProxy : public ArchRProxyMethods, public ArchRWProxyMethods { friend class Arch; private: -- cgit v1.2.3 From a71b576de6c404572439e30a56c4ff19497523a2 Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Fri, 13 Jul 2018 19:45:35 +0100 Subject: Slight simplification of proxy code --- ice40/arch.cc | 108 +++++++++++++++++++++++++++++----------------------------- ice40/arch.h | 53 ++++++++++++++++++++-------- 2 files changed, 93 insertions(+), 68 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.cc b/ice40/arch.cc index af31e147..af6e922c 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -736,19 +736,19 @@ bool Arch::isGlobalNet(const NetInfo *net) const bool ArchRProxyMethods::checkBelAvail(BelId bel) const { NPNR_ASSERT(bel != BelId()); - return parent_->bel_to_cell[bel.index] == IdString(); + return bel_to_cell[bel.index] == IdString(); } IdString ArchRProxyMethods::getBoundBelCell(BelId bel) const { NPNR_ASSERT(bel != BelId()); - return parent_->bel_to_cell[bel.index]; + return bel_to_cell[bel.index]; } IdString ArchRProxyMethods::getConflictingBelCell(BelId bel) const { NPNR_ASSERT(bel != BelId()); - return parent_->bel_to_cell[bel.index]; + return bel_to_cell[bel.index]; } WireId ArchRProxyMethods::getWireBelPin(BelId bel, PortPin pin) const @@ -757,8 +757,8 @@ WireId ArchRProxyMethods::getWireBelPin(BelId bel, PortPin pin) const NPNR_ASSERT(bel != BelId()); - int num_bel_wires = parent_->chip_info->bel_data[bel.index].num_bel_wires; - const BelWirePOD *bel_wires = parent_->chip_info->bel_data[bel.index].bel_wires.get(); + int num_bel_wires = chip_info->bel_data[bel.index].num_bel_wires; + const BelWirePOD *bel_wires = chip_info->bel_data[bel.index].bel_wires.get(); for (int i = 0; i < num_bel_wires; i++) if (bel_wires[i].port == pin) { @@ -773,13 +773,13 @@ WireId ArchRProxyMethods::getWireByName(IdString name) const { WireId ret; - if (parent_->wire_by_name.empty()) { - for (int i = 0; i < parent_->chip_info->num_wires; i++) - parent_->wire_by_name[parent_->id(parent_->chip_info->wire_data[i].name.get())] = i; + if (wire_by_name.empty()) { + for (int i = 0; i < chip_info->num_wires; i++) + wire_by_name[parent_->id(chip_info->wire_data[i].name.get())] = i; } - auto it = parent_->wire_by_name.find(name); - if (it != parent_->wire_by_name.end()) + auto it = wire_by_name.find(name); + if (it != wire_by_name.end()) ret.index = it->second; return ret; @@ -788,35 +788,35 @@ WireId ArchRProxyMethods::getWireByName(IdString name) const bool ArchRProxyMethods::checkWireAvail(WireId wire) const { NPNR_ASSERT(wire != WireId()); - return parent_->wire_to_net[wire.index] == IdString(); + return wire_to_net[wire.index] == IdString(); } IdString ArchRProxyMethods::getBoundWireNet(WireId wire) const { NPNR_ASSERT(wire != WireId()); - return parent_->wire_to_net[wire.index]; + return wire_to_net[wire.index]; } IdString ArchRProxyMethods::getConflictingWireNet(WireId wire) const { NPNR_ASSERT(wire != WireId()); - return parent_->wire_to_net[wire.index]; + return wire_to_net[wire.index]; } PipId ArchRProxyMethods::getPipByName(IdString name) const { PipId ret; - if (parent_->pip_by_name.empty()) { - for (int i = 0; i < parent_->chip_info->num_pips; i++) { + if (pip_by_name.empty()) { + for (int i = 0; i < chip_info->num_pips; i++) { PipId pip; pip.index = i; - parent_->pip_by_name[parent_->getPipName(pip)] = i; + pip_by_name[parent_->getPipName(pip)] = i; } } - auto it = parent_->pip_by_name.find(name); - if (it != parent_->pip_by_name.end()) + auto it = pip_by_name.find(name); + if (it != pip_by_name.end()) ret.index = it->second; return ret; @@ -825,32 +825,32 @@ PipId ArchRProxyMethods::getPipByName(IdString name) const bool ArchRProxyMethods::checkPipAvail(PipId pip) const { NPNR_ASSERT(pip != PipId()); - return parent_->switches_locked[parent_->chip_info->pip_data[pip.index].switch_index] == IdString(); + return switches_locked[chip_info->pip_data[pip.index].switch_index] == IdString(); } IdString ArchRProxyMethods::getBoundPipNet(PipId pip) const { NPNR_ASSERT(pip != PipId()); - return parent_->pip_to_net[pip.index]; + return pip_to_net[pip.index]; } IdString ArchRProxyMethods::getConflictingPipNet(PipId pip) const { NPNR_ASSERT(pip != PipId()); - return parent_->switches_locked[parent_->chip_info->pip_data[pip.index].switch_index]; + return switches_locked[chip_info->pip_data[pip.index].switch_index]; } BelId ArchRProxyMethods::getBelByName(IdString name) const { BelId ret; - if (parent_->bel_by_name.empty()) { - for (int i = 0; i < parent_->chip_info->num_bels; i++) - parent_->bel_by_name[parent_->id(parent_->chip_info->bel_data[i].name.get())] = i; + if (bel_by_name.empty()) { + for (int i = 0; i < chip_info->num_bels; i++) + bel_by_name[parent_->id(chip_info->bel_data[i].name.get())] = i; } - auto it = parent_->bel_by_name.find(name); - if (it != parent_->bel_by_name.end()) + auto it = bel_by_name.find(name); + if (it != bel_by_name.end()) ret.index = it->second; return ret; @@ -861,8 +861,8 @@ BelId ArchRProxyMethods::getBelByName(IdString name) const void ArchRWProxyMethods::bindBel(BelId bel, IdString cell, PlaceStrength strength) { NPNR_ASSERT(bel != BelId()); - NPNR_ASSERT(parent_->bel_to_cell[bel.index] == IdString()); - parent_->bel_to_cell[bel.index] = cell; + NPNR_ASSERT(bel_to_cell[bel.index] == IdString()); + bel_to_cell[bel.index] = cell; parent_->cells[cell]->bel = bel; parent_->cells[cell]->belStrength = strength; parent_->refreshUiBel(bel); @@ -871,19 +871,19 @@ void ArchRWProxyMethods::bindBel(BelId bel, IdString cell, PlaceStrength strengt void ArchRWProxyMethods::unbindBel(BelId bel) { NPNR_ASSERT(bel != BelId()); - NPNR_ASSERT(parent_->bel_to_cell[bel.index] != IdString()); - parent_->cells[parent_->bel_to_cell[bel.index]]->bel = BelId(); - parent_->cells[parent_->bel_to_cell[bel.index]]->belStrength = STRENGTH_NONE; - parent_->bel_to_cell[bel.index] = IdString(); + NPNR_ASSERT(bel_to_cell[bel.index] != IdString()); + parent_->cells[bel_to_cell[bel.index]]->bel = BelId(); + parent_->cells[bel_to_cell[bel.index]]->belStrength = STRENGTH_NONE; + bel_to_cell[bel.index] = IdString(); parent_->refreshUiBel(bel); } void ArchRWProxyMethods::bindWire(WireId wire, IdString net, PlaceStrength strength) { NPNR_ASSERT(wire != WireId()); - NPNR_ASSERT(parent_->wire_to_net[wire.index] == IdString()); + NPNR_ASSERT(wire_to_net[wire.index] == IdString()); - parent_->wire_to_net[wire.index] = net; + wire_to_net[wire.index] = net; parent_->nets[net]->wires[wire].pip = PipId(); parent_->nets[net]->wires[wire].strength = strength; parent_->refreshUiWire(wire); @@ -892,37 +892,37 @@ void ArchRWProxyMethods::bindWire(WireId wire, IdString net, PlaceStrength stren void ArchRWProxyMethods::unbindWire(WireId wire) { NPNR_ASSERT(wire != WireId()); - NPNR_ASSERT(parent_->wire_to_net[wire.index] != IdString()); + NPNR_ASSERT(wire_to_net[wire.index] != IdString()); - auto &net_wires = parent_->nets[parent_->wire_to_net[wire.index]]->wires; + auto &net_wires = parent_->nets[wire_to_net[wire.index]]->wires; auto it = net_wires.find(wire); NPNR_ASSERT(it != net_wires.end()); auto pip = it->second.pip; if (pip != PipId()) { - parent_->pip_to_net[pip.index] = IdString(); - parent_->switches_locked[parent_->chip_info->pip_data[pip.index].switch_index] = IdString(); + pip_to_net[pip.index] = IdString(); + switches_locked[chip_info->pip_data[pip.index].switch_index] = IdString(); parent_->refreshUiPip(pip); } net_wires.erase(it); - parent_->wire_to_net[wire.index] = IdString(); + wire_to_net[wire.index] = IdString(); parent_->refreshUiWire(wire); } void ArchRWProxyMethods::bindPip(PipId pip, IdString net, PlaceStrength strength) { NPNR_ASSERT(pip != PipId()); - NPNR_ASSERT(parent_->pip_to_net[pip.index] == IdString()); - NPNR_ASSERT(parent_->switches_locked[parent_->chip_info->pip_data[pip.index].switch_index] == IdString()); + NPNR_ASSERT(pip_to_net[pip.index] == IdString()); + NPNR_ASSERT(switches_locked[chip_info->pip_data[pip.index].switch_index] == IdString()); - parent_->pip_to_net[pip.index] = net; - parent_->switches_locked[parent_->chip_info->pip_data[pip.index].switch_index] = net; + pip_to_net[pip.index] = net; + switches_locked[chip_info->pip_data[pip.index].switch_index] = net; WireId dst; - dst.index = parent_->chip_info->pip_data[pip.index].dst; - NPNR_ASSERT(parent_->wire_to_net[dst.index] == IdString()); - parent_->wire_to_net[dst.index] = net; + dst.index = chip_info->pip_data[pip.index].dst; + NPNR_ASSERT(wire_to_net[dst.index] == IdString()); + wire_to_net[dst.index] = net; parent_->nets[net]->wires[dst].pip = pip; parent_->nets[net]->wires[dst].strength = strength; @@ -933,17 +933,17 @@ void ArchRWProxyMethods::bindPip(PipId pip, IdString net, PlaceStrength strength void ArchRWProxyMethods::unbindPip(PipId pip) { NPNR_ASSERT(pip != PipId()); - NPNR_ASSERT(parent_->pip_to_net[pip.index] != IdString()); - NPNR_ASSERT(parent_->switches_locked[parent_->chip_info->pip_data[pip.index].switch_index] != IdString()); + NPNR_ASSERT(pip_to_net[pip.index] != IdString()); + NPNR_ASSERT(switches_locked[chip_info->pip_data[pip.index].switch_index] != IdString()); WireId dst; - dst.index = parent_->chip_info->pip_data[pip.index].dst; - NPNR_ASSERT(parent_->wire_to_net[dst.index] != IdString()); - parent_->wire_to_net[dst.index] = IdString(); - parent_->nets[parent_->pip_to_net[pip.index]]->wires.erase(dst); + dst.index = chip_info->pip_data[pip.index].dst; + NPNR_ASSERT(wire_to_net[dst.index] != IdString()); + wire_to_net[dst.index] = IdString(); + parent_->nets[pip_to_net[pip.index]]->wires.erase(dst); - parent_->pip_to_net[pip.index] = IdString(); - parent_->switches_locked[parent_->chip_info->pip_data[pip.index].switch_index] = IdString(); + pip_to_net[pip.index] = IdString(); + switches_locked[chip_info->pip_data[pip.index].switch_index] = IdString(); parent_->refreshUiPip(pip); parent_->refreshUiWire(dst); diff --git a/ice40/arch.h b/ice40/arch.h index 8428dc29..da1e583a 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -339,7 +339,7 @@ class ArchRProxy; /// Arch/Context // Arch is the main state class of the PnR algorithms. It keeps note of mapped // cells/nets, locked switches, etc. -// +// // In order to mutate state in Arch, you can do one of two things: // - directly call one of the wrapper methods to mutate state // - get a read or readwrite proxy to the Arch, and call methods on it @@ -419,7 +419,7 @@ public: IdString getBoundPipNet(PipId pip) const; IdString getBoundBelCell(BelId bel) const; BelId getBelByName(IdString name) const; - + // ------------------------------------------------- /// Methods to get chip info - don't need to use a wrapper, as these are @@ -506,7 +506,7 @@ public: range.e.cursor = chip_info->num_pips; return range; } - + IdString getPipName(PipId pip) const; uint32_t getPipChecksum(PipId pip) const { return pip.index; } @@ -640,13 +640,27 @@ class ArchRProxyMethods { friend class ArchRWProxy; private: const Arch *parent_; - ArchRProxyMethods(const Arch *parent) : parent_(parent) {} - ArchRProxyMethods(ArchRProxyMethods &&other) noexcept : parent_(other.parent_) {} - ArchRProxyMethods(const ArchRProxyMethods &other) : parent_(other.parent_) {} - + ArchRProxyMethods(const Arch *parent) : parent_(parent), chip_info(parent->chip_info), + bel_to_cell(parent->bel_to_cell), wire_to_net(parent->wire_to_net), + pip_to_net(parent->pip_to_net), switches_locked(parent->switches_locked), + bel_by_name(parent->bel_by_name), wire_by_name(parent->wire_by_name), + pip_by_name(parent->pip_by_name) {} + ArchRProxyMethods(ArchRProxyMethods &&other) noexcept : ArchRProxyMethods(other.parent_) {} + ArchRProxyMethods(const ArchRProxyMethods &other) : ArchRProxyMethods(other.parent_) {} + + // Let methods access hot members directly without having to go through + // parent_. + const ChipInfoPOD *chip_info; + const std::vector &bel_to_cell; + const std::vector &wire_to_net; + const std::vector &pip_to_net; + const std::vector &switches_locked; + std::unordered_map &bel_by_name; + std::unordered_map &wire_by_name; + std::unordered_map &pip_by_name; public: ~ArchRProxyMethods() noexcept { } - + /// Perform placement validity checks, returning false on failure (all implemented in arch_place.cc) // Whether or not a given cell can be placed at a given Bel @@ -667,7 +681,7 @@ public: WireId getWireByName(IdString name) const; WireId getWireBelPin(BelId bel, PortPin pin) const; PipId getPipByName(IdString name) const; - + IdString getConflictingWireNet(WireId wire) const; IdString getConflictingPipNet(PipId pip) const; IdString getConflictingBelCell(BelId bel) const; @@ -709,9 +723,22 @@ class ArchRWProxyMethods { friend class ArchRWProxy; private: Arch *parent_; - ArchRWProxyMethods(Arch *parent) : parent_(parent) {} - ArchRWProxyMethods(ArchRWProxyMethods &&other) : parent_(other.parent_) {} - ArchRWProxyMethods(const ArchRWProxyMethods &other) : parent_(other.parent_) {} + ArchRWProxyMethods(Arch *parent) : parent_(parent), chip_info(parent->chip_info), + bel_to_cell(parent->bel_to_cell), wire_to_net(parent->wire_to_net), + pip_to_net(parent->pip_to_net), switches_locked(parent->switches_locked), + bel_by_name(parent->bel_by_name), wire_by_name(parent->wire_by_name), + pip_by_name(parent->pip_by_name) {} + ArchRWProxyMethods(ArchRWProxyMethods &&other) : ArchRWProxyMethods(other.parent_) {} + ArchRWProxyMethods(const ArchRWProxyMethods &other) : ArchRWProxyMethods(other.parent_) {} + + const ChipInfoPOD *chip_info; + std::vector &bel_to_cell; + std::vector &wire_to_net; + std::vector &pip_to_net; + std::vector &switches_locked; + std::unordered_map &bel_by_name; + std::unordered_map &wire_by_name; + std::unordered_map &pip_by_name; public: ~ArchRWProxyMethods() {} @@ -746,8 +773,6 @@ public: lock_->unlock(); } } - - }; NEXTPNR_NAMESPACE_END -- cgit v1.2.3 From a8c84e90a39c54174dd24b5b76bd17aed8311481 Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Fri, 13 Jul 2018 20:53:52 +0100 Subject: Make GUI nice and smooth. --- ice40/arch.cc | 10 +++++++--- ice40/arch.h | 8 ++++++-- ice40/main.cc | 3 ++- 3 files changed, 15 insertions(+), 6 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.cc b/ice40/arch.cc index af6e922c..547dbcd6 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -534,9 +534,8 @@ DecalXY Arch::getGroupDecal(GroupId group) const return decalxy; }; -std::vector Arch::getDecalGraphics(DecalId decal) const +std::vector ArchRProxyMethods::getDecalGraphics(DecalId decal) const { - boost::shared_lock_guard lock(mtx_); std::vector ret; if (decal.type == DecalId::TYPE_FRAME) { @@ -568,7 +567,7 @@ std::vector Arch::getDecalGraphics(DecalId decal) const BelId bel; bel.index = decal.index; - auto bel_type = getBelType(bel); + auto bel_type = parent_->getBelType(bel); if (bel_type == TYPE_ICESTORM_LC) { GraphicElement el; @@ -954,4 +953,9 @@ CellInfo *ArchRWProxyMethods::getCell(IdString cell) return parent_->cells.at(cell).get(); } +UIUpdatesRequired ArchRWProxyMethods::getUIUpdatesRequired(void) +{ + return parent_->getUIUpdatesRequired(); +} + NEXTPNR_NAMESPACE_END diff --git a/ice40/arch.h b/ice40/arch.h index da1e583a..4311f4a5 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -604,8 +604,6 @@ public: // ------------------------------------------------- - std::vector getDecalGraphics(DecalId decal) const; - DecalXY getFrameDecal() const; DecalXY getBelDecal(BelId bel) const; DecalXY getWireDecal(WireId wire) const; @@ -691,6 +689,8 @@ public: IdString getBoundBelCell(BelId bel) const; BelId getBelByName(IdString name) const; + + std::vector getDecalGraphics(DecalId decal) const; }; // A proxy object that keeps an Arch shared/readonly lock until it goes out @@ -750,6 +750,10 @@ public: void bindBel(BelId bel, IdString cell, PlaceStrength strength); // Returned pointer is valid as long as Proxy object exists. CellInfo *getCell(IdString cell); + + + // Methods to be used by UI for detecting whether we need to redraw. + UIUpdatesRequired getUIUpdatesRequired(void); }; // A proxy object that keeps an Arch readwrite lock until it goes out of scope. diff --git a/ice40/main.cc b/ice40/main.cc index e77bdd34..d38c786c 100644 --- a/ice40/main.cc +++ b/ice40/main.cc @@ -51,7 +51,8 @@ void svg_dump_decal(const Context *ctx, const DecalXY &decal) const float scale = 10.0, offset = 10.0; const std::string style = "stroke=\"black\" stroke-width=\"0.1\" fill=\"none\""; - for (auto &el : ctx->getDecalGraphics(decal.decal)) { + auto &&proxy = ctx->rproxy(); + for (auto &el : proxy.getDecalGraphics(decal.decal)) { if (el.type == GraphicElement::G_BOX) { std::cout << " Date: Sat, 14 Jul 2018 11:10:31 +0100 Subject: Refactor proxies to nextpnr. --- ice40/arch.cc | 77 +++++++++++----------------- ice40/arch.h | 130 ++++++++++------------------------------------- ice40/arch_place.cc | 6 +-- ice40/place_legaliser.cc | 6 +-- 4 files changed, 63 insertions(+), 156 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.cc b/ice40/arch.cc index 547dbcd6..790167e9 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -29,18 +29,6 @@ NEXTPNR_NAMESPACE_BEGIN -ArchRWProxy Arch::rwproxy(void) { - ArchRWProxy res(this); - return res; -} - -ArchRProxy Arch::rproxy(void) const { - ArchRProxy res(this); - return res; -} - -// ----------------------------------------------------------------------- - IdString Arch::belTypeToId(BelType type) const { if (type == TYPE_ICESTORM_LC) @@ -534,7 +522,7 @@ DecalXY Arch::getGroupDecal(GroupId group) const return decalxy; }; -std::vector ArchRProxyMethods::getDecalGraphics(DecalId decal) const +std::vector ArchReadMethods::getDecalGraphics(DecalId decal) const { std::vector ret; @@ -732,25 +720,25 @@ bool Arch::isGlobalNet(const NetInfo *net) const // ----------------------------------------------------------------------- -bool ArchRProxyMethods::checkBelAvail(BelId bel) const +bool ArchReadMethods::checkBelAvail(BelId bel) const { NPNR_ASSERT(bel != BelId()); return bel_to_cell[bel.index] == IdString(); } -IdString ArchRProxyMethods::getBoundBelCell(BelId bel) const +IdString ArchReadMethods::getBoundBelCell(BelId bel) const { NPNR_ASSERT(bel != BelId()); return bel_to_cell[bel.index]; } -IdString ArchRProxyMethods::getConflictingBelCell(BelId bel) const +IdString ArchReadMethods::getConflictingBelCell(BelId bel) const { NPNR_ASSERT(bel != BelId()); return bel_to_cell[bel.index]; } -WireId ArchRProxyMethods::getWireBelPin(BelId bel, PortPin pin) const +WireId ArchReadMethods::getWireBelPin(BelId bel, PortPin pin) const { WireId ret; @@ -768,7 +756,7 @@ WireId ArchRProxyMethods::getWireBelPin(BelId bel, PortPin pin) const return ret; } -WireId ArchRProxyMethods::getWireByName(IdString name) const +WireId ArchReadMethods::getWireByName(IdString name) const { WireId ret; @@ -784,25 +772,25 @@ WireId ArchRProxyMethods::getWireByName(IdString name) const return ret; } -bool ArchRProxyMethods::checkWireAvail(WireId wire) const +bool ArchReadMethods::checkWireAvail(WireId wire) const { NPNR_ASSERT(wire != WireId()); return wire_to_net[wire.index] == IdString(); } -IdString ArchRProxyMethods::getBoundWireNet(WireId wire) const +IdString ArchReadMethods::getBoundWireNet(WireId wire) const { NPNR_ASSERT(wire != WireId()); return wire_to_net[wire.index]; } -IdString ArchRProxyMethods::getConflictingWireNet(WireId wire) const +IdString ArchReadMethods::getConflictingWireNet(WireId wire) const { NPNR_ASSERT(wire != WireId()); return wire_to_net[wire.index]; } -PipId ArchRProxyMethods::getPipByName(IdString name) const +PipId ArchReadMethods::getPipByName(IdString name) const { PipId ret; @@ -821,25 +809,25 @@ PipId ArchRProxyMethods::getPipByName(IdString name) const return ret; } -bool ArchRProxyMethods::checkPipAvail(PipId pip) const +bool ArchReadMethods::checkPipAvail(PipId pip) const { NPNR_ASSERT(pip != PipId()); return switches_locked[chip_info->pip_data[pip.index].switch_index] == IdString(); } -IdString ArchRProxyMethods::getBoundPipNet(PipId pip) const +IdString ArchReadMethods::getBoundPipNet(PipId pip) const { NPNR_ASSERT(pip != PipId()); return pip_to_net[pip.index]; } -IdString ArchRProxyMethods::getConflictingPipNet(PipId pip) const +IdString ArchReadMethods::getConflictingPipNet(PipId pip) const { NPNR_ASSERT(pip != PipId()); return switches_locked[chip_info->pip_data[pip.index].switch_index]; } -BelId ArchRProxyMethods::getBelByName(IdString name) const +BelId ArchReadMethods::getBelByName(IdString name) const { BelId ret; @@ -857,27 +845,27 @@ BelId ArchRProxyMethods::getBelByName(IdString name) const // ----------------------------------------------------------------------- -void ArchRWProxyMethods::bindBel(BelId bel, IdString cell, PlaceStrength strength) +void ArchMutateMethods::bindBel(BelId bel, IdString cell, PlaceStrength strength) { NPNR_ASSERT(bel != BelId()); NPNR_ASSERT(bel_to_cell[bel.index] == IdString()); bel_to_cell[bel.index] = cell; parent_->cells[cell]->bel = bel; parent_->cells[cell]->belStrength = strength; - parent_->refreshUiBel(bel); + refreshUiBel(bel); } -void ArchRWProxyMethods::unbindBel(BelId bel) +void ArchMutateMethods::unbindBel(BelId bel) { NPNR_ASSERT(bel != BelId()); NPNR_ASSERT(bel_to_cell[bel.index] != IdString()); parent_->cells[bel_to_cell[bel.index]]->bel = BelId(); parent_->cells[bel_to_cell[bel.index]]->belStrength = STRENGTH_NONE; bel_to_cell[bel.index] = IdString(); - parent_->refreshUiBel(bel); + refreshUiBel(bel); } -void ArchRWProxyMethods::bindWire(WireId wire, IdString net, PlaceStrength strength) +void ArchMutateMethods::bindWire(WireId wire, IdString net, PlaceStrength strength) { NPNR_ASSERT(wire != WireId()); NPNR_ASSERT(wire_to_net[wire.index] == IdString()); @@ -885,10 +873,10 @@ void ArchRWProxyMethods::bindWire(WireId wire, IdString net, PlaceStrength stren wire_to_net[wire.index] = net; parent_->nets[net]->wires[wire].pip = PipId(); parent_->nets[net]->wires[wire].strength = strength; - parent_->refreshUiWire(wire); + refreshUiWire(wire); } -void ArchRWProxyMethods::unbindWire(WireId wire) +void ArchMutateMethods::unbindWire(WireId wire) { NPNR_ASSERT(wire != WireId()); NPNR_ASSERT(wire_to_net[wire.index] != IdString()); @@ -901,15 +889,15 @@ void ArchRWProxyMethods::unbindWire(WireId wire) if (pip != PipId()) { pip_to_net[pip.index] = IdString(); switches_locked[chip_info->pip_data[pip.index].switch_index] = IdString(); - parent_->refreshUiPip(pip); + refreshUiPip(pip); } net_wires.erase(it); wire_to_net[wire.index] = IdString(); - parent_->refreshUiWire(wire); + refreshUiWire(wire); } -void ArchRWProxyMethods::bindPip(PipId pip, IdString net, PlaceStrength strength) +void ArchMutateMethods::bindPip(PipId pip, IdString net, PlaceStrength strength) { NPNR_ASSERT(pip != PipId()); NPNR_ASSERT(pip_to_net[pip.index] == IdString()); @@ -925,11 +913,11 @@ void ArchRWProxyMethods::bindPip(PipId pip, IdString net, PlaceStrength strength parent_->nets[net]->wires[dst].pip = pip; parent_->nets[net]->wires[dst].strength = strength; - parent_->refreshUiPip(pip); - parent_->refreshUiWire(dst); + refreshUiPip(pip); + refreshUiWire(dst); } -void ArchRWProxyMethods::unbindPip(PipId pip) +void ArchMutateMethods::unbindPip(PipId pip) { NPNR_ASSERT(pip != PipId()); NPNR_ASSERT(pip_to_net[pip.index] != IdString()); @@ -944,18 +932,13 @@ void ArchRWProxyMethods::unbindPip(PipId pip) pip_to_net[pip.index] = IdString(); switches_locked[chip_info->pip_data[pip.index].switch_index] = IdString(); - parent_->refreshUiPip(pip); - parent_->refreshUiWire(dst); + refreshUiPip(pip); + refreshUiWire(dst); } -CellInfo *ArchRWProxyMethods::getCell(IdString cell) +CellInfo *ArchMutateMethods::getCell(IdString cell) { return parent_->cells.at(cell).get(); } -UIUpdatesRequired ArchRWProxyMethods::getUIUpdatesRequired(void) -{ - return parent_->getUIUpdatesRequired(); -} - NEXTPNR_NAMESPACE_END diff --git a/ice40/arch.h b/ice40/arch.h index 4311f4a5..5d4eaedf 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -22,9 +22,6 @@ #error Include "arch.h" via "nextpnr.h" only. #endif -#include -#include - NEXTPNR_NAMESPACE_BEGIN /**** Everything in this section must be kept in sync with chipdb.py ****/ @@ -330,11 +327,8 @@ struct ArchArgs /// Forward declare proxy classes for Arch. -class ArchRWProxyMethods; -class ArchRProxyMethods; -class ArchRWProxy; -class ArchRProxy; - +class ArchMutateMethods; +class ArchReadMethods; /// Arch/Context // Arch is the main state class of the PnR algorithms. It keeps note of mapped @@ -347,11 +341,8 @@ class ArchRProxy; class Arch : public BaseCtx { // We let proxy methods access our state. - friend class ArchRWProxyMethods; - friend class ArchRProxyMethods; - // We let proxy objects access our mutex. - friend class ArchRWProxy; - friend class ArchRProxy; + friend class ArchMutateMethods; + friend class ArchReadMethods; private: // All of the following... std::vector bel_to_cell; @@ -362,9 +353,6 @@ private: mutable std::unordered_map wire_by_name; mutable std::unordered_map pip_by_name; - // ... are guarded by the following lock: - mutable boost::shared_mutex mtx_; - public: const ChipInfoPOD *chip_info; const PackageInfoPOD *package_info; @@ -372,15 +360,6 @@ public: ArchArgs args; Arch(ArchArgs args); - // Get a readwrite proxy to arch - this will keep a readwrite lock on the - // entire architecture until the proxy object goes out of scope. - ArchRWProxy rwproxy(void); - // Get a read-only proxy to arch - this will keep a read lock on the - // entire architecture until the proxy object goes out of scope. Other read - // locks can be taken while this one still exists. Ie., the UI can draw - // elements while the PnR is going a RO operation. - ArchRProxy rproxy(void) const; - std::string getChipName(); IdString archId() const { return id("ice40"); } @@ -632,22 +611,9 @@ public: }; // Read-only methods on Arch that require state access. -class ArchRProxyMethods { - // We let proxy objects access our private constructors. - friend class ArchRProxy; - friend class ArchRWProxy; +class ArchReadMethods : public BaseReadCtx { private: const Arch *parent_; - ArchRProxyMethods(const Arch *parent) : parent_(parent), chip_info(parent->chip_info), - bel_to_cell(parent->bel_to_cell), wire_to_net(parent->wire_to_net), - pip_to_net(parent->pip_to_net), switches_locked(parent->switches_locked), - bel_by_name(parent->bel_by_name), wire_by_name(parent->wire_by_name), - pip_by_name(parent->pip_by_name) {} - ArchRProxyMethods(ArchRProxyMethods &&other) noexcept : ArchRProxyMethods(other.parent_) {} - ArchRProxyMethods(const ArchRProxyMethods &other) : ArchRProxyMethods(other.parent_) {} - - // Let methods access hot members directly without having to go through - // parent_. const ChipInfoPOD *chip_info; const std::vector &bel_to_cell; const std::vector &wire_to_net; @@ -656,8 +622,17 @@ private: std::unordered_map &bel_by_name; std::unordered_map &wire_by_name; std::unordered_map &pip_by_name; + public: - ~ArchRProxyMethods() noexcept { } + ~ArchReadMethods() noexcept { } + ArchReadMethods(const Arch *parent) : BaseReadCtx(parent), parent_(parent), + chip_info(parent->chip_info), bel_to_cell(parent->bel_to_cell), + wire_to_net(parent->wire_to_net), pip_to_net(parent->pip_to_net), + switches_locked(parent->switches_locked), + bel_by_name(parent->bel_by_name), wire_by_name(parent->wire_by_name), + pip_by_name(parent->pip_by_name) {} + ArchReadMethods(ArchReadMethods &&other) noexcept : ArchReadMethods(other.parent_) {} + ArchReadMethods(const ArchReadMethods &other) : ArchReadMethods(other.parent_) {} /// Perform placement validity checks, returning false on failure (all implemented in arch_place.cc) @@ -693,44 +668,11 @@ public: std::vector getDecalGraphics(DecalId decal) const; }; -// A proxy object that keeps an Arch shared/readonly lock until it goes out -// of scope. All const/read-only ArchRProxyMethods are available on it. -class ArchRProxy : public ArchRProxyMethods { - friend class Arch; - friend class ArchRWProxy; -private: - boost::shared_mutex *lock_; - ArchRProxy(const Arch *parent) : ArchRProxyMethods(parent), lock_(&parent->mtx_) - { - lock_->lock_shared(); - } - -public: - ~ArchRProxy() { - if (lock_ != nullptr) { - lock_->unlock_shared(); - } - } - ArchRProxy(ArchRProxy &&other) : ArchRProxyMethods(other), lock_(other.lock_) - { - other.lock_ = nullptr; - } -}; - // State mutating methods on Arch. -class ArchRWProxyMethods { - // We let proxy objects access our private constructors. - friend class ArchRWProxy; +class ArchMutateMethods : public BaseMutateCtx { + friend class MutateContext; private: Arch *parent_; - ArchRWProxyMethods(Arch *parent) : parent_(parent), chip_info(parent->chip_info), - bel_to_cell(parent->bel_to_cell), wire_to_net(parent->wire_to_net), - pip_to_net(parent->pip_to_net), switches_locked(parent->switches_locked), - bel_by_name(parent->bel_by_name), wire_by_name(parent->wire_by_name), - pip_by_name(parent->pip_by_name) {} - ArchRWProxyMethods(ArchRWProxyMethods &&other) : ArchRWProxyMethods(other.parent_) {} - ArchRWProxyMethods(const ArchRWProxyMethods &other) : ArchRWProxyMethods(other.parent_) {} - const ChipInfoPOD *chip_info; std::vector &bel_to_cell; std::vector &wire_to_net; @@ -739,8 +681,17 @@ private: std::unordered_map &bel_by_name; std::unordered_map &wire_by_name; std::unordered_map &pip_by_name; + public: - ~ArchRWProxyMethods() {} + ArchMutateMethods(Arch *parent) : BaseMutateCtx(parent), parent_(parent), + chip_info(parent->chip_info), bel_to_cell(parent->bel_to_cell), + wire_to_net(parent->wire_to_net), pip_to_net(parent->pip_to_net), + switches_locked(parent->switches_locked), + bel_by_name(parent->bel_by_name), wire_by_name(parent->wire_by_name), + pip_by_name(parent->pip_by_name) {} + ArchMutateMethods(ArchMutateMethods &&other) : ArchMutateMethods(other.parent_) {} + ArchMutateMethods(const ArchMutateMethods &other) : ArchMutateMethods(other.parent_) {} + ~ArchMutateMethods() {} void unbindWire(WireId wire); void unbindPip(PipId pip); @@ -750,33 +701,6 @@ public: void bindBel(BelId bel, IdString cell, PlaceStrength strength); // Returned pointer is valid as long as Proxy object exists. CellInfo *getCell(IdString cell); - - - // Methods to be used by UI for detecting whether we need to redraw. - UIUpdatesRequired getUIUpdatesRequired(void); -}; - -// A proxy object that keeps an Arch readwrite lock until it goes out of scope. -// All ArchRProxyMethods and ArchRWProxyMethods are available on it. -class ArchRWProxy : public ArchRProxyMethods, public ArchRWProxyMethods { - friend class Arch; -private: - boost::shared_mutex *lock_; - ArchRWProxy(Arch *parent) : ArchRProxyMethods(parent), ArchRWProxyMethods(parent), lock_(&parent->mtx_) { - lock_->lock(); - } - -public: - ArchRWProxy(ArchRWProxy &&other) : ArchRProxyMethods(other), ArchRWProxyMethods(other), lock_(other.lock_) - { - other.lock_ = nullptr; - } - ~ArchRWProxy() - { - if (lock_ != nullptr) { - lock_->unlock(); - } - } }; NEXTPNR_NAMESPACE_END diff --git a/ice40/arch_place.cc b/ice40/arch_place.cc index cb7c44b8..42efceab 100644 --- a/ice40/arch_place.cc +++ b/ice40/arch_place.cc @@ -25,7 +25,7 @@ NEXTPNR_NAMESPACE_BEGIN -bool ArchRProxyMethods::logicCellsCompatible(const std::vector &cells) const +bool ArchReadMethods::logicCellsCompatible(const std::vector &cells) const { bool dffs_exist = false, dffs_neg = false; const NetInfo *cen = nullptr, *clk = nullptr, *sr = nullptr; @@ -76,7 +76,7 @@ bool ArchRProxyMethods::logicCellsCompatible(const std::vector return locals_count <= 32; } -bool ArchRProxyMethods::isBelLocationValid(BelId bel) const +bool ArchReadMethods::isBelLocationValid(BelId bel) const { if (parent_->getBelType(bel) == TYPE_ICESTORM_LC) { std::vector bel_cells; @@ -97,7 +97,7 @@ bool ArchRProxyMethods::isBelLocationValid(BelId bel) const } } -bool ArchRProxyMethods::isValidBelForCell(CellInfo *cell, BelId bel) const +bool ArchReadMethods::isValidBelForCell(CellInfo *cell, BelId bel) const { if (cell->type == parent_->id_icestorm_lc) { NPNR_ASSERT(parent_->getBelType(bel) == TYPE_ICESTORM_LC); diff --git a/ice40/place_legaliser.cc b/ice40/place_legaliser.cc index 10a6f3ff..fcb47cfd 100644 --- a/ice40/place_legaliser.cc +++ b/ice40/place_legaliser.cc @@ -253,7 +253,7 @@ class PlacementLegaliser } // Find Bel closest to a location, meeting chain requirements - std::tuple find_closest_bel(ArchRWProxy &proxy, float target_x, float target_y, CellChain &chain) + std::tuple find_closest_bel(MutateContext &proxy, float target_x, float target_y, CellChain &chain) { std::tuple best_origin = std::make_tuple(-1, -1, -1); wirelen_t best_wirelength = std::numeric_limits::max(); @@ -283,7 +283,7 @@ class PlacementLegaliser } // Split a carry chain into multiple legal chains - std::vector split_carry_chain(const ArchRProxy &proxy, CellChain &carryc) + std::vector split_carry_chain(const ReadContext &proxy, CellChain &carryc) { bool start_of_chain = true; std::vector chains; @@ -335,7 +335,7 @@ class PlacementLegaliser } // Place a logic cell at a given grid location, handling rip-up etc - void place_lc(ArchRWProxy &proxy, CellInfo *cell, int x, int y, int z) + void place_lc(MutateContext &proxy, CellInfo *cell, int x, int y, int z) { auto &loc = logic_bels.at(x).at(y).at(z); NPNR_ASSERT(!loc.second); -- cgit v1.2.3 From 8ca7a6da2525463be5be4ee9f62cfae0acc06b01 Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Sat, 14 Jul 2018 11:10:59 +0100 Subject: clang-format --- ice40/arch.cc | 104 +++++++++++++--------------------------------------------- ice40/arch.h | 55 ++++++++++++++++--------------- 2 files changed, 50 insertions(+), 109 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.cc b/ice40/arch.cc index 790167e9..8f2731c6 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -259,99 +259,43 @@ BelRange Arch::getBelsAtSameTile(BelId bel) const // ----------------------------------------------------------------------- // Shorthands to ArchProxy -BelId Arch::getBelByName(IdString name) const -{ - return rproxy().getBelByName(name); -} +BelId Arch::getBelByName(IdString name) const { return rproxy().getBelByName(name); } -void Arch::bindWire(WireId wire, IdString net, PlaceStrength strength) -{ - rwproxy().bindWire(wire, net, strength); -} +void Arch::bindWire(WireId wire, IdString net, PlaceStrength strength) { rwproxy().bindWire(wire, net, strength); } -void Arch::unbindWire(WireId wire) -{ - rwproxy().unbindWire(wire); -} +void Arch::unbindWire(WireId wire) { rwproxy().unbindWire(wire); } -void Arch::bindBel(BelId bel, IdString cell, PlaceStrength strength) { - rwproxy().bindBel(bel, cell, strength); -} +void Arch::bindBel(BelId bel, IdString cell, PlaceStrength strength) { rwproxy().bindBel(bel, cell, strength); } -void Arch::unbindBel(BelId bel) -{ - rwproxy().unbindBel(bel); -} +void Arch::unbindBel(BelId bel) { rwproxy().unbindBel(bel); } -bool Arch::checkBelAvail(BelId bel) const -{ - return rproxy().checkBelAvail(bel); -} +bool Arch::checkBelAvail(BelId bel) const { return rproxy().checkBelAvail(bel); } -IdString Arch::getBoundBelCell(BelId bel) const -{ - return rproxy().getBoundBelCell(bel); -} +IdString Arch::getBoundBelCell(BelId bel) const { return rproxy().getBoundBelCell(bel); } -IdString Arch::getConflictingBelCell(BelId bel) const -{ - return rproxy().getConflictingBelCell(bel); -} +IdString Arch::getConflictingBelCell(BelId bel) const { return rproxy().getConflictingBelCell(bel); } -WireId Arch::getWireByName(IdString name) const -{ - return rproxy().getWireByName(name); -} +WireId Arch::getWireByName(IdString name) const { return rproxy().getWireByName(name); } -WireId Arch::getWireBelPin(BelId bel, PortPin pin) const -{ - return rproxy().getWireBelPin(bel, pin); -} +WireId Arch::getWireBelPin(BelId bel, PortPin pin) const { return rproxy().getWireBelPin(bel, pin); } -bool Arch::checkWireAvail(WireId wire) const -{ - return rproxy().checkWireAvail(wire); -} +bool Arch::checkWireAvail(WireId wire) const { return rproxy().checkWireAvail(wire); } -IdString Arch::getBoundWireNet(WireId wire) const -{ - return rproxy().getBoundWireNet(wire); -} +IdString Arch::getBoundWireNet(WireId wire) const { return rproxy().getBoundWireNet(wire); } -IdString Arch::getConflictingWireNet(WireId wire) const -{ - return rproxy().getConflictingWireNet(wire); -} +IdString Arch::getConflictingWireNet(WireId wire) const { return rproxy().getConflictingWireNet(wire); } -PipId Arch::getPipByName(IdString name) const -{ - return rproxy().getPipByName(name); -} +PipId Arch::getPipByName(IdString name) const { return rproxy().getPipByName(name); } -void Arch::bindPip(PipId pip, IdString net, PlaceStrength strength) -{ - return rwproxy().bindPip(pip, net, strength); -} +void Arch::bindPip(PipId pip, IdString net, PlaceStrength strength) { return rwproxy().bindPip(pip, net, strength); } -void Arch::unbindPip(PipId pip) -{ - return rwproxy().unbindPip(pip); -} +void Arch::unbindPip(PipId pip) { return rwproxy().unbindPip(pip); } -bool Arch::checkPipAvail(PipId pip) const -{ - return rproxy().checkPipAvail(pip); -} +bool Arch::checkPipAvail(PipId pip) const { return rproxy().checkPipAvail(pip); } -IdString Arch::getBoundPipNet(PipId pip) const -{ - return rproxy().getBoundPipNet(pip); -} +IdString Arch::getBoundPipNet(PipId pip) const { return rproxy().getBoundPipNet(pip); } -IdString Arch::getConflictingPipNet(PipId pip) const -{ - return rproxy().getConflictingPipNet(pip); -} +IdString Arch::getConflictingPipNet(PipId pip) const { return rproxy().getConflictingPipNet(pip); } // ----------------------------------------------------------------------- @@ -630,8 +574,7 @@ std::vector ArchReadMethods::getDecalGraphics(DecalId decal) con } if (bel_type == TYPE_ICESTORM_RAM) { - for (int i = 0; i < 2; i++) - { + for (int i = 0; i < 2; i++) { int tx = chip_info->bel_data[bel.index].x; int ty = chip_info->bel_data[bel.index].y + i; @@ -641,7 +584,7 @@ std::vector ArchReadMethods::getDecalGraphics(DecalId decal) con el.x1 = chip_info->bel_data[bel.index].x + logic_cell_x1; el.x2 = chip_info->bel_data[bel.index].x + logic_cell_x2; el.y1 = chip_info->bel_data[bel.index].y + logic_cell_y1; - el.y2 = chip_info->bel_data[bel.index].y + logic_cell_y2 + 7*logic_cell_pitch; + el.y2 = chip_info->bel_data[bel.index].y + logic_cell_y2 + 7 * logic_cell_pitch; el.z = 0; ret.push_back(el); @@ -936,9 +879,6 @@ void ArchMutateMethods::unbindPip(PipId pip) refreshUiWire(dst); } -CellInfo *ArchMutateMethods::getCell(IdString cell) -{ - return parent_->cells.at(cell).get(); -} +CellInfo *ArchMutateMethods::getCell(IdString cell) { return parent_->cells.at(cell).get(); } NEXTPNR_NAMESPACE_END diff --git a/ice40/arch.h b/ice40/arch.h index 5d4eaedf..f41990c3 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -343,7 +343,8 @@ class Arch : public BaseCtx // We let proxy methods access our state. friend class ArchMutateMethods; friend class ArchReadMethods; -private: + + private: // All of the following... std::vector bel_to_cell; std::vector wire_to_net; @@ -353,7 +354,7 @@ private: mutable std::unordered_map wire_by_name; mutable std::unordered_map pip_by_name; -public: + public: const ChipInfoPOD *chip_info; const PackageInfoPOD *package_info; @@ -410,10 +411,7 @@ public: return id(chip_info->bel_data[bel.index].name.get()); } - uint32_t getBelChecksum(BelId bel) const - { - return bel.index; - } + uint32_t getBelChecksum(BelId bel) const { return bel.index; } BelRange getBels() const { @@ -445,7 +443,6 @@ public: return chip_info->bel_data[bel.index].type; } - BelPin getBelPinUphill(WireId wire) const { BelPin ret; @@ -549,7 +546,6 @@ public: return range; } - BelId getPackagePinBel(const std::string &pin) const; std::string getBelPackagePin(BelId bel) const; @@ -611,8 +607,9 @@ public: }; // Read-only methods on Arch that require state access. -class ArchReadMethods : public BaseReadCtx { -private: +class ArchReadMethods : public BaseReadCtx +{ + private: const Arch *parent_; const ChipInfoPOD *chip_info; const std::vector &bel_to_cell; @@ -623,14 +620,15 @@ private: std::unordered_map &wire_by_name; std::unordered_map &pip_by_name; -public: - ~ArchReadMethods() noexcept { } - ArchReadMethods(const Arch *parent) : BaseReadCtx(parent), parent_(parent), - chip_info(parent->chip_info), bel_to_cell(parent->bel_to_cell), - wire_to_net(parent->wire_to_net), pip_to_net(parent->pip_to_net), - switches_locked(parent->switches_locked), - bel_by_name(parent->bel_by_name), wire_by_name(parent->wire_by_name), - pip_by_name(parent->pip_by_name) {} + public: + ~ArchReadMethods() noexcept {} + ArchReadMethods(const Arch *parent) + : BaseReadCtx(parent), parent_(parent), chip_info(parent->chip_info), bel_to_cell(parent->bel_to_cell), + wire_to_net(parent->wire_to_net), pip_to_net(parent->pip_to_net), + switches_locked(parent->switches_locked), bel_by_name(parent->bel_by_name), + wire_by_name(parent->wire_by_name), pip_by_name(parent->pip_by_name) + { + } ArchReadMethods(ArchReadMethods &&other) noexcept : ArchReadMethods(other.parent_) {} ArchReadMethods(const ArchReadMethods &other) : ArchReadMethods(other.parent_) {} @@ -669,9 +667,11 @@ public: }; // State mutating methods on Arch. -class ArchMutateMethods : public BaseMutateCtx { +class ArchMutateMethods : public BaseMutateCtx +{ friend class MutateContext; -private: + + private: Arch *parent_; const ChipInfoPOD *chip_info; std::vector &bel_to_cell; @@ -682,13 +682,14 @@ private: std::unordered_map &wire_by_name; std::unordered_map &pip_by_name; -public: - ArchMutateMethods(Arch *parent) : BaseMutateCtx(parent), parent_(parent), - chip_info(parent->chip_info), bel_to_cell(parent->bel_to_cell), - wire_to_net(parent->wire_to_net), pip_to_net(parent->pip_to_net), - switches_locked(parent->switches_locked), - bel_by_name(parent->bel_by_name), wire_by_name(parent->wire_by_name), - pip_by_name(parent->pip_by_name) {} + public: + ArchMutateMethods(Arch *parent) + : BaseMutateCtx(parent), parent_(parent), chip_info(parent->chip_info), bel_to_cell(parent->bel_to_cell), + wire_to_net(parent->wire_to_net), pip_to_net(parent->pip_to_net), + switches_locked(parent->switches_locked), bel_by_name(parent->bel_by_name), + wire_by_name(parent->wire_by_name), pip_by_name(parent->pip_by_name) + { + } ArchMutateMethods(ArchMutateMethods &&other) : ArchMutateMethods(other.parent_) {} ArchMutateMethods(const ArchMutateMethods &other) : ArchMutateMethods(other.parent_) {} ~ArchMutateMethods() {} -- cgit v1.2.3 From f333a68753655a4ccf7da9a4da96e7fdd19f9d08 Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Sat, 14 Jul 2018 11:25:38 +0100 Subject: Add read/mutate context stubs for ECP5 --- ice40/arch.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.h b/ice40/arch.h index f41990c3..cdee92e4 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -345,7 +345,6 @@ class Arch : public BaseCtx friend class ArchReadMethods; private: - // All of the following... std::vector bel_to_cell; std::vector wire_to_net; std::vector pip_to_net; @@ -633,15 +632,12 @@ class ArchReadMethods : public BaseReadCtx ArchReadMethods(const ArchReadMethods &other) : ArchReadMethods(other.parent_) {} /// Perform placement validity checks, returning false on failure (all implemented in arch_place.cc) - // Whether or not a given cell can be placed at a given Bel // This is not intended for Bel type checks, but finer-grained constraints // such as conflicting set/reset signals, etc bool isValidBelForCell(CellInfo *cell, BelId bel) const; - // Return true whether all Bels at a given location are valid bool isBelLocationValid(BelId bel) const; - // Helper function for above bool logicCellsCompatible(const std::vector &cells) const; -- cgit v1.2.3 From 3352ff4abbcac563e08d78ed8aa77728d00284a8 Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Sat, 14 Jul 2018 11:46:32 +0100 Subject: Move read methods to ReadMethods, remove some legacy access to Arch --- ice40/arch.h | 1 + ice40/picorv32.sh | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.h b/ice40/arch.h index cdee92e4..ec1e456f 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -578,6 +578,7 @@ class Arch : public BaseCtx // ------------------------------------------------- + // TODO(q3k) move this to archproxies? DecalXY getFrameDecal() const; DecalXY getBelDecal(BelId bel) const; DecalXY getWireDecal(WireId wire) const; diff --git a/ice40/picorv32.sh b/ice40/picorv32.sh index 2c67f641..0518db83 100755 --- a/ice40/picorv32.sh +++ b/ice40/picorv32.sh @@ -1,6 +1,6 @@ #!/bin/bash set -ex -rm -f picorv32.v -wget https://raw.githubusercontent.com/cliffordwolf/picorv32/master/picorv32.v -yosys -p 'synth_ice40 -nocarry -json picorv32.json -top top' picorv32.v picorv32_top.v -../nextpnr-ice40 --hx8k --asc picorv32.asc --json picorv32.json +#rm -f picorv32.v +#wget https://raw.githubusercontent.com/cliffordwolf/picorv32/master/picorv32.v +#yosys -p 'synth_ice40 -nocarry -json picorv32.json -top top' picorv32.v picorv32_top.v +CPUPROFILE=../profile ../nextpnr-ice40 --hx8k --asc picorv32.asc --json picorv32.json -- cgit v1.2.3 From 18b4b316782035daa259d65d26ea733ca4d16bea Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Sat, 14 Jul 2018 12:02:28 +0100 Subject: Remove legacy access to state via Arch --- ice40/arch.cc | 41 ------------------------------- ice40/arch.h | 28 --------------------- ice40/arch_pybindings.cc | 64 ++++++++++++++++++++++++------------------------ ice40/arch_pybindings.h | 18 +++++++++++--- ice40/bitstream.cc | 13 +++++----- ice40/main.cc | 21 ++++++++-------- 6 files changed, 65 insertions(+), 120 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.cc b/ice40/arch.cc index 8f2731c6..4727597b 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -256,47 +256,6 @@ BelRange Arch::getBelsAtSameTile(BelId bel) const return br; } -// ----------------------------------------------------------------------- -// Shorthands to ArchProxy - -BelId Arch::getBelByName(IdString name) const { return rproxy().getBelByName(name); } - -void Arch::bindWire(WireId wire, IdString net, PlaceStrength strength) { rwproxy().bindWire(wire, net, strength); } - -void Arch::unbindWire(WireId wire) { rwproxy().unbindWire(wire); } - -void Arch::bindBel(BelId bel, IdString cell, PlaceStrength strength) { rwproxy().bindBel(bel, cell, strength); } - -void Arch::unbindBel(BelId bel) { rwproxy().unbindBel(bel); } - -bool Arch::checkBelAvail(BelId bel) const { return rproxy().checkBelAvail(bel); } - -IdString Arch::getBoundBelCell(BelId bel) const { return rproxy().getBoundBelCell(bel); } - -IdString Arch::getConflictingBelCell(BelId bel) const { return rproxy().getConflictingBelCell(bel); } - -WireId Arch::getWireByName(IdString name) const { return rproxy().getWireByName(name); } - -WireId Arch::getWireBelPin(BelId bel, PortPin pin) const { return rproxy().getWireBelPin(bel, pin); } - -bool Arch::checkWireAvail(WireId wire) const { return rproxy().checkWireAvail(wire); } - -IdString Arch::getBoundWireNet(WireId wire) const { return rproxy().getBoundWireNet(wire); } - -IdString Arch::getConflictingWireNet(WireId wire) const { return rproxy().getConflictingWireNet(wire); } - -PipId Arch::getPipByName(IdString name) const { return rproxy().getPipByName(name); } - -void Arch::bindPip(PipId pip, IdString net, PlaceStrength strength) { return rwproxy().bindPip(pip, net, strength); } - -void Arch::unbindPip(PipId pip) { return rwproxy().unbindPip(pip); } - -bool Arch::checkPipAvail(PipId pip) const { return rproxy().checkPipAvail(pip); } - -IdString Arch::getBoundPipNet(PipId pip) const { return rproxy().getBoundPipNet(pip); } - -IdString Arch::getConflictingPipNet(PipId pip) const { return rproxy().getConflictingPipNet(pip); } - // ----------------------------------------------------------------------- IdString Arch::getPipName(PipId pip) const diff --git a/ice40/arch.h b/ice40/arch.h index ec1e456f..25ed8ebf 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -373,34 +373,6 @@ class Arch : public BaseCtx // ------------------------------------------------- - /// Wrappers around getting a r(w)proxy and calling a single method. - // Deprecated: please acquire a proxy yourself and call the methods - // you want on it. - // Warning: these will content with locks taken by the r(w)proxies, and - // thus can cause difficult to debug deadlocks - we'll be getting rid of - // them because of that. - void unbindWire(WireId wire); - void unbindPip(PipId pip); - void unbindBel(BelId bel); - void bindWire(WireId wire, IdString net, PlaceStrength strength); - void bindPip(PipId pip, IdString net, PlaceStrength strength); - void bindBel(BelId bel, IdString cell, PlaceStrength strength); - bool checkWireAvail(WireId wire) const; - bool checkPipAvail(PipId pip) const; - bool checkBelAvail(BelId bel) const; - WireId getWireByName(IdString name) const; - WireId getWireBelPin(BelId bel, PortPin pin) const; - PipId getPipByName(IdString name) const; - IdString getConflictingWireNet(WireId wire) const; - IdString getConflictingPipNet(PipId pip) const; - IdString getConflictingBelCell(BelId bel) const; - IdString getBoundWireNet(WireId wire) const; - IdString getBoundPipNet(PipId pip) const; - IdString getBoundBelCell(BelId bel) const; - BelId getBelByName(IdString name) const; - - // ------------------------------------------------- - /// Methods to get chip info - don't need to use a wrapper, as these are /// static per lifetime of object. diff --git a/ice40/arch_pybindings.cc b/ice40/arch_pybindings.cc index fd5109b4..aeb4348a 100644 --- a/ice40/arch_pybindings.cc +++ b/ice40/arch_pybindings.cc @@ -65,25 +65,25 @@ void arch_wrap_python() fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getBelType"); - fn_wrapper_1a, - conv_from_str>::def_wrap(ctx_cls, "checkBelAvail"); + //fn_wrapper_1a, + // conv_from_str>::def_wrap(ctx_cls, "checkBelAvail"); fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getBelChecksum"); - fn_wrapper_3a_v, - conv_from_str, pass_through>::def_wrap(ctx_cls, "bindBel"); - fn_wrapper_1a_v>::def_wrap( - ctx_cls, "unbindBel"); - fn_wrapper_1a, - conv_from_str>::def_wrap(ctx_cls, "getBoundBelCell"); - fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getConflictingBelCell"); + //fn_wrapper_3a_v, + // conv_from_str, pass_through>::def_wrap(ctx_cls, "bindBel"); + //fn_wrapper_1a_v>::def_wrap( + // ctx_cls, "unbindBel"); + //fn_wrapper_1a, + // conv_from_str>::def_wrap(ctx_cls, "getBoundBelCell"); + //fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getConflictingBelCell"); fn_wrapper_0a>::def_wrap(ctx_cls, "getBels"); fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getBelsAtSameTile"); - fn_wrapper_2a, - conv_from_str, conv_from_str>::def_wrap(ctx_cls, "getWireBelPin"); + //fn_wrapper_2a, + // conv_from_str, conv_from_str>::def_wrap(ctx_cls, "getWireBelPin"); fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getBelPinUphill"); fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getWireChecksum"); - fn_wrapper_3a_v, - conv_from_str, pass_through>::def_wrap(ctx_cls, "bindWire"); - fn_wrapper_1a_v>::def_wrap( - ctx_cls, "unbindWire"); - fn_wrapper_1a, - conv_from_str>::def_wrap(ctx_cls, "checkWireAvail"); - fn_wrapper_1a, - conv_from_str>::def_wrap(ctx_cls, "getBoundWireNet"); - fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getConflictingWireNet"); + //fn_wrapper_3a_v, + // conv_from_str, pass_through>::def_wrap(ctx_cls, "bindWire"); + //fn_wrapper_1a_v>::def_wrap( + // ctx_cls, "unbindWire"); + //fn_wrapper_1a, + // conv_from_str>::def_wrap(ctx_cls, "checkWireAvail"); + //fn_wrapper_1a, + // conv_from_str>::def_wrap(ctx_cls, "getBoundWireNet"); + //fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getConflictingWireNet"); fn_wrapper_0a>::def_wrap( ctx_cls, "getWires"); @@ -109,16 +109,16 @@ void arch_wrap_python() ctx_cls, "getPips"); fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getPipChecksum"); - fn_wrapper_3a_v, - conv_from_str, pass_through>::def_wrap(ctx_cls, "bindPip"); - fn_wrapper_1a_v>::def_wrap( - ctx_cls, "unbindPip"); - fn_wrapper_1a, - conv_from_str>::def_wrap(ctx_cls, "checkPipAvail"); - fn_wrapper_1a, - conv_from_str>::def_wrap(ctx_cls, "getBoundPipNet"); - fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getConflictingPipNet"); + //fn_wrapper_3a_v, + // conv_from_str, pass_through>::def_wrap(ctx_cls, "bindPip"); + //fn_wrapper_1a_v>::def_wrap( + // ctx_cls, "unbindPip"); + //fn_wrapper_1a, + // conv_from_str>::def_wrap(ctx_cls, "checkPipAvail"); + //fn_wrapper_1a, + // conv_from_str>::def_wrap(ctx_cls, "getBoundPipNet"); + //fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getConflictingPipNet"); fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getPipsDownhill"); diff --git a/ice40/arch_pybindings.h b/ice40/arch_pybindings.h index e502905f..7440e29d 100644 --- a/ice40/arch_pybindings.h +++ b/ice40/arch_pybindings.h @@ -31,7 +31,11 @@ namespace PythonConversion { template <> struct string_converter { - BelId from_str(Context *ctx, std::string name) { return ctx->getBelByName(ctx->id(name)); } + BelId from_str(Context *ctx, std::string name) + { + auto &&proxy = ctx->rproxy(); + return proxy.getBelByName(ctx->id(name)); + } std::string to_str(Context *ctx, BelId id) { @@ -50,14 +54,22 @@ template <> struct string_converter template <> struct string_converter { - WireId from_str(Context *ctx, std::string name) { return ctx->getWireByName(ctx->id(name)); } + WireId from_str(Context *ctx, std::string name) + { + auto &&proxy = ctx->rproxy(); + return proxy.getWireByName(ctx->id(name)); + } std::string to_str(Context *ctx, WireId id) { return ctx->getWireName(id).str(ctx); } }; template <> struct string_converter { - PipId from_str(Context *ctx, std::string name) { return ctx->getPipByName(ctx->id(name)); } + PipId from_str(Context *ctx, std::string name) + { + auto &&proxy = ctx->rproxy(); + return proxy.getPipByName(ctx->id(name)); + } std::string to_str(Context *ctx, PipId id) { return ctx->getPipName(id).str(ctx); } }; diff --git a/ice40/bitstream.cc b/ice40/bitstream.cc index 58a59366..87a96a22 100644 --- a/ice40/bitstream.cc +++ b/ice40/bitstream.cc @@ -92,6 +92,7 @@ char get_hexdigit(int i) { return std::string("0123456789ABCDEF").at(i); } void write_asc(const Context *ctx, std::ostream &out) { + auto &&proxy = ctx->rproxy(); // [y][x][row][col] const ChipInfoPOD &ci = *ctx->chip_info; const BitstreamInfoPOD &bi = *ci.bits_info; @@ -128,7 +129,7 @@ void write_asc(const Context *ctx, std::ostream &out) } // Set pips for (auto pip : ctx->getPips()) { - if (ctx->getBoundPipNet(pip) != IdString()) { + if (proxy.getBoundPipNet(pip) != IdString()) { const PipInfoPOD &pi = ci.pip_data[pip.index]; const SwitchInfoPOD &swi = bi.switches[pi.switch_index]; for (int i = 0; i < swi.num_bits; i++) { @@ -199,8 +200,8 @@ void write_asc(const Context *ctx, std::ostream &out) NPNR_ASSERT(iez != -1); bool input_en = false; - if (!ctx->checkWireAvail(ctx->getWireBelPin(bel, PIN_D_IN_0)) || - !ctx->checkWireAvail(ctx->getWireBelPin(bel, PIN_D_IN_1))) { + if (!proxy.checkWireAvail(proxy.getWireBelPin(bel, PIN_D_IN_0)) || + !proxy.checkWireAvail(proxy.getWireBelPin(bel, PIN_D_IN_1))) { input_en = true; } @@ -271,7 +272,7 @@ void write_asc(const Context *ctx, std::ostream &out) } // Set config bits in unused IO and RAM for (auto bel : ctx->getBels()) { - if (ctx->checkBelAvail(bel) && ctx->getBelType(bel) == TYPE_SB_IO) { + if (proxy.checkBelAvail(bel) && ctx->getBelType(bel) == TYPE_SB_IO) { const TileInfoPOD &ti = bi.tiles_nonrouting[TILE_IO]; const BelInfoPOD &beli = ci.bel_data[bel.index]; int x = beli.x, y = beli.y, z = beli.z; @@ -284,7 +285,7 @@ void write_asc(const Context *ctx, std::ostream &out) set_config(ti, config.at(iey).at(iex), "IoCtrl.REN_" + std::to_string(iez), false); } } - } else if (ctx->checkBelAvail(bel) && ctx->getBelType(bel) == TYPE_ICESTORM_RAM) { + } else if (proxy.checkBelAvail(bel) && ctx->getBelType(bel) == TYPE_ICESTORM_RAM) { const BelInfoPOD &beli = ci.bel_data[bel.index]; int x = beli.x, y = beli.y; const TileInfoPOD &ti = bi.tiles_nonrouting[TILE_RAMB]; @@ -431,7 +432,7 @@ void write_asc(const Context *ctx, std::ostream &out) // Write symbols // const bool write_symbols = 1; for (auto wire : ctx->getWires()) { - IdString net = ctx->getBoundWireNet(wire); + IdString net = proxy.getBoundWireNet(wire); if (net != IdString()) out << ".sym " << wire.index << " " << net.str(ctx) << std::endl; } diff --git a/ice40/main.cc b/ice40/main.cc index d38c786c..fdfe1f25 100644 --- a/ice40/main.cc +++ b/ice40/main.cc @@ -304,31 +304,32 @@ int main(int argc, char *argv[]) } if (vm.count("tmfuzz")) { + auto &&proxy = ctx->rproxy(); std::vector src_wires, dst_wires; /*for (auto w : ctx->getWires()) src_wires.push_back(w);*/ for (auto b : ctx->getBels()) { if (ctx->getBelType(b) == TYPE_ICESTORM_LC) { - src_wires.push_back(ctx->getWireBelPin(b, PIN_O)); + src_wires.push_back(proxy.getWireBelPin(b, PIN_O)); } if (ctx->getBelType(b) == TYPE_SB_IO) { - src_wires.push_back(ctx->getWireBelPin(b, PIN_D_IN_0)); + src_wires.push_back(proxy.getWireBelPin(b, PIN_D_IN_0)); } } for (auto b : ctx->getBels()) { if (ctx->getBelType(b) == TYPE_ICESTORM_LC) { - dst_wires.push_back(ctx->getWireBelPin(b, PIN_I0)); - dst_wires.push_back(ctx->getWireBelPin(b, PIN_I1)); - dst_wires.push_back(ctx->getWireBelPin(b, PIN_I2)); - dst_wires.push_back(ctx->getWireBelPin(b, PIN_I3)); - dst_wires.push_back(ctx->getWireBelPin(b, PIN_CEN)); - dst_wires.push_back(ctx->getWireBelPin(b, PIN_CIN)); + dst_wires.push_back(proxy.getWireBelPin(b, PIN_I0)); + dst_wires.push_back(proxy.getWireBelPin(b, PIN_I1)); + dst_wires.push_back(proxy.getWireBelPin(b, PIN_I2)); + dst_wires.push_back(proxy.getWireBelPin(b, PIN_I3)); + dst_wires.push_back(proxy.getWireBelPin(b, PIN_CEN)); + dst_wires.push_back(proxy.getWireBelPin(b, PIN_CIN)); } if (ctx->getBelType(b) == TYPE_SB_IO) { - dst_wires.push_back(ctx->getWireBelPin(b, PIN_D_OUT_0)); - dst_wires.push_back(ctx->getWireBelPin(b, PIN_OUTPUT_ENABLE)); + dst_wires.push_back(proxy.getWireBelPin(b, PIN_D_OUT_0)); + dst_wires.push_back(proxy.getWireBelPin(b, PIN_OUTPUT_ENABLE)); } } -- cgit v1.2.3 From 53393b993fb211a3ce98262b0dd636d2e8420d2d Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Sat, 14 Jul 2018 12:11:20 +0100 Subject: Remove unimplemented pybindings (for now) We need to re-jigger the template magic in common/pywrappers.h to be proxy context aware. --- ice40/arch_pybindings.cc | 32 -------------------------------- 1 file changed, 32 deletions(-) (limited to 'ice40') diff --git a/ice40/arch_pybindings.cc b/ice40/arch_pybindings.cc index aeb4348a..a2a90191 100644 --- a/ice40/arch_pybindings.cc +++ b/ice40/arch_pybindings.cc @@ -65,25 +65,13 @@ void arch_wrap_python() fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getBelType"); - //fn_wrapper_1a, - // conv_from_str>::def_wrap(ctx_cls, "checkBelAvail"); fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getBelChecksum"); - //fn_wrapper_3a_v, - // conv_from_str, pass_through>::def_wrap(ctx_cls, "bindBel"); - //fn_wrapper_1a_v>::def_wrap( - // ctx_cls, "unbindBel"); - //fn_wrapper_1a, - // conv_from_str>::def_wrap(ctx_cls, "getBoundBelCell"); - //fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getConflictingBelCell"); fn_wrapper_0a>::def_wrap(ctx_cls, "getBels"); fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getBelsAtSameTile"); - //fn_wrapper_2a, - // conv_from_str, conv_from_str>::def_wrap(ctx_cls, "getWireBelPin"); fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getBelPinUphill"); fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getWireChecksum"); - //fn_wrapper_3a_v, - // conv_from_str, pass_through>::def_wrap(ctx_cls, "bindWire"); - //fn_wrapper_1a_v>::def_wrap( - // ctx_cls, "unbindWire"); - //fn_wrapper_1a, - // conv_from_str>::def_wrap(ctx_cls, "checkWireAvail"); - //fn_wrapper_1a, - // conv_from_str>::def_wrap(ctx_cls, "getBoundWireNet"); - //fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getConflictingWireNet"); fn_wrapper_0a>::def_wrap( ctx_cls, "getWires"); @@ -109,16 +87,6 @@ void arch_wrap_python() ctx_cls, "getPips"); fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getPipChecksum"); - //fn_wrapper_3a_v, - // conv_from_str, pass_through>::def_wrap(ctx_cls, "bindPip"); - //fn_wrapper_1a_v>::def_wrap( - // ctx_cls, "unbindPip"); - //fn_wrapper_1a, - // conv_from_str>::def_wrap(ctx_cls, "checkPipAvail"); - //fn_wrapper_1a, - // conv_from_str>::def_wrap(ctx_cls, "getBoundPipNet"); - //fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getConflictingPipNet"); fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getPipsDownhill"); -- cgit v1.2.3 From 98c594885698b557311ac84195599b35968719e0 Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Sat, 14 Jul 2018 12:14:30 +0100 Subject: Undo accidental picorv32.sh commit --- ice40/picorv32.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'ice40') diff --git a/ice40/picorv32.sh b/ice40/picorv32.sh index 0518db83..2c67f641 100755 --- a/ice40/picorv32.sh +++ b/ice40/picorv32.sh @@ -1,6 +1,6 @@ #!/bin/bash set -ex -#rm -f picorv32.v -#wget https://raw.githubusercontent.com/cliffordwolf/picorv32/master/picorv32.v -#yosys -p 'synth_ice40 -nocarry -json picorv32.json -top top' picorv32.v picorv32_top.v -CPUPROFILE=../profile ../nextpnr-ice40 --hx8k --asc picorv32.asc --json picorv32.json +rm -f picorv32.v +wget https://raw.githubusercontent.com/cliffordwolf/picorv32/master/picorv32.v +yosys -p 'synth_ice40 -nocarry -json picorv32.json -top top' picorv32.v picorv32_top.v +../nextpnr-ice40 --hx8k --asc picorv32.asc --json picorv32.json -- cgit v1.2.3 From 9c013ce74c393c4bb14d1722fefaeb27d57ccae3 Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Sat, 14 Jul 2018 18:50:01 +0100 Subject: Revert "Undo accidental picorv32.sh commit" This reverts commit 98c594885698b557311ac84195599b35968719e0. --- ice40/picorv32.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'ice40') diff --git a/ice40/picorv32.sh b/ice40/picorv32.sh index 2c67f641..0518db83 100755 --- a/ice40/picorv32.sh +++ b/ice40/picorv32.sh @@ -1,6 +1,6 @@ #!/bin/bash set -ex -rm -f picorv32.v -wget https://raw.githubusercontent.com/cliffordwolf/picorv32/master/picorv32.v -yosys -p 'synth_ice40 -nocarry -json picorv32.json -top top' picorv32.v picorv32_top.v -../nextpnr-ice40 --hx8k --asc picorv32.asc --json picorv32.json +#rm -f picorv32.v +#wget https://raw.githubusercontent.com/cliffordwolf/picorv32/master/picorv32.v +#yosys -p 'synth_ice40 -nocarry -json picorv32.json -top top' picorv32.v picorv32_top.v +CPUPROFILE=../profile ../nextpnr-ice40 --hx8k --asc picorv32.asc --json picorv32.json -- cgit v1.2.3 From 339198b394b7f2cdd3bafb2c8c819c1561813f65 Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Sat, 14 Jul 2018 18:50:07 +0100 Subject: Revert "Remove unimplemented pybindings (for now)" This reverts commit 53393b993fb211a3ce98262b0dd636d2e8420d2d. --- ice40/arch_pybindings.cc | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'ice40') diff --git a/ice40/arch_pybindings.cc b/ice40/arch_pybindings.cc index a2a90191..aeb4348a 100644 --- a/ice40/arch_pybindings.cc +++ b/ice40/arch_pybindings.cc @@ -65,13 +65,25 @@ void arch_wrap_python() fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getBelType"); + //fn_wrapper_1a, + // conv_from_str>::def_wrap(ctx_cls, "checkBelAvail"); fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getBelChecksum"); + //fn_wrapper_3a_v, + // conv_from_str, pass_through>::def_wrap(ctx_cls, "bindBel"); + //fn_wrapper_1a_v>::def_wrap( + // ctx_cls, "unbindBel"); + //fn_wrapper_1a, + // conv_from_str>::def_wrap(ctx_cls, "getBoundBelCell"); + //fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getConflictingBelCell"); fn_wrapper_0a>::def_wrap(ctx_cls, "getBels"); fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getBelsAtSameTile"); + //fn_wrapper_2a, + // conv_from_str, conv_from_str>::def_wrap(ctx_cls, "getWireBelPin"); fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getBelPinUphill"); fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getWireChecksum"); + //fn_wrapper_3a_v, + // conv_from_str, pass_through>::def_wrap(ctx_cls, "bindWire"); + //fn_wrapper_1a_v>::def_wrap( + // ctx_cls, "unbindWire"); + //fn_wrapper_1a, + // conv_from_str>::def_wrap(ctx_cls, "checkWireAvail"); + //fn_wrapper_1a, + // conv_from_str>::def_wrap(ctx_cls, "getBoundWireNet"); + //fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getConflictingWireNet"); fn_wrapper_0a>::def_wrap( ctx_cls, "getWires"); @@ -87,6 +109,16 @@ void arch_wrap_python() ctx_cls, "getPips"); fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getPipChecksum"); + //fn_wrapper_3a_v, + // conv_from_str, pass_through>::def_wrap(ctx_cls, "bindPip"); + //fn_wrapper_1a_v>::def_wrap( + // ctx_cls, "unbindPip"); + //fn_wrapper_1a, + // conv_from_str>::def_wrap(ctx_cls, "checkPipAvail"); + //fn_wrapper_1a, + // conv_from_str>::def_wrap(ctx_cls, "getBoundPipNet"); + //fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getConflictingPipNet"); fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getPipsDownhill"); -- cgit v1.2.3 From 22330402018a212efd4ef2e337e34af2e79eb875 Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Sat, 14 Jul 2018 18:50:15 +0100 Subject: Revert "Remove legacy access to state via Arch" This reverts commit 18b4b316782035daa259d65d26ea733ca4d16bea. --- ice40/arch.cc | 41 +++++++++++++++++++++++++++++++ ice40/arch.h | 28 +++++++++++++++++++++ ice40/arch_pybindings.cc | 64 ++++++++++++++++++++++++------------------------ ice40/arch_pybindings.h | 18 +++----------- ice40/bitstream.cc | 13 +++++----- ice40/main.cc | 21 ++++++++-------- 6 files changed, 120 insertions(+), 65 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.cc b/ice40/arch.cc index 4727597b..8f2731c6 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -256,6 +256,47 @@ BelRange Arch::getBelsAtSameTile(BelId bel) const return br; } +// ----------------------------------------------------------------------- +// Shorthands to ArchProxy + +BelId Arch::getBelByName(IdString name) const { return rproxy().getBelByName(name); } + +void Arch::bindWire(WireId wire, IdString net, PlaceStrength strength) { rwproxy().bindWire(wire, net, strength); } + +void Arch::unbindWire(WireId wire) { rwproxy().unbindWire(wire); } + +void Arch::bindBel(BelId bel, IdString cell, PlaceStrength strength) { rwproxy().bindBel(bel, cell, strength); } + +void Arch::unbindBel(BelId bel) { rwproxy().unbindBel(bel); } + +bool Arch::checkBelAvail(BelId bel) const { return rproxy().checkBelAvail(bel); } + +IdString Arch::getBoundBelCell(BelId bel) const { return rproxy().getBoundBelCell(bel); } + +IdString Arch::getConflictingBelCell(BelId bel) const { return rproxy().getConflictingBelCell(bel); } + +WireId Arch::getWireByName(IdString name) const { return rproxy().getWireByName(name); } + +WireId Arch::getWireBelPin(BelId bel, PortPin pin) const { return rproxy().getWireBelPin(bel, pin); } + +bool Arch::checkWireAvail(WireId wire) const { return rproxy().checkWireAvail(wire); } + +IdString Arch::getBoundWireNet(WireId wire) const { return rproxy().getBoundWireNet(wire); } + +IdString Arch::getConflictingWireNet(WireId wire) const { return rproxy().getConflictingWireNet(wire); } + +PipId Arch::getPipByName(IdString name) const { return rproxy().getPipByName(name); } + +void Arch::bindPip(PipId pip, IdString net, PlaceStrength strength) { return rwproxy().bindPip(pip, net, strength); } + +void Arch::unbindPip(PipId pip) { return rwproxy().unbindPip(pip); } + +bool Arch::checkPipAvail(PipId pip) const { return rproxy().checkPipAvail(pip); } + +IdString Arch::getBoundPipNet(PipId pip) const { return rproxy().getBoundPipNet(pip); } + +IdString Arch::getConflictingPipNet(PipId pip) const { return rproxy().getConflictingPipNet(pip); } + // ----------------------------------------------------------------------- IdString Arch::getPipName(PipId pip) const diff --git a/ice40/arch.h b/ice40/arch.h index 25ed8ebf..ec1e456f 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -373,6 +373,34 @@ class Arch : public BaseCtx // ------------------------------------------------- + /// Wrappers around getting a r(w)proxy and calling a single method. + // Deprecated: please acquire a proxy yourself and call the methods + // you want on it. + // Warning: these will content with locks taken by the r(w)proxies, and + // thus can cause difficult to debug deadlocks - we'll be getting rid of + // them because of that. + void unbindWire(WireId wire); + void unbindPip(PipId pip); + void unbindBel(BelId bel); + void bindWire(WireId wire, IdString net, PlaceStrength strength); + void bindPip(PipId pip, IdString net, PlaceStrength strength); + void bindBel(BelId bel, IdString cell, PlaceStrength strength); + bool checkWireAvail(WireId wire) const; + bool checkPipAvail(PipId pip) const; + bool checkBelAvail(BelId bel) const; + WireId getWireByName(IdString name) const; + WireId getWireBelPin(BelId bel, PortPin pin) const; + PipId getPipByName(IdString name) const; + IdString getConflictingWireNet(WireId wire) const; + IdString getConflictingPipNet(PipId pip) const; + IdString getConflictingBelCell(BelId bel) const; + IdString getBoundWireNet(WireId wire) const; + IdString getBoundPipNet(PipId pip) const; + IdString getBoundBelCell(BelId bel) const; + BelId getBelByName(IdString name) const; + + // ------------------------------------------------- + /// Methods to get chip info - don't need to use a wrapper, as these are /// static per lifetime of object. diff --git a/ice40/arch_pybindings.cc b/ice40/arch_pybindings.cc index aeb4348a..fd5109b4 100644 --- a/ice40/arch_pybindings.cc +++ b/ice40/arch_pybindings.cc @@ -65,25 +65,25 @@ void arch_wrap_python() fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getBelType"); - //fn_wrapper_1a, - // conv_from_str>::def_wrap(ctx_cls, "checkBelAvail"); + fn_wrapper_1a, + conv_from_str>::def_wrap(ctx_cls, "checkBelAvail"); fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getBelChecksum"); - //fn_wrapper_3a_v, - // conv_from_str, pass_through>::def_wrap(ctx_cls, "bindBel"); - //fn_wrapper_1a_v>::def_wrap( - // ctx_cls, "unbindBel"); - //fn_wrapper_1a, - // conv_from_str>::def_wrap(ctx_cls, "getBoundBelCell"); - //fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getConflictingBelCell"); + fn_wrapper_3a_v, + conv_from_str, pass_through>::def_wrap(ctx_cls, "bindBel"); + fn_wrapper_1a_v>::def_wrap( + ctx_cls, "unbindBel"); + fn_wrapper_1a, + conv_from_str>::def_wrap(ctx_cls, "getBoundBelCell"); + fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getConflictingBelCell"); fn_wrapper_0a>::def_wrap(ctx_cls, "getBels"); fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getBelsAtSameTile"); - //fn_wrapper_2a, - // conv_from_str, conv_from_str>::def_wrap(ctx_cls, "getWireBelPin"); + fn_wrapper_2a, + conv_from_str, conv_from_str>::def_wrap(ctx_cls, "getWireBelPin"); fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getBelPinUphill"); fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getWireChecksum"); - //fn_wrapper_3a_v, - // conv_from_str, pass_through>::def_wrap(ctx_cls, "bindWire"); - //fn_wrapper_1a_v>::def_wrap( - // ctx_cls, "unbindWire"); - //fn_wrapper_1a, - // conv_from_str>::def_wrap(ctx_cls, "checkWireAvail"); - //fn_wrapper_1a, - // conv_from_str>::def_wrap(ctx_cls, "getBoundWireNet"); - //fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getConflictingWireNet"); + fn_wrapper_3a_v, + conv_from_str, pass_through>::def_wrap(ctx_cls, "bindWire"); + fn_wrapper_1a_v>::def_wrap( + ctx_cls, "unbindWire"); + fn_wrapper_1a, + conv_from_str>::def_wrap(ctx_cls, "checkWireAvail"); + fn_wrapper_1a, + conv_from_str>::def_wrap(ctx_cls, "getBoundWireNet"); + fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getConflictingWireNet"); fn_wrapper_0a>::def_wrap( ctx_cls, "getWires"); @@ -109,16 +109,16 @@ void arch_wrap_python() ctx_cls, "getPips"); fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getPipChecksum"); - //fn_wrapper_3a_v, - // conv_from_str, pass_through>::def_wrap(ctx_cls, "bindPip"); - //fn_wrapper_1a_v>::def_wrap( - // ctx_cls, "unbindPip"); - //fn_wrapper_1a, - // conv_from_str>::def_wrap(ctx_cls, "checkPipAvail"); - //fn_wrapper_1a, - // conv_from_str>::def_wrap(ctx_cls, "getBoundPipNet"); - //fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getConflictingPipNet"); + fn_wrapper_3a_v, + conv_from_str, pass_through>::def_wrap(ctx_cls, "bindPip"); + fn_wrapper_1a_v>::def_wrap( + ctx_cls, "unbindPip"); + fn_wrapper_1a, + conv_from_str>::def_wrap(ctx_cls, "checkPipAvail"); + fn_wrapper_1a, + conv_from_str>::def_wrap(ctx_cls, "getBoundPipNet"); + fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getConflictingPipNet"); fn_wrapper_1a, conv_from_str>::def_wrap(ctx_cls, "getPipsDownhill"); diff --git a/ice40/arch_pybindings.h b/ice40/arch_pybindings.h index 7440e29d..e502905f 100644 --- a/ice40/arch_pybindings.h +++ b/ice40/arch_pybindings.h @@ -31,11 +31,7 @@ namespace PythonConversion { template <> struct string_converter { - BelId from_str(Context *ctx, std::string name) - { - auto &&proxy = ctx->rproxy(); - return proxy.getBelByName(ctx->id(name)); - } + BelId from_str(Context *ctx, std::string name) { return ctx->getBelByName(ctx->id(name)); } std::string to_str(Context *ctx, BelId id) { @@ -54,22 +50,14 @@ template <> struct string_converter template <> struct string_converter { - WireId from_str(Context *ctx, std::string name) - { - auto &&proxy = ctx->rproxy(); - return proxy.getWireByName(ctx->id(name)); - } + WireId from_str(Context *ctx, std::string name) { return ctx->getWireByName(ctx->id(name)); } std::string to_str(Context *ctx, WireId id) { return ctx->getWireName(id).str(ctx); } }; template <> struct string_converter { - PipId from_str(Context *ctx, std::string name) - { - auto &&proxy = ctx->rproxy(); - return proxy.getPipByName(ctx->id(name)); - } + PipId from_str(Context *ctx, std::string name) { return ctx->getPipByName(ctx->id(name)); } std::string to_str(Context *ctx, PipId id) { return ctx->getPipName(id).str(ctx); } }; diff --git a/ice40/bitstream.cc b/ice40/bitstream.cc index 87a96a22..58a59366 100644 --- a/ice40/bitstream.cc +++ b/ice40/bitstream.cc @@ -92,7 +92,6 @@ char get_hexdigit(int i) { return std::string("0123456789ABCDEF").at(i); } void write_asc(const Context *ctx, std::ostream &out) { - auto &&proxy = ctx->rproxy(); // [y][x][row][col] const ChipInfoPOD &ci = *ctx->chip_info; const BitstreamInfoPOD &bi = *ci.bits_info; @@ -129,7 +128,7 @@ void write_asc(const Context *ctx, std::ostream &out) } // Set pips for (auto pip : ctx->getPips()) { - if (proxy.getBoundPipNet(pip) != IdString()) { + if (ctx->getBoundPipNet(pip) != IdString()) { const PipInfoPOD &pi = ci.pip_data[pip.index]; const SwitchInfoPOD &swi = bi.switches[pi.switch_index]; for (int i = 0; i < swi.num_bits; i++) { @@ -200,8 +199,8 @@ void write_asc(const Context *ctx, std::ostream &out) NPNR_ASSERT(iez != -1); bool input_en = false; - if (!proxy.checkWireAvail(proxy.getWireBelPin(bel, PIN_D_IN_0)) || - !proxy.checkWireAvail(proxy.getWireBelPin(bel, PIN_D_IN_1))) { + if (!ctx->checkWireAvail(ctx->getWireBelPin(bel, PIN_D_IN_0)) || + !ctx->checkWireAvail(ctx->getWireBelPin(bel, PIN_D_IN_1))) { input_en = true; } @@ -272,7 +271,7 @@ void write_asc(const Context *ctx, std::ostream &out) } // Set config bits in unused IO and RAM for (auto bel : ctx->getBels()) { - if (proxy.checkBelAvail(bel) && ctx->getBelType(bel) == TYPE_SB_IO) { + if (ctx->checkBelAvail(bel) && ctx->getBelType(bel) == TYPE_SB_IO) { const TileInfoPOD &ti = bi.tiles_nonrouting[TILE_IO]; const BelInfoPOD &beli = ci.bel_data[bel.index]; int x = beli.x, y = beli.y, z = beli.z; @@ -285,7 +284,7 @@ void write_asc(const Context *ctx, std::ostream &out) set_config(ti, config.at(iey).at(iex), "IoCtrl.REN_" + std::to_string(iez), false); } } - } else if (proxy.checkBelAvail(bel) && ctx->getBelType(bel) == TYPE_ICESTORM_RAM) { + } else if (ctx->checkBelAvail(bel) && ctx->getBelType(bel) == TYPE_ICESTORM_RAM) { const BelInfoPOD &beli = ci.bel_data[bel.index]; int x = beli.x, y = beli.y; const TileInfoPOD &ti = bi.tiles_nonrouting[TILE_RAMB]; @@ -432,7 +431,7 @@ void write_asc(const Context *ctx, std::ostream &out) // Write symbols // const bool write_symbols = 1; for (auto wire : ctx->getWires()) { - IdString net = proxy.getBoundWireNet(wire); + IdString net = ctx->getBoundWireNet(wire); if (net != IdString()) out << ".sym " << wire.index << " " << net.str(ctx) << std::endl; } diff --git a/ice40/main.cc b/ice40/main.cc index fdfe1f25..d38c786c 100644 --- a/ice40/main.cc +++ b/ice40/main.cc @@ -304,32 +304,31 @@ int main(int argc, char *argv[]) } if (vm.count("tmfuzz")) { - auto &&proxy = ctx->rproxy(); std::vector src_wires, dst_wires; /*for (auto w : ctx->getWires()) src_wires.push_back(w);*/ for (auto b : ctx->getBels()) { if (ctx->getBelType(b) == TYPE_ICESTORM_LC) { - src_wires.push_back(proxy.getWireBelPin(b, PIN_O)); + src_wires.push_back(ctx->getWireBelPin(b, PIN_O)); } if (ctx->getBelType(b) == TYPE_SB_IO) { - src_wires.push_back(proxy.getWireBelPin(b, PIN_D_IN_0)); + src_wires.push_back(ctx->getWireBelPin(b, PIN_D_IN_0)); } } for (auto b : ctx->getBels()) { if (ctx->getBelType(b) == TYPE_ICESTORM_LC) { - dst_wires.push_back(proxy.getWireBelPin(b, PIN_I0)); - dst_wires.push_back(proxy.getWireBelPin(b, PIN_I1)); - dst_wires.push_back(proxy.getWireBelPin(b, PIN_I2)); - dst_wires.push_back(proxy.getWireBelPin(b, PIN_I3)); - dst_wires.push_back(proxy.getWireBelPin(b, PIN_CEN)); - dst_wires.push_back(proxy.getWireBelPin(b, PIN_CIN)); + dst_wires.push_back(ctx->getWireBelPin(b, PIN_I0)); + dst_wires.push_back(ctx->getWireBelPin(b, PIN_I1)); + dst_wires.push_back(ctx->getWireBelPin(b, PIN_I2)); + dst_wires.push_back(ctx->getWireBelPin(b, PIN_I3)); + dst_wires.push_back(ctx->getWireBelPin(b, PIN_CEN)); + dst_wires.push_back(ctx->getWireBelPin(b, PIN_CIN)); } if (ctx->getBelType(b) == TYPE_SB_IO) { - dst_wires.push_back(proxy.getWireBelPin(b, PIN_D_OUT_0)); - dst_wires.push_back(proxy.getWireBelPin(b, PIN_OUTPUT_ENABLE)); + dst_wires.push_back(ctx->getWireBelPin(b, PIN_D_OUT_0)); + dst_wires.push_back(ctx->getWireBelPin(b, PIN_OUTPUT_ENABLE)); } } -- cgit v1.2.3 From ade67ecf21c274c73c99543e51eda99ac847686c Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Sat, 14 Jul 2018 18:50:23 +0100 Subject: Revert "Move read methods to ReadMethods, remove some legacy access to Arch" This reverts commit 3352ff4abbcac563e08d78ed8aa77728d00284a8. --- ice40/arch.h | 1 - ice40/picorv32.sh | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.h b/ice40/arch.h index ec1e456f..cdee92e4 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -578,7 +578,6 @@ class Arch : public BaseCtx // ------------------------------------------------- - // TODO(q3k) move this to archproxies? DecalXY getFrameDecal() const; DecalXY getBelDecal(BelId bel) const; DecalXY getWireDecal(WireId wire) const; diff --git a/ice40/picorv32.sh b/ice40/picorv32.sh index 0518db83..2c67f641 100755 --- a/ice40/picorv32.sh +++ b/ice40/picorv32.sh @@ -1,6 +1,6 @@ #!/bin/bash set -ex -#rm -f picorv32.v -#wget https://raw.githubusercontent.com/cliffordwolf/picorv32/master/picorv32.v -#yosys -p 'synth_ice40 -nocarry -json picorv32.json -top top' picorv32.v picorv32_top.v -CPUPROFILE=../profile ../nextpnr-ice40 --hx8k --asc picorv32.asc --json picorv32.json +rm -f picorv32.v +wget https://raw.githubusercontent.com/cliffordwolf/picorv32/master/picorv32.v +yosys -p 'synth_ice40 -nocarry -json picorv32.json -top top' picorv32.v picorv32_top.v +../nextpnr-ice40 --hx8k --asc picorv32.asc --json picorv32.json -- cgit v1.2.3 From d4a0feb1adb05b8b086422021cde152289e591a7 Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Sat, 14 Jul 2018 18:50:29 +0100 Subject: Revert "Add read/mutate context stubs for ECP5" This reverts commit f333a68753655a4ccf7da9a4da96e7fdd19f9d08. --- ice40/arch.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'ice40') diff --git a/ice40/arch.h b/ice40/arch.h index cdee92e4..f41990c3 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -345,6 +345,7 @@ class Arch : public BaseCtx friend class ArchReadMethods; private: + // All of the following... std::vector bel_to_cell; std::vector wire_to_net; std::vector pip_to_net; @@ -632,12 +633,15 @@ class ArchReadMethods : public BaseReadCtx ArchReadMethods(const ArchReadMethods &other) : ArchReadMethods(other.parent_) {} /// Perform placement validity checks, returning false on failure (all implemented in arch_place.cc) + // Whether or not a given cell can be placed at a given Bel // This is not intended for Bel type checks, but finer-grained constraints // such as conflicting set/reset signals, etc bool isValidBelForCell(CellInfo *cell, BelId bel) const; + // Return true whether all Bels at a given location are valid bool isBelLocationValid(BelId bel) const; + // Helper function for above bool logicCellsCompatible(const std::vector &cells) const; -- cgit v1.2.3 From d9c3c117a38c8bc42cfb96255b4762965bc1611b Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Sat, 14 Jul 2018 18:50:34 +0100 Subject: Revert "clang-format" This reverts commit 8ca7a6da2525463be5be4ee9f62cfae0acc06b01. --- ice40/arch.cc | 104 +++++++++++++++++++++++++++++++++++++++++++++------------- ice40/arch.h | 55 +++++++++++++++---------------- 2 files changed, 109 insertions(+), 50 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.cc b/ice40/arch.cc index 8f2731c6..790167e9 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -259,43 +259,99 @@ BelRange Arch::getBelsAtSameTile(BelId bel) const // ----------------------------------------------------------------------- // Shorthands to ArchProxy -BelId Arch::getBelByName(IdString name) const { return rproxy().getBelByName(name); } +BelId Arch::getBelByName(IdString name) const +{ + return rproxy().getBelByName(name); +} -void Arch::bindWire(WireId wire, IdString net, PlaceStrength strength) { rwproxy().bindWire(wire, net, strength); } +void Arch::bindWire(WireId wire, IdString net, PlaceStrength strength) +{ + rwproxy().bindWire(wire, net, strength); +} -void Arch::unbindWire(WireId wire) { rwproxy().unbindWire(wire); } +void Arch::unbindWire(WireId wire) +{ + rwproxy().unbindWire(wire); +} -void Arch::bindBel(BelId bel, IdString cell, PlaceStrength strength) { rwproxy().bindBel(bel, cell, strength); } +void Arch::bindBel(BelId bel, IdString cell, PlaceStrength strength) { + rwproxy().bindBel(bel, cell, strength); +} -void Arch::unbindBel(BelId bel) { rwproxy().unbindBel(bel); } +void Arch::unbindBel(BelId bel) +{ + rwproxy().unbindBel(bel); +} -bool Arch::checkBelAvail(BelId bel) const { return rproxy().checkBelAvail(bel); } +bool Arch::checkBelAvail(BelId bel) const +{ + return rproxy().checkBelAvail(bel); +} -IdString Arch::getBoundBelCell(BelId bel) const { return rproxy().getBoundBelCell(bel); } +IdString Arch::getBoundBelCell(BelId bel) const +{ + return rproxy().getBoundBelCell(bel); +} -IdString Arch::getConflictingBelCell(BelId bel) const { return rproxy().getConflictingBelCell(bel); } +IdString Arch::getConflictingBelCell(BelId bel) const +{ + return rproxy().getConflictingBelCell(bel); +} -WireId Arch::getWireByName(IdString name) const { return rproxy().getWireByName(name); } +WireId Arch::getWireByName(IdString name) const +{ + return rproxy().getWireByName(name); +} -WireId Arch::getWireBelPin(BelId bel, PortPin pin) const { return rproxy().getWireBelPin(bel, pin); } +WireId Arch::getWireBelPin(BelId bel, PortPin pin) const +{ + return rproxy().getWireBelPin(bel, pin); +} -bool Arch::checkWireAvail(WireId wire) const { return rproxy().checkWireAvail(wire); } +bool Arch::checkWireAvail(WireId wire) const +{ + return rproxy().checkWireAvail(wire); +} -IdString Arch::getBoundWireNet(WireId wire) const { return rproxy().getBoundWireNet(wire); } +IdString Arch::getBoundWireNet(WireId wire) const +{ + return rproxy().getBoundWireNet(wire); +} -IdString Arch::getConflictingWireNet(WireId wire) const { return rproxy().getConflictingWireNet(wire); } +IdString Arch::getConflictingWireNet(WireId wire) const +{ + return rproxy().getConflictingWireNet(wire); +} -PipId Arch::getPipByName(IdString name) const { return rproxy().getPipByName(name); } +PipId Arch::getPipByName(IdString name) const +{ + return rproxy().getPipByName(name); +} -void Arch::bindPip(PipId pip, IdString net, PlaceStrength strength) { return rwproxy().bindPip(pip, net, strength); } +void Arch::bindPip(PipId pip, IdString net, PlaceStrength strength) +{ + return rwproxy().bindPip(pip, net, strength); +} -void Arch::unbindPip(PipId pip) { return rwproxy().unbindPip(pip); } +void Arch::unbindPip(PipId pip) +{ + return rwproxy().unbindPip(pip); +} -bool Arch::checkPipAvail(PipId pip) const { return rproxy().checkPipAvail(pip); } +bool Arch::checkPipAvail(PipId pip) const +{ + return rproxy().checkPipAvail(pip); +} -IdString Arch::getBoundPipNet(PipId pip) const { return rproxy().getBoundPipNet(pip); } +IdString Arch::getBoundPipNet(PipId pip) const +{ + return rproxy().getBoundPipNet(pip); +} -IdString Arch::getConflictingPipNet(PipId pip) const { return rproxy().getConflictingPipNet(pip); } +IdString Arch::getConflictingPipNet(PipId pip) const +{ + return rproxy().getConflictingPipNet(pip); +} // ----------------------------------------------------------------------- @@ -574,7 +630,8 @@ std::vector ArchReadMethods::getDecalGraphics(DecalId decal) con } if (bel_type == TYPE_ICESTORM_RAM) { - for (int i = 0; i < 2; i++) { + for (int i = 0; i < 2; i++) + { int tx = chip_info->bel_data[bel.index].x; int ty = chip_info->bel_data[bel.index].y + i; @@ -584,7 +641,7 @@ std::vector ArchReadMethods::getDecalGraphics(DecalId decal) con el.x1 = chip_info->bel_data[bel.index].x + logic_cell_x1; el.x2 = chip_info->bel_data[bel.index].x + logic_cell_x2; el.y1 = chip_info->bel_data[bel.index].y + logic_cell_y1; - el.y2 = chip_info->bel_data[bel.index].y + logic_cell_y2 + 7 * logic_cell_pitch; + el.y2 = chip_info->bel_data[bel.index].y + logic_cell_y2 + 7*logic_cell_pitch; el.z = 0; ret.push_back(el); @@ -879,6 +936,9 @@ void ArchMutateMethods::unbindPip(PipId pip) refreshUiWire(dst); } -CellInfo *ArchMutateMethods::getCell(IdString cell) { return parent_->cells.at(cell).get(); } +CellInfo *ArchMutateMethods::getCell(IdString cell) +{ + return parent_->cells.at(cell).get(); +} NEXTPNR_NAMESPACE_END diff --git a/ice40/arch.h b/ice40/arch.h index f41990c3..5d4eaedf 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -343,8 +343,7 @@ class Arch : public BaseCtx // We let proxy methods access our state. friend class ArchMutateMethods; friend class ArchReadMethods; - - private: +private: // All of the following... std::vector bel_to_cell; std::vector wire_to_net; @@ -354,7 +353,7 @@ class Arch : public BaseCtx mutable std::unordered_map wire_by_name; mutable std::unordered_map pip_by_name; - public: +public: const ChipInfoPOD *chip_info; const PackageInfoPOD *package_info; @@ -411,7 +410,10 @@ class Arch : public BaseCtx return id(chip_info->bel_data[bel.index].name.get()); } - uint32_t getBelChecksum(BelId bel) const { return bel.index; } + uint32_t getBelChecksum(BelId bel) const + { + return bel.index; + } BelRange getBels() const { @@ -443,6 +445,7 @@ class Arch : public BaseCtx return chip_info->bel_data[bel.index].type; } + BelPin getBelPinUphill(WireId wire) const { BelPin ret; @@ -546,6 +549,7 @@ class Arch : public BaseCtx return range; } + BelId getPackagePinBel(const std::string &pin) const; std::string getBelPackagePin(BelId bel) const; @@ -607,9 +611,8 @@ class Arch : public BaseCtx }; // Read-only methods on Arch that require state access. -class ArchReadMethods : public BaseReadCtx -{ - private: +class ArchReadMethods : public BaseReadCtx { +private: const Arch *parent_; const ChipInfoPOD *chip_info; const std::vector &bel_to_cell; @@ -620,15 +623,14 @@ class ArchReadMethods : public BaseReadCtx std::unordered_map &wire_by_name; std::unordered_map &pip_by_name; - public: - ~ArchReadMethods() noexcept {} - ArchReadMethods(const Arch *parent) - : BaseReadCtx(parent), parent_(parent), chip_info(parent->chip_info), bel_to_cell(parent->bel_to_cell), - wire_to_net(parent->wire_to_net), pip_to_net(parent->pip_to_net), - switches_locked(parent->switches_locked), bel_by_name(parent->bel_by_name), - wire_by_name(parent->wire_by_name), pip_by_name(parent->pip_by_name) - { - } +public: + ~ArchReadMethods() noexcept { } + ArchReadMethods(const Arch *parent) : BaseReadCtx(parent), parent_(parent), + chip_info(parent->chip_info), bel_to_cell(parent->bel_to_cell), + wire_to_net(parent->wire_to_net), pip_to_net(parent->pip_to_net), + switches_locked(parent->switches_locked), + bel_by_name(parent->bel_by_name), wire_by_name(parent->wire_by_name), + pip_by_name(parent->pip_by_name) {} ArchReadMethods(ArchReadMethods &&other) noexcept : ArchReadMethods(other.parent_) {} ArchReadMethods(const ArchReadMethods &other) : ArchReadMethods(other.parent_) {} @@ -667,11 +669,9 @@ class ArchReadMethods : public BaseReadCtx }; // State mutating methods on Arch. -class ArchMutateMethods : public BaseMutateCtx -{ +class ArchMutateMethods : public BaseMutateCtx { friend class MutateContext; - - private: +private: Arch *parent_; const ChipInfoPOD *chip_info; std::vector &bel_to_cell; @@ -682,14 +682,13 @@ class ArchMutateMethods : public BaseMutateCtx std::unordered_map &wire_by_name; std::unordered_map &pip_by_name; - public: - ArchMutateMethods(Arch *parent) - : BaseMutateCtx(parent), parent_(parent), chip_info(parent->chip_info), bel_to_cell(parent->bel_to_cell), - wire_to_net(parent->wire_to_net), pip_to_net(parent->pip_to_net), - switches_locked(parent->switches_locked), bel_by_name(parent->bel_by_name), - wire_by_name(parent->wire_by_name), pip_by_name(parent->pip_by_name) - { - } +public: + ArchMutateMethods(Arch *parent) : BaseMutateCtx(parent), parent_(parent), + chip_info(parent->chip_info), bel_to_cell(parent->bel_to_cell), + wire_to_net(parent->wire_to_net), pip_to_net(parent->pip_to_net), + switches_locked(parent->switches_locked), + bel_by_name(parent->bel_by_name), wire_by_name(parent->wire_by_name), + pip_by_name(parent->pip_by_name) {} ArchMutateMethods(ArchMutateMethods &&other) : ArchMutateMethods(other.parent_) {} ArchMutateMethods(const ArchMutateMethods &other) : ArchMutateMethods(other.parent_) {} ~ArchMutateMethods() {} -- cgit v1.2.3 From b0c05c7f751cf68165849a8f28d389541456f956 Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Sat, 14 Jul 2018 18:50:37 +0100 Subject: Revert "Refactor proxies to nextpnr." This reverts commit 9b17fe385cf7e8d3025747b5f7c7822ac2d99920. --- ice40/arch.cc | 77 +++++++++++++++++----------- ice40/arch.h | 130 +++++++++++++++++++++++++++++++++++++---------- ice40/arch_place.cc | 6 +-- ice40/place_legaliser.cc | 6 +-- 4 files changed, 156 insertions(+), 63 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.cc b/ice40/arch.cc index 790167e9..547dbcd6 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -29,6 +29,18 @@ NEXTPNR_NAMESPACE_BEGIN +ArchRWProxy Arch::rwproxy(void) { + ArchRWProxy res(this); + return res; +} + +ArchRProxy Arch::rproxy(void) const { + ArchRProxy res(this); + return res; +} + +// ----------------------------------------------------------------------- + IdString Arch::belTypeToId(BelType type) const { if (type == TYPE_ICESTORM_LC) @@ -522,7 +534,7 @@ DecalXY Arch::getGroupDecal(GroupId group) const return decalxy; }; -std::vector ArchReadMethods::getDecalGraphics(DecalId decal) const +std::vector ArchRProxyMethods::getDecalGraphics(DecalId decal) const { std::vector ret; @@ -720,25 +732,25 @@ bool Arch::isGlobalNet(const NetInfo *net) const // ----------------------------------------------------------------------- -bool ArchReadMethods::checkBelAvail(BelId bel) const +bool ArchRProxyMethods::checkBelAvail(BelId bel) const { NPNR_ASSERT(bel != BelId()); return bel_to_cell[bel.index] == IdString(); } -IdString ArchReadMethods::getBoundBelCell(BelId bel) const +IdString ArchRProxyMethods::getBoundBelCell(BelId bel) const { NPNR_ASSERT(bel != BelId()); return bel_to_cell[bel.index]; } -IdString ArchReadMethods::getConflictingBelCell(BelId bel) const +IdString ArchRProxyMethods::getConflictingBelCell(BelId bel) const { NPNR_ASSERT(bel != BelId()); return bel_to_cell[bel.index]; } -WireId ArchReadMethods::getWireBelPin(BelId bel, PortPin pin) const +WireId ArchRProxyMethods::getWireBelPin(BelId bel, PortPin pin) const { WireId ret; @@ -756,7 +768,7 @@ WireId ArchReadMethods::getWireBelPin(BelId bel, PortPin pin) const return ret; } -WireId ArchReadMethods::getWireByName(IdString name) const +WireId ArchRProxyMethods::getWireByName(IdString name) const { WireId ret; @@ -772,25 +784,25 @@ WireId ArchReadMethods::getWireByName(IdString name) const return ret; } -bool ArchReadMethods::checkWireAvail(WireId wire) const +bool ArchRProxyMethods::checkWireAvail(WireId wire) const { NPNR_ASSERT(wire != WireId()); return wire_to_net[wire.index] == IdString(); } -IdString ArchReadMethods::getBoundWireNet(WireId wire) const +IdString ArchRProxyMethods::getBoundWireNet(WireId wire) const { NPNR_ASSERT(wire != WireId()); return wire_to_net[wire.index]; } -IdString ArchReadMethods::getConflictingWireNet(WireId wire) const +IdString ArchRProxyMethods::getConflictingWireNet(WireId wire) const { NPNR_ASSERT(wire != WireId()); return wire_to_net[wire.index]; } -PipId ArchReadMethods::getPipByName(IdString name) const +PipId ArchRProxyMethods::getPipByName(IdString name) const { PipId ret; @@ -809,25 +821,25 @@ PipId ArchReadMethods::getPipByName(IdString name) const return ret; } -bool ArchReadMethods::checkPipAvail(PipId pip) const +bool ArchRProxyMethods::checkPipAvail(PipId pip) const { NPNR_ASSERT(pip != PipId()); return switches_locked[chip_info->pip_data[pip.index].switch_index] == IdString(); } -IdString ArchReadMethods::getBoundPipNet(PipId pip) const +IdString ArchRProxyMethods::getBoundPipNet(PipId pip) const { NPNR_ASSERT(pip != PipId()); return pip_to_net[pip.index]; } -IdString ArchReadMethods::getConflictingPipNet(PipId pip) const +IdString ArchRProxyMethods::getConflictingPipNet(PipId pip) const { NPNR_ASSERT(pip != PipId()); return switches_locked[chip_info->pip_data[pip.index].switch_index]; } -BelId ArchReadMethods::getBelByName(IdString name) const +BelId ArchRProxyMethods::getBelByName(IdString name) const { BelId ret; @@ -845,27 +857,27 @@ BelId ArchReadMethods::getBelByName(IdString name) const // ----------------------------------------------------------------------- -void ArchMutateMethods::bindBel(BelId bel, IdString cell, PlaceStrength strength) +void ArchRWProxyMethods::bindBel(BelId bel, IdString cell, PlaceStrength strength) { NPNR_ASSERT(bel != BelId()); NPNR_ASSERT(bel_to_cell[bel.index] == IdString()); bel_to_cell[bel.index] = cell; parent_->cells[cell]->bel = bel; parent_->cells[cell]->belStrength = strength; - refreshUiBel(bel); + parent_->refreshUiBel(bel); } -void ArchMutateMethods::unbindBel(BelId bel) +void ArchRWProxyMethods::unbindBel(BelId bel) { NPNR_ASSERT(bel != BelId()); NPNR_ASSERT(bel_to_cell[bel.index] != IdString()); parent_->cells[bel_to_cell[bel.index]]->bel = BelId(); parent_->cells[bel_to_cell[bel.index]]->belStrength = STRENGTH_NONE; bel_to_cell[bel.index] = IdString(); - refreshUiBel(bel); + parent_->refreshUiBel(bel); } -void ArchMutateMethods::bindWire(WireId wire, IdString net, PlaceStrength strength) +void ArchRWProxyMethods::bindWire(WireId wire, IdString net, PlaceStrength strength) { NPNR_ASSERT(wire != WireId()); NPNR_ASSERT(wire_to_net[wire.index] == IdString()); @@ -873,10 +885,10 @@ void ArchMutateMethods::bindWire(WireId wire, IdString net, PlaceStrength streng wire_to_net[wire.index] = net; parent_->nets[net]->wires[wire].pip = PipId(); parent_->nets[net]->wires[wire].strength = strength; - refreshUiWire(wire); + parent_->refreshUiWire(wire); } -void ArchMutateMethods::unbindWire(WireId wire) +void ArchRWProxyMethods::unbindWire(WireId wire) { NPNR_ASSERT(wire != WireId()); NPNR_ASSERT(wire_to_net[wire.index] != IdString()); @@ -889,15 +901,15 @@ void ArchMutateMethods::unbindWire(WireId wire) if (pip != PipId()) { pip_to_net[pip.index] = IdString(); switches_locked[chip_info->pip_data[pip.index].switch_index] = IdString(); - refreshUiPip(pip); + parent_->refreshUiPip(pip); } net_wires.erase(it); wire_to_net[wire.index] = IdString(); - refreshUiWire(wire); + parent_->refreshUiWire(wire); } -void ArchMutateMethods::bindPip(PipId pip, IdString net, PlaceStrength strength) +void ArchRWProxyMethods::bindPip(PipId pip, IdString net, PlaceStrength strength) { NPNR_ASSERT(pip != PipId()); NPNR_ASSERT(pip_to_net[pip.index] == IdString()); @@ -913,11 +925,11 @@ void ArchMutateMethods::bindPip(PipId pip, IdString net, PlaceStrength strength) parent_->nets[net]->wires[dst].pip = pip; parent_->nets[net]->wires[dst].strength = strength; - refreshUiPip(pip); - refreshUiWire(dst); + parent_->refreshUiPip(pip); + parent_->refreshUiWire(dst); } -void ArchMutateMethods::unbindPip(PipId pip) +void ArchRWProxyMethods::unbindPip(PipId pip) { NPNR_ASSERT(pip != PipId()); NPNR_ASSERT(pip_to_net[pip.index] != IdString()); @@ -932,13 +944,18 @@ void ArchMutateMethods::unbindPip(PipId pip) pip_to_net[pip.index] = IdString(); switches_locked[chip_info->pip_data[pip.index].switch_index] = IdString(); - refreshUiPip(pip); - refreshUiWire(dst); + parent_->refreshUiPip(pip); + parent_->refreshUiWire(dst); } -CellInfo *ArchMutateMethods::getCell(IdString cell) +CellInfo *ArchRWProxyMethods::getCell(IdString cell) { return parent_->cells.at(cell).get(); } +UIUpdatesRequired ArchRWProxyMethods::getUIUpdatesRequired(void) +{ + return parent_->getUIUpdatesRequired(); +} + NEXTPNR_NAMESPACE_END diff --git a/ice40/arch.h b/ice40/arch.h index 5d4eaedf..4311f4a5 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -22,6 +22,9 @@ #error Include "arch.h" via "nextpnr.h" only. #endif +#include +#include + NEXTPNR_NAMESPACE_BEGIN /**** Everything in this section must be kept in sync with chipdb.py ****/ @@ -327,8 +330,11 @@ struct ArchArgs /// Forward declare proxy classes for Arch. -class ArchMutateMethods; -class ArchReadMethods; +class ArchRWProxyMethods; +class ArchRProxyMethods; +class ArchRWProxy; +class ArchRProxy; + /// Arch/Context // Arch is the main state class of the PnR algorithms. It keeps note of mapped @@ -341,8 +347,11 @@ class ArchReadMethods; class Arch : public BaseCtx { // We let proxy methods access our state. - friend class ArchMutateMethods; - friend class ArchReadMethods; + friend class ArchRWProxyMethods; + friend class ArchRProxyMethods; + // We let proxy objects access our mutex. + friend class ArchRWProxy; + friend class ArchRProxy; private: // All of the following... std::vector bel_to_cell; @@ -353,6 +362,9 @@ private: mutable std::unordered_map wire_by_name; mutable std::unordered_map pip_by_name; + // ... are guarded by the following lock: + mutable boost::shared_mutex mtx_; + public: const ChipInfoPOD *chip_info; const PackageInfoPOD *package_info; @@ -360,6 +372,15 @@ public: ArchArgs args; Arch(ArchArgs args); + // Get a readwrite proxy to arch - this will keep a readwrite lock on the + // entire architecture until the proxy object goes out of scope. + ArchRWProxy rwproxy(void); + // Get a read-only proxy to arch - this will keep a read lock on the + // entire architecture until the proxy object goes out of scope. Other read + // locks can be taken while this one still exists. Ie., the UI can draw + // elements while the PnR is going a RO operation. + ArchRProxy rproxy(void) const; + std::string getChipName(); IdString archId() const { return id("ice40"); } @@ -611,9 +632,22 @@ public: }; // Read-only methods on Arch that require state access. -class ArchReadMethods : public BaseReadCtx { +class ArchRProxyMethods { + // We let proxy objects access our private constructors. + friend class ArchRProxy; + friend class ArchRWProxy; private: const Arch *parent_; + ArchRProxyMethods(const Arch *parent) : parent_(parent), chip_info(parent->chip_info), + bel_to_cell(parent->bel_to_cell), wire_to_net(parent->wire_to_net), + pip_to_net(parent->pip_to_net), switches_locked(parent->switches_locked), + bel_by_name(parent->bel_by_name), wire_by_name(parent->wire_by_name), + pip_by_name(parent->pip_by_name) {} + ArchRProxyMethods(ArchRProxyMethods &&other) noexcept : ArchRProxyMethods(other.parent_) {} + ArchRProxyMethods(const ArchRProxyMethods &other) : ArchRProxyMethods(other.parent_) {} + + // Let methods access hot members directly without having to go through + // parent_. const ChipInfoPOD *chip_info; const std::vector &bel_to_cell; const std::vector &wire_to_net; @@ -622,17 +656,8 @@ private: std::unordered_map &bel_by_name; std::unordered_map &wire_by_name; std::unordered_map &pip_by_name; - public: - ~ArchReadMethods() noexcept { } - ArchReadMethods(const Arch *parent) : BaseReadCtx(parent), parent_(parent), - chip_info(parent->chip_info), bel_to_cell(parent->bel_to_cell), - wire_to_net(parent->wire_to_net), pip_to_net(parent->pip_to_net), - switches_locked(parent->switches_locked), - bel_by_name(parent->bel_by_name), wire_by_name(parent->wire_by_name), - pip_by_name(parent->pip_by_name) {} - ArchReadMethods(ArchReadMethods &&other) noexcept : ArchReadMethods(other.parent_) {} - ArchReadMethods(const ArchReadMethods &other) : ArchReadMethods(other.parent_) {} + ~ArchRProxyMethods() noexcept { } /// Perform placement validity checks, returning false on failure (all implemented in arch_place.cc) @@ -668,11 +693,44 @@ public: std::vector getDecalGraphics(DecalId decal) const; }; +// A proxy object that keeps an Arch shared/readonly lock until it goes out +// of scope. All const/read-only ArchRProxyMethods are available on it. +class ArchRProxy : public ArchRProxyMethods { + friend class Arch; + friend class ArchRWProxy; +private: + boost::shared_mutex *lock_; + ArchRProxy(const Arch *parent) : ArchRProxyMethods(parent), lock_(&parent->mtx_) + { + lock_->lock_shared(); + } + +public: + ~ArchRProxy() { + if (lock_ != nullptr) { + lock_->unlock_shared(); + } + } + ArchRProxy(ArchRProxy &&other) : ArchRProxyMethods(other), lock_(other.lock_) + { + other.lock_ = nullptr; + } +}; + // State mutating methods on Arch. -class ArchMutateMethods : public BaseMutateCtx { - friend class MutateContext; +class ArchRWProxyMethods { + // We let proxy objects access our private constructors. + friend class ArchRWProxy; private: Arch *parent_; + ArchRWProxyMethods(Arch *parent) : parent_(parent), chip_info(parent->chip_info), + bel_to_cell(parent->bel_to_cell), wire_to_net(parent->wire_to_net), + pip_to_net(parent->pip_to_net), switches_locked(parent->switches_locked), + bel_by_name(parent->bel_by_name), wire_by_name(parent->wire_by_name), + pip_by_name(parent->pip_by_name) {} + ArchRWProxyMethods(ArchRWProxyMethods &&other) : ArchRWProxyMethods(other.parent_) {} + ArchRWProxyMethods(const ArchRWProxyMethods &other) : ArchRWProxyMethods(other.parent_) {} + const ChipInfoPOD *chip_info; std::vector &bel_to_cell; std::vector &wire_to_net; @@ -681,17 +739,8 @@ private: std::unordered_map &bel_by_name; std::unordered_map &wire_by_name; std::unordered_map &pip_by_name; - public: - ArchMutateMethods(Arch *parent) : BaseMutateCtx(parent), parent_(parent), - chip_info(parent->chip_info), bel_to_cell(parent->bel_to_cell), - wire_to_net(parent->wire_to_net), pip_to_net(parent->pip_to_net), - switches_locked(parent->switches_locked), - bel_by_name(parent->bel_by_name), wire_by_name(parent->wire_by_name), - pip_by_name(parent->pip_by_name) {} - ArchMutateMethods(ArchMutateMethods &&other) : ArchMutateMethods(other.parent_) {} - ArchMutateMethods(const ArchMutateMethods &other) : ArchMutateMethods(other.parent_) {} - ~ArchMutateMethods() {} + ~ArchRWProxyMethods() {} void unbindWire(WireId wire); void unbindPip(PipId pip); @@ -701,6 +750,33 @@ public: void bindBel(BelId bel, IdString cell, PlaceStrength strength); // Returned pointer is valid as long as Proxy object exists. CellInfo *getCell(IdString cell); + + + // Methods to be used by UI for detecting whether we need to redraw. + UIUpdatesRequired getUIUpdatesRequired(void); +}; + +// A proxy object that keeps an Arch readwrite lock until it goes out of scope. +// All ArchRProxyMethods and ArchRWProxyMethods are available on it. +class ArchRWProxy : public ArchRProxyMethods, public ArchRWProxyMethods { + friend class Arch; +private: + boost::shared_mutex *lock_; + ArchRWProxy(Arch *parent) : ArchRProxyMethods(parent), ArchRWProxyMethods(parent), lock_(&parent->mtx_) { + lock_->lock(); + } + +public: + ArchRWProxy(ArchRWProxy &&other) : ArchRProxyMethods(other), ArchRWProxyMethods(other), lock_(other.lock_) + { + other.lock_ = nullptr; + } + ~ArchRWProxy() + { + if (lock_ != nullptr) { + lock_->unlock(); + } + } }; NEXTPNR_NAMESPACE_END diff --git a/ice40/arch_place.cc b/ice40/arch_place.cc index 42efceab..cb7c44b8 100644 --- a/ice40/arch_place.cc +++ b/ice40/arch_place.cc @@ -25,7 +25,7 @@ NEXTPNR_NAMESPACE_BEGIN -bool ArchReadMethods::logicCellsCompatible(const std::vector &cells) const +bool ArchRProxyMethods::logicCellsCompatible(const std::vector &cells) const { bool dffs_exist = false, dffs_neg = false; const NetInfo *cen = nullptr, *clk = nullptr, *sr = nullptr; @@ -76,7 +76,7 @@ bool ArchReadMethods::logicCellsCompatible(const std::vector & return locals_count <= 32; } -bool ArchReadMethods::isBelLocationValid(BelId bel) const +bool ArchRProxyMethods::isBelLocationValid(BelId bel) const { if (parent_->getBelType(bel) == TYPE_ICESTORM_LC) { std::vector bel_cells; @@ -97,7 +97,7 @@ bool ArchReadMethods::isBelLocationValid(BelId bel) const } } -bool ArchReadMethods::isValidBelForCell(CellInfo *cell, BelId bel) const +bool ArchRProxyMethods::isValidBelForCell(CellInfo *cell, BelId bel) const { if (cell->type == parent_->id_icestorm_lc) { NPNR_ASSERT(parent_->getBelType(bel) == TYPE_ICESTORM_LC); diff --git a/ice40/place_legaliser.cc b/ice40/place_legaliser.cc index fcb47cfd..10a6f3ff 100644 --- a/ice40/place_legaliser.cc +++ b/ice40/place_legaliser.cc @@ -253,7 +253,7 @@ class PlacementLegaliser } // Find Bel closest to a location, meeting chain requirements - std::tuple find_closest_bel(MutateContext &proxy, float target_x, float target_y, CellChain &chain) + std::tuple find_closest_bel(ArchRWProxy &proxy, float target_x, float target_y, CellChain &chain) { std::tuple best_origin = std::make_tuple(-1, -1, -1); wirelen_t best_wirelength = std::numeric_limits::max(); @@ -283,7 +283,7 @@ class PlacementLegaliser } // Split a carry chain into multiple legal chains - std::vector split_carry_chain(const ReadContext &proxy, CellChain &carryc) + std::vector split_carry_chain(const ArchRProxy &proxy, CellChain &carryc) { bool start_of_chain = true; std::vector chains; @@ -335,7 +335,7 @@ class PlacementLegaliser } // Place a logic cell at a given grid location, handling rip-up etc - void place_lc(MutateContext &proxy, CellInfo *cell, int x, int y, int z) + void place_lc(ArchRWProxy &proxy, CellInfo *cell, int x, int y, int z) { auto &loc = logic_bels.at(x).at(y).at(z); NPNR_ASSERT(!loc.second); -- cgit v1.2.3 From 36b4e3382dc552fcd1b078bdd246dc14379394a1 Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Sat, 14 Jul 2018 18:50:50 +0100 Subject: Revert "Make GUI nice and smooth." This reverts commit a8c84e90a39c54174dd24b5b76bd17aed8311481. --- ice40/arch.cc | 10 +++------- ice40/arch.h | 8 ++------ ice40/main.cc | 3 +-- 3 files changed, 6 insertions(+), 15 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.cc b/ice40/arch.cc index 547dbcd6..af6e922c 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -534,8 +534,9 @@ DecalXY Arch::getGroupDecal(GroupId group) const return decalxy; }; -std::vector ArchRProxyMethods::getDecalGraphics(DecalId decal) const +std::vector Arch::getDecalGraphics(DecalId decal) const { + boost::shared_lock_guard lock(mtx_); std::vector ret; if (decal.type == DecalId::TYPE_FRAME) { @@ -567,7 +568,7 @@ std::vector ArchRProxyMethods::getDecalGraphics(DecalId decal) c BelId bel; bel.index = decal.index; - auto bel_type = parent_->getBelType(bel); + auto bel_type = getBelType(bel); if (bel_type == TYPE_ICESTORM_LC) { GraphicElement el; @@ -953,9 +954,4 @@ CellInfo *ArchRWProxyMethods::getCell(IdString cell) return parent_->cells.at(cell).get(); } -UIUpdatesRequired ArchRWProxyMethods::getUIUpdatesRequired(void) -{ - return parent_->getUIUpdatesRequired(); -} - NEXTPNR_NAMESPACE_END diff --git a/ice40/arch.h b/ice40/arch.h index 4311f4a5..da1e583a 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -604,6 +604,8 @@ public: // ------------------------------------------------- + std::vector getDecalGraphics(DecalId decal) const; + DecalXY getFrameDecal() const; DecalXY getBelDecal(BelId bel) const; DecalXY getWireDecal(WireId wire) const; @@ -689,8 +691,6 @@ public: IdString getBoundBelCell(BelId bel) const; BelId getBelByName(IdString name) const; - - std::vector getDecalGraphics(DecalId decal) const; }; // A proxy object that keeps an Arch shared/readonly lock until it goes out @@ -750,10 +750,6 @@ public: void bindBel(BelId bel, IdString cell, PlaceStrength strength); // Returned pointer is valid as long as Proxy object exists. CellInfo *getCell(IdString cell); - - - // Methods to be used by UI for detecting whether we need to redraw. - UIUpdatesRequired getUIUpdatesRequired(void); }; // A proxy object that keeps an Arch readwrite lock until it goes out of scope. diff --git a/ice40/main.cc b/ice40/main.cc index d38c786c..e77bdd34 100644 --- a/ice40/main.cc +++ b/ice40/main.cc @@ -51,8 +51,7 @@ void svg_dump_decal(const Context *ctx, const DecalXY &decal) const float scale = 10.0, offset = 10.0; const std::string style = "stroke=\"black\" stroke-width=\"0.1\" fill=\"none\""; - auto &&proxy = ctx->rproxy(); - for (auto &el : proxy.getDecalGraphics(decal.decal)) { + for (auto &el : ctx->getDecalGraphics(decal.decal)) { if (el.type == GraphicElement::G_BOX) { std::cout << " Date: Sat, 14 Jul 2018 18:50:54 +0100 Subject: Revert "Slight simplification of proxy code" This reverts commit a71b576de6c404572439e30a56c4ff19497523a2. --- ice40/arch.cc | 108 +++++++++++++++++++++++++++++----------------------------- ice40/arch.h | 53 ++++++++-------------------- 2 files changed, 68 insertions(+), 93 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.cc b/ice40/arch.cc index af6e922c..af31e147 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -736,19 +736,19 @@ bool Arch::isGlobalNet(const NetInfo *net) const bool ArchRProxyMethods::checkBelAvail(BelId bel) const { NPNR_ASSERT(bel != BelId()); - return bel_to_cell[bel.index] == IdString(); + return parent_->bel_to_cell[bel.index] == IdString(); } IdString ArchRProxyMethods::getBoundBelCell(BelId bel) const { NPNR_ASSERT(bel != BelId()); - return bel_to_cell[bel.index]; + return parent_->bel_to_cell[bel.index]; } IdString ArchRProxyMethods::getConflictingBelCell(BelId bel) const { NPNR_ASSERT(bel != BelId()); - return bel_to_cell[bel.index]; + return parent_->bel_to_cell[bel.index]; } WireId ArchRProxyMethods::getWireBelPin(BelId bel, PortPin pin) const @@ -757,8 +757,8 @@ WireId ArchRProxyMethods::getWireBelPin(BelId bel, PortPin pin) const NPNR_ASSERT(bel != BelId()); - int num_bel_wires = chip_info->bel_data[bel.index].num_bel_wires; - const BelWirePOD *bel_wires = chip_info->bel_data[bel.index].bel_wires.get(); + int num_bel_wires = parent_->chip_info->bel_data[bel.index].num_bel_wires; + const BelWirePOD *bel_wires = parent_->chip_info->bel_data[bel.index].bel_wires.get(); for (int i = 0; i < num_bel_wires; i++) if (bel_wires[i].port == pin) { @@ -773,13 +773,13 @@ WireId ArchRProxyMethods::getWireByName(IdString name) const { WireId ret; - if (wire_by_name.empty()) { - for (int i = 0; i < chip_info->num_wires; i++) - wire_by_name[parent_->id(chip_info->wire_data[i].name.get())] = i; + if (parent_->wire_by_name.empty()) { + for (int i = 0; i < parent_->chip_info->num_wires; i++) + parent_->wire_by_name[parent_->id(parent_->chip_info->wire_data[i].name.get())] = i; } - auto it = wire_by_name.find(name); - if (it != wire_by_name.end()) + auto it = parent_->wire_by_name.find(name); + if (it != parent_->wire_by_name.end()) ret.index = it->second; return ret; @@ -788,35 +788,35 @@ WireId ArchRProxyMethods::getWireByName(IdString name) const bool ArchRProxyMethods::checkWireAvail(WireId wire) const { NPNR_ASSERT(wire != WireId()); - return wire_to_net[wire.index] == IdString(); + return parent_->wire_to_net[wire.index] == IdString(); } IdString ArchRProxyMethods::getBoundWireNet(WireId wire) const { NPNR_ASSERT(wire != WireId()); - return wire_to_net[wire.index]; + return parent_->wire_to_net[wire.index]; } IdString ArchRProxyMethods::getConflictingWireNet(WireId wire) const { NPNR_ASSERT(wire != WireId()); - return wire_to_net[wire.index]; + return parent_->wire_to_net[wire.index]; } PipId ArchRProxyMethods::getPipByName(IdString name) const { PipId ret; - if (pip_by_name.empty()) { - for (int i = 0; i < chip_info->num_pips; i++) { + if (parent_->pip_by_name.empty()) { + for (int i = 0; i < parent_->chip_info->num_pips; i++) { PipId pip; pip.index = i; - pip_by_name[parent_->getPipName(pip)] = i; + parent_->pip_by_name[parent_->getPipName(pip)] = i; } } - auto it = pip_by_name.find(name); - if (it != pip_by_name.end()) + auto it = parent_->pip_by_name.find(name); + if (it != parent_->pip_by_name.end()) ret.index = it->second; return ret; @@ -825,32 +825,32 @@ PipId ArchRProxyMethods::getPipByName(IdString name) const bool ArchRProxyMethods::checkPipAvail(PipId pip) const { NPNR_ASSERT(pip != PipId()); - return switches_locked[chip_info->pip_data[pip.index].switch_index] == IdString(); + return parent_->switches_locked[parent_->chip_info->pip_data[pip.index].switch_index] == IdString(); } IdString ArchRProxyMethods::getBoundPipNet(PipId pip) const { NPNR_ASSERT(pip != PipId()); - return pip_to_net[pip.index]; + return parent_->pip_to_net[pip.index]; } IdString ArchRProxyMethods::getConflictingPipNet(PipId pip) const { NPNR_ASSERT(pip != PipId()); - return switches_locked[chip_info->pip_data[pip.index].switch_index]; + return parent_->switches_locked[parent_->chip_info->pip_data[pip.index].switch_index]; } BelId ArchRProxyMethods::getBelByName(IdString name) const { BelId ret; - if (bel_by_name.empty()) { - for (int i = 0; i < chip_info->num_bels; i++) - bel_by_name[parent_->id(chip_info->bel_data[i].name.get())] = i; + if (parent_->bel_by_name.empty()) { + for (int i = 0; i < parent_->chip_info->num_bels; i++) + parent_->bel_by_name[parent_->id(parent_->chip_info->bel_data[i].name.get())] = i; } - auto it = bel_by_name.find(name); - if (it != bel_by_name.end()) + auto it = parent_->bel_by_name.find(name); + if (it != parent_->bel_by_name.end()) ret.index = it->second; return ret; @@ -861,8 +861,8 @@ BelId ArchRProxyMethods::getBelByName(IdString name) const void ArchRWProxyMethods::bindBel(BelId bel, IdString cell, PlaceStrength strength) { NPNR_ASSERT(bel != BelId()); - NPNR_ASSERT(bel_to_cell[bel.index] == IdString()); - bel_to_cell[bel.index] = cell; + NPNR_ASSERT(parent_->bel_to_cell[bel.index] == IdString()); + parent_->bel_to_cell[bel.index] = cell; parent_->cells[cell]->bel = bel; parent_->cells[cell]->belStrength = strength; parent_->refreshUiBel(bel); @@ -871,19 +871,19 @@ void ArchRWProxyMethods::bindBel(BelId bel, IdString cell, PlaceStrength strengt void ArchRWProxyMethods::unbindBel(BelId bel) { NPNR_ASSERT(bel != BelId()); - NPNR_ASSERT(bel_to_cell[bel.index] != IdString()); - parent_->cells[bel_to_cell[bel.index]]->bel = BelId(); - parent_->cells[bel_to_cell[bel.index]]->belStrength = STRENGTH_NONE; - bel_to_cell[bel.index] = IdString(); + NPNR_ASSERT(parent_->bel_to_cell[bel.index] != IdString()); + parent_->cells[parent_->bel_to_cell[bel.index]]->bel = BelId(); + parent_->cells[parent_->bel_to_cell[bel.index]]->belStrength = STRENGTH_NONE; + parent_->bel_to_cell[bel.index] = IdString(); parent_->refreshUiBel(bel); } void ArchRWProxyMethods::bindWire(WireId wire, IdString net, PlaceStrength strength) { NPNR_ASSERT(wire != WireId()); - NPNR_ASSERT(wire_to_net[wire.index] == IdString()); + NPNR_ASSERT(parent_->wire_to_net[wire.index] == IdString()); - wire_to_net[wire.index] = net; + parent_->wire_to_net[wire.index] = net; parent_->nets[net]->wires[wire].pip = PipId(); parent_->nets[net]->wires[wire].strength = strength; parent_->refreshUiWire(wire); @@ -892,37 +892,37 @@ void ArchRWProxyMethods::bindWire(WireId wire, IdString net, PlaceStrength stren void ArchRWProxyMethods::unbindWire(WireId wire) { NPNR_ASSERT(wire != WireId()); - NPNR_ASSERT(wire_to_net[wire.index] != IdString()); + NPNR_ASSERT(parent_->wire_to_net[wire.index] != IdString()); - auto &net_wires = parent_->nets[wire_to_net[wire.index]]->wires; + auto &net_wires = parent_->nets[parent_->wire_to_net[wire.index]]->wires; auto it = net_wires.find(wire); NPNR_ASSERT(it != net_wires.end()); auto pip = it->second.pip; if (pip != PipId()) { - pip_to_net[pip.index] = IdString(); - switches_locked[chip_info->pip_data[pip.index].switch_index] = IdString(); + parent_->pip_to_net[pip.index] = IdString(); + parent_->switches_locked[parent_->chip_info->pip_data[pip.index].switch_index] = IdString(); parent_->refreshUiPip(pip); } net_wires.erase(it); - wire_to_net[wire.index] = IdString(); + parent_->wire_to_net[wire.index] = IdString(); parent_->refreshUiWire(wire); } void ArchRWProxyMethods::bindPip(PipId pip, IdString net, PlaceStrength strength) { NPNR_ASSERT(pip != PipId()); - NPNR_ASSERT(pip_to_net[pip.index] == IdString()); - NPNR_ASSERT(switches_locked[chip_info->pip_data[pip.index].switch_index] == IdString()); + NPNR_ASSERT(parent_->pip_to_net[pip.index] == IdString()); + NPNR_ASSERT(parent_->switches_locked[parent_->chip_info->pip_data[pip.index].switch_index] == IdString()); - pip_to_net[pip.index] = net; - switches_locked[chip_info->pip_data[pip.index].switch_index] = net; + parent_->pip_to_net[pip.index] = net; + parent_->switches_locked[parent_->chip_info->pip_data[pip.index].switch_index] = net; WireId dst; - dst.index = chip_info->pip_data[pip.index].dst; - NPNR_ASSERT(wire_to_net[dst.index] == IdString()); - wire_to_net[dst.index] = net; + dst.index = parent_->chip_info->pip_data[pip.index].dst; + NPNR_ASSERT(parent_->wire_to_net[dst.index] == IdString()); + parent_->wire_to_net[dst.index] = net; parent_->nets[net]->wires[dst].pip = pip; parent_->nets[net]->wires[dst].strength = strength; @@ -933,17 +933,17 @@ void ArchRWProxyMethods::bindPip(PipId pip, IdString net, PlaceStrength strength void ArchRWProxyMethods::unbindPip(PipId pip) { NPNR_ASSERT(pip != PipId()); - NPNR_ASSERT(pip_to_net[pip.index] != IdString()); - NPNR_ASSERT(switches_locked[chip_info->pip_data[pip.index].switch_index] != IdString()); + NPNR_ASSERT(parent_->pip_to_net[pip.index] != IdString()); + NPNR_ASSERT(parent_->switches_locked[parent_->chip_info->pip_data[pip.index].switch_index] != IdString()); WireId dst; - dst.index = chip_info->pip_data[pip.index].dst; - NPNR_ASSERT(wire_to_net[dst.index] != IdString()); - wire_to_net[dst.index] = IdString(); - parent_->nets[pip_to_net[pip.index]]->wires.erase(dst); + dst.index = parent_->chip_info->pip_data[pip.index].dst; + NPNR_ASSERT(parent_->wire_to_net[dst.index] != IdString()); + parent_->wire_to_net[dst.index] = IdString(); + parent_->nets[parent_->pip_to_net[pip.index]]->wires.erase(dst); - pip_to_net[pip.index] = IdString(); - switches_locked[chip_info->pip_data[pip.index].switch_index] = IdString(); + parent_->pip_to_net[pip.index] = IdString(); + parent_->switches_locked[parent_->chip_info->pip_data[pip.index].switch_index] = IdString(); parent_->refreshUiPip(pip); parent_->refreshUiWire(dst); diff --git a/ice40/arch.h b/ice40/arch.h index da1e583a..8428dc29 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -339,7 +339,7 @@ class ArchRProxy; /// Arch/Context // Arch is the main state class of the PnR algorithms. It keeps note of mapped // cells/nets, locked switches, etc. -// +// // In order to mutate state in Arch, you can do one of two things: // - directly call one of the wrapper methods to mutate state // - get a read or readwrite proxy to the Arch, and call methods on it @@ -419,7 +419,7 @@ public: IdString getBoundPipNet(PipId pip) const; IdString getBoundBelCell(BelId bel) const; BelId getBelByName(IdString name) const; - + // ------------------------------------------------- /// Methods to get chip info - don't need to use a wrapper, as these are @@ -506,7 +506,7 @@ public: range.e.cursor = chip_info->num_pips; return range; } - + IdString getPipName(PipId pip) const; uint32_t getPipChecksum(PipId pip) const { return pip.index; } @@ -640,27 +640,13 @@ class ArchRProxyMethods { friend class ArchRWProxy; private: const Arch *parent_; - ArchRProxyMethods(const Arch *parent) : parent_(parent), chip_info(parent->chip_info), - bel_to_cell(parent->bel_to_cell), wire_to_net(parent->wire_to_net), - pip_to_net(parent->pip_to_net), switches_locked(parent->switches_locked), - bel_by_name(parent->bel_by_name), wire_by_name(parent->wire_by_name), - pip_by_name(parent->pip_by_name) {} - ArchRProxyMethods(ArchRProxyMethods &&other) noexcept : ArchRProxyMethods(other.parent_) {} - ArchRProxyMethods(const ArchRProxyMethods &other) : ArchRProxyMethods(other.parent_) {} - - // Let methods access hot members directly without having to go through - // parent_. - const ChipInfoPOD *chip_info; - const std::vector &bel_to_cell; - const std::vector &wire_to_net; - const std::vector &pip_to_net; - const std::vector &switches_locked; - std::unordered_map &bel_by_name; - std::unordered_map &wire_by_name; - std::unordered_map &pip_by_name; + ArchRProxyMethods(const Arch *parent) : parent_(parent) {} + ArchRProxyMethods(ArchRProxyMethods &&other) noexcept : parent_(other.parent_) {} + ArchRProxyMethods(const ArchRProxyMethods &other) : parent_(other.parent_) {} + public: ~ArchRProxyMethods() noexcept { } - + /// Perform placement validity checks, returning false on failure (all implemented in arch_place.cc) // Whether or not a given cell can be placed at a given Bel @@ -681,7 +667,7 @@ public: WireId getWireByName(IdString name) const; WireId getWireBelPin(BelId bel, PortPin pin) const; PipId getPipByName(IdString name) const; - + IdString getConflictingWireNet(WireId wire) const; IdString getConflictingPipNet(PipId pip) const; IdString getConflictingBelCell(BelId bel) const; @@ -723,22 +709,9 @@ class ArchRWProxyMethods { friend class ArchRWProxy; private: Arch *parent_; - ArchRWProxyMethods(Arch *parent) : parent_(parent), chip_info(parent->chip_info), - bel_to_cell(parent->bel_to_cell), wire_to_net(parent->wire_to_net), - pip_to_net(parent->pip_to_net), switches_locked(parent->switches_locked), - bel_by_name(parent->bel_by_name), wire_by_name(parent->wire_by_name), - pip_by_name(parent->pip_by_name) {} - ArchRWProxyMethods(ArchRWProxyMethods &&other) : ArchRWProxyMethods(other.parent_) {} - ArchRWProxyMethods(const ArchRWProxyMethods &other) : ArchRWProxyMethods(other.parent_) {} - - const ChipInfoPOD *chip_info; - std::vector &bel_to_cell; - std::vector &wire_to_net; - std::vector &pip_to_net; - std::vector &switches_locked; - std::unordered_map &bel_by_name; - std::unordered_map &wire_by_name; - std::unordered_map &pip_by_name; + ArchRWProxyMethods(Arch *parent) : parent_(parent) {} + ArchRWProxyMethods(ArchRWProxyMethods &&other) : parent_(other.parent_) {} + ArchRWProxyMethods(const ArchRWProxyMethods &other) : parent_(other.parent_) {} public: ~ArchRWProxyMethods() {} @@ -773,6 +746,8 @@ public: lock_->unlock(); } } + + }; NEXTPNR_NAMESPACE_END -- cgit v1.2.3 From 09ca9ea39edbb33bfb23119786a3fa2792785e87 Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Sat, 14 Jul 2018 18:50:58 +0100 Subject: Revert "Comment arch.h" This reverts commit dc3256e62fce923a3dc703c521bea5a13cef4443. --- ice40/arch.h | 35 +---------------------------------- 1 file changed, 1 insertion(+), 34 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.h b/ice40/arch.h index 8428dc29..36e34d7b 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -328,28 +328,15 @@ struct ArchArgs std::string package; }; -/// Forward declare proxy classes for Arch. - class ArchRWProxyMethods; class ArchRProxyMethods; class ArchRWProxy; class ArchRProxy; - -/// Arch/Context -// Arch is the main state class of the PnR algorithms. It keeps note of mapped -// cells/nets, locked switches, etc. -// -// In order to mutate state in Arch, you can do one of two things: -// - directly call one of the wrapper methods to mutate state -// - get a read or readwrite proxy to the Arch, and call methods on it - class Arch : public BaseCtx { - // We let proxy methods access our state. friend class ArchRWProxyMethods; friend class ArchRProxyMethods; - // We let proxy objects access our mutex. friend class ArchRWProxy; friend class ArchRProxy; private: @@ -372,13 +359,7 @@ public: ArchArgs args; Arch(ArchArgs args); - // Get a readwrite proxy to arch - this will keep a readwrite lock on the - // entire architecture until the proxy object goes out of scope. ArchRWProxy rwproxy(void); - // Get a read-only proxy to arch - this will keep a read lock on the - // entire architecture until the proxy object goes out of scope. Other read - // locks can be taken while this one still exists. Ie., the UI can draw - // elements while the PnR is going a RO operation. ArchRProxy rproxy(void) const; std::string getChipName(); @@ -397,9 +378,6 @@ public: /// Wrappers around getting a r(w)proxy and calling a single method. // Deprecated: please acquire a proxy yourself and call the methods // you want on it. - // Warning: these will content with locks taken by the r(w)proxies, and - // thus can cause difficult to debug deadlocks - we'll be getting rid of - // them because of that. void unbindWire(WireId wire); void unbindPip(PipId pip); void unbindBel(BelId bel); @@ -576,7 +554,6 @@ public: // ------------------------------------------------- - // TODO(q3k) move this to archproxies? GroupId getGroupByName(IdString name) const; IdString getGroupName(GroupId group) const; std::vector getGroups() const; @@ -587,8 +564,6 @@ public: // ------------------------------------------------- - // These are also specific to the chip and not state, so they're available - // on arch directly. void estimatePosition(BelId bel, int &x, int &y, bool &gb) const; delay_t estimateDelay(WireId src, WireId dst) const; delay_t getDelayEpsilon() const { return 20; } @@ -633,9 +608,7 @@ public: IdString id_dff_en, id_neg_clk; }; -// Read-only methods on Arch that require state access. class ArchRProxyMethods { - // We let proxy objects access our private constructors. friend class ArchRProxy; friend class ArchRWProxy; private: @@ -668,6 +641,7 @@ public: WireId getWireBelPin(BelId bel, PortPin pin) const; PipId getPipByName(IdString name) const; + IdString getConflictingWireNet(WireId wire) const; IdString getConflictingPipNet(PipId pip) const; IdString getConflictingBelCell(BelId bel) const; @@ -679,8 +653,6 @@ public: BelId getBelByName(IdString name) const; }; -// A proxy object that keeps an Arch shared/readonly lock until it goes out -// of scope. All const/read-only ArchRProxyMethods are available on it. class ArchRProxy : public ArchRProxyMethods { friend class Arch; friend class ArchRWProxy; @@ -703,9 +675,7 @@ public: } }; -// State mutating methods on Arch. class ArchRWProxyMethods { - // We let proxy objects access our private constructors. friend class ArchRWProxy; private: Arch *parent_; @@ -721,12 +691,9 @@ public: void bindWire(WireId wire, IdString net, PlaceStrength strength); void bindPip(PipId pip, IdString net, PlaceStrength strength); void bindBel(BelId bel, IdString cell, PlaceStrength strength); - // Returned pointer is valid as long as Proxy object exists. CellInfo *getCell(IdString cell); }; -// A proxy object that keeps an Arch readwrite lock until it goes out of scope. -// All ArchRProxyMethods and ArchRWProxyMethods are available on it. class ArchRWProxy : public ArchRProxyMethods, public ArchRWProxyMethods { friend class Arch; private: -- cgit v1.2.3 From 447ed83638ef35967adae801430f24e92acb6010 Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Sat, 14 Jul 2018 18:52:56 +0100 Subject: Revert "Introduce proxies for locked access to ctx" This reverts commit 89809a8b810dd57f50f365d70a0ce547705f8dbb. --- ice40/arch.cc | 368 ++++++++----------------------------------- ice40/arch.h | 402 ++++++++++++++++++++++++++++++----------------- ice40/arch_place.cc | 75 +++++---- ice40/place_legaliser.cc | 73 ++++----- 4 files changed, 387 insertions(+), 531 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.cc b/ice40/arch.cc index af31e147..30eea776 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -2,7 +2,6 @@ * nextpnr -- Next Generation Place and Route * * Copyright (C) 2018 Clifford Wolf - * Copyright (C) 2018 Serge Bazanski * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -29,16 +28,6 @@ NEXTPNR_NAMESPACE_BEGIN -ArchRWProxy Arch::rwproxy(void) { - ArchRWProxy res(this); - return res; -} - -ArchRProxy Arch::rproxy(void) const { - ArchRProxy res(this); - return res; -} - // ----------------------------------------------------------------------- IdString Arch::belTypeToId(BelType type) const @@ -250,6 +239,28 @@ IdString Arch::archArgsToId(ArchArgs args) const // ----------------------------------------------------------------------- +BelId Arch::getBelByName(IdString name) const +{ + boost::lock_guard lock(mtx_); + return getBelByNameUnlocked(name); +} + +BelId Arch::getBelByNameUnlocked(IdString name) const +{ + BelId ret; + + if (bel_by_name.empty()) { + for (int i = 0; i < chip_info->num_bels; i++) + bel_by_name[id(chip_info->bel_data[i].name.get())] = i; + } + + auto it = bel_by_name.find(name); + if (it != bel_by_name.end()) + ret.index = it->second; + + return ret; +} + BelRange Arch::getBelsAtSameTile(BelId bel) const { BelRange br; @@ -268,105 +279,81 @@ BelRange Arch::getBelsAtSameTile(BelId bel) const return br; } -// ----------------------------------------------------------------------- -// Shorthands to ArchProxy - -BelId Arch::getBelByName(IdString name) const -{ - return rproxy().getBelByName(name); -} - -void Arch::bindWire(WireId wire, IdString net, PlaceStrength strength) +WireId Arch::getWireBelPin(BelId bel, PortPin pin) const { - rwproxy().bindWire(wire, net, strength); + boost::shared_lock_guard lock(mtx_); + return getWireBelPinUnlocked(bel, pin); } -void Arch::unbindWire(WireId wire) +WireId Arch::getWireBelPinUnlocked(BelId bel, PortPin pin) const { - rwproxy().unbindWire(wire); -} + WireId ret; -void Arch::bindBel(BelId bel, IdString cell, PlaceStrength strength) { - rwproxy().bindBel(bel, cell, strength); -} + NPNR_ASSERT(bel != BelId()); -void Arch::unbindBel(BelId bel) -{ - rwproxy().unbindBel(bel); -} + int num_bel_wires = chip_info->bel_data[bel.index].num_bel_wires; + const BelWirePOD *bel_wires = chip_info->bel_data[bel.index].bel_wires.get(); -bool Arch::checkBelAvail(BelId bel) const -{ - return rproxy().checkBelAvail(bel); -} + for (int i = 0; i < num_bel_wires; i++) + if (bel_wires[i].port == pin) { + ret.index = bel_wires[i].wire_index; + break; + } -IdString Arch::getBoundBelCell(BelId bel) const -{ - return rproxy().getBoundBelCell(bel); + return ret; } -IdString Arch::getConflictingBelCell(BelId bel) const -{ - return rproxy().getConflictingBelCell(bel); -} +// ----------------------------------------------------------------------- WireId Arch::getWireByName(IdString name) const { - return rproxy().getWireByName(name); + boost::shared_lock_guard lock(mtx_); + return getWireByNameUnlocked(name); } -WireId Arch::getWireBelPin(BelId bel, PortPin pin) const +WireId Arch::getWireByNameUnlocked(IdString name) const { - return rproxy().getWireBelPin(bel, pin); -} + WireId ret; -bool Arch::checkWireAvail(WireId wire) const -{ - return rproxy().checkWireAvail(wire); -} + if (wire_by_name.empty()) { + for (int i = 0; i < chip_info->num_wires; i++) + wire_by_name[id(chip_info->wire_data[i].name.get())] = i; + } -IdString Arch::getBoundWireNet(WireId wire) const -{ - return rproxy().getBoundWireNet(wire); -} + auto it = wire_by_name.find(name); + if (it != wire_by_name.end()) + ret.index = it->second; -IdString Arch::getConflictingWireNet(WireId wire) const -{ - return rproxy().getConflictingWireNet(wire); + return ret; } -PipId Arch::getPipByName(IdString name) const -{ - return rproxy().getPipByName(name); -} +// ----------------------------------------------------------------------- -void Arch::bindPip(PipId pip, IdString net, PlaceStrength strength) +PipId Arch::getPipByName(IdString name) const { - return rwproxy().bindPip(pip, net, strength); + boost::shared_lock_guard lock(mtx_); + return getPipByNameUnlocked(name); } -void Arch::unbindPip(PipId pip) +PipId Arch::getPipByNameUnlocked(IdString name) const { - return rwproxy().unbindPip(pip); -} + PipId ret; -bool Arch::checkPipAvail(PipId pip) const -{ - return rproxy().checkPipAvail(pip); -} + if (pip_by_name.empty()) { + for (int i = 0; i < chip_info->num_pips; i++) { + PipId pip; + pip.index = i; + pip_by_name[getPipName(pip)] = i; + } + } -IdString Arch::getBoundPipNet(PipId pip) const -{ - return rproxy().getBoundPipNet(pip); -} + auto it = pip_by_name.find(name); + if (it != pip_by_name.end()) + ret.index = it->second; -IdString Arch::getConflictingPipNet(PipId pip) const -{ - return rproxy().getConflictingPipNet(pip); + return ret; } -// ----------------------------------------------------------------------- - IdString Arch::getPipName(PipId pip) const { NPNR_ASSERT(pip != PipId()); @@ -731,227 +718,4 @@ bool Arch::isGlobalNet(const NetInfo *net) const return net->driver.cell != nullptr && net->driver.port == id_glb_buf_out; } -// ----------------------------------------------------------------------- - -bool ArchRProxyMethods::checkBelAvail(BelId bel) const -{ - NPNR_ASSERT(bel != BelId()); - return parent_->bel_to_cell[bel.index] == IdString(); -} - -IdString ArchRProxyMethods::getBoundBelCell(BelId bel) const -{ - NPNR_ASSERT(bel != BelId()); - return parent_->bel_to_cell[bel.index]; -} - -IdString ArchRProxyMethods::getConflictingBelCell(BelId bel) const -{ - NPNR_ASSERT(bel != BelId()); - return parent_->bel_to_cell[bel.index]; -} - -WireId ArchRProxyMethods::getWireBelPin(BelId bel, PortPin pin) const -{ - WireId ret; - - NPNR_ASSERT(bel != BelId()); - - int num_bel_wires = parent_->chip_info->bel_data[bel.index].num_bel_wires; - const BelWirePOD *bel_wires = parent_->chip_info->bel_data[bel.index].bel_wires.get(); - - for (int i = 0; i < num_bel_wires; i++) - if (bel_wires[i].port == pin) { - ret.index = bel_wires[i].wire_index; - break; - } - - return ret; -} - -WireId ArchRProxyMethods::getWireByName(IdString name) const -{ - WireId ret; - - if (parent_->wire_by_name.empty()) { - for (int i = 0; i < parent_->chip_info->num_wires; i++) - parent_->wire_by_name[parent_->id(parent_->chip_info->wire_data[i].name.get())] = i; - } - - auto it = parent_->wire_by_name.find(name); - if (it != parent_->wire_by_name.end()) - ret.index = it->second; - - return ret; -} - -bool ArchRProxyMethods::checkWireAvail(WireId wire) const -{ - NPNR_ASSERT(wire != WireId()); - return parent_->wire_to_net[wire.index] == IdString(); -} - -IdString ArchRProxyMethods::getBoundWireNet(WireId wire) const -{ - NPNR_ASSERT(wire != WireId()); - return parent_->wire_to_net[wire.index]; -} - -IdString ArchRProxyMethods::getConflictingWireNet(WireId wire) const -{ - NPNR_ASSERT(wire != WireId()); - return parent_->wire_to_net[wire.index]; -} - -PipId ArchRProxyMethods::getPipByName(IdString name) const -{ - PipId ret; - - if (parent_->pip_by_name.empty()) { - for (int i = 0; i < parent_->chip_info->num_pips; i++) { - PipId pip; - pip.index = i; - parent_->pip_by_name[parent_->getPipName(pip)] = i; - } - } - - auto it = parent_->pip_by_name.find(name); - if (it != parent_->pip_by_name.end()) - ret.index = it->second; - - return ret; -} - -bool ArchRProxyMethods::checkPipAvail(PipId pip) const -{ - NPNR_ASSERT(pip != PipId()); - return parent_->switches_locked[parent_->chip_info->pip_data[pip.index].switch_index] == IdString(); -} - -IdString ArchRProxyMethods::getBoundPipNet(PipId pip) const -{ - NPNR_ASSERT(pip != PipId()); - return parent_->pip_to_net[pip.index]; -} - -IdString ArchRProxyMethods::getConflictingPipNet(PipId pip) const -{ - NPNR_ASSERT(pip != PipId()); - return parent_->switches_locked[parent_->chip_info->pip_data[pip.index].switch_index]; -} - -BelId ArchRProxyMethods::getBelByName(IdString name) const -{ - BelId ret; - - if (parent_->bel_by_name.empty()) { - for (int i = 0; i < parent_->chip_info->num_bels; i++) - parent_->bel_by_name[parent_->id(parent_->chip_info->bel_data[i].name.get())] = i; - } - - auto it = parent_->bel_by_name.find(name); - if (it != parent_->bel_by_name.end()) - ret.index = it->second; - - return ret; -} - -// ----------------------------------------------------------------------- - -void ArchRWProxyMethods::bindBel(BelId bel, IdString cell, PlaceStrength strength) -{ - NPNR_ASSERT(bel != BelId()); - NPNR_ASSERT(parent_->bel_to_cell[bel.index] == IdString()); - parent_->bel_to_cell[bel.index] = cell; - parent_->cells[cell]->bel = bel; - parent_->cells[cell]->belStrength = strength; - parent_->refreshUiBel(bel); -} - -void ArchRWProxyMethods::unbindBel(BelId bel) -{ - NPNR_ASSERT(bel != BelId()); - NPNR_ASSERT(parent_->bel_to_cell[bel.index] != IdString()); - parent_->cells[parent_->bel_to_cell[bel.index]]->bel = BelId(); - parent_->cells[parent_->bel_to_cell[bel.index]]->belStrength = STRENGTH_NONE; - parent_->bel_to_cell[bel.index] = IdString(); - parent_->refreshUiBel(bel); -} - -void ArchRWProxyMethods::bindWire(WireId wire, IdString net, PlaceStrength strength) -{ - NPNR_ASSERT(wire != WireId()); - NPNR_ASSERT(parent_->wire_to_net[wire.index] == IdString()); - - parent_->wire_to_net[wire.index] = net; - parent_->nets[net]->wires[wire].pip = PipId(); - parent_->nets[net]->wires[wire].strength = strength; - parent_->refreshUiWire(wire); -} - -void ArchRWProxyMethods::unbindWire(WireId wire) -{ - NPNR_ASSERT(wire != WireId()); - NPNR_ASSERT(parent_->wire_to_net[wire.index] != IdString()); - - auto &net_wires = parent_->nets[parent_->wire_to_net[wire.index]]->wires; - auto it = net_wires.find(wire); - NPNR_ASSERT(it != net_wires.end()); - - auto pip = it->second.pip; - if (pip != PipId()) { - parent_->pip_to_net[pip.index] = IdString(); - parent_->switches_locked[parent_->chip_info->pip_data[pip.index].switch_index] = IdString(); - parent_->refreshUiPip(pip); - } - - net_wires.erase(it); - parent_->wire_to_net[wire.index] = IdString(); - parent_->refreshUiWire(wire); -} - -void ArchRWProxyMethods::bindPip(PipId pip, IdString net, PlaceStrength strength) -{ - NPNR_ASSERT(pip != PipId()); - NPNR_ASSERT(parent_->pip_to_net[pip.index] == IdString()); - NPNR_ASSERT(parent_->switches_locked[parent_->chip_info->pip_data[pip.index].switch_index] == IdString()); - - parent_->pip_to_net[pip.index] = net; - parent_->switches_locked[parent_->chip_info->pip_data[pip.index].switch_index] = net; - - WireId dst; - dst.index = parent_->chip_info->pip_data[pip.index].dst; - NPNR_ASSERT(parent_->wire_to_net[dst.index] == IdString()); - parent_->wire_to_net[dst.index] = net; - parent_->nets[net]->wires[dst].pip = pip; - parent_->nets[net]->wires[dst].strength = strength; - - parent_->refreshUiPip(pip); - parent_->refreshUiWire(dst); -} - -void ArchRWProxyMethods::unbindPip(PipId pip) -{ - NPNR_ASSERT(pip != PipId()); - NPNR_ASSERT(parent_->pip_to_net[pip.index] != IdString()); - NPNR_ASSERT(parent_->switches_locked[parent_->chip_info->pip_data[pip.index].switch_index] != IdString()); - - WireId dst; - dst.index = parent_->chip_info->pip_data[pip.index].dst; - NPNR_ASSERT(parent_->wire_to_net[dst.index] != IdString()); - parent_->wire_to_net[dst.index] = IdString(); - parent_->nets[parent_->pip_to_net[pip.index]]->wires.erase(dst); - - parent_->pip_to_net[pip.index] = IdString(); - parent_->switches_locked[parent_->chip_info->pip_data[pip.index].switch_index] = IdString(); - - parent_->refreshUiPip(pip); - parent_->refreshUiWire(dst); -} - -CellInfo *ArchRWProxyMethods::getCell(IdString cell) -{ - return parent_->cells.at(cell).get(); -} - NEXTPNR_NAMESPACE_END diff --git a/ice40/arch.h b/ice40/arch.h index 36e34d7b..6f281d4a 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -2,7 +2,6 @@ * nextpnr -- Next Generation Place and Route * * Copyright (C) 2018 Clifford Wolf - * Copyright (C) 2018 Serge Bazanski * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -328,40 +327,27 @@ struct ArchArgs std::string package; }; -class ArchRWProxyMethods; -class ArchRProxyMethods; -class ArchRWProxy; -class ArchRProxy; - class Arch : public BaseCtx { - friend class ArchRWProxyMethods; - friend class ArchRProxyMethods; - friend class ArchRWProxy; - friend class ArchRProxy; private: // All of the following... std::vector bel_to_cell; std::vector wire_to_net; std::vector pip_to_net; std::vector switches_locked; - mutable std::unordered_map bel_by_name; - mutable std::unordered_map wire_by_name; - mutable std::unordered_map pip_by_name; - // ... are guarded by the following lock: mutable boost::shared_mutex mtx_; - public: const ChipInfoPOD *chip_info; const PackageInfoPOD *package_info; + mutable std::unordered_map bel_by_name; + mutable std::unordered_map wire_by_name; + mutable std::unordered_map pip_by_name; + ArchArgs args; Arch(ArchArgs args); - ArchRWProxy rwproxy(void); - ArchRProxy rproxy(void) const; - std::string getChipName(); IdString archId() const { return id("ice40"); } @@ -375,33 +361,8 @@ public: // ------------------------------------------------- - /// Wrappers around getting a r(w)proxy and calling a single method. - // Deprecated: please acquire a proxy yourself and call the methods - // you want on it. - void unbindWire(WireId wire); - void unbindPip(PipId pip); - void unbindBel(BelId bel); - void bindWire(WireId wire, IdString net, PlaceStrength strength); - void bindPip(PipId pip, IdString net, PlaceStrength strength); - void bindBel(BelId bel, IdString cell, PlaceStrength strength); - bool checkWireAvail(WireId wire) const; - bool checkPipAvail(PipId pip) const; - bool checkBelAvail(BelId bel) const; - WireId getWireByName(IdString name) const; - WireId getWireBelPin(BelId bel, PortPin pin) const; - PipId getPipByName(IdString name) const; - IdString getConflictingWireNet(WireId wire) const; - IdString getConflictingPipNet(PipId pip) const; - IdString getConflictingBelCell(BelId bel) const; - IdString getBoundWireNet(WireId wire) const; - IdString getBoundPipNet(PipId pip) const; - IdString getBoundBelCell(BelId bel) const; BelId getBelByName(IdString name) const; - - // ------------------------------------------------- - - /// Methods to get chip info - don't need to use a wrapper, as these are - /// static per lifetime of object. + BelId getBelByNameUnlocked(IdString name) const; IdString getBelName(BelId bel) const { @@ -409,9 +370,71 @@ public: return id(chip_info->bel_data[bel.index].name.get()); } - uint32_t getBelChecksum(BelId bel) const + uint32_t getBelChecksum(BelId bel) const { return bel.index; } + + void bindBel(BelId bel, IdString cell, PlaceStrength strength) { + boost::lock_guard lock(mtx_); + bindBelUnlocked(bel, cell, strength); + } + + void bindBelUnlocked(BelId bel, IdString cell, PlaceStrength strength) { - return bel.index; + NPNR_ASSERT(bel != BelId()); + NPNR_ASSERT(bel_to_cell[bel.index] == IdString()); + bel_to_cell[bel.index] = cell; + cells[cell]->bel = bel; + cells[cell]->belStrength = strength; + } + + void unbindBel(BelId bel) + { + boost::lock_guard lock(mtx_); + unbindBelUnlocked(bel); + } + + void unbindBelUnlocked(BelId bel) + { + NPNR_ASSERT(bel != BelId()); + NPNR_ASSERT(bel_to_cell[bel.index] != IdString()); + cells[bel_to_cell[bel.index]]->bel = BelId(); + cells[bel_to_cell[bel.index]]->belStrength = STRENGTH_NONE; + bel_to_cell[bel.index] = IdString(); + } + + bool checkBelAvail(BelId bel) const + { + boost::shared_lock_guard lock(mtx_); + return checkBelAvailUnlocked(bel); + } + + bool checkBelAvailUnlocked(BelId bel) const + { + NPNR_ASSERT(bel != BelId()); + return bel_to_cell[bel.index] == IdString(); + } + + IdString getBoundBelCell(BelId bel) const + { + boost::shared_lock_guard lock(mtx_); + return getBoundBelCellUnlocked(bel); + } + + IdString getBoundBelCellUnlocked(BelId bel) const + { + NPNR_ASSERT(bel != BelId()); + return bel_to_cell[bel.index]; + } + + IdString getConflictingBelCell(BelId bel) const + { + boost::shared_lock_guard lock(mtx_); + return getConflictingBelCellUnlocked(bel); + } + + IdString getConflictingBelCellUnlocked(BelId bel) const + { + NPNR_ASSERT(bel != BelId()); + return bel_to_cell[bel.index]; } BelRange getBels() const @@ -444,6 +467,8 @@ public: return chip_info->bel_data[bel.index].type; } + WireId getWireBelPin(BelId bel, PortPin pin) const; + WireId getWireBelPinUnlocked(BelId bel, PortPin pin) const; BelPin getBelPinUphill(WireId wire) const { @@ -469,6 +494,9 @@ public: // ------------------------------------------------- + WireId getWireByName(IdString name) const; + WireId getWireByNameUnlocked(IdString name) const; + IdString getWireName(WireId wire) const { NPNR_ASSERT(wire != WireId()); @@ -477,6 +505,180 @@ public: uint32_t getWireChecksum(WireId wire) const { return wire.index; } + void bindWire(WireId wire, IdString net, PlaceStrength strength) + { + boost::lock_guard lock(mtx_); + bindWireUnlocked(wire, net, strength); + } + + void bindWireUnlocked(WireId wire, IdString net, PlaceStrength strength) + { + NPNR_ASSERT(wire != WireId()); + NPNR_ASSERT(wire_to_net[wire.index] == IdString()); + + wire_to_net[wire.index] = net; + nets[net]->wires[wire].pip = PipId(); + nets[net]->wires[wire].strength = strength; + } + + void unbindWire(WireId wire) + { + boost::lock_guard lock(mtx_); + unbindWireUnlocked(wire); + } + + void unbindWireUnlocked(WireId wire) + { + NPNR_ASSERT(wire != WireId()); + NPNR_ASSERT(wire_to_net[wire.index] != IdString()); + + auto &net_wires = nets[wire_to_net[wire.index]]->wires; + auto it = net_wires.find(wire); + NPNR_ASSERT(it != net_wires.end()); + + auto pip = it->second.pip; + if (pip != PipId()) { + pip_to_net[pip.index] = IdString(); + switches_locked[chip_info->pip_data[pip.index].switch_index] = IdString(); + } + + net_wires.erase(it); + wire_to_net[wire.index] = IdString(); + } + + bool checkWireAvail(WireId wire) const + { + boost::shared_lock_guard lock(mtx_); + return checkWireAvailUnlocked(wire); + } + + bool checkWireAvailUnlocked(WireId wire) const + { + NPNR_ASSERT(wire != WireId()); + return wire_to_net[wire.index] == IdString(); + } + + IdString getBoundWireNet(WireId wire) const + { + boost::shared_lock_guard lock(mtx_); + return getBoundWireNetUnlocked(wire); + } + + IdString getBoundWireNetUnlocked(WireId wire) const + { + NPNR_ASSERT(wire != WireId()); + return wire_to_net[wire.index]; + } + + IdString getConflictingWireNet(WireId wire) const + { + boost::shared_lock_guard lock(mtx_); + return getConflictingWireNetUnlocked(wire); + } + + IdString getConflictingWireNetUnlocked(WireId wire) const + { + NPNR_ASSERT(wire != WireId()); + return wire_to_net[wire.index]; + } + + WireRange getWires() const + { + WireRange range; + range.b.cursor = 0; + range.e.cursor = chip_info->num_wires; + return range; + } + + // ------------------------------------------------- + + PipId getPipByName(IdString name) const; + PipId getPipByNameUnlocked(IdString name) const; + IdString getPipName(PipId pip) const; + + uint32_t getPipChecksum(PipId pip) const { return pip.index; } + + void bindPip(PipId pip, IdString net, PlaceStrength strength) + { + boost::lock_guard lock(mtx_); + bindPipUnlocked(pip, net, strength); + } + + void bindPipUnlocked(PipId pip, IdString net, PlaceStrength strength) + { + NPNR_ASSERT(pip != PipId()); + NPNR_ASSERT(pip_to_net[pip.index] == IdString()); + NPNR_ASSERT(switches_locked[chip_info->pip_data[pip.index].switch_index] == IdString()); + + pip_to_net[pip.index] = net; + switches_locked[chip_info->pip_data[pip.index].switch_index] = net; + + WireId dst; + dst.index = chip_info->pip_data[pip.index].dst; + NPNR_ASSERT(wire_to_net[dst.index] == IdString()); + wire_to_net[dst.index] = net; + nets[net]->wires[dst].pip = pip; + nets[net]->wires[dst].strength = strength; + } + + void unbindPip(PipId pip) + { + boost::lock_guard lock(mtx_); + unbindPipUnlocked(pip); + } + + void unbindPipUnlocked(PipId pip) + { + NPNR_ASSERT(pip != PipId()); + NPNR_ASSERT(pip_to_net[pip.index] != IdString()); + NPNR_ASSERT(switches_locked[chip_info->pip_data[pip.index].switch_index] != IdString()); + + WireId dst; + dst.index = chip_info->pip_data[pip.index].dst; + NPNR_ASSERT(wire_to_net[dst.index] != IdString()); + wire_to_net[dst.index] = IdString(); + nets[pip_to_net[pip.index]]->wires.erase(dst); + + pip_to_net[pip.index] = IdString(); + switches_locked[chip_info->pip_data[pip.index].switch_index] = IdString(); + } + + bool checkPipAvail(PipId pip) const + { + boost::shared_lock_guard lock(mtx_); + return checkPipAvailUnlocked(pip); + } + + bool checkPipAvailUnlocked(PipId pip) const + { + NPNR_ASSERT(pip != PipId()); + return switches_locked[chip_info->pip_data[pip.index].switch_index] == IdString(); + } + + IdString getBoundPipNet(PipId pip) const + { + boost::shared_lock_guard lock(mtx_); + return getBoundPipNetUnlocked(pip); + } + + IdString getBoundPipNetUnlocked(PipId pip) const + { + NPNR_ASSERT(pip != PipId()); + return pip_to_net[pip.index]; + } + + IdString getConflictingPipNet(PipId pip) const + { + boost::shared_lock_guard lock(mtx_); + return getConflictingPipNetUnlocked(pip); + } + + IdString getConflictingPipNetUnlocked(PipId pip) const + { + NPNR_ASSERT(pip != PipId()); + return switches_locked[chip_info->pip_data[pip.index].switch_index]; + } + AllPipRange getPips() const { AllPipRange range; @@ -601,26 +803,7 @@ public: // ------------------------------------------------- - IdString id_glb_buf_out; - IdString id_icestorm_lc, id_sb_io, id_sb_gb; - IdString id_cen, id_clk, id_sr; - IdString id_i0, id_i1, id_i2, id_i3; - IdString id_dff_en, id_neg_clk; -}; - -class ArchRProxyMethods { - friend class ArchRProxy; - friend class ArchRWProxy; -private: - const Arch *parent_; - ArchRProxyMethods(const Arch *parent) : parent_(parent) {} - ArchRProxyMethods(ArchRProxyMethods &&other) noexcept : parent_(other.parent_) {} - ArchRProxyMethods(const ArchRProxyMethods &other) : parent_(other.parent_) {} - -public: - ~ArchRProxyMethods() noexcept { } - - /// Perform placement validity checks, returning false on failure (all implemented in arch_place.cc) + // Perform placement validity checks, returning false on failure (all implemented in arch_place.cc) // Whether or not a given cell can be placed at a given Bel // This is not intended for Bel type checks, but finer-grained constraints @@ -633,88 +816,11 @@ public: // Helper function for above bool logicCellsCompatible(const std::vector &cells) const; - bool checkWireAvail(WireId wire) const; - bool checkPipAvail(PipId pip) const; - bool checkBelAvail(BelId bel) const; - - WireId getWireByName(IdString name) const; - WireId getWireBelPin(BelId bel, PortPin pin) const; - PipId getPipByName(IdString name) const; - - - IdString getConflictingWireNet(WireId wire) const; - IdString getConflictingPipNet(PipId pip) const; - IdString getConflictingBelCell(BelId bel) const; - - IdString getBoundWireNet(WireId wire) const; - IdString getBoundPipNet(PipId pip) const; - IdString getBoundBelCell(BelId bel) const; - - BelId getBelByName(IdString name) const; -}; - -class ArchRProxy : public ArchRProxyMethods { - friend class Arch; - friend class ArchRWProxy; -private: - boost::shared_mutex *lock_; - ArchRProxy(const Arch *parent) : ArchRProxyMethods(parent), lock_(&parent->mtx_) - { - lock_->lock_shared(); - } - -public: - ~ArchRProxy() { - if (lock_ != nullptr) { - lock_->unlock_shared(); - } - } - ArchRProxy(ArchRProxy &&other) : ArchRProxyMethods(other), lock_(other.lock_) - { - other.lock_ = nullptr; - } -}; - -class ArchRWProxyMethods { - friend class ArchRWProxy; -private: - Arch *parent_; - ArchRWProxyMethods(Arch *parent) : parent_(parent) {} - ArchRWProxyMethods(ArchRWProxyMethods &&other) : parent_(other.parent_) {} - ArchRWProxyMethods(const ArchRWProxyMethods &other) : parent_(other.parent_) {} -public: - ~ArchRWProxyMethods() {} - - void unbindWire(WireId wire); - void unbindPip(PipId pip); - void unbindBel(BelId bel); - void bindWire(WireId wire, IdString net, PlaceStrength strength); - void bindPip(PipId pip, IdString net, PlaceStrength strength); - void bindBel(BelId bel, IdString cell, PlaceStrength strength); - CellInfo *getCell(IdString cell); -}; - -class ArchRWProxy : public ArchRProxyMethods, public ArchRWProxyMethods { - friend class Arch; -private: - boost::shared_mutex *lock_; - ArchRWProxy(Arch *parent) : ArchRProxyMethods(parent), ArchRWProxyMethods(parent), lock_(&parent->mtx_) { - lock_->lock(); - } - -public: - ArchRWProxy(ArchRWProxy &&other) : ArchRProxyMethods(other), ArchRWProxyMethods(other), lock_(other.lock_) - { - other.lock_ = nullptr; - } - ~ArchRWProxy() - { - if (lock_ != nullptr) { - lock_->unlock(); - } - } - - + IdString id_glb_buf_out; + IdString id_icestorm_lc, id_sb_io, id_sb_gb; + IdString id_cen, id_clk, id_sr; + IdString id_i0, id_i1, id_i2, id_i3; + IdString id_dff_en, id_neg_clk; }; NEXTPNR_NAMESPACE_END diff --git a/ice40/arch_place.cc b/ice40/arch_place.cc index cb7c44b8..c9dd26c5 100644 --- a/ice40/arch_place.cc +++ b/ice40/arch_place.cc @@ -3,7 +3,6 @@ * * Copyright (C) 2018 Clifford Wolf * Copyright (C) 2018 David Shah - * Copyright (C) 2018 Serge Bazanski * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -25,44 +24,44 @@ NEXTPNR_NAMESPACE_BEGIN -bool ArchRProxyMethods::logicCellsCompatible(const std::vector &cells) const +bool Arch::logicCellsCompatible(const std::vector &cells) const { bool dffs_exist = false, dffs_neg = false; const NetInfo *cen = nullptr, *clk = nullptr, *sr = nullptr; int locals_count = 0; for (auto cell : cells) { - if (bool_or_default(cell->params, parent_->id_dff_en)) { + if (bool_or_default(cell->params, id_dff_en)) { if (!dffs_exist) { dffs_exist = true; - cen = get_net_or_empty(cell, parent_->id_cen); - clk = get_net_or_empty(cell, parent_->id_clk); - sr = get_net_or_empty(cell, parent_->id_sr); + cen = get_net_or_empty(cell, id_cen); + clk = get_net_or_empty(cell, id_clk); + sr = get_net_or_empty(cell, id_sr); - if (!parent_->isGlobalNet(cen) && cen != nullptr) + if (!isGlobalNet(cen) && cen != nullptr) locals_count++; - if (!parent_->isGlobalNet(clk) && clk != nullptr) + if (!isGlobalNet(clk) && clk != nullptr) locals_count++; - if (!parent_->isGlobalNet(sr) && sr != nullptr) + if (!isGlobalNet(sr) && sr != nullptr) locals_count++; - if (bool_or_default(cell->params, parent_->id_neg_clk)) { + if (bool_or_default(cell->params, id_neg_clk)) { dffs_neg = true; } } else { - if (cen != get_net_or_empty(cell, parent_->id_cen)) + if (cen != get_net_or_empty(cell, id_cen)) return false; - if (clk != get_net_or_empty(cell, parent_->id_clk)) + if (clk != get_net_or_empty(cell, id_clk)) return false; - if (sr != get_net_or_empty(cell, parent_->id_sr)) + if (sr != get_net_or_empty(cell, id_sr)) return false; - if (dffs_neg != bool_or_default(cell->params, parent_->id_neg_clk)) + if (dffs_neg != bool_or_default(cell->params, id_neg_clk)) return false; } } - const NetInfo *i0 = get_net_or_empty(cell, parent_->id_i0), *i1 = get_net_or_empty(cell, parent_->id_i1), - *i2 = get_net_or_empty(cell, parent_->id_i2), *i3 = get_net_or_empty(cell, parent_->id_i3); + const NetInfo *i0 = get_net_or_empty(cell, id_i0), *i1 = get_net_or_empty(cell, id_i1), + *i2 = get_net_or_empty(cell, id_i2), *i3 = get_net_or_empty(cell, id_i3); if (i0 != nullptr) locals_count++; if (i1 != nullptr) @@ -76,57 +75,57 @@ bool ArchRProxyMethods::logicCellsCompatible(const std::vector return locals_count <= 32; } -bool ArchRProxyMethods::isBelLocationValid(BelId bel) const +bool Arch::isBelLocationValid(BelId bel) const { - if (parent_->getBelType(bel) == TYPE_ICESTORM_LC) { + if (getBelType(bel) == TYPE_ICESTORM_LC) { std::vector bel_cells; - for (auto bel_other : parent_->getBelsAtSameTile(bel)) { - IdString cell_other = getBoundBelCell(bel_other); + for (auto bel_other : getBelsAtSameTile(bel)) { + IdString cell_other = getBoundBelCellUnlocked(bel_other); if (cell_other != IdString()) { - const CellInfo *ci_other = parent_->cells.at(cell_other).get(); + const CellInfo *ci_other = cells.at(cell_other).get(); bel_cells.push_back(ci_other); } } return logicCellsCompatible(bel_cells); } else { - IdString cellId = getBoundBelCell(bel); + IdString cellId = getBoundBelCellUnlocked(bel); if (cellId == IdString()) return true; else - return isValidBelForCell(parent_->cells.at(cellId).get(), bel); + return isValidBelForCell(cells.at(cellId).get(), bel); } } -bool ArchRProxyMethods::isValidBelForCell(CellInfo *cell, BelId bel) const +bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const { - if (cell->type == parent_->id_icestorm_lc) { - NPNR_ASSERT(parent_->getBelType(bel) == TYPE_ICESTORM_LC); + if (cell->type == id_icestorm_lc) { + NPNR_ASSERT(getBelType(bel) == TYPE_ICESTORM_LC); std::vector bel_cells; - for (auto bel_other : parent_->getBelsAtSameTile(bel)) { - IdString cell_other = getBoundBelCell(bel_other); + for (auto bel_other : getBelsAtSameTile(bel)) { + IdString cell_other = getBoundBelCellUnlocked(bel_other); if (cell_other != IdString() && bel_other != bel) { - const CellInfo *ci_other = parent_->cells.at(cell_other).get(); + const CellInfo *ci_other = cells.at(cell_other).get(); bel_cells.push_back(ci_other); } } bel_cells.push_back(cell); return logicCellsCompatible(bel_cells); - } else if (cell->type == parent_->id_sb_io) { - return parent_->getBelPackagePin(bel) != ""; - } else if (cell->type == parent_->id_sb_gb) { + } else if (cell->type == id_sb_io) { + return getBelPackagePin(bel) != ""; + } else if (cell->type == id_sb_gb) { bool is_reset = false, is_cen = false; - NPNR_ASSERT(cell->ports.at(parent_->id_glb_buf_out).net != nullptr); - for (auto user : cell->ports.at(parent_->id_glb_buf_out).net->users) { - if (is_reset_port(parent_, user)) + NPNR_ASSERT(cell->ports.at(id_glb_buf_out).net != nullptr); + for (auto user : cell->ports.at(id_glb_buf_out).net->users) { + if (is_reset_port(this, user)) is_reset = true; - if (is_enable_port(parent_, user)) + if (is_enable_port(this, user)) is_cen = true; } - IdString glb_net = parent_->getWireName(getWireBelPin(bel, PIN_GLOBAL_BUFFER_OUTPUT)); - int glb_id = std::stoi(std::string("") + glb_net.str(parent_).back()); + IdString glb_net = getWireName(getWireBelPin(bel, PIN_GLOBAL_BUFFER_OUTPUT)); + int glb_id = std::stoi(std::string("") + glb_net.str(this).back()); if (is_reset && is_cen) return false; else if (is_reset) diff --git a/ice40/place_legaliser.cc b/ice40/place_legaliser.cc index 10a6f3ff..d42188f0 100644 --- a/ice40/place_legaliser.cc +++ b/ice40/place_legaliser.cc @@ -119,17 +119,13 @@ class PlacementLegaliser bool legalise() { - log_info("Legalising logic cells...\n"); + log_info("Legalising design..\n"); init_logic_cells(); - log_info("Legalising carries...\n"); bool legalised_carries = legalise_carries(); if (!legalised_carries && !ctx->force) return false; - log_info("Legalising others...\n"); legalise_others(); - log_info("Legalising logic tiles...\n"); legalise_logic_tiles(); - log_info("Replacing cells...\n"); bool replaced_cells = replace_cells(); return legalised_carries && replaced_cells; } @@ -137,7 +133,6 @@ class PlacementLegaliser private: void init_logic_cells() { - auto &&proxy = ctx->rproxy(); for (auto bel : ctx->getBels()) { // Initialise the logic bels vector with unavailable invalid bels, dimensions [0..width][0..height[0..7] logic_bels.resize(ctx->chip_info->width + 1, @@ -148,7 +143,7 @@ class PlacementLegaliser // Using the non-standard API here to get (x, y, z) rather than just (x, y) auto bi = ctx->chip_info->bel_data[bel.index]; int x = bi.x, y = bi.y, z = bi.z; - IdString cell = proxy.getBoundBelCell(bel); + IdString cell = ctx->getBoundBelCellUnlocked(bel); if (cell != IdString() && ctx->cells.at(cell)->belStrength >= STRENGTH_FIXED) logic_bels.at(x).at(y).at(z) = std::make_pair(bel, true); // locked out of use else @@ -200,33 +195,28 @@ class PlacementLegaliser } } bool success = true; - // Find midpoints for all chains, before we start tearing them up std::vector all_chains; - { - auto &&proxy = ctx->rproxy(); - for (auto &base_chain : carry_chains) { - if (ctx->verbose) { - log_info("Found carry chain: \n"); - for (auto entry : base_chain.cells) - log_info(" %s\n", entry->name.c_str(ctx)); - log_info("\n"); - } - std::vector split_chains = split_carry_chain(proxy, base_chain); - for (auto &chain : split_chains) { - get_chain_midpoint(ctx, chain, chain.mid_x, chain.mid_y); - all_chains.push_back(chain); - } + for (auto &base_chain : carry_chains) { + if (ctx->verbose) { + log_info("Found carry chain: \n"); + for (auto entry : base_chain.cells) + log_info(" %s\n", entry->name.c_str(ctx)); + log_info("\n"); + } + std::vector split_chains = split_carry_chain(base_chain); + for (auto &chain : split_chains) { + get_chain_midpoint(ctx, chain, chain.mid_x, chain.mid_y); + all_chains.push_back(chain); } } // Actual chain placement - auto &&proxy = ctx->rwproxy(); for (auto &chain : all_chains) { if (ctx->verbose) log_info("Placing carry chain starting at '%s'\n", chain.cells.front()->name.c_str(ctx)); float base_x = chain.mid_x, base_y = chain.mid_y - (chain.cells.size() / 16.0f); // Find Bel meeting requirements closest to the target base, returning location as - auto chain_origin_bel = find_closest_bel(proxy, base_x, base_y, chain); + auto chain_origin_bel = find_closest_bel(base_x, base_y, chain); int place_x = std::get<0>(chain_origin_bel), place_y = std::get<1>(chain_origin_bel), place_z = std::get<2>(chain_origin_bel); if (place_x == -1) { @@ -243,7 +233,7 @@ class PlacementLegaliser // Place carry chain for (int i = 0; i < int(chain.cells.size()); i++) { int target_z = place_y * 8 + place_z + i; - place_lc(proxy, chain.cells.at(i), place_x, target_z / 8, target_z % 8); + place_lc(chain.cells.at(i), place_x, target_z / 8, target_z % 8); if (ctx->verbose) log_info(" Cell '%s' placed at (%d, %d, %d)\n", chain.cells.at(i)->name.c_str(ctx), place_x, target_z / 8, target_z % 8); @@ -253,7 +243,7 @@ class PlacementLegaliser } // Find Bel closest to a location, meeting chain requirements - std::tuple find_closest_bel(ArchRWProxy &proxy, float target_x, float target_y, CellChain &chain) + std::tuple find_closest_bel(float target_x, float target_y, CellChain &chain) { std::tuple best_origin = std::make_tuple(-1, -1, -1); wirelen_t best_wirelength = std::numeric_limits::max(); @@ -270,7 +260,7 @@ class PlacementLegaliser valid = false; break; } else { - wirelen += get_cell_wirelength_at_bel(proxy, ctx, chain.cells.at(k), lb.first); + wirelen += get_cell_wirelength_at_bel(ctx, chain.cells.at(k), lb.first); } } if (valid && wirelen < best_wirelength) { @@ -283,7 +273,7 @@ class PlacementLegaliser } // Split a carry chain into multiple legal chains - std::vector split_carry_chain(const ArchRProxy &proxy, CellChain &carryc) + std::vector split_carry_chain(CellChain &carryc) { bool start_of_chain = true; std::vector chains; @@ -308,7 +298,7 @@ class PlacementLegaliser } tile.push_back(cell); chains.back().cells.push_back(cell); - bool split_chain = (!proxy.logicCellsCompatible(tile)) || (int(chains.back().cells.size()) > max_length); + bool split_chain = (!ctx->logicCellsCompatible(tile)) || (int(chains.back().cells.size()) > max_length); if (split_chain) { CellInfo *passout = make_carry_pass_out(cell->ports.at(ctx->id("COUT"))); tile.pop_back(); @@ -335,22 +325,22 @@ class PlacementLegaliser } // Place a logic cell at a given grid location, handling rip-up etc - void place_lc(ArchRWProxy &proxy, CellInfo *cell, int x, int y, int z) + void place_lc(CellInfo *cell, int x, int y, int z) { auto &loc = logic_bels.at(x).at(y).at(z); NPNR_ASSERT(!loc.second); BelId bel = loc.first; // Check if there is a cell presently at the location, which we will need to rip up - IdString existing = proxy.getBoundBelCell(bel); + IdString existing = ctx->getBoundBelCellUnlocked(bel); if (existing != IdString()) { // TODO: keep track of the previous position of the ripped up cell, as a hint rippedCells.insert(existing); - proxy.unbindBel(bel); + ctx->unbindBelUnlocked(bel); } if (cell->bel != BelId()) { - proxy.unbindBel(cell->bel); + ctx->unbindBelUnlocked(cell->bel); } - proxy.bindBel(bel, cell->name, STRENGTH_LOCKED); + ctx->bindBelUnlocked(bel, cell->name, STRENGTH_LOCKED); rippedCells.erase(cell->name); // If cell was ripped up previously, no need to re-place loc.second = true; // Bel is now unavailable for further use } @@ -433,20 +423,19 @@ class PlacementLegaliser // Legalise logic tiles void legalise_logic_tiles() { - auto &&proxy = ctx->rwproxy(); int width = ctx->chip_info->width, height = ctx->chip_info->height; for (int x = 1; x < width; x++) { for (int y = 1; y < height; y++) { BelId tileBel = logic_bels.at(x).at(y).at(0).first; if (tileBel != BelId()) { bool changed = true; - while (!proxy.isBelLocationValid(tileBel) && changed) { + while (!ctx->isBelLocationValid(tileBel) && changed) { changed = false; int max_score = 0; CellInfo *target = nullptr; for (int z = 0; z < 8; z++) { BelId bel = logic_bels.at(x).at(y).at(z).first; - IdString cell = proxy.getBoundBelCell(bel); + IdString cell = ctx->getBoundBelCellUnlocked(bel); if (cell != IdString()) { CellInfo *ci = ctx->cells.at(cell).get(); if (ci->belStrength >= STRENGTH_STRONG) @@ -459,7 +448,7 @@ class PlacementLegaliser } } if (target != nullptr) { - proxy.unbindBel(target->bel); + ctx->unbindBelUnlocked(target->bel); rippedCells.insert(target->name); changed = true; } @@ -472,14 +461,13 @@ class PlacementLegaliser // Legalise other tiles void legalise_others() { - auto &&proxy = ctx->rwproxy(); std::vector legalised_others; for (auto cell : sorted(ctx->cells)) { CellInfo *ci = cell.second; if (!is_lc(ctx, ci)) { if (ci->belStrength < STRENGTH_STRONG && ci->bel != BelId()) { - if (!proxy.isValidBelForCell(ci, ci->bel)) { - place_single_cell(proxy, ctx, ci, true); + if (!ctx->isValidBelForCell(ci, ci->bel)) { + place_single_cell(ctx, ci, true); } legalised_others.push_back(ci); } @@ -494,11 +482,10 @@ class PlacementLegaliser // Replace ripped-up cells bool replace_cells() { - auto &&proxy = ctx->rwproxy(); bool success = true; for (auto cell : sorted(rippedCells)) { CellInfo *ci = ctx->cells.at(cell).get(); - bool placed = place_single_cell(proxy, ctx, ci, true); + bool placed = place_single_cell(ctx, ci, true); if (!placed) { if (ctx->force) { log_warning("failed to place cell '%s' of type '%s'\n", cell.c_str(ctx), ci->type.c_str(ctx)); -- cgit v1.2.3 From 57f75385b0960d6e1e30112a395a89ee4df07056 Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Sat, 14 Jul 2018 18:53:08 +0100 Subject: Revert "Make PnR use Unlocked methods" This reverts commit 9e4f97290a50fc5d9dc0cbe6ead945840b9811b1. --- ice40/arch.cc | 26 ++--------- ice40/arch.h | 117 +++++++++-------------------------------------- ice40/arch_place.cc | 6 +-- ice40/place_legaliser.cc | 14 +++--- 4 files changed, 34 insertions(+), 129 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.cc b/ice40/arch.cc index 30eea776..74353fe6 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -242,11 +242,6 @@ IdString Arch::archArgsToId(ArchArgs args) const BelId Arch::getBelByName(IdString name) const { boost::lock_guard lock(mtx_); - return getBelByNameUnlocked(name); -} - -BelId Arch::getBelByNameUnlocked(IdString name) const -{ BelId ret; if (bel_by_name.empty()) { @@ -280,14 +275,9 @@ BelRange Arch::getBelsAtSameTile(BelId bel) const } WireId Arch::getWireBelPin(BelId bel, PortPin pin) const -{ - boost::shared_lock_guard lock(mtx_); - return getWireBelPinUnlocked(bel, pin); -} - -WireId Arch::getWireBelPinUnlocked(BelId bel, PortPin pin) const { WireId ret; + boost::shared_lock_guard lock(mtx_); NPNR_ASSERT(bel != BelId()); @@ -306,14 +296,9 @@ WireId Arch::getWireBelPinUnlocked(BelId bel, PortPin pin) const // ----------------------------------------------------------------------- WireId Arch::getWireByName(IdString name) const -{ - boost::shared_lock_guard lock(mtx_); - return getWireByNameUnlocked(name); -} - -WireId Arch::getWireByNameUnlocked(IdString name) const { WireId ret; + boost::shared_lock_guard lock(mtx_); if (wire_by_name.empty()) { for (int i = 0; i < chip_info->num_wires; i++) @@ -330,14 +315,9 @@ WireId Arch::getWireByNameUnlocked(IdString name) const // ----------------------------------------------------------------------- PipId Arch::getPipByName(IdString name) const -{ - boost::shared_lock_guard lock(mtx_); - return getPipByNameUnlocked(name); -} - -PipId Arch::getPipByNameUnlocked(IdString name) const { PipId ret; + boost::shared_lock_guard lock(mtx_); if (pip_by_name.empty()) { for (int i = 0; i < chip_info->num_pips; i++) { diff --git a/ice40/arch.h b/ice40/arch.h index 6f281d4a..a7af3269 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -362,7 +362,6 @@ public: // ------------------------------------------------- BelId getBelByName(IdString name) const; - BelId getBelByNameUnlocked(IdString name) const; IdString getBelName(BelId bel) const { @@ -372,68 +371,44 @@ public: uint32_t getBelChecksum(BelId bel) const { return bel.index; } - void bindBel(BelId bel, IdString cell, PlaceStrength strength) { - boost::lock_guard lock(mtx_); - bindBelUnlocked(bel, cell, strength); - } - - void bindBelUnlocked(BelId bel, IdString cell, PlaceStrength strength) + void bindBel(BelId bel, IdString cell, PlaceStrength strength) { NPNR_ASSERT(bel != BelId()); NPNR_ASSERT(bel_to_cell[bel.index] == IdString()); + boost::lock_guard lock(mtx_); bel_to_cell[bel.index] = cell; cells[cell]->bel = bel; cells[cell]->belStrength = strength; } void unbindBel(BelId bel) - { - boost::lock_guard lock(mtx_); - unbindBelUnlocked(bel); - } - - void unbindBelUnlocked(BelId bel) { NPNR_ASSERT(bel != BelId()); NPNR_ASSERT(bel_to_cell[bel.index] != IdString()); + boost::lock_guard lock(mtx_); cells[bel_to_cell[bel.index]]->bel = BelId(); cells[bel_to_cell[bel.index]]->belStrength = STRENGTH_NONE; bel_to_cell[bel.index] = IdString(); } bool checkBelAvail(BelId bel) const - { - boost::shared_lock_guard lock(mtx_); - return checkBelAvailUnlocked(bel); - } - - bool checkBelAvailUnlocked(BelId bel) const { NPNR_ASSERT(bel != BelId()); + boost::shared_lock_guard lock(mtx_); return bel_to_cell[bel.index] == IdString(); } IdString getBoundBelCell(BelId bel) const - { - boost::shared_lock_guard lock(mtx_); - return getBoundBelCellUnlocked(bel); - } - - IdString getBoundBelCellUnlocked(BelId bel) const { NPNR_ASSERT(bel != BelId()); + boost::shared_lock_guard lock(mtx_); return bel_to_cell[bel.index]; } IdString getConflictingBelCell(BelId bel) const - { - boost::shared_lock_guard lock(mtx_); - return getConflictingBelCellUnlocked(bel); - } - - IdString getConflictingBelCellUnlocked(BelId bel) const { NPNR_ASSERT(bel != BelId()); + boost::shared_lock_guard lock(mtx_); return bel_to_cell[bel.index]; } @@ -450,11 +425,11 @@ public: BelRange range; // FIXME #if 0 - if (type == "TYPE_A") { - range.b.cursor = bels_type_a_begin; - range.e.cursor = bels_type_a_end; - } - ... + if (type == "TYPE_A") { + range.b.cursor = bels_type_a_begin; + range.e.cursor = bels_type_a_end; + } + ... #endif return range; } @@ -468,7 +443,6 @@ public: } WireId getWireBelPin(BelId bel, PortPin pin) const; - WireId getWireBelPinUnlocked(BelId bel, PortPin pin) const; BelPin getBelPinUphill(WireId wire) const { @@ -495,7 +469,6 @@ public: // ------------------------------------------------- WireId getWireByName(IdString name) const; - WireId getWireByNameUnlocked(IdString name) const; IdString getWireName(WireId wire) const { @@ -506,15 +479,10 @@ public: uint32_t getWireChecksum(WireId wire) const { return wire.index; } void bindWire(WireId wire, IdString net, PlaceStrength strength) - { - boost::lock_guard lock(mtx_); - bindWireUnlocked(wire, net, strength); - } - - void bindWireUnlocked(WireId wire, IdString net, PlaceStrength strength) { NPNR_ASSERT(wire != WireId()); NPNR_ASSERT(wire_to_net[wire.index] == IdString()); + boost::lock_guard lock(mtx_); wire_to_net[wire.index] = net; nets[net]->wires[wire].pip = PipId(); @@ -522,15 +490,10 @@ public: } void unbindWire(WireId wire) - { - boost::lock_guard lock(mtx_); - unbindWireUnlocked(wire); - } - - void unbindWireUnlocked(WireId wire) { NPNR_ASSERT(wire != WireId()); NPNR_ASSERT(wire_to_net[wire.index] != IdString()); + boost::lock_guard lock(mtx_); auto &net_wires = nets[wire_to_net[wire.index]]->wires; auto it = net_wires.find(wire); @@ -548,37 +511,25 @@ public: bool checkWireAvail(WireId wire) const { + NPNR_ASSERT(wire != WireId()); boost::shared_lock_guard lock(mtx_); - return checkWireAvailUnlocked(wire); - } - bool checkWireAvailUnlocked(WireId wire) const - { - NPNR_ASSERT(wire != WireId()); return wire_to_net[wire.index] == IdString(); } IdString getBoundWireNet(WireId wire) const { + NPNR_ASSERT(wire != WireId()); boost::shared_lock_guard lock(mtx_); - return getBoundWireNetUnlocked(wire); - } - IdString getBoundWireNetUnlocked(WireId wire) const - { - NPNR_ASSERT(wire != WireId()); return wire_to_net[wire.index]; } IdString getConflictingWireNet(WireId wire) const { + NPNR_ASSERT(wire != WireId()); boost::shared_lock_guard lock(mtx_); - return getConflictingWireNetUnlocked(wire); - } - IdString getConflictingWireNetUnlocked(WireId wire) const - { - NPNR_ASSERT(wire != WireId()); return wire_to_net[wire.index]; } @@ -593,22 +544,16 @@ public: // ------------------------------------------------- PipId getPipByName(IdString name) const; - PipId getPipByNameUnlocked(IdString name) const; IdString getPipName(PipId pip) const; uint32_t getPipChecksum(PipId pip) const { return pip.index; } void bindPip(PipId pip, IdString net, PlaceStrength strength) - { - boost::lock_guard lock(mtx_); - bindPipUnlocked(pip, net, strength); - } - - void bindPipUnlocked(PipId pip, IdString net, PlaceStrength strength) { NPNR_ASSERT(pip != PipId()); NPNR_ASSERT(pip_to_net[pip.index] == IdString()); NPNR_ASSERT(switches_locked[chip_info->pip_data[pip.index].switch_index] == IdString()); + boost::lock_guard lock(mtx_); pip_to_net[pip.index] = net; switches_locked[chip_info->pip_data[pip.index].switch_index] = net; @@ -622,16 +567,11 @@ public: } void unbindPip(PipId pip) - { - boost::lock_guard lock(mtx_); - unbindPipUnlocked(pip); - } - - void unbindPipUnlocked(PipId pip) { NPNR_ASSERT(pip != PipId()); NPNR_ASSERT(pip_to_net[pip.index] != IdString()); NPNR_ASSERT(switches_locked[chip_info->pip_data[pip.index].switch_index] != IdString()); + boost::lock_guard lock(mtx_); WireId dst; dst.index = chip_info->pip_data[pip.index].dst; @@ -644,38 +584,23 @@ public: } bool checkPipAvail(PipId pip) const - { - boost::shared_lock_guard lock(mtx_); - return checkPipAvailUnlocked(pip); - } - - bool checkPipAvailUnlocked(PipId pip) const { NPNR_ASSERT(pip != PipId()); + boost::shared_lock_guard lock(mtx_); return switches_locked[chip_info->pip_data[pip.index].switch_index] == IdString(); } IdString getBoundPipNet(PipId pip) const - { - boost::shared_lock_guard lock(mtx_); - return getBoundPipNetUnlocked(pip); - } - - IdString getBoundPipNetUnlocked(PipId pip) const { NPNR_ASSERT(pip != PipId()); + boost::shared_lock_guard lock(mtx_); return pip_to_net[pip.index]; } IdString getConflictingPipNet(PipId pip) const - { - boost::shared_lock_guard lock(mtx_); - return getConflictingPipNetUnlocked(pip); - } - - IdString getConflictingPipNetUnlocked(PipId pip) const { NPNR_ASSERT(pip != PipId()); + boost::shared_lock_guard lock(mtx_); return switches_locked[chip_info->pip_data[pip.index].switch_index]; } diff --git a/ice40/arch_place.cc b/ice40/arch_place.cc index c9dd26c5..dc1bc3eb 100644 --- a/ice40/arch_place.cc +++ b/ice40/arch_place.cc @@ -80,7 +80,7 @@ bool Arch::isBelLocationValid(BelId bel) const if (getBelType(bel) == TYPE_ICESTORM_LC) { std::vector bel_cells; for (auto bel_other : getBelsAtSameTile(bel)) { - IdString cell_other = getBoundBelCellUnlocked(bel_other); + IdString cell_other = getBoundBelCell(bel_other); if (cell_other != IdString()) { const CellInfo *ci_other = cells.at(cell_other).get(); bel_cells.push_back(ci_other); @@ -88,7 +88,7 @@ bool Arch::isBelLocationValid(BelId bel) const } return logicCellsCompatible(bel_cells); } else { - IdString cellId = getBoundBelCellUnlocked(bel); + IdString cellId = getBoundBelCell(bel); if (cellId == IdString()) return true; else @@ -104,7 +104,7 @@ bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const std::vector bel_cells; for (auto bel_other : getBelsAtSameTile(bel)) { - IdString cell_other = getBoundBelCellUnlocked(bel_other); + IdString cell_other = getBoundBelCell(bel_other); if (cell_other != IdString() && bel_other != bel) { const CellInfo *ci_other = cells.at(cell_other).get(); bel_cells.push_back(ci_other); diff --git a/ice40/place_legaliser.cc b/ice40/place_legaliser.cc index d42188f0..559358c7 100644 --- a/ice40/place_legaliser.cc +++ b/ice40/place_legaliser.cc @@ -143,7 +143,7 @@ class PlacementLegaliser // Using the non-standard API here to get (x, y, z) rather than just (x, y) auto bi = ctx->chip_info->bel_data[bel.index]; int x = bi.x, y = bi.y, z = bi.z; - IdString cell = ctx->getBoundBelCellUnlocked(bel); + IdString cell = ctx->getBoundBelCell(bel); if (cell != IdString() && ctx->cells.at(cell)->belStrength >= STRENGTH_FIXED) logic_bels.at(x).at(y).at(z) = std::make_pair(bel, true); // locked out of use else @@ -331,16 +331,16 @@ class PlacementLegaliser NPNR_ASSERT(!loc.second); BelId bel = loc.first; // Check if there is a cell presently at the location, which we will need to rip up - IdString existing = ctx->getBoundBelCellUnlocked(bel); + IdString existing = ctx->getBoundBelCell(bel); if (existing != IdString()) { // TODO: keep track of the previous position of the ripped up cell, as a hint rippedCells.insert(existing); - ctx->unbindBelUnlocked(bel); + ctx->unbindBel(bel); } if (cell->bel != BelId()) { - ctx->unbindBelUnlocked(cell->bel); + ctx->unbindBel(cell->bel); } - ctx->bindBelUnlocked(bel, cell->name, STRENGTH_LOCKED); + ctx->bindBel(bel, cell->name, STRENGTH_LOCKED); rippedCells.erase(cell->name); // If cell was ripped up previously, no need to re-place loc.second = true; // Bel is now unavailable for further use } @@ -435,7 +435,7 @@ class PlacementLegaliser CellInfo *target = nullptr; for (int z = 0; z < 8; z++) { BelId bel = logic_bels.at(x).at(y).at(z).first; - IdString cell = ctx->getBoundBelCellUnlocked(bel); + IdString cell = ctx->getBoundBelCell(bel); if (cell != IdString()) { CellInfo *ci = ctx->cells.at(cell).get(); if (ci->belStrength >= STRENGTH_STRONG) @@ -448,7 +448,7 @@ class PlacementLegaliser } } if (target != nullptr) { - ctx->unbindBelUnlocked(target->bel); + ctx->unbindBel(target->bel); rippedCells.insert(target->name); changed = true; } -- cgit v1.2.3 From d327a0afbb6a92553647444c0baaeb4971a0847b Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Sat, 14 Jul 2018 19:01:33 +0100 Subject: Revert "Make ice40::Arch thread-safe" This reverts commit 0816f447b768ebe0632f419e9b696714dda4e860. --- ice40/arch.cc | 7 ------- ice40/arch.h | 38 ++++++-------------------------------- ice40/bitstream.cc | 10 +++++----- 3 files changed, 11 insertions(+), 44 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.cc b/ice40/arch.cc index 74353fe6..adc37dbd 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -241,7 +241,6 @@ IdString Arch::archArgsToId(ArchArgs args) const BelId Arch::getBelByName(IdString name) const { - boost::lock_guard lock(mtx_); BelId ret; if (bel_by_name.empty()) { @@ -277,7 +276,6 @@ BelRange Arch::getBelsAtSameTile(BelId bel) const WireId Arch::getWireBelPin(BelId bel, PortPin pin) const { WireId ret; - boost::shared_lock_guard lock(mtx_); NPNR_ASSERT(bel != BelId()); @@ -298,7 +296,6 @@ WireId Arch::getWireBelPin(BelId bel, PortPin pin) const WireId Arch::getWireByName(IdString name) const { WireId ret; - boost::shared_lock_guard lock(mtx_); if (wire_by_name.empty()) { for (int i = 0; i < chip_info->num_wires; i++) @@ -317,7 +314,6 @@ WireId Arch::getWireByName(IdString name) const PipId Arch::getPipByName(IdString name) const { PipId ret; - boost::shared_lock_guard lock(mtx_); if (pip_by_name.empty()) { for (int i = 0; i < chip_info->num_pips; i++) { @@ -376,8 +372,6 @@ std::string Arch::getBelPackagePin(BelId bel) const // ----------------------------------------------------------------------- -// TODO(cliffordvienna): lock all of this - GroupId Arch::getGroupByName(IdString name) const { for (auto g : getGroups()) @@ -503,7 +497,6 @@ DecalXY Arch::getGroupDecal(GroupId group) const std::vector Arch::getDecalGraphics(DecalId decal) const { - boost::shared_lock_guard lock(mtx_); std::vector ret; if (decal.type == DecalId::TYPE_FRAME) { diff --git a/ice40/arch.h b/ice40/arch.h index a7af3269..e42da422 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -21,9 +21,6 @@ #error Include "arch.h" via "nextpnr.h" only. #endif -#include -#include - NEXTPNR_NAMESPACE_BEGIN /**** Everything in this section must be kept in sync with chipdb.py ****/ @@ -327,17 +324,8 @@ struct ArchArgs std::string package; }; -class Arch : public BaseCtx +struct Arch : BaseCtx { -private: - // All of the following... - std::vector bel_to_cell; - std::vector wire_to_net; - std::vector pip_to_net; - std::vector switches_locked; - // ... are guarded by the following lock: - mutable boost::shared_mutex mtx_; -public: const ChipInfoPOD *chip_info; const PackageInfoPOD *package_info; @@ -345,6 +333,11 @@ public: mutable std::unordered_map wire_by_name; mutable std::unordered_map pip_by_name; + std::vector bel_to_cell; + std::vector wire_to_net; + std::vector pip_to_net; + std::vector switches_locked; + ArchArgs args; Arch(ArchArgs args); @@ -375,7 +368,6 @@ public: { NPNR_ASSERT(bel != BelId()); NPNR_ASSERT(bel_to_cell[bel.index] == IdString()); - boost::lock_guard lock(mtx_); bel_to_cell[bel.index] = cell; cells[cell]->bel = bel; cells[cell]->belStrength = strength; @@ -385,7 +377,6 @@ public: { NPNR_ASSERT(bel != BelId()); NPNR_ASSERT(bel_to_cell[bel.index] != IdString()); - boost::lock_guard lock(mtx_); cells[bel_to_cell[bel.index]]->bel = BelId(); cells[bel_to_cell[bel.index]]->belStrength = STRENGTH_NONE; bel_to_cell[bel.index] = IdString(); @@ -394,21 +385,18 @@ public: bool checkBelAvail(BelId bel) const { NPNR_ASSERT(bel != BelId()); - boost::shared_lock_guard lock(mtx_); return bel_to_cell[bel.index] == IdString(); } IdString getBoundBelCell(BelId bel) const { NPNR_ASSERT(bel != BelId()); - boost::shared_lock_guard lock(mtx_); return bel_to_cell[bel.index]; } IdString getConflictingBelCell(BelId bel) const { NPNR_ASSERT(bel != BelId()); - boost::shared_lock_guard lock(mtx_); return bel_to_cell[bel.index]; } @@ -482,8 +470,6 @@ public: { NPNR_ASSERT(wire != WireId()); NPNR_ASSERT(wire_to_net[wire.index] == IdString()); - boost::lock_guard lock(mtx_); - wire_to_net[wire.index] = net; nets[net]->wires[wire].pip = PipId(); nets[net]->wires[wire].strength = strength; @@ -493,7 +479,6 @@ public: { NPNR_ASSERT(wire != WireId()); NPNR_ASSERT(wire_to_net[wire.index] != IdString()); - boost::lock_guard lock(mtx_); auto &net_wires = nets[wire_to_net[wire.index]]->wires; auto it = net_wires.find(wire); @@ -512,24 +497,18 @@ public: bool checkWireAvail(WireId wire) const { NPNR_ASSERT(wire != WireId()); - boost::shared_lock_guard lock(mtx_); - return wire_to_net[wire.index] == IdString(); } IdString getBoundWireNet(WireId wire) const { NPNR_ASSERT(wire != WireId()); - boost::shared_lock_guard lock(mtx_); - return wire_to_net[wire.index]; } IdString getConflictingWireNet(WireId wire) const { NPNR_ASSERT(wire != WireId()); - boost::shared_lock_guard lock(mtx_); - return wire_to_net[wire.index]; } @@ -553,7 +532,6 @@ public: NPNR_ASSERT(pip != PipId()); NPNR_ASSERT(pip_to_net[pip.index] == IdString()); NPNR_ASSERT(switches_locked[chip_info->pip_data[pip.index].switch_index] == IdString()); - boost::lock_guard lock(mtx_); pip_to_net[pip.index] = net; switches_locked[chip_info->pip_data[pip.index].switch_index] = net; @@ -571,7 +549,6 @@ public: NPNR_ASSERT(pip != PipId()); NPNR_ASSERT(pip_to_net[pip.index] != IdString()); NPNR_ASSERT(switches_locked[chip_info->pip_data[pip.index].switch_index] != IdString()); - boost::lock_guard lock(mtx_); WireId dst; dst.index = chip_info->pip_data[pip.index].dst; @@ -586,21 +563,18 @@ public: bool checkPipAvail(PipId pip) const { NPNR_ASSERT(pip != PipId()); - boost::shared_lock_guard lock(mtx_); return switches_locked[chip_info->pip_data[pip.index].switch_index] == IdString(); } IdString getBoundPipNet(PipId pip) const { NPNR_ASSERT(pip != PipId()); - boost::shared_lock_guard lock(mtx_); return pip_to_net[pip.index]; } IdString getConflictingPipNet(PipId pip) const { NPNR_ASSERT(pip != PipId()); - boost::shared_lock_guard lock(mtx_); return switches_locked[chip_info->pip_data[pip.index].switch_index]; } diff --git a/ice40/bitstream.cc b/ice40/bitstream.cc index 58a59366..a62c6c09 100644 --- a/ice40/bitstream.cc +++ b/ice40/bitstream.cc @@ -128,7 +128,7 @@ void write_asc(const Context *ctx, std::ostream &out) } // Set pips for (auto pip : ctx->getPips()) { - if (ctx->getBoundPipNet(pip) != IdString()) { + if (ctx->pip_to_net[pip.index] != IdString()) { const PipInfoPOD &pi = ci.pip_data[pip.index]; const SwitchInfoPOD &swi = bi.switches[pi.switch_index]; for (int i = 0; i < swi.num_bits; i++) { @@ -199,8 +199,8 @@ void write_asc(const Context *ctx, std::ostream &out) NPNR_ASSERT(iez != -1); bool input_en = false; - if (!ctx->checkWireAvail(ctx->getWireBelPin(bel, PIN_D_IN_0)) || - !ctx->checkWireAvail(ctx->getWireBelPin(bel, PIN_D_IN_1))) { + if ((ctx->wire_to_net[ctx->getWireBelPin(bel, PIN_D_IN_0).index] != IdString()) || + (ctx->wire_to_net[ctx->getWireBelPin(bel, PIN_D_IN_1).index] != IdString())) { input_en = true; } @@ -271,7 +271,7 @@ void write_asc(const Context *ctx, std::ostream &out) } // Set config bits in unused IO and RAM for (auto bel : ctx->getBels()) { - if (ctx->checkBelAvail(bel) && ctx->getBelType(bel) == TYPE_SB_IO) { + if (ctx->bel_to_cell[bel.index] == IdString() && ctx->getBelType(bel) == TYPE_SB_IO) { const TileInfoPOD &ti = bi.tiles_nonrouting[TILE_IO]; const BelInfoPOD &beli = ci.bel_data[bel.index]; int x = beli.x, y = beli.y, z = beli.z; @@ -284,7 +284,7 @@ void write_asc(const Context *ctx, std::ostream &out) set_config(ti, config.at(iey).at(iex), "IoCtrl.REN_" + std::to_string(iez), false); } } - } else if (ctx->checkBelAvail(bel) && ctx->getBelType(bel) == TYPE_ICESTORM_RAM) { + } else if (ctx->bel_to_cell[bel.index] == IdString() && ctx->getBelType(bel) == TYPE_ICESTORM_RAM) { const BelInfoPOD &beli = ci.bel_data[bel.index]; int x = beli.x, y = beli.y; const TileInfoPOD &ti = bi.tiles_nonrouting[TILE_RAMB]; -- cgit v1.2.3 From eafb9b4281db82b7f5b2cfcab4dfcfd1dcb038aa Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Sat, 14 Jul 2018 19:02:52 +0100 Subject: Fix revert issues. --- ice40/arch.h | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'ice40') diff --git a/ice40/arch.h b/ice40/arch.h index e42da422..a02e0ced 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -523,9 +523,6 @@ struct Arch : BaseCtx // ------------------------------------------------- PipId getPipByName(IdString name) const; - IdString getPipName(PipId pip) const; - - uint32_t getPipChecksum(PipId pip) const { return pip.index; } void bindPip(PipId pip, IdString net, PlaceStrength strength) { @@ -641,15 +638,6 @@ struct Arch : BaseCtx return range; } - WireRange getWires() const - { - WireRange range; - range.b.cursor = 0; - range.e.cursor = chip_info->num_wires; - return range; - } - - BelId getPackagePinBel(const std::string &pin) const; std::string getBelPackagePin(BelId bel) const; -- cgit v1.2.3