File: fit_reg.c

package info (click to toggle)
iverilog 12.0-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 30,148 kB
  • sloc: cpp: 109,972; ansic: 62,713; yacc: 10,216; sh: 3,470; vhdl: 3,246; perl: 1,814; makefile: 1,774; python: 78; csh: 2
file content (132 lines) | stat: -rw-r--r-- 3,419 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
 * Copyright (c) 2000 Stephen Williams (steve@icarus.com)
 *
 *    This source code is free software; you can redistribute it
 *    and/or modify it in source code form under the terms of the GNU
 *    General Public License as published by the Free Software
 *    Foundation; either version 2 of the License, or (at your option)
 *    any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program; if not, write to the Free Software
 *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

# include "config.h"

# include  "ivl_target.h"
# include  <stdio.h>
# include  <assert.h>
# include  "priv.h"

/*
 * The fit_registers function scans all the scopes for flip-flop
 * devices to be assigned to macrocells. First look to see if the
 * device is connected to a PAD directly or through a bufif device. If
 * not, then just pick a free macrocell and drop it there.
 */

static int scan_ff_q(ivl_lpm_t ff, unsigned q);

int fit_registers(ivl_scope_t scope, void*x)
{
      int rc;
      unsigned idx;
      unsigned lpms;

	/* Scan child scopes first... */
      rc = ivl_scope_children(scope, fit_registers, 0);
      if (rc != 0)
	    return rc;


	/* Scan the current scope for flip-flop devices. Pass the
	   devices we find to the scan_ff_q function to assign to a
	   macrocell. */

      lpms = ivl_scope_lpms(scope);
      for (idx = 0 ;  idx < lpms ;  idx += 1) {
	    ivl_lpm_t lpm = ivl_scope_lpm(scope, idx);
	    unsigned wid, q;

	    if (ivl_lpm_type(lpm) != IVL_LPM_FF)
		  continue;

	    wid = ivl_lpm_width(lpm);

	    for (q = 0 ;  q < wid ;  q += 1) {
		  rc = scan_ff_q(lpm, q);
		  if (rc != 0)
			return rc;
	    }
      }

      return 0;
}

/*
 * This is the part that actually assigns the single bit of a single
 * flip-flop to a single macrocell.
 */
int scan_ff_q(ivl_lpm_t ff, unsigned q)
{
      unsigned idx;
      ivl_nexus_t nex;

      nex = ivl_lpm_q(ff, q);

	/* First, look to see if the Q is already connected to a pin
	   or an enable. If I find such a connection, then immediately
	   finish. */

      for (idx = 0 ; idx < pins ;  idx += 1) {
	    struct pal_bind_s*pin = bind_pin + idx;

	    if (pin->sop == 0)
		  continue;

	    if (pin->enable) {

		  if (nex == ivl_logic_pin(pin->enable, 1)) {
			pin->reg = ff;
			pin->reg_q = q;
			return 0;
		  }

	    } else if (pin->nexus == nex) {

		  pin->reg = ff;
		  pin->reg_q = q;
		  return 0;
	    }
      }

	/* There is no pin connection, so try setting this to an
	   unbound sop cell. We know that a sop is unbound if there
	   are no enables, nexus or ff devices connected to it. */

      for (idx = 0 ;  idx < pins ;  idx += 1) {
	    struct pal_bind_s*pin = bind_pin + idx;

	    if (pin->sop == 0)
		  continue;

	    if (pin->enable || pin->nexus || pin->reg)
		  continue;

	      /* Found one. Put the reg here. Leave the nexus empty so
		 that the code generator knows to disable the pin. */
	    pin->reg = ff;
	    pin->reg_q = q;
	    return 0;
      }

      fprintf(stderr, "No room for this ff.\n");
      error_count += 1;
      return 0;
}