Verilog Coding Tips and Tricks: flip flops
Showing posts with label flip flops. Show all posts
Showing posts with label flip flops. Show all posts

Monday, November 16, 2015

Synthesiable Verilog code for a 4 tap FIR Filter

Few years back I wrote a VHDL code for implementing a FIR filter. In this post, I want to implement the same algorithm in Verilog.

Finite Impulse Response(FIR) filters are one of the two main type of filters available for signal processing. As the name suggests the output of a FIR filter is finite and it settles down to zero after some time. For a basic FAQ on FIR filters see this post by dspguru.

A FIR filter output, 'y' can be defined by the following equation:



Here, 'y' is the filter output, 'x' in the input signal and 'b' is the filter coefficients. 'N' is the filter order. The higher the value of N is, the more complex the filter will be.

For writing the code in Verilog I have referred to the paper, VHDL generation of optimized FIR filters. You can say I have coded the exact block diagram available in the paper, "Figure 2".

This is a 4 tap filter. That means the order of the filter is 4 and so it has 4 coefficients. The inputs are chosen to be 8 bits wide and outputs are chosen to be 16 bits wide. Both inputs and outputs can store negative numbers, in two's complement format. If you want to handle inputs with bigger range you can simply increase the size of the inputs and intermediate variables. The structure of the code will remain the same.

The design contains two files. One is the main file with all the multiplications and adders defined in it, and another one for defining the D flip flop operation.

The codes are given below:

fir_4tap:

module fir_4tap(
        input Clk,
        input signed [7:0] Xin,
        output reg signed [15:0] Yout
        );
    
    //Internal variables.
    wire signed   [7:0] H0,H1,H2,H3;
    wire signed   [15:0] MCM0,MCM1,MCM2,MCM3,add_out1,add_out2,add_out3;
    wire signed     [15:0] Q1,Q2,Q3;
    
//filter coefficient initializations.
//H = [-2 -1 3 4].
    assign H0 = -2;
    assign H1 = -1;
    assign H2 = 3;
    assign H3 = 4;

//Multiple constant multiplications.
    assign MCM3 = H3*Xin;
    assign MCM2 = H2*Xin;
    assign MCM1 = H1*Xin;
    assign MCM0 = H0*Xin;

//adders
    assign add_out1 = Q1 + MCM2;
    assign add_out2 = Q2 + MCM1;
    assign add_out3 = Q3 + MCM0;    

//flipflop instantiations (for introducing a delay).
    DFF dff1 (.Clk(Clk),.D(MCM3),.Q(Q1));
    DFF dff2 (.Clk(Clk),.D(add_out1),.Q(Q2));
    DFF dff3 (.Clk(Clk),.D(add_out2),.Q(Q3));

//Assign the last adder output to final output.
    always@ (posedge Clk)
        Yout <= add_out3;

endmodule

DFF:

module DFF
        (input Clk,
        input [15:0] D,
        output reg [15:0]   Q
        );
    
    always@ (posedge Clk)
        Q = D;
    
endmodule

Testbench for the FIR filter:

module tb;

    // Inputs
    reg Clk;
    reg signed [7:0] Xin;

    // Outputs
    wire signed [15:0] Yout;

    // Instantiate the Unit Under Test (UUT)
    fir_4tap uut (
        .Clk(Clk), 
        .Xin(Xin), 
        .Yout(Yout)
    );
    
    //Generate a clock with 10 ns clock period.
    initial Clk = 0;
    always #5 Clk =~Clk;

//Initialize and apply the inputs.
    initial begin
          Xin = 0;  #40;
          Xin = -3; #10;
          Xin = 1;  #10;
          Xin = 0;  #10;
          Xin = -2; #10;
          Xin = -1; #10;
          Xin = 4;  #10;
          Xin = -5; #10;
          Xin = 6;  #10;
          Xin = 0;  #10;
    end
      
endmodule

Simulation waveform:

The following waveform was obtained in Xilinx ISE 14.6 after successful simulation.


Synthesis Results:

The modules were successfully synthesised for Virtex 4 device and a maximum frequency of 528 MHz was obtained.


Wednesday, November 11, 2015

Verilog Code for JK flip flop with Synchronous reset,set and clock enable

In this post, I want to share the Verilog code for a JK flip flop with synchronous reset,set and clock enable. The particular flip flop I want to talk about is designed by Xilinx and is called by the name, FJKRSE.

The truth table for FJKRSE:


From the truth table, we can see that reset(R) has the highest priority and set(S) the next priority, then the clock enable (CE) and then the J or K inputs.

JK flip flop:

//JK flip flop module
module FJKRSE(J,K,Clk,R,S,CE,Qout);

    input J,K;  //inputs
    input Clk;  //Clock
    input R;    //synchronous reset (R) 
    input S; //synchronous set (S)
    input CE; //clock enable (CE) 
    output Qout;  //data output (Q)
    
    //Internal variable
    reg Qout;
    
    always@ (posedge(Clk))  //Everything is synchronous to positive edge of clock
    begin
        if(R == 1) //reset has highest priority.
            Qout = 0;
        else    
            if(S == 1)  //set has next priority
                Qout = 1;
            else
                if(CE == 1) //J,K values are considered only when CE is ON.
                    if(J == 0 && K == 0)    
                        Qout = Qout; //no change
                    else if(J == 0 && K == 1)
                        Qout = 0;  //reset
                    else if(J == 1 && K == 0)
                        Qout = 1;  //set
                    else
                        Qout = ~Qout;  //toggle
                else
                    Qout = Qout; //no change
    end
    
endmodule

Testbench for JK flip flop:

module tb_jkff;

    // Inputs
    reg J;
    reg K;
    reg Clk;
    reg R;
    reg S;
    reg CE;

    // Outputs
    wire Qout;

    // Instantiate the Unit Under Test (UUT)
    FJKRSE uut (
        .J(J), 
        .K(K), 
        .Clk(Clk), 
        .R(R), 
        .S(S), 
        .CE(CE), 
        .Qout(Qout)
    );
    
    //Create 50 Mhz clock(20 ns clock period).
    initial Clk = 0;
    always #10 Clk = ~Clk;

    initial begin
        // Initialize Inputs
        J = 0;
        K = 0;
        R = 0;
        S = 0;
        CE = 0;
        #30;
        //Apply inputs
        R = 1;  #50;
        R = 0;
        S = 1;  #50;
        S = 0;
        J = 1;  K = 1;  #50;
        CE = 1; #50;
        J = 0;  K = 0;  #50;
        J = 0;  K = 1;  #50;
        J = 1;  K = 0;  #50;
        J = 1;  K = 1;  #50;
        CE = 0;
    end
      
endmodule

Simulation Waveform:

The codes were simulated in Xilinx ISE 13.1 and we got the following waveform.

Note how the outputs are changed only at the positive edge of the clock. Also note how the priority of reset,set and clock enable works,