FONT SIZE : AAA
While a shift register is, strictly speaking, not a counter, it is useful to consider this in the context of other counters as it can be converted into a counter with very small changes. We will consider this element layer in this book, in more detail, but consider a simple case of a shift register that takes a single bit and stores in the least significant bit of a register and shifts each bit up one bit on the occurrence of a clock edge. If we consider an n-bit register and show the status before and after a clock edge, then the functionality of the shift register becomes clear, as shown in Figure 24.4.
A basic shift register can be implemented in VHDL as shown here:
Figure 24.4 Simple shift register functionality: (a) Before the clock edge; (b) After the clock edge.
1 library ieee;
2 use ieee.std_logic_1164.all;
3
4 entity shift_register is
5 generic (
6 n : integer := 4;
7 port (
8 clk : in std_logic;
9 rst : in std_logic;
10 din : in std_logic;
11 q : out std_logic_vector((n−1) downto 0)
12 );
13 end entity;
14
15 architecture simple of shift_register is
16 begin
17 process(clk, rst)
18 variable shift_reg : std_logic_vector((n−1) downto 0);
19 begin
20 if rst = ’0’ then
21 shift_reg := (others => ’0’);
22 elsif rising_edge(clk) then
23 shift_reg := shift_reg(n−2 downto 0) & din;
24 end if;
25 q <= shift_reg;
26 end process;
27 end architecture simple;
The interesting parts of this model are very similar to the simple binary counter, but subtly different. As for the counter, we have defined an internal variable (shift_reg), but unlike the counter we do not need to carry out arithmetic functions, so we do not need to define this as an unsignedvariable.Instead,wecandefinedirectlyasastd_logic_vector,thesameastheoutputq.
Notice that we have an asynchronous clock in this case. As we have discussed previously in this book, there are techniques for completely synchronous sets or resets, and these can be used if required.
The fundamental difference between the counter and the shift register is in how we move the bits around. In the counter we use arithmetic to add one to the internal counter variable (count). In this case, we just require shifting the register up by one bit, and to achieve this we simply assign the lowest (n − 1) bits of the internal register variable (shift_reg) to the upper (n − 1) bits and concatenate the input bit (din), effectively setting the lowest bit of the register to the input signal (din). This can be accomplished using the VHDL following:
1 shift_reg := shift_reg(n−2 downto 0) & din;
The final stage of the model is similar to the basic counter in that we then assign the output signal to the value of the internal variable (shift_reg) using a standard signal assignment. In the shift register, we do not need to cast the type as both the internal and signal variable types are std_logic_vector:
1 q <= shift_reg;
We can also implement the shift register in Verilog, with the listing as shown here:
1 module shift_register (
2 clk, / clock input
3 rst, / reset (active low)
4 din, / Digital Input
5 shiftreg / shift register
6 );
7
8 input clk;
9 input rst;
10 input din;
11
12 output [7:0] shiftreg;
13
14 wire clk;
15 wire rst;
16 wire din;
17
18 reg [7:0] shiftreg ;
19
20 always @ (posedge clk)
21 begin : count
22 if (rst == 1’b0) begin
23 shiftreg <= #1 4’b00000000;
24 end
25 else begin
26 shiftreg <= #1 {din, shiftreg[7:1]};
27 end
28 end
29
30 endmodule
In both cases (VHDL and Verilog) we can test the behavior of the shift register by applying a data sequence and observing the shift register variable in the model, and in the case of the Verilog we can also add a $monitor command to display the transitions as they happen in the transcript of the simulator. The Verilog test bench code is given as:
1
2 module shift_register_tb();
3 / declare the signals
4 reg clk;
5 reg rst;
6 reg din;
7 wire [7:0] shift_register_values;
8
9 / Set up the initial variables and reset
10 initial begin
11 $display ("time\t clk reset counter");
12 $monitor ("%g\t %b %b %b %h",
13 $time, clk, rst, din, shift_register_values);
14 clk = 1; / initialize the clock to 1
15 rst = 1; / set the reset to 1 (not reset)
16 din = 0; / Initialize the digital input
17 #5 rst = 0; / reset = 0 : resets the counter
18 #10 rst = 1; / reset back to 1 : counter can start
19 #4 din = 0; / test data sequence starting at cycle time 16
20 #10 din = 1; / din = 1 test data sequence
21 #10 din = 0; / din = 0 test data sequence
22 #10 din = 0; / din = 0 test data sequence
23 #10 din = 1; / din = 1 test data sequence
24 #10 din = 1; / din = 1 test data sequence
25 #10 din = 0; / din = 0 test data sequence
26 #10 din = 1; / din = 1 test data sequence
27 #10 din = 0; / din = 0 test data sequence
28 #10 din = 1; / din = 1 test data sequence
29 #1000 $finish; / Finish the simulation
30 end
31
32 / Clock generator
33 always begin
34 #5 clk = ~clk; / Clock every 5 time slots
35 end
36
37 / Connect DUT to test bench
38 shift_register DUT (
39 clk,
40 rst,
41 din,
42 shift_register_values
43 );
44
45 endmodule
The resulting simulation of the shift register can be seen in Figure 24.5.
Figure 24.5 Simple shift register simulation.
Manufacturer:Xilinx
Product Categories:
Lifecycle:Obsolete -
RoHS:
Manufacturer:Xilinx
Product Categories: FPGAs (Field Programmable Gate Array)
Lifecycle:Obsolete -
RoHS:
Manufacturer:Xilinx
Product Categories:
Lifecycle:Obsolete -
RoHS:
Manufacturer:Xilinx
Product Categories:
Lifecycle:Obsolete -
RoHS: No RoHS
Manufacturer:Xilinx
Product Categories: Voltage regulator tube
Lifecycle:Obsolete -
RoHS: No RoHS
Support