Определение моего собственного компонента цифровой схемы в формате «white-box»

Определение моего собственного компонента цифровой схемы в формате «white-box»

Tikz имеет кучу полезных цифровых компонентов схем, базовых или сложных. Здесь мне нужнонекоторыйиз моих собственных, не обязательно даже из удобных. Но давайте возьмем один, довольно удобный пример: Компаратор величин.

Я хотел бы иметь этокомпаратор величинкомпонент для моей задачи, с его сигнальными портами, определенными как anchors. Я могу сделать коробку с метками на портах и ​​именем на ней, но этонедостаточно!

Мне нужно показать, что внутри. Подробности не должны выходить за рамки ворот, я не хочу, чтобы транзисторы были рядом, но мне нужны воротца.

Вот что у меня на руках на данный момент, большая часть из этого просто скопирована/подражаемаэтот (знаменитый?) пример переворота данных:

\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

Это отдельный файл, который я включаю в преамбулу моего основного файла LaTeX.

Здесь нет никаких вентилей, он просто рисует ящик. Я попытался просто поставить случайный вентиль И обычным способом, который я делаю вне этой \pgfdeclareshapeштуки, что, конечно, не сработало. Я закомментировал это, эту попытку.

Должен быть способ определить дополнительные формы поверх существующих. Что это?

Редактировать:Я ожидаю, что у меня в руках окажется что-то вроде этого, что я смогу разместить и к портам которого я смогу легко добраться как к якорям, подобно тому, как это происходит с вентилем AND/OR/NOR/XOR/NAND:

введите описание изображения здесь

Обратите внимание, что внутренняя часть коробки на самом деле не выполняет функцию компаратора величин, это просто фиктивный пример того, что я ожидаю.

решение1

В зависимости от сложности ваших вариантов использования и того, сколько таких форм вам нужно... вот начало.

Ответ состоит в следующем:

  • Декларация формы, которая заимствует rectangle eeопределение из circuits.ee(которая является просто заимствованной rectangleформой с якорями .inputи .output).

    Я также заимствую из ссылкиTeXampleдля текста внутри определения фигуры. Якоря устанавливаются с помощью \pgfpointlineattime(это похоже на posключ вдоль прямой линии или фактор внутри calcнотации ($(<p1>)!<factor>!(<p2>)$)).

    Если у вас есть намного больше таких фигур, которым нужно несколько разных якорей вдоль границы прямоугольника, это можно сериализовать с помощью ключей fey и цикла внутри объявления фигуры. Это также применимо к текстам.

  • Теперь, когда у нас есть форма с якорями и текстами, мы можем ее использовать. Для правильной формы схемы мы объявляем символ с помощью circuit declare symbolи устанавливаем его с помощью set <symbol name> graphic.

    Ключи circuit symbol sizeустанавливают minimum widthи minimum heightпо отношению к circuit symbol unit(измерение TeX под капотом). Это делает его масштабируемым по отношению к другим символам схемы. Ключ transform shapeнеобходим для вращения по circuits' toпутям.

  • A path picture, который использует предложенный код изеще один мой ответ. Чтобы настроить локальную систему координат, которая вращается и масштабируется вместе со своим узлом: Координата (0, 0)находится в центре узла.Иксвектор указывает на east(= output),увектор к северному якорю. Это важно для спецификаций координат, например, (left:.2)так как он использует .2половину горизонтального размера узлаиприменяемое вращение.

    Символы схемы внутри path pictureполучают опции gray(как и линии) и circuit symbol unit=.1cmкоторые уменьшают масштаб символов до подходящего размера. Может потребоваться поиграться с этим значением, чтобы получить правильный размер. Также может быть возможно сделать это зависимым от вышеупомянутой локальной системы координат с размерами \pgf@xxи \pgf@yy.

    Очевидно, если вам нужно несколько символов с одинаковой схемой привязки и соединения, но с разными затворами, можно сделать определение фигур гибким в соответствии с тремя ключами-значениями, которые в этом случае будут установлены на not gate, nand gateи nor gate.

Я использовал свойpaths.orthoбиблиотекадля соединений внутри path picture. Очевидно, что вы можете использовать любой способ для соединения этих линий.

Код

\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}

Выход

введите описание изображения здесь

решение2

Возможное решение с pics. Его трудно использовать pic-anchorsдля позиционирования (Закрепление фотографий TiKZ), но они служат опорными точками для установления связей между ними.

\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}

введите описание изображения здесь

Связанный контент