OpenCores
URL https://opencores.org/ocsvn/common/common/trunk

Subversion Repositories common

[/] [common/] [trunk/] [grey_to_binary.v] - Diff between revs 18 and 48

Show entire file | Details | Blame | View Log

Rev 18 Rev 48
Line 1... Line 1...
 
//////////////////////////////////////////////////////////////////////
 
////                                                              ////
 
//// grey_to_binary #(N), binary_to_grey #(N)                     ////
 
////                                                              ////
 
//// This file is part of the general opencores effort.           ////
 
//// <http://www.opencores.org/cores/misc/>                       ////
 
////                                                              ////
 
//// Module Description:                                          ////
 
////    Example of how to convert Grey Code to Binary.            ////
 
////    Example of how to convert Binary to Grey Code.            ////
 
////                                                              ////
 
//// CRITICAL USAGE NOTE:                                         ////
 
////    These functions produce combinational outputs which       ////
 
////      have glitches.  To use these safely, the outputs        ////
 
////      must be latched using the same clock before and         ////
 
////      after the combinational function.                       ////
 
////                                                              ////
 
////    There are other sequences of numbers which share the      ////
 
////      property of Grey Code that only 1 bit transitions per   ////
 
////      value change.                                           ////
 
////    The sequence 0x00, 0x1, 0x3, 0x2, 0x6, 0x4 is one such    ////
 
////      sequence.                                               ////
 
////    It should be possible to make a library which counts      ////
 
////      in sequences less than 2**n long, yet which still       ////
 
////      change only 1 bot per increment.                        ////
 
////                                                              ////
 
//// To Do:                                                       ////
 
//// Might make this handle more than 16 bits.                    ////
 
////                                                              ////
 
//// Author(s):                                                   ////
 
//// - Anonymous                                                  ////
 
////                                                              ////
 
//////////////////////////////////////////////////////////////////////
 
////                                                              ////
 
//// Copyright (C) 2000 Anonymous and OPENCORES.ORG               ////
 
////                                                              ////
 
//// This source file may be used and distributed without         ////
 
//// restriction provided that this copyright statement is not    ////
 
//// removed from the file and that any derivative work contains  ////
 
//// the original copyright notice and the associated disclaimer. ////
 
////                                                              ////
 
//// This source file is free software; you can redistribute it   ////
 
//// and/or modify it under the terms of the GNU Lesser General   ////
 
//// Public License as published by the Free Software Foundation; ////
 
//// either version 2.1 of the License, or (at your option) any   ////
 
//// later version.                                               ////
 
////                                                              ////
 
//// This source is distributed in the hope that it will be       ////
 
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
 
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
 
//// PURPOSE. See the GNU Lesser General Public License for more  ////
 
//// details.                                                     ////
 
////                                                              ////
 
//// You should have received a copy of the GNU Lesser General    ////
 
//// Public License along with this source; if not, download it   ////
 
//// from <http://www.opencores.org/lgpl.shtml>                   ////
 
////                                                              ////
 
//////////////////////////////////////////////////////////////////////
 
//
 
// $Id: grey_to_binary.v,v 1.5 2001-10-22 12:29:08 bbeaver Exp $
 
//
 
// CVS Revision History
 
//
 
// $Log: not supported by cvs2svn $
 
// Revision 1.3  2001/09/03 12:12:44  Blue Beaver
 
// no message
 
//
 
// Revision 1.2  2001/09/03 12:09:24  Blue Beaver
 
// no message
 
//
 
//
 
 
 
