This repository was archived by the owner on Mar 6, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmap.c
More file actions
151 lines (126 loc) · 5.16 KB
/
map.c
File metadata and controls
151 lines (126 loc) · 5.16 KB
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
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
//Date type used for each slot in the map
typedef unsigned long int mapdata_t;
/* What data type should be use?
* Bigger data type is useful if the map is large,
* because this data is used to trace the distance from net source to drain and obstruction info.
* Smaller data type saves memory space (and gives good cache performance),
* and may be accelerated by SIMD or MMX instruction.
* MAX ROUTE DISTANCE FROM SOURCE TO DRAIN IS mapdata_t / 2 - 1
* MAX NUMBER OF NETS IS mapdata_t / 2 - 1
*/
#define MAPDATA_T_HALF (~(((mapdata_t)-1)>>1)) //~0b0111111...=0b10000000...
//Data type used to represent the x-y position of map
typedef unsigned long int mapaddr_t;
/* What data type should be used?
* This data type should be able to hold the width and height of the map.
* Generally speaking, the length of this data type should be half of the map_t for NxN table.
* But, it is safer to make this larger, it has a very small impact on performance and memory consumption.
*/
//Structure used to represents a map
typedef struct Map {
mapaddr_t width;
mapaddr_t height;
mapdata_t* map;
} Map;
/* About the map
* Width and height represent the size of the map.
* *map is a ptr to the map, which is a 2D array (but saved in 1D structure), saved in heap (created by malloc).
* Map is of type mapdata_t, defined at the beginning of the file.
* Map[y*width+x] is:
0x8000... This slot is an obstruction. (MAPDATA_T_HALF)
0x8000...~(unsigned)-1 This slot is used by net (netID = this - 0x8000...)
0: This net is free to use
Others: Wave (distance to source)
*/
/* NOTE IMPORTANT: /////////////////////////////////////////////////////////////
* Map data (slots) is saved in HEAP and access by POINTER
* This means, passing Map by VALUE acturally passing pointer to map slots.
* Modify map slots in function WILL affect the map slots data out of the function.
*///////////////////////////////////////////////////////////////////////////////
mapdata_t getMapValueAt(Map, mapaddr_t, mapaddr_t);
void setMapValueAt(Map, mapaddr_t, mapaddr_t, mapdata_t);
/************* Constructor *************/
//To create an empty map, all slots in this map are empty (not used)
Map createMap(mapaddr_t width, mapaddr_t height) {
Map newMap;
newMap.width = width;
newMap.height = height;
newMap.map = calloc(width * height, sizeof(mapdata_t));
if (newMap.map == NULL) {
fputs("SYSTEM ERROR\tCannot alloc memory.",stderr);
}
return newMap;
}
//To create a map exactly like the given map
Map copyMapAsNew(Map srcMap) {
Map newMap;
newMap.width = srcMap.width;
newMap.height = srcMap.height;
newMap.map = malloc( sizeof(mapdata_t) * newMap.width * newMap.height );
if (newMap.map == NULL) {
fputs("SYSTEM ERROR\tCannot alloc memory.",stderr);
}
for (mapaddr_t i = 0; i < newMap.height; i++) {
for (mapaddr_t j = 0; j < newMap.width; j++) {
setMapValueAt(newMap, j, i, getMapValueAt(srcMap, j, i));
}
}
return newMap;
}
//To copy the content of one map to another, without create a new one, map should be same size
void copyMapM2M(Map destMap, Map srcMap) {
if (destMap.width != srcMap.width || destMap.height != srcMap.height) {
fputs("Map not aligned.\n",stderr);
exit(-2);
}
for (mapaddr_t i = 0; i < destMap.height; i++) {
for (mapaddr_t j = 0; j < destMap.width; j++) {
setMapValueAt(destMap, j, i, getMapValueAt(srcMap, j, i));
}
}
}
//Destroy a map, release the map slot memory space
void destroyMap(Map targetMap) {
free(targetMap.map);
}
/************* Getter, setter, checker *************/
//Set a slot to be obstruction
void setMapSlotObstruction(Map writeMap, mapaddr_t x, mapaddr_t y) {
setMapValueAt(writeMap,x,y,MAPDATA_T_HALF);
}
//Set a slot to be used by a net
void setMapSlotUsedByNet(Map writeMap, mapaddr_t x, mapaddr_t y, mapdata_t netID) {
setMapValueAt(writeMap,x,y,MAPDATA_T_HALF|netID);
}
void setMapSlotWave(Map writeMap, mapaddr_t x, mapaddr_t y, mapdata_t wave) {
setMapValueAt(writeMap,x,y,(MAPDATA_T_HALF-1)&wave);
}
void setMapSlotFree(Map writeMap, mapaddr_t x, mapaddr_t y) {
setMapValueAt(writeMap,x,y,0);
}
//Get map slot attribute (free, wave, obstruction, used by net)
typedef enum mapslot_type {mapslot_free, mapslot_wave, mapslot_obstruction, mapslot_net} mapslot_type;
mapslot_type getMapSlotType(Map checkMap, mapaddr_t x, mapaddr_t y) {
mapdata_t value = getMapValueAt(checkMap,x,y);
if (!value) return mapslot_free;
else if (value == MAPDATA_T_HALF) return mapslot_obstruction;
else if (value&MAPDATA_T_HALF) return mapslot_net;
else return mapslot_wave;
}
//After check the map slot type, get the value of it, either netID or wave, or 0 for free/obstruction
mapdata_t getMapSlotValue(Map checkMap, mapaddr_t x, mapaddr_t y) {
return getMapValueAt(checkMap,x,y) & (MAPDATA_T_HALF-1);
}
/************* Util *************/
//Get the content of a slot in the map, using x-y position
mapdata_t getMapValueAt(Map readMap, mapaddr_t x, mapaddr_t y) {
return readMap.map[ y * readMap.width + x ];
}
//Set the content of a slot in the map, using x-y position
void setMapValueAt(Map writeMap, mapaddr_t x, mapaddr_t y, mapdata_t value) {
writeMap.map[ y * writeMap.width + x ] = value;
}