2

\foreach is very restricted, how may I insert three different numbers into a dipchip, the x and y position as well as the chip number?

See this question and answer.

enter image description here

I was requested to share my knowledge, therefore I wrote the answer myself.

Uwe
  • 239
  • 1
    Your chip numbering scheme doesn't seem to have be consistent. Nor is the number of pins. You can do this with \foreach \x/\y/\name/\pins = {...} but the list itself is about as painful as not using a loop at all. – John Kormylo Mar 01 '21 at 14:17
  • @JohnKormylo IC1.1 to IC1.38 are the 38 bits of a word ( 32 data bit + 6 bit ECC). IC2.1 to IC2.38 is a second memory bank. IC3.1 to IC3.4 are adress buffers. The chip numbering scheme is somewhat unconventional, but it is functional and consistent. The bit number within a word should be shown. Ok, bits may be numbered from 0 to 37 instead of 1 to 38. The number of pins is different because there are different chips used, the memory chips with 16 pins and the buffer chips with 14 pins. – Uwe Mar 01 '21 at 18:56
  • @JohnKormylo I wanted no painful foreach list and I don't wanted no loop at all. If there is a small modification of the chips distance, all 80 list entries must be changed. I hope you understand the chip numbering scheme now. – Uwe Mar 02 '21 at 08:11
  • @Uwe --- I have proposed a solution directly in TikZ that I think has the same level of complexity as the python solution, and, as a bonus, it's all in LaTeX. \foreach is quite powerful, the only problem sometimes is the TeX local group semantics. – Rmano Mar 02 '21 at 10:19
  • I find that it often takes longer to debug a loop than just copy, paste and edit. One \path per row seems about right. – John Kormylo Mar 02 '21 at 14:21
  • @JohnKormylo But when you did copy, paste and edit a long list and want to change the distance just a little, you have to do the edit all over again. Using a loop you have to change only one value for the step size. – Uwe Mar 02 '21 at 15:38
  • Not necessarily. You could use a predefined step distance. The is also the replace all editor command. See https://tex.stackexchange.com/questions/202230/how-to-draw-an-integrated-circuit-pin-configuration-like-in-data-sheets/202449?r=SearchResults&s=1|30.8459#202449 – John Kormylo Mar 02 '21 at 21:20

2 Answers2

2

