Ads

Get STM32 tutorial using HAL at $10 for a limited time!

Saturday, July 16, 2016

Verilog Tutorial 1 - ModelSim - Multifunction Barrel Shifter

A barrel shifter is a digital circuit that can shift a data word by a specified number of bits without use of any sequential logic, only pure combinational logic[1]. There are 3 type of bitwise shift operation: logical shift, arithmetic shift, and circular shift (rotate). We can shift the data to the left as well as to the right. The barrel shifter in this tutorial is a multifunction barrel shifter that can perform left or right circular shift. The basic barrel shifter in this tutorial is based on this book: FPGA Prototyping by Verilog Example by Pong P. Chu. You can also learn the basic of Verilog language from this book.

The multifunction barrel shifter in this tutorial is actually a suggested experiment from chapter 3 of the book. There are 2 design that will be implemented in this tutorial. The first design is using 1 rotate-left circuit, 1 rotate-right circuit, and one 2-to-1 multiplexer to select the desired result. The top level schematic of the first design is like this:


The second design is implemented using 1 rotate-left shifter with pre- and post- reversing circuit. The reversing circuit either pass the original input or reverses the input bitwise. For example, if the input is a7,a6,a5,a4,a3,a2,a1,a0 then the reversed result become a0,a1,a2,a3,a4,a5,a6,a7. The top level schematic of the second design is like this:


This is the calculation for comparing the two design above. In this example we want to rotate right 3 times using rotate right shifter and rotate left shifter + reverse bit.


In this tutorial, both of the circuit is implemented using behavioral modeling. With behavioral modeling, you write code based on its functionality. It is like writing the algorithm that sloves the problem rather than construct from basic lowest level blocks (e.g. gates, flip-flop). Modeling from basic lowest level blocks is called structural modeling.

In this tutorial, I will use ModelSim student edition software from Mentor Graphis. Tutorial for make a new project in ModelSim can be found in here. This is the code for the first design:
// rotate_left.v
module rotate_left
    (
        input wire [7:0] a,
        input wire [2:0] amt,
        output reg [7:0] y
    );

    // Body
    always @*
        case (amt)
            3'o0: y = a;
            3'o1: y = {a[0], a[7:1]};
            3'o2: y = {a[1:0], a[7:2]};
            3'o3: y = {a[2:0], a[7:3]};
            3'o4: y = {a[3:0], a[7:4]};
            3'o5: y = {a[4:0], a[7:5]};
            3'o6: y = {a[5:0], a[7:6]};
            default: y = {a[6:0], a[7]};
        endcase

endmodule
// rotate_right.v
module rotate_right
    (
        input wire [7:0] a,
        input wire [2:0] amt,
        output reg [7:0] y
    );

    // Body
    always @*
        case (amt)
            3'o0: y = a;
            3'o1: y = {a[6:0], a[7]};
            3'o2: y = {a[5:0], a[7:6]};
            3'o3: y = {a[4:0], a[7:5]};
            3'o4: y = {a[3:0], a[7:4]};
            3'o5: y = {a[2:0], a[7:3]};
            3'o6: y = {a[1:0], a[7:2]};
            default: y = {a[0], a[7:1]};
        endcase

endmodule
// mux2.v
module mux2
    #(
        parameter D_BIT = 8    // Number of data bits
    )
    (
        input wire [D_BIT-1:0] d0, d1,
        input wire s,
        output reg [D_BIT-1:0] y
    );

    // Body
    always @*
        if (~s)
            y = d0;
        else
            y = d1;

endmodule
// top.v
module top
    (
        input wire [7:0] a,      // Input
        input wire [2:0] amt,    // Number of rotation
        input wire lr,           // Rotate left(lr=0) or right(lr=1) 
        output wire [7:0] y      // Output
    );

    // Signal declaration
    wire [7:0] rotated_left, rotated_right;

    // Body
    rotate_left rotate_left_unit
        (.a(a), .amt(amt), .y(rotated_left));

    rotate_right rotate_right_unit
        (.a(a), .amt(amt), .y(rotated_right));
 
    mux2 mux2_unit
        (.d0(rotated_left), .d1(rotated_right), .s(lr), .y(y));
 
endmodule
This is the code for the second design:
// barrel_shifter.v
module barrel_shifter
    (
        input wire [7:0] a,
        input wire [2:0] amt,
        output reg [7:0] y
    );

    // Body
    always @*
        case (amt)
            3'o0: y = a;
            3'o1: y = {a[0], a[7:1]};
            3'o2: y = {a[1:0], a[7:2]};
            3'o3: y = {a[2:0], a[7:3]};
            3'o4: y = {a[3:0], a[7:4]};
            3'o5: y = {a[4:0], a[7:5]};
            3'o6: y = {a[5:0], a[7:6]};
            default: y = {a[6:0], a[7]};
        endcase

endmodule
// reverse_bit.v
module reverse_bit
    (
        input wire [7:0] a,
        input wire en,
        output reg [7:0] y
    );

    // Body
    always @*
        if (en)
            y = {a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]};
        else
            y = a;

endmodule
// top.v
module top
    (
        input wire [7:0] a,      // Input
        input wire [2:0] amt,    // Number of rotation
        input wire lr,           // Rotate left(lr=0) or right(lr=1) 
        output wire [7:0] y      // Output
    );
 
    // Signal declaration
    wire [7:0] pre_reversed, post_reverse;

    // Body
    barrel_shifter barrel_shifter_unit
        (.a(pre_reversed), .amt(amt), .y(post_reverse));
 
    reverse_bit pre_reverse_bit_unit 
        (.a(a), .en(lr), .y(pre_reversed));
 
    reverse_bit post_reverse_bit_unit 
        (.a(post_reverse), .en(lr), .y(y));

endmodule
After you write the code, you must to write a testbench code and use simulation to verify its operation. This is the testbench code for both design:
// top_tb.v
`timescale 1 ns/10 ps

module top_tb;
    // Signal declaration
    reg [7:0] a_test;
    reg [2:0] amt_test;
    reg lr_test;
    wire [7:0] y_test;

    // Instantiate the circuit under test
    top uut (.a(a_test), .amt(amt_test), .lr(lr_test), .y(y_test));

    // Test vector generator
    initial
    begin
        a_test = 8'b10010011;    // Input data

        lr_test = 1'b0;    // Rotate left
  
        amt_test = 3'o1;
        # 200;
        amt_test = 3'o3;
        # 200;
        amt_test = 3'o5;
        # 200;
 
        lr_test = 1'b1;    // Rotate right
  
        amt_test = 3'o2;
        # 200; 
        amt_test = 3'o4;
        # 200; 
        amt_test = 3'o6;
        # 200;
 
        // Stop simulation
        $stop;
    end
endmodule
This is the simulation result from the first and second design:


The waveform result from both design is same. The different is on the number of logic cells and propagation delays if you synthesis this circuit to FPGA or ASIC. You can download full project file of this tutorial from my repository.

2 comments :

  1. Great Information shared by you. Subhe eLearning provides one of the best ux design course online in India with studio-recorded videos and live workshops and cohort-based practical oriented pedagogy with dedicated mentorship. Subhe provides learning from industry experts ux designer in india and mentors along with One-to-One Sessions, practical learning, placements training and 100% internship placements.
    Also, check out our other courses:
    Graphic design and video editing courses
    Photoshop tutorials in hindi
    digital marketing course

    ReplyDelete
  2. LeaderJam’s list of the best cohort-based courses online includes both online and in-person courses. There are a variety of reasons why leaders may want to take a cohort-based course, including gaining new skills, networking with other leaders, and building a community of like-minded individuals.

    ReplyDelete