The Shift Register

I will start with the register since we need two of it. In its simplest form we need an 8-bit serial-in serial-out synchronously clocked right-shift register. I can write a simple behavioral description of such a register pretty easily.

SRegister.v
//
//	Serial-in, serial-out right-shift register.
//	sin : serial input
// pout : parallel output
//	sout : rightmost bit shifted out
//
module sregister(sin, clk, pout, sout);
 parameter WIDTH = 8;
 output [WIDTH-1:0] pout;
           output sout;
           input  sin, clk;
           wire sin, clk;
           reg sout;
 reg [WIDTH-1 : 0]   pout;
 always @(posedge clk)
           begin
           sout = pout[0];
           pout = {sin, pout[7:1]};
           end
endmodule // sregister

This is mostly what you might expect. Two bits are worth comment. First, the line

          pout = {sin, pout[7:1]};

does a new bit of Verilog to actually compute the shift. It uses the braces to build a new 8-bit output by concatenating the serial input bit with the shifted bits of the previous value. Second, I added an extraneous parallel output simply to facilitate debugging.

The test for this uses a clock like that used for the counter and then simply waggles the serial input in a well-defined pattern. First it puts in a couple of zero and then goes to one for a while to fill the register with ones. It returns to zero to clear the register and then alternates before settling to zero and letting the register empty out.

SRegister_tb.v
//
//	Test for serial in-out register.
//	Register is defined as module sregister(sin, clk, pout, sout);
//
module test;
 /*	Make reg inputs and wire outputs for register */
 /*	We need sin and clock as inputs */
 reg clk = 0;
 reg sin = 0;
 
 /* Make a regular pulsing clock. */
 always #5 clk = !clk;
 /* Change the value on the input pin every so often */
 initial begin
    #   8 sin = 1; // Start to fill with ones
    #  80 sin = 0; // Start to fill with zeros
    #  80 sin = 1;
    #  10 sin = 0;
    #  10 sin = 1;
    #  10 sin = 0;
    #  10 sin = 1;
    #  10 sin = 0;
    # 100 $stop;
    end
  wire [7:0] value;
  wire sdata;
  sregister r1 (sin, clk, value, sdata);
 initial
    $monitor("At time %t, sin = %d, value = %h, sout = %d",
           $time, sin, value, sdata);

endmodule // test

This produces quite a lot of output that looks exactly as we would expect. The serial output starts undefined and it takes a while for information to percolate through the register. Once it does so the soutput is a copy of the input but delayed by 8 clocks.

   At time                    0, sin = 0, value = xx, sout = x
   At time                    5, sin = 0, value = Xx, sout = x
   At time                    8, sin = 1, value = Xx, sout = x
   At time                   15, sin = 1, value = Xx, sout = x
   At time                   25, sin = 1, value = Xx, sout = x
   At time                   35, sin = 1, value = ex, sout = x
   At time                   45, sin = 1, value = fX, sout = x
   At time                   55, sin = 1, value = fX, sout = x
   At time                   65, sin = 1, value = fX, sout = x
   At time                   75, sin = 1, value = fe, sout = x
   At time                   85, sin = 1, value = ff, sout = 0
   At time                   88, sin = 0, value = ff, sout = 0
   At time                   95, sin = 0, value = 7f, sout = 1
   At time                  105, sin = 0, value = 3f, sout = 1
   At time                  115, sin = 0, value = 1f, sout = 1
   At time                  125, sin = 0, value = 0f, sout = 1
   At time                  135, sin = 0, value = 07, sout = 1
   At time                  145, sin = 0, value = 03, sout = 1
   At time                  155, sin = 0, value = 01, sout = 1
   At time                  165, sin = 0, value = 00, sout = 1
   At time                  168, sin = 1, value = 00, sout = 1
   At time                  175, sin = 1, value = 80, sout = 0
   At time                  178, sin = 0, value = 80, sout = 0
   At time                  185, sin = 0, value = 40, sout = 0
   At time                  188, sin = 1, value = 40, sout = 0
   At time                  195, sin = 1, value = a0, sout = 0
   At time                  198, sin = 0, value = a0, sout = 0
   At time                  205, sin = 0, value = 50, sout = 0
   At time                  208, sin = 1, value = 50, sout = 0
   At time                  215, sin = 1, value = a8, sout = 0
   At time                  218, sin = 0, value = a8, sout = 0
   At time                  225, sin = 0, value = 54, sout = 0
   At time                  235, sin = 0, value = 2a, sout = 0
   At time                  245, sin = 0, value = 15, sout = 0
   At time                  255, sin = 0, value = 0a, sout = 1
   At time                  265, sin = 0, value = 05, sout = 0
   At time                  275, sin = 0, value = 02, sout = 1
   At time                  285, sin = 0, value = 01, sout = 0
   At time                  295, sin = 0, value = 00, sout = 1
   At time                  305, sin = 0, value = 00, sout = 0
   ** VVP Stop(0) **
   ** Flushing output streams.
   ** Current simulation time is 318 ticks.

 

Brian Collett