File: fpga.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 (155 lines) | stat: -rw-r--r-- 3,953 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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*
 * Copyright (c) 2001-2014 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"

/*
 * This is the FPGA target module.
 */

# include  <ivl_target.h>
# include  <string.h>
# include  "fpga_priv.h"
# include  <assert.h>

/* This is the opened xnf file descriptor. It is the output that this
   code generator writes to. */
FILE*xnf = 0;

const char*part = 0;
const char*arch = 0;
device_t device = 0;

int scope_has_attribute(ivl_scope_t s, const char *name)
{
      int i;
      for (i=0; i<ivl_scope_attr_cnt(s); i++) {
	    const struct ivl_attribute_s *a;
	    a = ivl_scope_attr_val(s, i);
	    if (strcmp(a->key,name) == 0) return 1;
      }
      return 0;
}

static int show_process(ivl_process_t net, void*x)
{
      ivl_scope_t scope = ivl_process_scope(net);

	/* Ignore processes that are within scopes that are cells. The
	   cell_scope will generate a cell to represent the entire
	   scope. */
      if (scope_has_attribute(scope, "ivl_synthesis_cell"))
	    return 0;

      fprintf(stderr, "fpga target: unsynthesized behavioral code\n");
      return 0;
}

static void show_pads(ivl_scope_t scope)
{
      unsigned idx;

      if (device->show_pad == 0)
	    return;

      for (idx = 0 ;  idx < ivl_scope_sigs(scope) ;  idx += 1) {
	    ivl_signal_t sig = ivl_scope_sig(scope, idx);
	    const char*pad;

	    if (ivl_signal_port(sig) == IVL_SIP_NONE)
		  continue;

	    pad = ivl_signal_attr(sig, "PAD");
	    if (pad == 0)
		  continue;

	    assert(device->show_pad);
	    device->show_pad(sig, pad);
      }
}

static void show_constants(ivl_design_t des)
{
      unsigned idx;

      if (device->show_constant == 0)
	    return;

      for (idx = 0 ;  idx < ivl_design_consts(des) ;  idx += 1) {
	    ivl_net_const_t con = ivl_design_const(des, idx);
	    device->show_constant(con);
      }
}

/*
 * This is the main entry point that ivl uses to invoke me, the code
 * generator.
 */
int target_design(ivl_design_t des)
{
      ivl_scope_t root = ivl_design_root(des);
      const char*path = ivl_design_flag(des, "-o");

      xnf = fopen(path, "w");
      if (xnf == 0) {
	    perror(path);
	    return -1;
      }

      part = ivl_design_flag(des, "part");
      if (part && (part[0] == 0))
	    part = 0;

      arch = ivl_design_flag(des, "arch");
      if (arch && (arch[0] == 0))
	    arch = 0;

      if (arch == 0)
	    arch = "lpm";

      device = device_from_arch(arch);
      if (device == 0) {
	    fprintf(stderr, "Unknown architecture arch=%s\n", arch);
	    return -1;
      }

	/* Call the device driver to generate the netlist header. */
      device->show_header(des);

	/* Catch any behavioral code that is left, and write warnings
	   that it is not supported. */
      ivl_design_process(des, show_process, 0);

	/* Get the pads from the design, and draw them to connect to
	   the associated signals. */
      show_pads(root);

	/* Scan the scopes, looking for gates to draw into the output
	   netlist. */
      show_scope_gates(root, 0);

      show_constants(des);

	/* Call the device driver to close out the file. */
      device->show_footer(des);

      fclose(xnf);
      xnf = 0;
      return 0;
}