URL
https://opencores.org/ocsvn/common/common/trunk
Subversion Repositories common
[/] [common/] [trunk/] [grey_to_binary.v] - Rev 48
Compare with Previous | Blame | View Log
////////////////////////////////////////////////////////////////////// //// //// //// 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