`timescale 1ns/1ps
 
 
 
// Convert 2-bit up to 16-bit binary value into same sized grey-code value
 
 
 
module bin_to_grey_code (
 
  grey_code_out,
 
  binary_in
 
);
 
  parameter NUM_BITS = 1;  // instantiate as "bin_to_grey_code #(width) instance ()"
 
 
 
  output [NUM_BITS - 1 : 0] grey_code_out;
 
  input  [NUM_BITS - 1 : 0] binary_in;
 
 
 
// Consider the sequences
 
//   Binary  Grey Code
 
//     00       00
 
//     01       01
 
//     10       11
 
//     11       10
 
// It seems that G[1] = B[1], and G[0] = B[1] ^ B[0];
 
// Now consider the sequences
 
//   Binary  Grey Code
 
//     000      000
 
//     001      001
 
//     010      011
 
//     011      010
 
//     100      110
 
//     101      111
 
//     110      101
 
//     111      100
 
// It seems that G[2] = B[2], and
 
//               G[1] = B[2] ^ B[1], and
 
//               G[0] = B[1] ^ B[0];
 
//
 
// But how to write that using a parameter?  Well, instead of
 
//   figuring it out, how about just making something which works
 
//   for a range of widths, like 2 to 16?
 
 
 
  wire   [15:0] widened_input = {binary_in[NUM_BITS - 1 : 0], {16 - NUM_BITS{1'b0}}};
 
 
 
  wire   [15:0] widened_output = {
 
                      widened_input[15],
 
                      widened_input[15] ^ widened_input[14],
 
                      widened_input[14] ^ widened_input[13],
 
                      widened_input[13] ^ widened_input[12],
 
                      widened_input[12] ^ widened_input[11],
 
                      widened_input[11] ^ widened_input[10],
 
                      widened_input[10] ^ widened_input[9],
 
                      widened_input[9]  ^ widened_input[8],
 
                      widened_input[8]  ^ widened_input[7],
 
                      widened_input[7]  ^ widened_input[6],
 
                      widened_input[6]  ^ widened_input[5],
 
                      widened_input[5]  ^ widened_input[4],
 
                      widened_input[4]  ^ widened_input[3],
 
                      widened_input[3]  ^ widened_input[2],
 
                      widened_input[2]  ^ widened_input[1],
 
                      widened_input[1]  ^ widened_input[0]
 
                  };
 
 
 
  assign  grey_code_out[NUM_BITS - 1 : 0] = widened_output[15 : 16 - NUM_BITS];
 
 
 
// synopsys translate_off
 
  initial
 
  begin
 
    if (NUM_BITS < 2)
 
    begin
 
      $display ("*** Exiting because %m bin_to_grey_code Number of bits %d < 2",
 
                   NUM_BITS);
 
      $finish;
 
    end
 
    if (NUM_BITS > 16)
 
    begin
 
      $display ("*** Exiting because %m bin_to_grey_code Number of bits %d > 16",
 
                   NUM_BITS);
 
      $finish;
 
    end
 
  end
 
// synopsys translate_on
 
endmodule
 
 
 
// Convert 2-bit up to 16-bit binary value into same sized grey-code value
 
 
 
module grey_code_to_bin (
 
  binary_out,
 
  grey_code_in
 
);
 
  parameter NUM_BITS = 1;  // instantiate as "grey_code_to_bin #(width) instance ()"
 
 
 
  output [NUM_BITS - 1 : 0] binary_out;
 
  input  [NUM_BITS - 1 : 0] grey_code_in;
 
 
 
// Consider the sequences
 
//   Grey Code   Binary
 
//       00        00
 
//       01        01
 
//       11        10
 
//       10        11
 
// It seems that B[1] = G[1], and B[0] = G[1] ^ G[0];
 
// Now consider the sequences
 
//   Grey Code   Binary
 
//      000       000
 
//      001       001
 
//      011       010
 
//      010       011
 
//      110       100
 
//      111       101
 
//      101       110
 
//      100       111
 
// It seems that B[2] = G[2], and
 
//               B[1] = G[2] ^ G[1], and
 
//               B[0] = G[2] ^ G[1] ^ G[0];
 
//
 
// But how to write that using a parameter?  Well, instead of
 
//   figuring it out, how about just making something which works
 
//   for a range of widths, like 2 to 16?
 
 
 
  wire   [15:0] widened_input = {grey_code_in[NUM_BITS - 1 : 0], {16 - NUM_BITS{1'b0}}};
 
  wire    xor_15_12 = widened_input[15] ^ widened_input[14]
 
                    ^ widened_input[13] ^ widened_input[12];
 
  wire    xor_11_10 = widened_input[11] ^ widened_input[10];
 
  wire    xor_11_8  = widened_input[11] ^ widened_input[10]
 
                    ^ widened_input[9]  ^ widened_input[8];
 
  wire    xor_7_6   = widened_input[7]  ^ widened_input[6];
 
  wire    xor_7_4   = widened_input[7]  ^ widened_input[6]
 
                    ^ widened_input[5]  ^ widened_input[4];
 
  wire    xor_3_2   = widened_input[3]  ^ widened_input[2];
 
  wire    xor_1_0   = widened_input[1]  ^ widened_input[0];
 
 
 
  wire   [15:0] widened_output = {
 
                      widened_input[15],
 
                      widened_input[15] ^ widened_input[14],
 
                      widened_input[15] ^ widened_input[14] ^ widened_input[13],
 
                      xor_15_12,
 
                      xor_15_12 ^ widened_input[11],
 
                      xor_15_12 ^ xor_11_10,
 
                      xor_15_12 ^ xor_11_10 ^ widened_input[9],
 
                      xor_15_12 ^ xor_11_8,
 
                      xor_15_12 ^ xor_11_8 ^ widened_input[7],
 
                      xor_15_12 ^ xor_11_8 ^ xor_7_6,
 
                      xor_15_12 ^ xor_11_8 ^ xor_7_6 ^ widened_input[5],
 
                      xor_15_12 ^ xor_11_8 ^ xor_7_4,
 
                      xor_15_12 ^ xor_11_8 ^ xor_7_4 ^ widened_input[3],
 
                      xor_15_12 ^ xor_11_8 ^ xor_7_4 ^ xor_3_2,
 
                      xor_15_12 ^ xor_11_8 ^ xor_7_4 ^ xor_3_2 ^ widened_input[1],
 
                      xor_15_12 ^ xor_11_8 ^ xor_7_4 ^ xor_3_2 ^ xor_1_0
 
                  };
 
 
 
  assign  binary_out[NUM_BITS - 1 : 0] = widened_output[15 : 16 - NUM_BITS];
 
 
 
// synopsys translate_off
 
  initial
 
  begin
 
    if (NUM_BITS < 2)
 
    begin
 
      $display ("*** Exiting because %m grey_code_to_bin Number of bits %d < 2",
 
                   NUM_BITS);
 
      $finish;
 
    end
 
    if (NUM_BITS > 16)
 
    begin
 
      $display ("*** Exiting because %m grey_code_to_bin Number of bits %d > 16",
 
                   NUM_BITS);
 
      $finish;
 
    end
 
  end
 
// synopsys translate_on
 
endmodule
 
 
 
 `define TEST_GREY_CODE
 
