Definieren meiner eigenen benutzerdefinierten White-Box-Digitalschaltungskomponente

Definieren meiner eigenen benutzerdefinierten White-Box-Digitalschaltungskomponente

Tikz hat eine Reihe nützlicher digitaler Schaltkreiskomponenten, ob einfach oder komplex. Hier brauche ichmanchevon mir, nicht unbedingt eines der bequemen. Aber nehmen wir ein ziemlich bequemes Beispiel: einen Größenkomparator.

Das hätte ich gerneMagnitudenkomparatorKomponente für meine Aufgabe, mit seinen Signal-Ports definiert als anchors. Ich kann eine Box mit Beschriftungen auf den Ports und einem Namen darauf erstellen, aber das istnicht genug!

Ich muss auch zeigen, was im Inneren ist. Details dürfen nicht über die Gates hinausgehen, ich möchte die Transistoren nicht herumliegen haben, aber ich brauche die Gates.

Hier ist, was ich bisher in meinen Händen habe, das meiste davon ist nur kopiert/nachgeahmt vondieses (berühmte?) Daten-Flip-Flop-Beispiel:

\makeatletter

% Magnitude Comparator (magn comparator) shape
\pgfdeclareshape{magn comparator}
{
    % The 'minimum width' and 'minimum height' keys, not the content, determine
    % the size
    \savedanchor\northeast
    {%
        \pgfmathsetlength\pgf@x{\pgfshapeminwidth}%
        \pgfmathsetlength\pgf@y{\pgfshapeminheight}%
        \pgf@x=0.5\pgf@x
        \pgf@y=0.5\pgf@y
    }
    % This is redundant, but makes some things easier:
    \savedanchor\southwest
    {%
        \pgfmathsetlength\pgf@x{\pgfshapeminwidth}%
        \pgfmathsetlength\pgf@y{\pgfshapeminheight}%
        \pgf@x=-0.5\pgf@x
        \pgf@y=-0.5\pgf@y
    }
    % Inherit from rectangle
    \inheritanchorborder[from=rectangle]

    % Define same anchor a normal rectangle has
    \anchor{center}{\pgfpointorigin}
    \anchor{north}{\northeast \pgf@x=0pt}
    \anchor{east}{\northeast \pgf@y=0pt}
    \anchor{south}{\southwest \pgf@x=0pt}
    \anchor{west}{\southwest \pgf@y=0pt}
    \anchor{north east}{\northeast}
    \anchor{north west}{\northeast \pgf@x=-\pgf@x}
    \anchor{south west}{\southwest}
    \anchor{south east}{\southwest \pgf@x=-\pgf@x}
    \anchor{text}
    {
        \pgfpointorigin
        \advance\pgf@x by -.5\wd\pgfnodeparttextbox%
        \advance\pgf@y by -.5\ht\pgfnodeparttextbox%
        \advance\pgf@y by +.5\dp\pgfnodeparttextbox%
    }

    % Define anchors for input signal ports
    \anchor{input gt}
    {
        \pgf@process{\southwest}%
        \pgf@y=-.5\pgf@y%
    }
    \anchor{input eq}
    {
        \pgf@process{\southwest}%
        \pgf@y=0pt%
    }
    \anchor{input lt}
    {
        \pgf@process{\southwest}%
        \pgf@y=.5\pgf@y%
    }
    \anchor{input a}
    {
        \pgf@process{\northeast}%
        \pgf@x=-.3\pgf@x%
    }
    \anchor{input b}
    {
        \pgf@process{\northeast}%
        \pgf@x=.3\pgf@x%
    }

    % Define anchors for output signal ports
    \anchor{output gt}
    {
        \pgf@process{\northeast}%
        \pgf@y=.5\pgf@y%
    }
    \anchor{output eq}
    {
        \pgf@process{\northeast}%
        \pgf@y=0pt%
    }
    \anchor{output lt}
    {
        \pgf@process{\northeast}%
        \pgf@y=-.5\pgf@y%
    }

    % Draw the rectangle box and the port labels
    \backgroundpath
    {
        % Rectangle box
        \pgfpathrectanglecorners{\southwest}{\northeast}
        % \node [and gate] (kek) at (0, 0) {};
    }
}

% Define default style for this node
\tikzset
{
    every magn comparator node/.style =
    {
        draw,
        minimum width = 2cm,
        minimum height = 2cm,
        thick,
        inner sep = 1mm,
        outer sep = 0pt,
        cap = round
    }
}

\makeatother

Dies befindet sich in einer separaten Datei, die ich in die Präambel meiner Haupt-LaTeX-Datei einfüge.

