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