Document ClassesBytefield and \newcommand

Information and discussion about specific document classes and how to create your own document classes.
Post Reply
duboismathieu
Posts: 18
Joined: Tue Apr 01, 2008 1:09 pm

Bytefield and \newcommand

Post by duboismathieu »

Hello everybody,

I'm not really a latex newbie nor an expert.
My question is about the bytefield package and how to define a new command.

I would like to represent graphically a fictive 32 bits instruction set. Of course there are different formats (register-register, register-immediate...). The commands are made of:
-a 5 bits wide opcode
-one bit to indicate the type of instruction
-data which can be 3 register ID (each 5 bits wide) or 2 register IDs and 16 bits immediate data (according to the previous bit)

I know how to draw such things with the bytefield package which is something like:

Code: Select all

\begin{bytefield}{32}
	\bitheader[b]{31,27,26,25,21,20,16,15,0} \\
	\bitbox{5}{$10000$} & \bitbox{1}{$1$} & \bitbox{5}{$00001$} & \bitbox{5}{$11111$} & \bitbox{5}{$11111$} & \bitbox{11}{$000000000000000$}
\end{bytefield}
So the idea is to have a command like this:
\regreg{opcode}{ID1}{ID2}{ID3} for register-register instructions

I tried the following:

Code: Select all

