Skip to main content

Universal Shift Left - Right Register/Circuit in Verilog

A shift register will "shift" itself to the left or right by one position every clock cycle. A shift left - shift left circuit, as simple as it sounds is a very important part of many circuits and will be a part of many of my future projects and that is why it needs to be addressed. The code for this circuit in verilog is written below. It is very simple and does not need any detailed explanation.

It is controlled by 2 control signals which determines whether the circuit will shift right or left. If control[0] is high the circuit will shift right and if control[1] is high the circuit will shift left and if both are low stay with the default value. The data shifted is stored in an internal register and is output as a bus. I have coded it using if - else statements. This can also be coded using a case block if further control is required.

module shift(
    input clock,
    input reset,
    input [1:0] control,
    input in,
    output [7:0] out
    );

reg [7:0] r_reg, r_next; //a 7 bit shift register which will be output as is, this can be changed to any size

always @ (posedge clock or posedge reset)
begin
 if(reset)
  r_reg <= 0;
 else
  r_reg <= r_next;
end

always @ (*)
begin
 
 if(control[0]) //shift right
  r_next = {in, r_reg[7:1]};
 
 else if(control[1]) //shift left
  r_next = {r_reg[6:0], in};
 
 else
  r_next = r_reg; //default state stays the same

end

assign out = r_reg;

endmodule

Testbench code below:

module test;

	// Inputs
	reg clock;
	reg reset;
	reg [1:0] control;
	reg in;

	// Outputs
	wire [7:0] out;

	// Instantiate the Unit Under Test (UUT)
	shift uut (
		.clock(clock), 
		.reset(reset), 
		.control(control),
		.in(in), 
		.out(out)
	);

	initial begin
		clock = 0;
		forever
			#50 clock = ~clock;
		end

	initial begin
		// Initialize Inputs
		
		reset = 0;
		control = 0;
		in = 0;

		// Wait 100 ns for global reset to finish
		#100;
      reset = 1;
		#200;
		reset = 0;
		in = 1'b1;
		#200;
		control = 2'b01;
		#300;
		control = 2'b10;
		#300;
		control = 2'b00;
		#300;
		control = 2'b11;
		#200
		$stop;
			
		// Add stimulus here
	

	end
  
  initial begin
	$display("clock control r_reg");
	$monitor("%b,%b,%b", clock, control, out);
	end
endmodule

Comments

  1. Can you tell me the test bench code for simulation working?

    ReplyDelete

Post a Comment

Popular posts from this blog

To Code a Stopwatch in Verilog

The stopwatch coded here will be able to keep time till 10 minutes. It will be a 4 digit stopwatch counting from 0:00:0 till 9:59:9. The right most digit will be incremented every 0.1 second, when it reaches 9 it will increment the middle two digits, which represent the second count. When it reaches 59 seconds it will increment the right most minute display. The stopwatch will be in the format M:SS:D. How to Create an Accurate Delay in Verilog: To make the stop watch an accurate device we need to be able to produce an accurate 0.1 second delay. I have already explained how to do this before in my decimal counter in verilog post. But since it is of great importance to the design will be explained in more detail here. Since we know that the BASYS2 (the one I am using, yours may be different) has a 50 MHz clock which means that the clock cycle is repeated 50M times in one second. So to create a 0.1 second delay we multiply the clock with the required time: 50MHz * 0.1 sec = ...

Seven Segment LED Multiplexing Circuit in Verilog

The seven segment LED circuit uses seven different and individual LED's to display a hexadecimal symbol. It has 7 wires to control the individual LED's one wire to control the decimal point and one enable wire. The demo board I am using here consists of four such 7-segment LED's(As do any other demo board). To reduce the number of wires a multiplexing circuit is used to control the display. Using the multiplexing circuit the number of wires required to light up all 4 displays are reduced from 32 to 12 (8 data bits and 4 enable bits). All bits here are active low, such that to enable them a '0' is required. For example the figure below shows how to display a 3 on the seven segment. The multiplexing circuit can take 4 inputs and have only one output. But the inputs should be displayed on the output fast enough to fool the viewer into thinking all outputs are enabled individually and simultaneously. This is achieved by having an enable signal that changes so fast t...

Random Number Generator in Verilog | FPGA

In verilog a random number can be generated by using the $random keyword but that works only for simulation purposes and cannot be implemented. So when we need a random number for implementation i.e. in hardware it can be achieved using an LFSR (Liner Feedback Shift Register). An LFSR is simply a shift register with some of its bits (known as taps) XOR'd with themselves to create a feedback term. When implementing an LFSR it's width and it's repeatability must be kept under consideration .An N-bit LFSR will be able to generate (2**N) - 1 random bits before it starts repeating. For example a 30 bit LFSR will have 1073741823 random states before repeating, so for most practical purposes this can be considered true random. In an LFSR the MSB will always be the feedback point also the main thing to take care of while coding an LFSR is to know which bits are the taps (to be selected for XOR ). This is confusing as the taps are different for different size registers. For e...