\subsubsection{LFSR} \index{LFSR@\te{LFSR} (package)} {\bf Package} \begin{verbatim} import LFSR :: * ; \end{verbatim} {\bf Description} The \te{LFSR} package implements Linear Feedback Shift Registers (LFSRs). LFSRs can be used to obtain reasonable pseudo-random numbers for many purposes (though not good enough for cryptography). The \te{seed} method must be called first, to prime the algorithm. Then values may be read using the \te{value} method, and the algorithm stepped on to the next value by the \te{next} method. When a LFSR is created the start value, or seed, is 1. {\bf Interfaces and Methods} The \te{LFSR} package provides an interface, \te{LFSR}, which contains three methods; \te{seed}, \te{value}, and \te{next}. To prime the LFSR the \te{seed} method is called with the parameter \te{seed\_value}, of datatype \te{a\_type}. The value is read with the \te{value} method. The \te{next} method is used to shift the register on to the next value. \begin{center} \begin{tabular}{|p{.5in}|p{.5in}|p{2.2 in}|p{.7in}|p{1.1 in}|} \hline \multicolumn{5}{|c|}{\te{LFSR} Interface}\\ \hline \multicolumn{3}{|c|}{Method}&\multicolumn{2}{|c|}{Arguments}\\ \hline Name & Type & Description& Name &\multicolumn{1}{|c|}{Description} \\ \hline \hline \te{seed}&\te{Action}&Sets the value of the shift register.&\te{a\_type}&datatype of the seed value\\ &&&\te{seed\_value}&the initial value\\ \hline \te{value}&\te{a\_type}&returns the value of the shift register&&\\ \hline \te{next}&\te{Action}&signals the shift register to shift to the next value.&&\\ \hline \end{tabular} \end{center} \begin{libverbatim} interface LFSR #(type a_type); method Action seed(a_type seed_value); method a_type value(); method Action next(); endinterface: LFSR \end{libverbatim} {\bf Modules} \index{mkFeedLFSR@\te{mkFeedLFSR}(module)} The module \te{mkFeedLFSR} creates a LFSR where the polynomial is specified by the mask used for feedback. \begin{center} \begin{tabular}{|p{1 in}|p{4.5 in}|} \hline &\\ \te{mkFeedLFSR}&Creates a LFSR where the polynomial is specified by the mask (\emph{feed}) used for feedback. \\ \cline{2-2} &\begin{libverbatim} module mkFeedLFSR#( Bit#(n) feed )( LFSR#(Bit#(n)) ); \end{libverbatim} \\ \hline \end{tabular} \end{center} For example, the polynominal $x^7+x^3+x^2+x+1$ is defined by the expression \verb|mkFeedLFSR#(8'b1000_1111)| Using the module \te{mkFeedLFSR}, the following maximal length LFSR's are defined in this package. \begin{center} %\begin{tabular}{|p{1 in}|p{4 in}|} \begin{tabular}{|p{1in}|p{1in}|p{3.5 in}|} \hline Module Name&feed&Module Definition\\ \hline \hline &&\\ \te{mkLFSR\_4}&4'h9&\verb'module mkLFSR_4 (LFSR#(Bit#(4)));'\\ &$x^3 + 1$&\\ \hline &&\\ \te{mkLFSR\_8}&8'h8E &\verb'module mkLFSR_8 (LFSR#(Bit#(8)))';\\ \hline &&\\ \te{mkLFSR\_16}&16'h8016&\verb'module mkLFSR_16 (LFSR#(Bit#(16)));'\\ \hline &&\\ \te{mkLFSR\_32}&32'h80000057&\verb'module mkLFSR_32 (LFSR#(Bit#(32)));'\\ \hline \end{tabular} \end{center} For example, \begin{libverbatim} mkLFSR_4 = mkFeedLFSR( 4'h9 ); \end{libverbatim} The module \te{mkLFSR\_4} instantiates the interface \te{LFSR} with the value \te{Bit\#(4)} to produce a 4 bit shift register. The module uses the polynomial defined by the mask 4'h9 ($x^3 + 1$) and the module \te{mkFeedLFSR}. % \begin{libverbatim} % module mkLFSR_4 (LFSR#(Bit#(4))); % \end{libverbatim} % Some maximal length LFSRs. % Many more can be found at \te{http://www-2.cs.cmu.edu/ {\TILDE}koopman/lfsr/} % \begin{libverbatim} % module mkLFSR_8 (LFSR#(Bit#(8))); % mkLFSR_8 = mkFeedLFSR( 8'h8E ); % module mkLFSR_16 (LFSR#(Bit#(16))); % mkLFSR_16 = mkFeedLFSR( 16'h8016 ); % module mkLFSR_32 (LFSR#(Bit#(32))); % mkLFSR_32 = mkFeedLFSR( 32'h80000057 ); % \end{libverbatim} The \te{mkRCounter} function creates a counter with a LFSR interface. This is useful during debugging when a non-random sequence is desired. This function can be used in place of the other mkLFSR module constructors, without changing any method calls or behavior. \begin{center} \begin{tabular}{|p{1 in}|p{4.5 in}|} \hline &\\ \te{mkRCounter}&Creates a counter with a LFSR interface.\\ \cline{2-2} &\begin{libverbatim} module mkRCounter#( Bit#(n) seed ) ( LFSR#(Bit#(n)) ); \end{libverbatim} \\ \hline \end{tabular} \end{center} {\bf Example - Random Number Generator} \begin{verbatim} import GetPut::*; import FIFO::*; import LFSR::*; // We want 6-bit random numbers, so we will use the 16-bit version of // LFSR and take the most significant six bits. // The interface for the random number generator is parameterized on bit // length. It is a "get" interface, defined in the GetPut package. typedef Get#(Bit#(n)) RandI#(type n); module mkRn_6(RandI#(6)); // First we instantiate the LFSR module LFSR#(Bit#(16)) lfsr <- mkLFSR_16 ; // Next comes a FIFO for storing the results until needed FIFO#(Bit#(6)) fi <- mkFIFO ; // A boolean flag for ensuring that we first seed the LFSR module Reg#(Bool) starting <- mkReg(True) ; // This rule fires first, and sends a suitable seed to the module. rule start (starting); starting <= False; lfsr.seed('h11); endrule: start // After that, the following rule runs as often as it can, retrieving // results from the LFSR module and enqueing them on the FIFO. rule run (!starting); fi.enq(lfsr.value[10:5]); lfsr.next; endrule: run // The interface for mkRn_6 is a Get interface. We can produce this from a // FIFO using the fifoToGet function. We therefore don't need to define any // new methods explicitly in this module: we can simply return the produced // Get interface as the "result" of this module instantiation. return fifoToGet(fi); endmodule \end{verbatim}