\newcommand{\regreg}[4]{
  \begin{bytefield}{32}
   \bitheader[b]{31,27,26,21,20,16,15,11,10,0} \\
   \bitbox{5}{#1} & \bitbox{1}{$0$} & \bitbox{5}{#2} & \bitbox{5}{#3} & \bitbox{5}{#4} & \bitbox{11}{$00000000000$}
  \end{bytefield}
}
But when I try to compile the document it fails with the following error:
"Extra alignment tab has been changed to \cr. ".
The error seems to come from \bitbox{1} (because if I comment after this, it works).

So is there something wrong with the definition of the command?
Maybe I should define a new environment but I don't know how to do this.

Any help would be appreciated.
Regards,
Mathieu

Recommended reading 2024:

LaTeXguide.org • LaTeX-Cookbook.net • TikZ.org
LaTeX Beginner's Guide LaTeX Cookbook LaTeX TikZ graphics TikZによるLaTeXグラフィックス
User avatar
Juanjo
Posts: 657
Joined: Sat Jan 27, 2007 12:46 am

Bytefield and \newcommand

Post by Juanjo »

Try this:

Code: Select all

\documentclass{article}
\usepackage{bytefield}

\begin{document}

\newcommand{\regreg}[4]{%
  \begin{bytefield}{32}
     \bitheader[b]{31,27,26,21,20,16,15,11,10,0} \\
     \bitbox{5}{$#1$} \bitbox{1}{$0$} \bitbox{5}{$#2$} \bitbox{5}{$#3$} 
     \bitbox{5}{$#4$} \bitbox{11}{$00000000000$}
  \end{bytefield}}

\regreg{01011}{11111}{11100}{10101}

\bigskip
\regreg{11011}{10110}{10011}{00001}

\end{document}
The above code works, at least in my computer. The trick is to remove the & characters between two \bitbox. When the bytefield environment is "normally" used, the ampersands can be put separating \bitboxes. In fact, that's the syntax given in the manual of the bytefield package. However, when the bytefield environment appears in a definition, as above, the &'s cause the error you reported (some kind of misalignment).

I don't know why that happens. Anyway, I looked at the code of the bytefield environment, where I discovered the line

Code: Select all

\catcode‘\&=10
This is a bit cryptic, but it means that, inside bytefield, the ampersand is considered as a space, instead of a column separator (as in tabular). I don't know if the ampersand plays really some role in the bytefield environment, but it seems that it can be replaced by space. At least in the above definition, this works.

Just a final remark. I assume that the arguments of \regreg will be always numbers (in fact, series of 0's and 1's). This is why, compared with your original definition, I've moved the $ $ to the definition. This simplifies a bit entering the arguments.

Edited: After writing the above message, I realized that you also posted your request in other forum. It is a matter of fairness to mention this fact in your posts.
duboismathieu
Posts: 18
Joined: Tue Apr 01, 2008 1:09 pm

Bytefield and \newcommand

Post by duboismathieu »

Hi Juanjo,

First sorry for the double post. I was really in a hurry...

Second your solution works. Thanks a lot for my students. This is my first dive into TeX's guts...

Maybe someone could answer another question.
I can now "draw" an instruction. But I would like to make an array of such drawings.

Something like:

Code: Select all

\begin{tabular}{ll}
 instr1 & \regreg{01011}{11111}{11100}{10101}
\end{tabular}
at the end of the file Juanjo provided.

But then I got the following error:
"Extra }, or forgotten \endgroup. ...regreg{01011}{11111}{11100}{10101}"

So, is it another problem with different "&"?

Thanks again.
Mathieu
User avatar
Juanjo
Posts: 657
Joined: Sat Jan 27, 2007 12:46 am

Bytefield and \newcommand

Post by Juanjo »

Just enclose \regreg in braces. Here you have the complete code including the alternative solution by Stefan in the other forum. It also works:

Code: Select all

\documentclass{article}
\usepackage{bytefield}

\begin{document}

% Solution in the other forum by Stefan
% (with slight changes)

\catcode`\&=10
\newcommand{\regreg}[4]{%
  \begin{bytefield}{32}
     \bitheader[b]{31,27,26,21,20,16,15,11,10,0} \\
     \bitbox{5}{$#1$} & \bitbox{1}{$0$} & \bitbox{5}{$#2$} & \bitbox{5}{$#3$} & 
     \bitbox{5}{$#4$} & \bitbox{11}{$00000000000$}
  \end{bytefield}}
\catcode`\&=4

\regreg{01011}{11111}{11100}{10101}

\bigskip
\regreg{11011}{10110}{10011}{00001}

\bigskip
\begin{tabular}{ll}
   instr1 & {\regreg{01011}{11111}{11100}{10101}}
\end{tabular}

\bigskip

% Solution given in this forum

\renewcommand{\regreg}[4]{%
  \begin{bytefield}{32}
     \bitheader[b]{31,27,26,21,20,16,15,11,10,0} \\
     \bitbox{5}{$#1$} \bitbox{1}{$0$} \bitbox{5}{$#2$} \bitbox{5}{$#3$} 
     \bitbox{5}{$#4$} \bitbox{11}{$00000000000$}
  \end{bytefield}}

\regreg{01011}{11111}{11100}{10101}

\bigskip
\regreg{11011}{10110}{10011}{00001}

\bigskip
\begin{tabular}{ll}
   instr1 & {\regreg{01011}{11111}{11100}{10101}}
\end{tabular}
\end{document}
duboismathieu
Posts: 18
Joined: Tue Apr 01, 2008 1:09 pm

Re: Bytefield and \newcommand

Post by duboismathieu »

Thanks a lot, it works, but... could you simply explain why (if you have time)?

Thanks again!
Mathieu
User avatar
Juanjo
Posts: 657
Joined: Sat Jan 27, 2007 12:46 am

Bytefield and \newcommand

Post by Juanjo »

duboismathieu wrote:Thanks a lot, it works, but... could you simply explain why (if you have time)?
I don't really know why, since the internals of the bytefield environment, involved here, is hard to understand. Anyway, without enclosing \regreg in braces, one gets an error of the form: "Extra }, or forgotten \endgroup. .." At first sight there are no unbalanced braces nor a \begin command without its matching \end.
So, one tries to put the offending code in a box or in a group and see what happens. The second option works. That's all.
User avatar
Stefan Kottwitz
Site Admin
Posts: 10290
Joined: Mon Mar 10, 2008 9:44 pm

Bytefield and \newcommand

Post by Stefan Kottwitz »

Hi Mathieu,

it is also possible to use the additional braces inside \regreg, so you don't have to type them always when you use \regreg:

Code: Select all

\renewcommand{\regreg}[4]{{%
  \begin{bytefield}{32}
     \bitheader[b]{31,27,26,21,20,16,15,11,10,0} \\
     \bitbox{5}{$#1$} \bitbox{1}{$0$} \bitbox{5}{$#2$} \bitbox{5}{$#3$}
     \bitbox{5}{$#4$} \bitbox{11}{$00000000000$}
  \end{bytefield}}}
...
\begin{tabular}{ll}
   instr1 & \regreg{01011}{11111}{11100}{10101}
\end{tabular}
Now it's working inside tables too without enclosing in braces.

Stefan
duboismathieu
Posts: 18
Joined: Tue Apr 01, 2008 1:09 pm

Re: Bytefield and \newcommand

Post by duboismathieu »

Hello,

Thanks to both of you!

Best regards,
Mathieu
Post Reply