⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ff_pack.c

📁 fpga设计评估软件
💻 C
字号:
#include <stdio.h>#include <string.h>#include "util.h"#include "vpack.h"#include "globals.h"#include "ff_pack.h"void pack_luts_and_ffs (int lut_size) {/* This routine uses a simple pattern matching algorithm to pack flip-  * * flops into the same clb as a LUT, where possible.  Currently the     * * pattern to be matched is hard-coded into the program.  It is a FF    * * following a LUT whose output does not fan-out.  If a FF does not     * * fit this pattern, it is left as in its own clb (the LUT in this      * * clb is unused).  This pattern corresponds to a clb with n LUT inputs *  * and a clock input.  It has only one output -- a multiplexer selects  * * whether this output comes from the LUT or the FF.  As well, all      * * unconnected pins in a clb are set to OPEN by this routine.           */ int bnum, in_blk, ipin, out_net, clock_net, in_net; char *tmp_name;/* Pin ordering for the clb blocks (1 LUT + 1 FF in each block) is      * * output, n LUT inputs, clock input.                                   */ for (bnum=0;bnum<num_blocks;bnum++) {    if (block[bnum].type == LATCH) {       clock_net = block[bnum].nets[lut_size + 1];       in_net = block[bnum].nets[1];   /* Net driving the latch. */       if (net[in_net].num_pins == 2) {   /* No fanout from driver */          in_blk = net[in_net].pins[0];   /* Drives the FF input */          if (block[in_blk].type == LUT) {    /* We match! *//* Fold the LATCH into previous LUT block.  Update block and net data. */                          net[in_net].pins[0] = OPEN; /* This net disappears; mark. */             out_net = block[bnum].nets[0];             block[in_blk].nets[0] = out_net;  /* New output */             tmp_name = block[in_blk].name;             block[in_blk].name = block[bnum].name;  /* Rename block */             block[bnum].name = tmp_name;      /* Keep pointer to free later *//* Clock new FF location. */             block[in_blk].nets[lut_size+1] = clock_net;              block[in_blk].num_nets++;             block[bnum].type = EMPTY;   /* Mark block that had FF */             block[in_blk].type = LUT_AND_LATCH;/* Nets that connected to old LATCH move from block bnum to block in_blk */             for (ipin=0;ipin<net[out_net].num_pins;ipin++) {                if (net[out_net].pins[ipin] == bnum)                    net[out_net].pins[ipin] = in_blk;              }             for (ipin=0;ipin<net[clock_net].num_pins;ipin++) {                if (net[clock_net].pins[ipin] == bnum)                    net[clock_net].pins[ipin] = in_blk;              }          }                    }    } }}void compress_netlist (int lut_size) {/* This routine removes all the EMPTY blocks and OPEN nets that * * may have been created by the ff_pack routine.  After this    * * routine, all the LUT+FF blocks that exist in the netlist     * * are in a contiguous list with no unused spots.  The same     * * goes for the list of nets.  This means that blocks and nets  * * have to be renumbered somewhat.                              */ int inet, iblk, index, ipin, new_num_nets, new_num_blocks, max_pin; int *net_remap, *block_remap; new_num_nets = 0; new_num_blocks = 0; net_remap = my_malloc (num_nets * sizeof(int)); block_remap = my_malloc (num_blocks * sizeof(int)); for (inet=0;inet<num_nets;inet++) {    if (net[inet].pins[0] != OPEN) {       net_remap[inet] = new_num_nets;       new_num_nets++;    }    else {       net_remap[inet] = OPEN;    } } for (iblk=0;iblk<num_blocks;iblk++) {    if (block[iblk].type != EMPTY) {       block_remap[iblk] = new_num_blocks;       new_num_blocks++;    }    else {       block_remap[iblk] = -1;    } }  if (new_num_nets != num_nets || new_num_blocks != num_blocks) {    for (inet=0;inet<num_nets;inet++) {       if (net[inet].pins[0] != OPEN) {          index = net_remap[inet];          net[index] = net[inet];          for (ipin=0;ipin<net[index].num_pins;ipin++)              net[index].pins[ipin] = block_remap[net[index].pins[ipin]];       }       else {          free (net[inet].name);          free (net[inet].pins);       }    }      num_nets = new_num_nets;    net = (struct s_net *) my_realloc (net,              num_nets * sizeof (struct s_net));    for (iblk=0;iblk<num_blocks;iblk++) {       if (block[iblk].type != EMPTY) {          index = block_remap[iblk];          block[index] = block[iblk];          if (block[index].type == INPAD || block[index].type == OUTPAD)              max_pin = 1;          else             max_pin = lut_size+2;          for (ipin=0;ipin<max_pin;ipin++) {              if (block[index].nets[ipin] != OPEN)                  block[index].nets[ipin] =                     net_remap[block[index].nets[ipin]];              else                  block[index].nets[ipin] = OPEN;          }       }       else {          free (block[iblk].name);/* The nets element is statically allocated, so I can't deallocate it.      */       }    }    num_blocks = new_num_blocks;    block = (struct s_block *) my_realloc (block,               num_blocks * sizeof (struct s_block)); }/* Now I have to recompute the number of primary inputs and outputs, since * * some inputs may have been unused and been removed.  No real need to     * * recount primary outputs -- it's just done as defensive coding.          */ num_p_inputs = 0; num_p_outputs = 0;  for (iblk=0;iblk<num_blocks;iblk++) {    if (block[iblk].type == INPAD)        num_p_inputs++;    else if (block[iblk].type == OUTPAD)        num_p_outputs++; }   free (net_remap); free (block_remap);}boolean *alloc_and_load_is_clock (boolean global_clocks, int lut_size) {/* Looks through all the block to find and mark all the clocks, by setting * * the corresponding entry in is_clock to true.  global_clocks is used     * * only for an error check.                                                */ int num_clocks, bnum, clock_net; boolean *is_clock; num_clocks = 0; is_clock = (boolean *) my_calloc (num_nets, sizeof(boolean));/* Want to identify all the clock nets.  */ for (bnum=0;bnum<num_blocks;bnum++) {    if (block[bnum].type == LATCH || block[bnum].type == LUT_AND_LATCH) {       clock_net = block[bnum].nets[lut_size + 1];       if (is_clock[clock_net] == FALSE) {          is_clock[clock_net] = TRUE;          num_clocks++;       }    } }/* If we have multiple clocks and we're supposed to declare them global, * * print a warning message, since it looks like this circuit may have    * * locally generated clocks.                                             */ if (num_clocks > 1 && global_clocks) {    printf("Warning:  circuit contains %d clocks.\n", num_clocks);    printf("          All will be marked global.\n"); } return (is_clock);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -