When I examined the code for the left-shift operation in my first version I found an error. The code read
pout = {pout[WIDTH-1],sin};
which only concatenates two bits, the original top bit and the new serial input bit, to make the output. I intended to concatenate the lower 7 original bits with sin like this
pout = {pout[WIDTH-2:0],sin};
With that change I reran the simulation an obtained the expected output
At time 0, rst=1, sin=0, pin= 0, mode=0 -> value = xx (x), sout = x At time 17, rst=0, sin=0, pin= 0, mode=0 -> value = 00 (0), sout = 0 At time 28, rst=1, sin=0, pin= 0, mode=0 -> value = 00 (0), sout = 0 At time 33, rst=1, sin=0, pin=170, mode=0 -> value = 00 (0), sout = 0 At time 38, rst=1, sin=0, pin=172, mode=0 -> value = 00 (0), sout = 0 At time 42, rst=1, sin=0, pin=172, mode=3 -> value = 00 (0), sout = 0 At time 43, rst=1, sin=0, pin= 10, mode=3 -> value = 00 (0), sout = 0 At time 45, rst=1, sin=0, pin= 10, mode=3 -> value = 0a (10), sout = 0 At time 47, rst=1, sin=0, pin= 10, mode=0 -> value = 0a (10), sout = 0 At time 52, rst=1, sin=0, pin=240, mode=0 -> value = 0a (10), sout = 0 At time 61, rst=1, sin=0, pin=240, mode=3 -> value = 0a (10), sout = 0 At time 62, rst=1, sin=0, pin=138, mode=3 -> value = 0a (10), sout = 0 At time 65, rst=1, sin=0, pin=138, mode=3 -> value = 8a (138), sout = 0 At time 66, rst=1, sin=0, pin=138, mode=0 -> value = 8a (138), sout = 0 At time 69, rst=1, sin=0, pin=138, mode=1 -> value = 8a (138), sout = 0 At time 75, rst=1, sin=0, pin=138, mode=1 -> value = 14 (20), sout = 1 At time 85, rst=1, sin=0, pin=138, mode=1 -> value = 28 (40), sout = 0 At time 95, rst=1, sin=0, pin=138, mode=1 -> value = 50 (80), sout = 0 At time 105, rst=1, sin=0, pin=138, mode=1 -> value = a0 (160), sout = 0 At time 115, rst=1, sin=0, pin=138, mode=1 -> value = 40 (64), sout = 1 At time 125, rst=1, sin=0, pin=138, mode=1 -> value = 80 (128), sout = 0 At time 135, rst=1, sin=0, pin=138, mode=1 -> value = 00 (0), sout = 1 At time 145, rst=1, sin=0, pin=138, mode=1 -> value = 00 (0), sout = 0 At time 151, rst=1, sin=0, pin=138, mode=0 -> value = 00 (0), sout = 0 ** VVP Stop(0) ** ** Flushing output streams. ** Current simulation time is 230 ticks.
With the register working correctly in the wrong direction I changed the mode to right shift and re-ran the test, getting the correct output. Here is the corrected Verilog code for our shift register.
// // Parallel-in, parallel-out, serial out register with // synchronous load & shift and asynchronous clear (reset). // Design based on the 74194 universal shift register // extended to arbitrary number of bits. // pin[8] : parallel input // mode[2] : mode control 0 hold, 1 shl, 2 shr, 3 load // reset : asynchronous reset to zero (active low) // pout[8] : parallel output // sout : rightmost bit shifted out // module psregister(sin, pin, clk, mode, reset, pout, sout); parameter WIDTH = 8; output [WIDTH-1 : 0] pout; output sout; input [WIDTH-1:0] pin; input [1:0] mode; input clk, sin, reset; reg [WIDTH-1 : 0] pout; reg sout; wire sin, pin, clk, mode, reset; always @(posedge clk) if (mode == 3) pout <= pin; else if (mode == 2) begin sout = pout[0]; pout = {1'b0, pout[WIDTH-1:1]}; end else if (mode == 1) begin sout = pout[WIDTH-1]; pout = {pout[WIDTH-2:0],sin}; end always @reset if (reset == 0) begin assign sout = 0; assign pout = 0; end else begin deassign sout; deassign pout; end endmodule // psregister |
Notice that this is still a dataflow model of the register. It does not attempt to explain how the register operates, merely what it does. It corresponds to a state-table representation of the logic and not to a gate level diagram. The gate-level diagram could correspond to a behavioral model of the register and be much more complicated. A look in the data sheet for this chip shows that we would need about 25 AND gates, 10 NOR gates, about 14 NOT gates, and 8 clocked RS flip-flops to produce a behavioral model.