From c75a924c3f9dba4fd7d5c4e9674b29f7869a4e52 Mon Sep 17 00:00:00 2001
From: David Shah <davey1576@gmail.com>
Date: Wed, 18 Jul 2018 12:12:05 +0200
Subject: ice40: Assign ArchArgs after packing

Signed-off-by: David Shah <davey1576@gmail.com>
---
 ice40/arch.cc      |  5 ++---
 ice40/arch.h       |  2 +-
 ice40/archdefs.h   | 22 ++++++++++++++++++++--
 ice40/bitstream.cc |  5 +++--
 ice40/gfx.cc       |  9 ++++-----
 ice40/gfx.h        |  3 ++-
 ice40/pack.cc      | 31 +++++++++++++++++++++++++++++++
 7 files changed, 63 insertions(+), 14 deletions(-)

diff --git a/ice40/arch.cc b/ice40/arch.cc
index 69848aff..1c6dd6a5 100644
--- a/ice40/arch.cc
+++ b/ice40/arch.cc
@@ -610,8 +610,7 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
         }
 
         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;
 
@@ -621,7 +620,7 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
                 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);
 
diff --git a/ice40/arch.h b/ice40/arch.h
index 5dab414b..1c47e958 100644
--- a/ice40/arch.h
+++ b/ice40/arch.h
@@ -584,7 +584,7 @@ struct Arch : BaseCtx
         range.e.cursor = chip_info->num_pips;
         return range;
     }
-    
+
     IdString getPipName(PipId pip) const;
 
     uint32_t getPipChecksum(PipId pip) const { return pip.index; }
diff --git a/ice40/archdefs.h b/ice40/archdefs.h
index ce7d3f52..cf8a78f4 100644
--- a/ice40/archdefs.h
+++ b/ice40/archdefs.h
@@ -150,8 +150,26 @@ struct DecalId
     bool operator!=(const DecalId &other) const { return (type != other.type) || (index != other.index); }
 };
 
-struct ArchNetInfo { };
-struct ArchCellInfo { };
+struct ArchNetInfo
+{
+    bool is_global = false;
+};
+
+struct NetInfo;
+
+struct ArchCellInfo
+{
+    BelType belType = TYPE_NONE;
+    union
+    {
+        struct
+        {
+            bool dffEnable, negClk;
+            int inputCount;
+            const NetInfo *clk, *cen, *sr;
+        } lcInfo;
+    };
+};
 
 NEXTPNR_NAMESPACE_END
 
diff --git a/ice40/bitstream.cc b/ice40/bitstream.cc
index a62c6c09..98a7a0e4 100644
--- a/ice40/bitstream.cc
+++ b/ice40/bitstream.cc
@@ -341,8 +341,9 @@ 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/gfx.cc b/ice40/gfx.cc
index aa2fc9ce..f6ed789f 100644
--- a/ice40/gfx.cc
+++ b/ice40/gfx.cc
@@ -640,10 +640,8 @@ static bool getWireXY_local(GfxTileWireId id, float &x, float &y)
     return false;
 }
 
-void pipGfx(std::vector<GraphicElement> &g, int x, int y,
-            float x1, float y1, float x2, float y2,
-            float swx1, float swy1, float swx2, float swy2,
-            GraphicElement::style_t style)
+void pipGfx(std::vector<GraphicElement> &g, int x, int y, float x1, float y1, float x2, float y2, float swx1,
+            float swy1, float swx2, float swy2, GraphicElement::style_t style)
 {
     float tx = 0.5 * (x1 + x2);
     float ty = 0.5 * (y1 + y2);
@@ -693,7 +691,8 @@ edge_pip:
     g.push_back(el);
 }
 
-void gfxTilePip(std::vector<GraphicElement> &g, int x, int y, GfxTileWireId src, GfxTileWireId dst, GraphicElement::style_t style)
+void gfxTilePip(std::vector<GraphicElement> &g, int x, int y, GfxTileWireId src, GfxTileWireId dst,
+                GraphicElement::style_t style)
 {
     float x1, y1, x2, y2;
 
diff --git a/ice40/gfx.h b/ice40/gfx.h
index a1cbd65b..8a55407d 100644
--- a/ice40/gfx.h
+++ b/ice40/gfx.h
@@ -468,7 +468,8 @@ enum GfxTileWireId
 };
 
 void gfxTileWire(std::vector<GraphicElement> &g, int x, int y, GfxTileWireId id, GraphicElement::style_t style);
-void gfxTilePip(std::vector<GraphicElement> &g, int x, int y, GfxTileWireId src, GfxTileWireId dst, GraphicElement::style_t style);
+void gfxTilePip(std::vector<GraphicElement> &g, int x, int y, GfxTileWireId src, GfxTileWireId dst,
+                GraphicElement::style_t style);
 
 NEXTPNR_NAMESPACE_END
 
diff --git a/ice40/pack.cc b/ice40/pack.cc
index 76a52be0..e656e596 100644
--- a/ice40/pack.cc
+++ b/ice40/pack.cc
@@ -575,6 +575,36 @@ static void pack_special(Context *ctx)
     }
 }
 
+// Assign arch arg info
+static void assign_archargs(Context *ctx)
+{
+    for (auto &net : ctx->nets) {
+        NetInfo *ni = net.second.get();
+        if (ctx->isGlobalNet(ni))
+            ni->is_global = true;
+    }
+    for (auto &cell : ctx->cells) {
+        CellInfo *ci = cell.second.get();
+        ci->belType = ctx->belTypeFromId(ci->type);
+        if (is_lc(ctx, ci)) {
+            ci->lcInfo.dffEnable = bool_or_default(ci->params, ctx->id("DFF_ENABLE"));
+            ci->lcInfo.negClk = bool_or_default(ci->params, ctx->id("NEG_CLK"));
+            ci->lcInfo.clk = get_net_or_empty(ci, ctx->id("CLK"));
+            ci->lcInfo.cen = get_net_or_empty(ci, ctx->id("CEN"));
+            ci->lcInfo.sr = get_net_or_empty(ci, ctx->id("SR"));
+            ci->lcInfo.inputCount = 0;
+            if (get_net_or_empty(ci, ctx->id("I0")))
+                ci->lcInfo.inputCount++;
+            if (get_net_or_empty(ci, ctx->id("I1")))
+                ci->lcInfo.inputCount++;
+            if (get_net_or_empty(ci, ctx->id("I2")))
+                ci->lcInfo.inputCount++;
+            if (get_net_or_empty(ci, ctx->id("I3")))
+                ci->lcInfo.inputCount++;
+        }
+    }
+}
+
 // Main pack function
 bool Arch::pack()
 {
@@ -589,6 +619,7 @@ bool Arch::pack()
         pack_carries(ctx);
         pack_ram(ctx);
         pack_special(ctx);
+        assign_archargs(ctx);
         log_info("Checksum: 0x%08x\n", ctx->checksum());
         return true;
     } catch (log_execution_error_exception) {
-- 
cgit v1.2.3