Hier gibt es keine Gatter, es wird nur die Box gezeichnet. Ich habe versucht, einfach ein zufälliges UND-Gatter zu setzen, so wie ich es außerhalb dieses \pgfdeclareshapeDings normalerweise mache, was natürlich nicht funktioniert hat. Ich habe diesen Versuch auskommentiert.

Es sollte eine Möglichkeit für mich geben, über den vorhandenen Formen weitere Formen zu definieren. Wie sieht diese Möglichkeit aus?

Bearbeiten:Ich gehe davon aus, dass ich so etwas in den Händen halten werde, was ich platzieren können sollte und dessen Ports ich leicht als Anker erreichen kann, ähnlich wie es bei einem AND/OR/NOR/XOR/NAND-Gatter der Fall ist:

Bildbeschreibung hier eingeben

Beachten Sie, dass das Innere der Box nicht wirklich als Größenkomparator fungiert, sondern nur ein Blindbeispiel meiner Erwartung ist.

Antwort1

Abhängig von der Komplexität Ihrer Anwendungsfälle und davon, wie viele dieser Formen Sie benötigen … hier ist ein Anfang.

Die Antwort lautet wie folgt:

  • Eine Formdeklaration, die die rectangle eeDefinition von circuits.ee(was lediglich eine geliehene rectangleForm mit .inputund .outputAnkern ist) übernimmt.

    Ich leihe mir auch den verlinktenTeXamplefür den Text innerhalb der Definition einer Form. Die Anker werden mit gesetzt \pgfpointlineattime(ähnlich der Notation pos„Schlüssel entlang einer geraden Linie“ oder „Faktor innerhalb calc($(<p1>)!<factor>!(<p2>)$)).

    Wenn Sie viele dieser Formen haben, die mehrere verschiedene dieser Anker entlang der Grenzen eines Rechtecks ​​benötigen, kann dies mit einem Fey-Schlüssel und einer Schleife innerhalb der Deklaration der Form serialisiert werden. Dies gilt auch für die Texte.

  • Jetzt, da wir eine Form mit Ankern und Texten haben, können wir sie verwenden. Für eine richtige Schaltkreisform deklarieren wir ein Symbol mit circuit declare symbolund richten es mit ein set <symbol name> graphic.

    Die Schlüsselsätze circuit symbol sizeund minimum widthin minimum heightBezug auf circuit symbol unit(eine TeX-Dimension unter der Haube). Dies macht es skalierbar in Bezug auf andere Schaltsymbole. Der transform shapeSchlüssel wird benötigt, um es entlang circuits' toPfaden rotieren zu lassen.

  • A path picture, das vorgeschlagenen Code verwendet vonnoch eine Antwort von mir. So richten Sie ein lokales Koordinatensystem ein, das mit seinem Knoten rotiert und skaliert: Die Koordinate (0, 0)befindet sich im Mittelpunkt des Knotens.XVektor zeigt auf east(= output), diejVektor zum Nordanker. Dies ist wichtig für Koordinatenangaben wie, da es die Hälfte der horizontalen Dimension des Knotens (left:.2)verwendet.2Unddie angewandte Drehung.

    Die Schaltsymbole im Inneren path pictureerhalten die Optionen gray(ebenso wie die Leitungen) und skalieren die Symbole auf eine geeignete Größe. Möglicherweise müssen Sie mit diesem Wert herumspielen, um die richtige Größe zu erhalten. Es ist möglicherweise auch möglich, dies mit den Abmessungen und circuit symbol unit=.1cmvom oben genannten lokalen Koordinatensystem abhängig zu machen .\pgf@xx\pgf@yy

    Wenn Sie mehrere Symbole mit demselben Anker- und Verbindungslayout, aber mit unterschiedlichen Gates benötigen, ist es natürlich möglich, die Formdefinition entsprechend dreier Wertschlüssel formbar zu machen, die in diesem Fall auf not gate, nand gateund gesetzt würden nor gate.

Ich habe meinepaths.orthoBibliothekfür die Verbindungen innerhalb des path picture. Sie können diese Leitungen natürlich auf jede beliebige Weise verbinden.

Code

