Friday, 4 November 2016

2. Counter Design (Magic_Counter using clock divisor).

/*Verilog code for 3 module circuit*/
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: RED_BLUE
// Engineer:
//
// Create Date:    17:20:12 11/04/2016
// Designer Name:  Madhu Krishna
// Module Name:    magic_counter
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////


module magic_counter  ( clk_in,
                        reset_n,
                        clk_divisor, 
                        cntr_en,                       
                        up_down_cntr_en,
                        match_val,
                        clk_div,
                        up_down_cnt,
                        match_en,
                        magic_cntr);

  input           clk_in;
  input            reset_n; 
  input   [4:0] clk_divisor;
  input            cntr_en;
  input            up_down_cntr_en;
  input   [3:0] match_val;
  output           clk_div;
  output  [3:0] up_down_cnt;
  output          match_en;
  output  [3:0] magic_cntr;
      
  reg           clk_div;
  reg [15:0] clk_cnt;
  reg [3:0]  up_down_cnt;
  reg           match_en;
  reg [2:0]  magic_bin_cntr;
  reg [3:0]  magic_cntr;

// Clock divider Module-1
  always @(*) begin : CLK_DIV_PROC   
    case (clk_divisor)   
      0:  clk_div  = 1'b1;
      1:  clk_div  = clk_cnt[0];
      2:  clk_div  = clk_cnt[1];
      3:  clk_div  = clk_cnt[2];
      4:  clk_div  = clk_cnt[3];
      5:  clk_div  = clk_cnt[4];
      6:  clk_div  = clk_cnt[5];
      7:  clk_div  = clk_cnt[6];
      8:  clk_div  = clk_cnt[7];
      9:  clk_div  = clk_cnt[8];
      10: clk_div  = clk_cnt[9];
      11: clk_div  = clk_cnt[10];
      12: clk_div  = clk_cnt[11];
      13: clk_div  = clk_cnt[12];
      14: clk_div  = clk_cnt[13];
      15: clk_div  = clk_cnt[14];
      16: clk_div  = clk_cnt[15];
      default : clk_div = 1'b1;
    endcase           
  end             
                   
  always @(posedge clk_in or negedge reset_n) begin : CLK_DIV_CNTR_PROC
    if (reset_n == 1'b0) begin
      clk_cnt <= 16'b0;
    end else begin
      clk_cnt <= clk_cnt + 16'b1;
    end
  end

//Up-Down Counter Module-2
  always @(posedge clk_in or negedge reset_n) begin : UP_DOWN_CNTR_PROC
    if (reset_n == 1'b0) begin    
      up_down_cnt <= 4'b0;
    end else begin
      if (clk_div == 1'b1) begin
        if (cntr_en == 1'b1) begin
          if (up_down_cntr_en == 1'b1) begin
            up_down_cnt <= up_down_cnt + 1'b1;
          end else begin
            up_down_cnt <= up_down_cnt - 1'b1;
          end
        end
      end  
    end
  end 
  always @(posedge clk_in or negedge reset_n) begin : MATCH_EN_PROC
    if (reset_n == 1'b0) begin    
      match_en <= 1'b0;
    end else begin
      if (clk_div == 1'b1) begin
        if(match_val == up_down_cnt) begin
          match_en <= 1'b1;
        end else begin
          match_en <= 1'b0;
        end
      end  
    end
  end
  
//Magic_Counter Module-3 
  always @(posedge clk_in or negedge reset_n) begin : MAGIC_BIN_CNTR_PROC
    if (reset_n == 1'b0) begin    
      magic_bin_cntr <= 3'b110;
    end else begin
      if (clk_div == 1'b1) begin
        if (cntr_en == 1'b1) begin  
          if (match_en == 1'b1) begin  
            magic_bin_cntr <= magic_bin_cntr + 1'b1;
          end
        end  
      end  
    end 
  end

  always @(*) begin : MAGIC_CNTR_PROC
    case (magic_bin_cntr)
      3'b000 : magic_cntr = 4'b0011;
      3'b001 : magic_cntr = 4'b0111;
      3'b010 : magic_cntr = 4'b0010;
      3'b011 : magic_cntr = 4'b0100;
      3'b100 : magic_cntr = 4'b1000;
      3'b101 : magic_cntr = 4'b1101;
      3'b110 : magic_cntr = 4'b0000;
      3'b111 : magic_cntr = 4'b0001;
      default :magic_cntr = 4'b0000;
    endcase  
  end      
      
endmodule


----------------------------------------------------------------------------------------------------------------------------------

// Verilog test_b code for magic_counter.
// -------------------------------------------------------------------
//
// Release version  :
//
// File    : Counter.v
//
//
// Author  : Madhu Krishna
// Created :
// Abstract:
//
// -------------------------------------------------------------------
// -------------------------------------------------------------------

//`timescale 1ns/100ps

module tb_magic_counter;

  // Counter Width
  `define COUNTER_WIDTH 4

  // Clock Period
  `define CLK_IN_PRD    5

  // Net Type and Variable Type declaration
  // Inputs
  reg                           clk_in = 1'b0;
  reg                           reset_n = 1'b0;
  reg  [4:0]                    clk_divisor = 5'b00000;
  reg                           cntr_en = 1'b0;
  reg                           up_down_cntr_en = 1'b0;
  reg  [3:0]                    match_val = 4'b0000;
  // Outputs
  wire                          clk_div;
  wire [3:0]                    up_down_cnt;
  wire                          match_en;
  wire [`COUNTER_WIDTH-1 : 0]   magic_cntr;
 
  magic_counter U_MAGIC_COUNTER
  (
    .clk_in               (clk_in)
    ,.reset_n             (reset_n)
    ,.clk_divisor         (clk_divisor)        
    ,.cntr_en             (cntr_en)
    ,.up_down_cntr_en     (up_down_cntr_en)
    ,.match_val           (match_val)
    ,.clk_div             (clk_div)
    ,.up_down_cnt         (up_down_cnt)
    ,.match_en            (match_en)
    ,.magic_cntr          (magic_cntr)
  );

  // VPD Dump instruction
  initial begin : VPD_DUMP_ROC
    $vcdpluson();
  end

  // Clock In Generation
  always begin : CLK_IN_PROC
    clk_in = #`CLK_IN_PRD ~clk_in;  
  end

  // Reset Generation
  initial begin : RESET_IN_PROC
    reset_n = #10000 1'b1;  
    #100000000;
    $finish;
  end

  // Clock Divisor Generation
  initial begin : CLK_DIVISOR_IN_PROC
    #20000;
    clk_divisor = 5'b00001;
    #10000;
    clk_divisor = 5'b00010;
    #10000;
    clk_divisor = 5'b00011;
    #10000;
    clk_divisor = 5'b00111;
  end

  // Counter Enable Generation
  initial begin : COUNTER_EN_PROC
    cntr_en = #20000 1'b1;
  end

  // Up Down Enable Generation
  initial begin : UP_DOWN_ENABLE_IN_PROC
    #20000;
    up_down_cntr_en = 1'b0;
    #10000;
    up_down_cntr_en = 1'b1;
    #10000;
    up_down_cntr_en = 1'b1;
    #10000;
    up_down_cntr_en = 1'b0;
  end

  // Match Value Generation
  initial begin : MATCH_VALUE_IN_PROC
    #20000;
    match_val = 4'b1000;
    #10000;
    match_val = 4'b0111;
    #10000;
    match_val = 4'b1110;
    #10000;
    match_val = 4'b1010;
  end

endmodule


--------------------------------------------------------------------------------------------------------------------------

//  Verilog  Structural code for Magic_counter

/*Verilog code for 3 module circuit*/

//Module-1
module magic_counter_str ( clk_in,
                           reset_n,
                           clk_divisor,
                           cntr_en,                      
                           up_down_cntr_en,
                           match_val,
                           clk_div,
                           up_down_cnt,
                           match_en,
                           magic_cntr);

  input            clk_in;
  input             reset_n;
  input   [4:0]  clk_divisor;
  input             cntr_en;
  input              up_down_cntr_en;
  input   [3:0]   match_val;
  output           clk_div;
  output  [3:0] up_down_cnt;
  output           match_en;
  output  [3:0] magic_cntr;
     
  wire          clk_div;
  wire [3:0] up_down_cnt;
  wire          match_en;
  wire [3:0] magic_cntr;

  // Clock divider Module-1
  clk_divider U_CLK_DIVIDER
  (
    .clk_in      (clk_in),
    .reset_n     (reset_n),
    .clk_divisor (clk_divisor),
    .clk_div     (clk_div)
  );

  // Up-Down Counter Module-2
  up_down_cntr U_UP_DOWN_CNTR
  (
    .clk_in          (clk_in),
    .reset_n         (reset_n),
    .clk_div         (clk_div),
    .cntr_en         (cntr_en),
    .up_down_cntr_en (up_down_cntr_en),
    .match_val       (match_val),
    .up_down_cnt     (up_down_cnt),
    .match_en        (match_en)
  );
 
  // Magic_Counter Module-3
  magic_counter U_MAGIC_COUNTER
  (
    .clk_in     (clk_in),
    .reset_n    (reset_n),
    .clk_div    (clk_div),
    .cntr_en    (cntr_en),
    .match_en   (match_en),
    .magic_cntr (magic_cntr)
  );    
     
endmodule
     
-------------------------------------------------------------------------------------------------------------------------------



No comments:

Post a Comment