Although I also do a lot of things writing Python and outputting LaTeX (invaluable for student's feedback sheets from excel!), in this case, I think that it is easier to write the loops directly in LaTeX, and as customizable as the Python ones (notice that you can \define a macro for the various 5.5, 11, etc...)

I wrote this basically directly translating your Python loops into LaTeX:

\documentclass[]{article}
\usepackage[siunitx, RPvoltages]{circuitikz}

%\usepackage{verbatim} \usepackage{geometry} % to change the page dimensions \geometry{a3paper} % or letterpaper (US) or a5paper or.... % set the basic length to 0.5in (1 in is very big, but could work) % SET THIS ONCE and only in the preamble. \ctikzset{bipoles/length=0.5in} % pin spacing is in basic lengths, see manual, section 3.27.1, around page 135 \ctikzset{multipoles/dipchip/pin spacing=0.2} %0.1in \ctikzset{multipoles/external pins width=0.1} %0.05in \ctikzset{multipoles/dipchip/width=0.8} %0.4in \ctikzset{multipoles/dipchip/width=0.7} %0.35in body + 2*0.025in half pads \ctikzset{multipoles/external pad fraction=4} %draw the pad \begin{document}

\begin{figure}[ht]

% work with units of pin distance \begin{circuitikz}[x=0.1in, y=0.1in, chip16/.style={dipchip, anchor=pin 1, num pins=16, hide numbers, rotate=90}, chip14/.style={dipchip, anchor=pin 1, num pins=14, hide numbers, rotate=90}, ] \newcounter{chipN}\setcounter{chipN}{38} % redefine the labels here \newcommand{\mylabel}[1]{\large\ttfamily\rotatebox{-90}{#1}} \newcommand{\xstep}{11} \newcommand{\ystep}{5.5} \foreach \j in {0,...,5} { \path (9,{ 2.5+\j\ystep}) node[chip16]{\mylabel{IC 1.\arabic{chipN}}}; \path (9,{57.5+\j\ystep}) node[chip16]{\mylabel{IC 2.\arabic{chipN}}}; \addtocounter{chipN}{-1} }

\foreach \i in {0,...,3} {
    \pgfmathsetmacro{\y}{52-\ystep*\i}
    \pgfmathsetmacro{\x}{20+\xstep*\i}
    \pgfmathtruncatemacro{\n}{\i+1}
    \path (9, \y) node[chip14]{\mylabel{IC 3.\n}};
    \foreach \j in {0,...,7} {
        \path (\x, {2.5+\j*\ystep}) node[chip16]{\mylabel{IC 1.\arabic{chipN}}};
        \path (\x, {46.5+\j*\ystep}) node[chip16]{\mylabel{IC 2.\arabic{chipN}}};
        \addtocounter{chipN}{-1}
    }
}


\draw [black, thin] (0in, 0in) rectangle (160.0mm, 233.4mm); % draw the rectangle for the double euro format board

\end{circuitikz} \end{figure} \end{document}

...and you have the same (I had to switch IC 1. and IC 2. in your last loop, I think that the image corresponds to this). I had also used a mix of things to do the calculations (directly in coordinates, using various \pgfmath... things, etc.) to show several possibilities.

For the chip number, I used a counter, because they are global in LaTeX and they save a few local group headaches.

enter image description here

Rmano
  • 40,848
  • 3
  • 64
  • 125
1

This may be done combining the power of LaTex and Python.

The LaTex code:

\documentclass[border=10pt]{article}
\usepackage[siunitx, RPvoltages]{circuitikz}
% set the basic length to 0.5in (1 in is very big, but could work)
% SET THIS ONCE and only in the preamble.
%\usepackage{verbatim}
\usepackage{geometry} % to change the page dimensions
\geometry{a3paper} % or letterpaper (US) or a5paper or....

\ctikzset{bipoles/length=0.5in} % pin spacing is in basic lengths, see manual, section 3.27.1, around page 135 \ctikzset{multipoles/dipchip/pin spacing=0.2} %0.1in \ctikzset{multipoles/external pins width=0.1} %0.05in \ctikzset{multipoles/dipchip/width=0.8} %0.4in \ctikzset{multipoles/dipchip/width=0.7} %0.35in body + 2*0.025in half pads \ctikzset{multipoles/external pad fraction=4} %draw the pad \begin{document}

\begin{figure}[h]

% work with units of pin distance \begin{circuitikz}[x=0.1in, y=0.1in]

\input{mountICs.tex} % import the Python generated file with the placement of 80 chips

\draw [black, thin] (0in, 0in) rectangle (160.0mm, 233.4mm); % draw the rectangle for the double euro format board

\end{circuitikz}

\end{figure}

\end{document}

The Python code:

# define the LaTex strings
# the double backslash \\ is needed in Python to get a single \ for the LaTex string

first part of the LaTex string

left = '\path ('

second part of the LaTex string, two versions: mid1 and mid2

num pins = 16

mid1 = ") node[dipchip, anchor=pin 1, num pins=16, hide numbers, rotate=90] {\large\rotatebox{-90}{"

num pins = 14

mid2 = ") node[dipchip, anchor=pin 1, num pins=14, hide numbers, rotate=90] {\large\rotatebox{-90}{"

third and last part of the LaTex string

right = "}};\n"

tex = open('mountICs.tex', 'w') # open output file mountICs.tex for writing

n = 38 # number for chip label

for j in range(6) : # 6 chips in a row

compose a LaTex string using the left, mid1 and right string constants

and write it to the opened .tex file

chip label number n is pasted to IC 1.

y = 2.5 + j * 5.5 tex.write(left + "9, " + str(y) + mid1 + "IC 1." + str(n) + right) y = 57.5 + j * 5.5 tex.write(left + "9, " + str(y) + mid1 + "IC 2." + str(n) + right) n -= 1 # decrement chip label number n

for i in range(4) : # 4 chips in a row y = 52 - i * 5.5 # vertical position x = 20 + i * 11 # horizontal position tex.write(left + "9, " + str(y) + mid2 + "IC 3." + str(i+1) + right) for j in range(8) : # 8 chips in a column # insert the numbers x, y and n as strings into the LaTex string y = 2.5 + j * 5.5 # vertical position tex.write(left + str(x) + ", " + str(y) + mid1 + "IC 2." + str(n) + right) y = 46.5 + j * 5.5 # vertical position tex.write(left + str(x) + ", " + str(y) + mid1 + "IC 1." + str(n) + right) n -= 1

tex.close() #close the file and write all to the disk

The Python script writes to the file mountICs.tex, this file is inserted into the LaTex code using \input{}.

Python and LaTex should use the same local directory for the exchange of mountICs.tex, a filepath may be added if another than the local directory should be used.

No parameters are passed from LaTex to the Python script, if the number of chips in rows and columns should be changed, the Python script must be edited and rerun. There is no automatic build of mountICs.tex whenever the Python script is edited.

The Python script is modification friendly, if the number of chips in a row or column is to be changed, just change the number in range(4) or range(8). If the distance of chips is to be changed modify only the 5.5 in y = 2.5 + j * 5.5

Uwe
  • 239
  • Well, I do not know if it's easier like this or writing the foreach in LaTeX, but notice that I think that all of these Python for loops are writable in LaTeX. Look at the evaluate option of the foreach if interested! – Rmano Mar 01 '21 at 14:21
  • @Rmano I will have a look at the evaluate option. The Python for y in range(25, 465, 5) is easier when you need a lot of steps, you only need start, stop and stepsize value to do hundreds of steps if neccessary. Using foreach, you have type hundreds of values to do hundreds of steps. The Python for y in (57.5,63,68.5,74,79.5,85) is similar to foreach. I may use for y in range(start, stop, step) only if I like to do anything between 2 and some 100 steps needing three values only. – Uwe Mar 01 '21 at 15:49
  • foreach \i in {25, 30,..., 465} will do exactly the same as python range(25, 465, 5), barring rounding errors – Rmano Mar 02 '21 at 09:19