00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <stdlib.h>
00025 #include <stdio.h>
00026 #include <string.h>
00027 #include "errors.h"
00028 #include "types.h"
00029 #include "globals.h"
00030 #include "hard_blocks.h"
00031 #include "memories.h"
00032
00033 STRING_CACHE *hard_block_names = NULL;
00034
00035 #ifdef VPR6
00036 void register_hard_blocks()
00037 {
00038 t_model *hard_blocks = NULL;
00039 t_model_ports *hb_ports = NULL;
00040
00041 hard_blocks = Arch.models;
00042 hard_block_names = sc_new_string_cache();
00043 while (hard_blocks != NULL)
00044 {
00045 sc_add_string(hard_block_names, hard_blocks->name);
00046
00047
00048
00049
00050 if (strcmp(hard_blocks->name, "single_port_ram") == 0)
00051 {
00052 hard_blocks->outputs->size = 1;
00053
00054
00055 if (configuration.split_memory_depth == 1)
00056 {
00057 hb_ports = hard_blocks->inputs;
00058 while ((hb_ports != NULL) && (strcmp(hb_ports->name, "addr") != 0))
00059 hb_ports = hb_ports->next;
00060 if (hb_ports == NULL)
00061 error_message(1, 0, -1, "No \"addr\" port on single port RAM");
00062
00063 if (configuration.split_memory_depth == -1)
00064 split_size = hb_ports->min_size;
00065 if (configuration.split_memory_depth == -2)
00066 split_size = hb_ports->size;
00067 else
00068 split_size = configuration.split_memory_depth;
00069 }
00070
00071 hb_ports = hard_blocks->inputs;
00072 while ((hb_ports != NULL) && (strcmp(hb_ports->name, "data") != 0))
00073 hb_ports = hb_ports->next;
00074 if (hb_ports != NULL)
00075 hb_ports->size = 1;
00076 }
00077
00078 if (strcmp(hard_blocks->name, "dual_port_ram") == 0)
00079 {
00080 hb_ports = hard_blocks->outputs;
00081 hb_ports->size = 1;
00082 if (hb_ports->next != NULL)
00083 hb_ports->next->size = 1;
00084 hb_ports = hard_blocks->inputs;
00085 while (hb_ports != NULL)
00086 {
00087 if ((strcmp(hb_ports->name, "data1") == 0) ||
00088 (strcmp(hb_ports->name, "data2") == 0))
00089 hb_ports->size = 1;
00090 hb_ports = hb_ports->next;
00091 }
00092 }
00093 hard_blocks = hard_blocks->next;
00094 }
00095 return;
00096 }
00097
00098 void deregister_hard_blocks()
00099 {
00100 sc_free_string_cache(hard_block_names);
00101 return;
00102 }
00103
00104 t_model* find_hard_block(char *name)
00105 {
00106 t_model *hard_blocks;
00107
00108 hard_blocks = Arch.models;
00109 while (hard_blocks != NULL)
00110 if (strcmp(hard_blocks->name, name) == 0)
00111 return hard_blocks;
00112 else
00113 hard_blocks = hard_blocks->next;
00114
00115 return NULL;
00116 }
00117
00118 void define_hard_block(nnode_t *node, short type, FILE *out)
00119 {
00120 int i, j;
00121 int index, port;
00122 int count;
00123 char buffer[MAX_BUF];
00124
00125
00126 oassert(node->input_port_sizes[0] > 0);
00127 oassert(node->output_port_sizes[0] > 0);
00128
00129 count = fprintf(out, "\n.subckt ");
00130 count--;
00131 count += fprintf(out, "%s", node->related_ast_node->children[0]->types.identifier);
00132
00133
00134 port = index = 0;
00135 for (i = 0; i < node->num_input_pins; i++)
00136 {
00137 if (node->input_port_sizes[port] == 1)
00138 j = sprintf(buffer, " %s=%s", node->input_pins[i]->mapping, node->input_pins[i]->net->driver_pin->node->name);
00139 else
00140 {
00141 if (node->input_pins[i]->net->driver_pin->name != NULL)
00142 j = sprintf(buffer, " %s[%d]=%s", node->input_pins[i]->mapping, index, node->input_pins[i]->net->driver_pin->name);
00143 else
00144 j = sprintf(buffer, " %s[%d]=%s", node->input_pins[i]->mapping, index, node->input_pins[i]->net->driver_pin->node->name);
00145 }
00146
00147 if (count + j > 79)
00148 {
00149 fprintf(out, "\\\n");
00150 count = 0;
00151 }
00152 count += fprintf(out, "%s", buffer);
00153
00154 index++;
00155 if (node->input_port_sizes[port] == index)
00156 {
00157 index = 0;
00158 port++;
00159 }
00160 }
00161
00162
00163 port = index = 0;
00164 for (i = 0; i < node->num_output_pins; i++)
00165 {
00166 if (node->output_port_sizes[port] != 1)
00167 j = sprintf(buffer, " %s[%d]=%s", node->output_pins[i]->mapping, index, node->output_pins[i]->name);
00168 else
00169 j = sprintf(buffer, " %s=%s", node->output_pins[i]->mapping, node->output_pins[i]->name);
00170
00171 if (count + j > 79)
00172 {
00173 fprintf(out, "\\\n");
00174 count = 0;
00175 }
00176 count += fprintf(out, "%s", buffer);
00177
00178 index++;
00179 if (node->output_port_sizes[port] == index)
00180 {
00181 index = 0;
00182 port++;
00183 }
00184 }
00185
00186 count += fprintf(out, "\n\n");
00187 return;
00188 }
00189
00190 void output_hard_blocks(FILE *out)
00191 {
00192 t_model_ports *hb_ports;
00193 t_model *hard_blocks;
00194 char buffer[MAX_BUF];
00195 int count;
00196 int i;
00197
00198 oassert(out != NULL);
00199 hard_blocks = Arch.models;
00200 while (hard_blocks != NULL)
00201 {
00202 if (hard_blocks->used == 1)
00203 {
00204 fprintf(out, "\n.model %s\n", hard_blocks->name);
00205 count = fprintf(out, ".inputs");
00206 hb_ports = hard_blocks->inputs;
00207 while (hb_ports != NULL)
00208 {
00209 for (i = 0; i < hb_ports->size; i++)
00210 {
00211 if (hb_ports->size == 1)
00212 count = count + sprintf(buffer, " %s", hb_ports->name);
00213 else
00214 count = count + sprintf(buffer, " %s[%d]", hb_ports->name, i);
00215 if (count >= 78)
00216 count = fprintf(out, " \\\n%s", buffer) - 3;
00217 else
00218 fprintf(out, "%s", buffer);
00219 }
00220 hb_ports = hb_ports->next;
00221 }
00222
00223 count = fprintf(out, "\n.outputs") - 1;
00224 hb_ports = hard_blocks->outputs;
00225 while (hb_ports != NULL)
00226 {
00227 for (i = 0; i < hb_ports->size; i++)
00228 {
00229 if (hb_ports->size == 1)
00230 count = count + sprintf(buffer, " %s", hb_ports->name);
00231 else
00232 count = count + sprintf(buffer, " %s[%d]", hb_ports->name, i);
00233 if (count >= 78)
00234 count = fprintf(out, " \\\n%s", buffer) - 3;
00235 else
00236 fprintf(out, "%s", buffer);
00237 }
00238 hb_ports = hb_ports->next;
00239 }
00240
00241 fprintf(out, "\n.blackbox\n.end\n\n");
00242 }
00243 hard_blocks = hard_blocks->next;
00244 }
00245
00246 return;
00247 }
00248
00249 void
00250 instantiate_hard_block(nnode_t *node, short mark, netlist_t *netlist)
00251 {
00252 int i, port, index;
00253
00254 port = index = 0;
00255
00256 for (i = 0; i < node->num_output_pins; i++)
00257 {
00258 if (node->output_pins[i]->name == NULL)
00259 node->output_pins[i]->name = make_full_ref_name(node->name, NULL, NULL, node->output_pins[i]->mapping, -1);
00260
00261 index++;
00262 if (node->output_port_sizes[port] == index)
00263 {
00264 index = 0;
00265 port++;
00266 }
00267 }
00268
00269 node->traverse_visited = mark;
00270 return;
00271 }
00272
00273 int
00274 hard_block_port_size(t_model *hb, char *pname)
00275 {
00276 t_model_ports *tmp;
00277
00278 if (hb == NULL)
00279 return 0;
00280
00281
00282
00283
00284
00285 if ((strcmp(hb->name, "single_port_ram") == 0) ||
00286 (strcmp(hb->name, "dual_port_ram") == 0))
00287 {
00288 return -1;
00289 }
00290
00291 tmp = hb->inputs;
00292 while (tmp != NULL)
00293 if ((tmp->name != NULL) && (strcmp(tmp->name, pname) == 0))
00294 return tmp->size;
00295 else
00296 tmp = tmp->next;
00297
00298 tmp = hb->outputs;
00299 while (tmp != NULL)
00300 if ((tmp->name != NULL) && (strcmp(tmp->name, pname) == 0))
00301 return tmp->size;
00302 else
00303 tmp = tmp->next;
00304
00305 return 0;
00306 }
00307
00308 enum PORTS
00309 hard_block_port_direction(t_model *hb, char *pname)
00310 {
00311 t_model_ports *tmp;
00312
00313 if (hb == NULL)
00314 return ERR_PORT;
00315
00316 tmp = hb->inputs;
00317 while (tmp != NULL)
00318 if ((tmp->name != NULL) && (strcmp(tmp->name, pname) == 0))
00319 return tmp->dir;
00320 else
00321 tmp = tmp->next;
00322
00323 tmp = hb->outputs;
00324 while (tmp != NULL)
00325 if ((tmp->name != NULL) && (strcmp(tmp->name, pname) == 0))
00326 return tmp->dir;
00327 else
00328 tmp = tmp->next;
00329
00330 return ERR_PORT;
00331 }
00332 #endif