\documentclass[tikz]{standalone}
\usetikzlibrary{circuits.ee,circuits.logic.US,paths.ortho}
\makeatletter
\pgfdeclareshape{my complicated box}{%
  \inheritsavedanchors[from=rectangle ee]
  \inheritanchor[from=rectangle ee]{center}
  \inheritanchor[from=rectangle ee]{north}
  \inheritanchor[from=rectangle ee]{south}
  \inheritanchor[from=rectangle ee]{east}
  \inheritanchor[from=rectangle ee]{west}
  \inheritanchor[from=rectangle ee]{north east}
  \inheritanchor[from=rectangle ee]{north west}
  \inheritanchor[from=rectangle ee]{south east}
  \inheritanchor[from=rectangle ee]{south west}
  \inheritanchor[from=rectangle ee]{input}
  \inheritanchor[from=rectangle ee]{output}
  \inheritanchorborder[from=rectangle ee]
  \inheritbackgroundpath[from=rectangle ee]
  \anchor{eq in} {\pgf@sh@reanchor{\pgf@sm@shape@name}{input}}
  \anchor{eq out}{\pgf@sh@reanchor{\pgf@sm@shape@name}{output}}
  \anchor{lt in}{%
    \pgfpointlineattime{.2}{\southwest}
    {\southwest\pgf@xc\pgf@x\northeast\pgf@x\pgf@xc}}
  \anchor{gt in}{%
    \pgfpointlineattime{.8}{\southwest}
    {\southwest\pgf@xc\pgf@x\northeast\pgf@x\pgf@xc}}
  \anchor{gt out}{%
    \pgfpointlineattime{.3}{\northeast}
    {\southwest\pgf@yc\pgf@y\northeast\pgf@y\pgf@yc}}
  \anchor{lt out}{%
    \pgfpointlineattime{.7}{\northeast}
    {\southwest\pgf@yc\pgf@y\northeast\pgf@y\pgf@yc}}
  \anchor{a}{%
    \pgfpointlineattime{.4}
      {\southwest\pgf@xc\pgf@x\northeast\pgf@x\pgf@xc}{\northeast}}
  \anchor{b}{%
    \pgfpointlineattime{.6}
      {\southwest\pgf@xc\pgf@x\northeast\pgf@x\pgf@xc}{\northeast}}
  \beforebackgroundpath{%
    \begingroup
      \tikzset{my complicated box/labels/.try}\tikz@textfont
      \pgf@sh@reanchor{\pgf@sm@shape@name}{eq in}
      \pgftext[at=\pgfqpoint{\pgf@x}{\pgf@y},left,%
                x=\pgfkeysvalueof{/pgf/inner xsep}]{$\mathrm{eq}_{\mathrm{in}}$}
      \pgf@sh@reanchor{\pgf@sm@shape@name}{eq out}
      \pgftext[at=\pgfqpoint{\pgf@x}{\pgf@y},right,%
                x=-\pgfkeysvalueof{/pgf/inner xsep}]{$\mathrm{eq}_{\mathrm{out}}$}
      \pgf@sh@reanchor{\pgf@sm@shape@name}{gt in}
      \pgftext[at=\pgfqpoint{\pgf@x}{\pgf@y},left,%
                x=\pgfkeysvalueof{/pgf/inner xsep}]{$\mathrm{gt}_{\mathrm{in}}$}
      \pgf@sh@reanchor{\pgf@sm@shape@name}{gt out}
      \pgftext[at=\pgfqpoint{\pgf@x}{\pgf@y},right,%
                x=-\pgfkeysvalueof{/pgf/inner xsep}]{$\mathrm{gt}_{\mathrm{out}}$}
      \pgf@sh@reanchor{\pgf@sm@shape@name}{lt in}
      \pgftext[at=\pgfqpoint{\pgf@x}{\pgf@y},left,%
                x=\pgfkeysvalueof{/pgf/inner xsep}]{$\mathrm{lt}_{\mathrm{in}}$}
      \pgf@sh@reanchor{\pgf@sm@shape@name}{lt out}
      \pgftext[at=\pgfqpoint{\pgf@x}{\pgf@y},right,%
                x=-\pgfkeysvalueof{/pgf/inner xsep}]{$\mathrm{lt}_{\mathrm{out}}$}
      \pgf@sh@reanchor{\pgf@sm@shape@name}{a}
      \pgftext[at=\pgfqpoint{\pgf@x}{\pgf@y},top,%
                y=-\pgfkeysvalueof{/pgf/inner ysep}]{a\vphantom{b}}
      \pgf@sh@reanchor{\pgf@sm@shape@name}{b}
      \pgftext[at=\pgfqpoint{\pgf@x}{\pgf@y},top,%
                y=-\pgfkeysvalueof{/pgf/inner ysep}]{b}
    \endgroup}
}
\makeatother
\tikzset{my complicated box/labels/.style={font=\footnotesize, inner sep=.1667em}}
\tikzset{
  circuit declare symbol=my complicated symbol,
  set my complicated symbol graphic={
    draw, shape=my complicated box, circuit symbol size=width 10 height 8,
    transform shape,
    path picture={
      \expandafter\let\expandafter\tfn\csname tikz@fig@name\endcsname
      \pgftransformshift{\pgfpointanchor{\tfn}{center}}%
      \pgfsetxvec{\pgfpointdiff{\pgfpointanchor{\tfn}{center}}
                 {\pgfpointanchor{\tfn}{east}}}%
      \pgfsetyvec{\pgfpointdiff{\pgfpointanchor{\tfn}{center}}
                 {\pgfpointanchor{\tfn}{north}}}
      \tikzset{every circuit symbol/.append style={circuit symbol unit=.1cm, gray}}
      \path[thin, draw=gray]
        (\tfn.eq in) to[not gate=near end] (\tfn.eq out)
        (\tfn.lt out) to ++ (left:.2)
          node[anchor=output, logic gate inputs=nn, nand gate] (\tfn-nand) {}
        (\tfn-nand.input 2) to[-|-=.6] (\tfn.lt in)
        (\tfn-nand.input 1) to[-|] (\tfn.a)
        (\tfn.gt out) to ++ (left:.2)
          node[anchor=output, logic gate inputs=nn, nor gate] (\tfn-nor) {}
        (\tfn-nor.input 2) to[-|-=.6] (\tfn.gt in)
        (\tfn-nor.input 1) to[-|] (\tfn.b);
    }},
}
\begin{document}
\begin{tikzpicture}[circuit logic US]
\draw (0,0) to[my complicated symbol] ++ (30:4);
\end{tikzpicture}
\end{document}

