1 /****************************************************************************
2 Copyright (C) 1987-2015 by Jeffery P. Hansen
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
18 Last edit by hansen on Mon Jan 19 18:15:00 2009
19 ****************************************************************************/
20 #include "tkgate.h"
21
22 #define DIVIDE_A 0
23 #define DIVIDE_B 1
24 #define DIVIDE_Q 2
25 #define DIVIDE_R 3
26
27 static void Div_WriteCellDef(FILE *f,GCellSpec *gcs);
28
29
30 static iconDimensions divide_iconDims[] = {
31 {0, 0, 59, 28, 29, 15},
32 {60, 0, 28, 59, 15, 29},
33 {29, 60, 59, 28, 28, 12},
34 {0, 29, 28, 59, 12, 29},
35 };
36 static int divide_iconBoldOffset = 89;
37
38 GPadLoc divide_A_loc[] = {
39 {-16,-16,-16,-16,D_UP},
40 {-16,16,-16,16,D_LEFT},
41 {16,16,16,16,D_DOWN},
42 {16,-16,16,-16,D_RIGHT}};
43
44 GPadLoc divide_B_loc[] = {
45 {16,-16,16,-16,D_UP},
46 {-16,-16,-16,-16,D_LEFT},
47 {-16,16,-16,16,D_DOWN},
48 {16,16,16,16,D_RIGHT}};
49
50 GPadLoc divide_Q_loc[] = {
51 {10,13,10,13,D_DOWN},
52 {13,-10,13,-10,D_RIGHT},
53 {-10,-13,-10,-13,D_UP},
54 {-13,10,-13,10,D_LEFT}};
55
56 GPadLoc divide_R_loc[] = {
57 {-10,13,-10,13,D_DOWN},
58 {13,10,13,10,D_RIGHT},
59 {10,-13,10,-13,D_UP},
60 {-13,-10,-13,-10,D_LEFT}};
61
62 static char *psDivide[] = {
63 "%",
64 "% x y r psdiv",
65 "%",
66 "/psdiv {",
67 " startgate",
68 " -30 15.5 moveto",
69 " -5 15.5 lineto",
70 " 0 10 lineto",
71 " 5 15.5 lineto",
72 " 30 15.5 lineto",
73 " 16 -12.5 lineto",
74 " -16 -12.5 lineto",
75 " closepath stroke",
76 " -3 0 moveto 3 0 lineto stroke",
77 " 0 3 1 0 360 arc closepath fill",
78 " 0 -3 1 0 360 arc closepath fill",
79 " grestore",
80 "} def",
81 0
82 };
83
84
85 GGateInfo gate_divide_info = {
86 0,
87 "DIV",
88 "div",0x0,
89 "psdiv",psDivide,
90 -1,2,
91
92 {{"/", {"gm.alu",0}, {"gm.alu.div",0,0,300}, "gat_make DIV"},
93 {0}},
94
95 divide_iconDims,
96
97 4,{{"A",IN,8,1,divide_A_loc},
98 {"B",IN,8,1,divide_B_loc},
99 {"Q",OUT,8,1,divide_Q_loc},
100 {"R",OUT,8,1,divide_R_loc}},
101 {{24,10,LJ},{8,-24,LJ},{-24,-8,RJ},{-12,24,RJ}},
102 {1},
103
104 {"Dab_q","Dab_r",0},
105
106 Generic_Make,
107 Div_WriteCellDef,
108 Generic_Init,
109 Generic_Delete,
110 Generic_GetExtents,
111 Generic_HitDistance,
112 Generic_Draw,
113 Generic_Move,
114 Generic_Copy,
115 Err_AddInput,
116 Err_AddOutput,
117 Err_AddInOut,
118 Generic_Rotate,
119 Err_RemovePort,
120 Err_ChangePin,
121 Nop_SimInitFunc,
122 Nop_SimHitFunc,
123 Generic_PSWrite,
124 Generic_EditProps,
125 Generic_VerSave
126 };
127
128 /*****************************************************************************
129 *
130 * Generate primitive cell definition for dividers.
131 *
132 * Parameters:
133 * f File to write cell to.
134 * name Name of cell to write.
135 *
136 *****************************************************************************/
Div_WriteCellDef(FILE * f,GCellSpec * gcs)137 static void Div_WriteCellDef(FILE *f,GCellSpec *gcs)
138 {
139 int numBit = gcs->gc_numBits;
140 const char *invSpec = gcs->gc_invSpec;
141 int invQ = 0,invR = 0;
142 PrimParm primParm;
143
144 if (*invSpec) {
145 if (*invSpec == 'N')
146 invQ = 1;
147 if (!invSpec[1] || invSpec[1] == 'N')
148 invR = 0;
149 }
150
151 PrimParm_init(&primParm);
152 PrimParm_rangeSet(&primParm,"ABQR_RANGE",numBit);
153 PrimParm_invSet(&primParm,"invQ",invQ);
154 PrimParm_invSet(&primParm,"invR",invR);
155 Primitive_write(f,"div",gcs,&primParm);
156 }
157
158 #if 0
159 static void Div_WriteCellDef(FILE *f,GCellSpec *gcs)
160 {
161 int numBit = gcs->gc_numBits;
162 const char *invSpec = gcs->gc_invSpec;
163 int negQ = 0,negR = 0;
164
165 if (*invSpec) {
166 if (*invSpec == 'N')
167 negQ = 1;
168 if (!invSpec[1] || invSpec[1] == 'N')
169 negR = 0;
170 }
171
172 GCellSpec_writeBeginModule(f,gcs);
173
174 fprintf(f,"input%s A,B;\n", bitrangeSpec(numBit));
175 fprintf(f,"output%s Q,R;\n", bitrangeSpec(numBit));
176 if (negQ) fprintf(f,"wire%s _Q;\n", bitrangeSpec(numBit));
177 if (negR) fprintf(f,"wire%s _R;\n", bitrangeSpec(numBit));
178
179 fprintf(f," assign #Dab_q %sQ = A / B;\n",(negQ ? "_" : ""));
180 fprintf(f," assign #Dab_r %sR = A %% B;\n",(negR ? "_" : ""));
181 if (negQ) fprintf(f," assign Q = ~ _Q;\n");
182 if (negR) fprintf(f," assign R = ~ _R;\n");
183
184 GCellSpec_writeEndModule(f,gcs);
185 }
186 #endif
187
init_divide()188 void init_divide()
189 {
190 Pixmap P;
191
192 P = Pixmap_registerFromFile("divide","divide.b");
193 gateinfo_iconInit(&gate_divide_info,P,divide_iconDims,divide_iconBoldOffset);
194 RegisterGate(&gate_divide_info);
195 }
196