`ifdef TEST_GREY_CODE
 
module test_grey_code;
 
  reg    [7:0] test_val;
 
  wire   [1:0] grey_2;
 
  wire   [2:0] grey_3;
 
  wire   [3:0] grey_4;
 
 
 
  wire   [1:0] bin_2;
 
  wire   [2:0] bin_3;
 
  wire   [3:0] bin_4;
 
 
 
  initial
 
  begin
 
    for (test_val = 8'h00; test_val < 8'h04; test_val = test_val + 8'h01)
 
    begin
 
      # 0; $display ("test val, result %x %x %x", test_val[1:0], grey_2[1:0], bin_2[1:0]);
 
      if (test_val[1:0] !== bin_2[1:0])
 
        $display ("*** Encode, Decode failed %x %x", test_val[1:0], bin_2[1:0]);
 
    end
 
    $display (" ");
 
    for (test_val = 8'h00; test_val < 8'h08; test_val = test_val + 8'h01)
 
    begin
 
      # 0; $display ("test val, result %x %x %x", test_val[2:0], grey_3[2:0], bin_3[2:0]);
 
      if (test_val[2:0] !== bin_3[2:0])
 
        $display ("*** Encode, Decode failed %x %x", test_val[2:0], bin_3[2:0]);
 
    end
 
    $display (" ");
 
    for (test_val = 8'h00; test_val < 8'h10; test_val = test_val + 8'h01)
 
    begin
 
      # 0; $display ("test val, result %x %x %x", test_val[3:0], grey_4[3:0], bin_4[3:0]);
 
      if (test_val[3:0] !== bin_4[3:0])
 
        $display ("*** Encode, Decode failed %x %x", test_val[3:0], bin_4[3:0]);
 
    end
 
 
 
  end
 
 
 
bin_to_grey_code #(2) bin_to_grey_code_2 (
 
  .grey_code_out              (grey_2[1:0]),
 
  .binary_in                  (test_val[1:0])
 
);
 
bin_to_grey_code #(3) bin_to_grey_code_3 (
 
  .grey_code_out              (grey_3[2:0]),
 
  .binary_in                  (test_val[2:0])
 
);
 
bin_to_grey_code #(4) bin_to_grey_code_4 (
 
  .grey_code_out              (grey_4[3:0]),
 
  .binary_in                  (test_val[3:0])
 
);
 
 
 
grey_code_to_bin #(2) grey_code_to_bin_2 (
 
  .binary_out                 (bin_2[1:0]),
 
  .grey_code_in               (grey_2[1:0])
 
);
 
grey_code_to_bin #(3) grey_code_to_bin_3 (
 
  .binary_out                 (bin_3[2:0]),
 
  .grey_code_in               (grey_3[2:0])
 
);
 
grey_code_to_bin #(4) grey_code_to_bin_4 (
 
  .binary_out                 (bin_4[3:0]),
 
  .grey_code_in               (grey_4[3:0])
 
);
 
 
 
endmodule
 
`endif  // TEST_GREY_CODE
 
 
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.