Ausgabe

Bildbeschreibung hier eingeben

Antwort2

Eine mögliche Lösung mit pics. Es ist schwierig, es pic-anchorszur Positionierung zu verwenden (TiKZ-Bilder verankern), aber sie dienen als Bezugspunkte, um Verbindungen zwischen ihnen herzustellen.

\documentclass[tikz,border=2mm]{standalone}

\usetikzlibrary{positioning,circuits.logic.US, fit}

\tikzset{
    mycircuit/.pic={
        \begin{scope}[circuit logic US]
        \node[gray, thick, draw, nor gate] (-gt) at (2,0.75) {};
        \node[gray, thick, draw, not gate] (-eq) at (2,0) {};
        \node[gray, thick, draw, nand gate] (-lt) at (2,-0.75) {};

        \draw[gray] (-gt.output)--++(3mm,0) 
             coordinate[label={[black]left:$\mathrm{gt}_\mathrm{out}$}] (-gtout);

        \draw[gray] (-eq.output)--(-eq.output-|-gtout) 
             coordinate[label={[black]left:$\mathrm{eq}_\mathrm{out}$}] (-eqout);

        \draw[gray] (-lt.output)--(-lt.output-|-gtout) 
             coordinate[label={[black]left:$\mathrm{lt}_\mathrm{out}$}] (-eqout);

        \draw[gray] (-gt.input 1)-|++(-3mm,.5cm) 
             coordinate[label={[black]below:$\mathrm{b}$}] (-b);

        \draw[gray] (-lt.input 1)-|([xshift=-6mm]-b.center) 
             coordinate[label={[black]below:$\mathrm{a}$}] (-a);

        \draw[gray] (-eq.input)--++(-2cm,0) 
             coordinate[label={[black]right:$\mathrm{eq}_\mathrm{in}$}] (-eqin);

        \draw[gray] (-gt.input 2)--++(-1.2cm,0) |- ([yshift=1cm]-eqin.center)  
             coordinate[label={[black]right:$\mathrm{gt}_\mathrm{in}$}] (-gtin);

        \draw[gray] (-lt.input 2)--++(-1.2cm,0) |- ([yshift=-1cm]-eqin.center)  
             coordinate[label={[black]right:$\mathrm{lt}_\mathrm{in}$}] (-ltin);

        \node[draw, fit={(-ltin) (-b) ([yshift=-.5cm]-lt.input 2) (-gtout)}, 
              inner sep=0pt] (-box) {};
        \end{scope}
    }}

\begin{document}
\begin{tikzpicture}

\pic (a) at (0,0) {mycircuit};

\pic (b) at (5,1) {mycircuit};

\draw (a-gtout) -- (b-gtin);
\draw ([yshift=2cm]a-a) coordinate (aux)--(a-a);
\draw ([yshift=-5mm]aux)-|(b-a);
\end{tikzpicture}
\end{document}

Bildbeschreibung hier eingeben

verwandte Informationen