VIEWS: 5,386 PAGES: 16 CATEGORY: Education POSTED ON: 12/30/2009
CMOS hamming code encoder and decoder Verilog programs by N.G.Radhakrishna.Padala
CMOS HAMMING CODE ENCODER AND DECODER The main aspect of this hamming encoder and decoder is to know how a code can be encoded and decoded using Hamming code. To analyse this here I’m using Verilog software, here the waveforms observed which are explaining us operation of encoder and decoder. For better understanding first lets know about Hamming code and how it encodes and decodes a code. In the late 1940s Richard Hamming at Bell labs recognized that the further evolution of computers required greater reliability, in particular the ability to detect and correct errors. (At the time, parity checking was being used to detect errors, but was unable to correct any errors.) He created the, Hamming Codes, perfect 1-error correcting codes, and the extended Hamming Codes, 1-error correcting and 2-error detecting codes. Hamming Codes are still widely used in computing, telecommunication, and other applications including data compression. Hamming studied the existing coding schemes, including two-of-five, and generalized their concepts. To start with he developed a nomenclature to describe the system, including the number of data bits and error-correction bits in a block. For instance, parity includes a single bit for any data word, so assuming ASCII words with 7-bits, Hamming described this as an (8,7) code, with eight bits in total, of which 7 are data. Hamming also noticed the problems with flipping two or more bits, and described this as the "distance" (it is now called the Hamming Distance. Parity has a distance of 2, as any two bit flips will be invisible. The (3,1) repetition has a distance of 3, as three bits need to be flipped in the same triple to obtain another code word with no visible errors. Hamming was interested in two problems at once; increasing the distance as much as possible, while at the same time increasing the information rate as much as possible General algorithm The following general Hamming code algorithm positions the parity bits at powers of two to ease calculation of which bit was flipped upon detection of incorrect parity. 1. All bit positions that are powers of two are used as parity bits. (Positions 1, 2, 4, 8, 16, 32, 64, etc.) 2. All other bit positions are for the data to be encoded. (Positions 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, etc.), each parity bit calculates the parity for some of the bits in the code word. The position of the parity bit determines the sequence of bits that it alternately checks and skips. Position 1 (n=1): skip 0 bits (0=n−1), check 1 bit (n), skip 1 bit (n), check 1 bit (n), skip 1 bit (n), etc. (1,3,5,7,9,11,13,15,...) Position 2 (n=2): skip 1 bit (1=n−1), check 2 bits (n), skip 2 bits (n), check 2 bits (n), skip 2 bits (n), etc. (2,3,6,7,10,11,14,15,...) Position 4 (n=4): skip 3 bits (3=n−1), check 4 bits (n), skip 4 bits (n), check 4 bits (n), skip 4 bits (n), etc. (4,5,6,7,12,13,14,15,20,21,22,23,...) Position 8 (n=8): skip 7 bits (7=n−1), check 8 bits (n), skip 8 bits (n), check 8 bits (n), skip 8 bits (n), etc. (8-15,24-31,40-47,...) 1 Position 16 (n=16): skip 15 bits (15=n−1), check 16 bits (n), skip 16 bits (n), check 16 bits (n), skip 16 bits (n), etc. (16-31,48-63,80-95,...) Position 32 (n=32): skip 31 bits (31=n−1), check 32 bits (n), skip 32 bits (n), check 32 bits (n), skip 32 bits (n), etc. (32-63,96-127,160-191,...) General rule for position n: skip n−1 bits, check n bits, skip n bits, check n bits... And so on. In other words, the parity bit at position 2k checks bits in positions having bit k set in their binary representation. Conversely, for instance, bit 13, i.e. 1101(2), is checked by bits 1000(2) = 8, 0100(2)=4 and 0001(2) = 1. Calculating the Hamming Code The key to the Hamming Code is the use of extra parity bits to allow the identification of a single error. Create the code word as follows: 1. Mark all bit positions that are powers of two as parity bits. (Positions 1, 2, 4, 8, 16, 32, 64, etc.) 2. All other bit positions are for the data to be encoded. (Positions 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, etc.) 3. Each parity bit calculates the parity for some of the bits in the code word. The position of the parity bit determines the sequence of bits that it alternately checks and skips. Position 1: check 1 bit, skip 1 bit, check 1 bit, skip 1 bit, etc. (1,3,5,7,9,11,13,15,...) Position 2: check 2 bits, skip 2 bits, check 2 bits, skip 2 bits, etc. (2,3,6,7,10,11,14,15,...) Position 4: check 4 bits, skip 4 bits, check 4 bits, skip 4 bits, etc. (4,5,6,7,12,13,14,15,20,21,22,23,...) Position 8: check 8 bits, skip 8 bits, check 8 bits, skip 8 bits, etc. (8-15,24-31,4047,...) Position 16: check 16 bits, skip 16 bits, check 16 bits, skip 16 bits, etc. (16-31,4863,80-95,...) Position 32: check 32 bits, skip 32 bits, check 32 bits, skip 32 bits, etc. (32-63,96127,160-191,...) etc. 4. Set a parity bit to 1 if the total number of ones in the positions it checks is odd. Set a parity bit to 0 if the total number of ones in the positions it checks is even. For example let’s consider the following: A byte of data: 10011010 lets Create the data word, leaving spaces for the parity bits: _ _ 1 _ 0 0 1 _ 1 0 1 0 and Calculate the parity for each parity bit “x” represents the bit position being set. Position 1 checks bits 1, 3,5,7,9, 11: x_ 1 _ 0 0 1 _ 1 0 1 0. Even parity so set position 1 to a 0: 0 _ 1 _ 0 0 1 _ 1 0 1 0 Position 2 checks bits 2,3,6,7,10,11: 0 x 1 _ 0 0 1 _ 1 0 1 0. Odd parity so set position 2 to a 1: 0 1 1 _ 0 0 1 _ 1 0 1 0 2 Position 4 checks bits 4,5,6,7,12: 0 1 1 x 0 0 1 _ 1 0 1 0. Odd parity so set position 4 to a 1: 0 1 1 1 0 0 1 _ 1 0 1 0 Position 8 checks bits 8,9,10,11,12: 0 1 1 1 0 0 1 x 1 0 1 0. Even parity so set position 8 to a 0: 0 1 1 1 0 0 1 0 1 0 1 0 Code word: 011100101010. Algorithm for Hamming Decoder: To implement a basic Algorithm for decoder, it is necessary to develop a scheme for dynamic calculation of Hamming Distances and Next State/Previous State outputs. To do this, one can assign two variables to each state in the Trellis Diagram (as illustrated above) – one to calculate the minimum path metric (total Hamming Distances) to that point so far and the other to record the previous state input/output transition pair. The first of the two variables can be used to ultimately calculate the minimum path metric to the final state (most probabilistic path) and the second variable could be used in the Path Determination walkup (to regenerate the inputs from our output pairs). Once the minimum path is determined, a series of comparisons can be done to work backwards from the ending point to the origination point via the most probabilistic path. This would yield our original sequence. With the algorithm implemented we could then check it by introducing errors at different parts along the trellis, increasing the probabilistic likelihood of an error to test the accuracy of the algorithm. For a single instance (1-bit) error starting from an input of (00000) we can generate 10 possible sequences. A function can be written to run each of these 10 errorcontaining sequences through our decoder and to measure the resultant effect on the output. From this data it would be seen that every sequences would be correctly decoded, as the Viterbi algorithm would work absolutely under that configuration. Complementary metal–oxide–semiconductor (CMOS): CMOS technology is used in Microprocessors, Static RAM and other Digital logic circuits. CMOS technology is also used for a wide variety of analoge circuits such as image sensors, data convertors, and highly integrated transreceivers for many types of communication. Frank .Wanlass successfully patented CMOS in 1967.CMOS is a combinational circuit of p-mos and n-mos. CMOS was also sometimes referred to as complementary-symmetry metal–oxide–semiconductor. The words "complementary-symmetry" refer to the fact that the typical digital design style with CMOS uses complementary and symmetrical pairs of p-type and n-type metal oxide semiconductor field effect transistors (MOSFETs) for logic functions. 3 Two important characteristics of CMOS devices are high noise immunity and low static low power consumption. Significant power is only drawn when the transistors in the CMOS device are switching between on and off states. Consequently, CMOS devices do not produce as much waste heat as other forms of logic, for example transistor-transistor (TTL) or NMOS logic, which uses all n-channel devices without p-channel devices. CMOS also allows a high density of logic functions on a chip. Composition: The main principle behind CMOS circuits that allows them to implement logic gates is the use of p-type and n-type mosfet to create paths to the output from either the voltage source or ground. When a path to output is created from the voltage source, the circuit is said to be pulled up. On the other hand, the circuit is said to be pulled down when a path to output is created from ground Inversion: CMOS circuits are constructed so that all PMOS transistors must have either an input from the voltage source or from another PMOS transistor. Similarly, all NMOS transistors must have either an input from ground or from another NMOS transistor. The composition of a PMOS transistor creates low resistance when a low voltage is applied to it and high resistance when a high voltage is applied to it. On the other hand, the composition of an NMOS transistor creates high resistance when a low voltage is applied to it and low resistance when a high voltage is applied to it. The image on the right shows what happens when an input is connected to both a PMOS transistor and an NMOS transistor. When the voltage of input A is low, the NMOS transistor has high resistance so it stops voltage from leaking into ground, while the PMOS transistor has low resistance so it allows the voltage source to transfer voltage through the PMOS transistor to the output. The output would therefore register a high voltage. On the other hand, when the voltage of input A is high, the PMOS transistor would have high resistance so it would block voltage source from the output, while the NMOS transistor would have low resistance allowing the output to drain to ground. This would result in the output registering a low voltage. In short, the outputs of the PMOS and NMOS transistors are complementary such that when the input is low, the output would be high, and when the input is high, the output would be low. Because of this, the CMOS circuits' output is by default the inversion of the input. Duality: An important characteristic of a CMOS circuit is the duality that exists between its PMOS transistors and NMOS transistors. A CMOS circuit is created so that a path would always exist from the output to either the power source or ground. In order to accomplish this, the set of all paths to the voltage source must be the complement of the set of all paths to ground. This can be easily accomplished by defining one in terms of the NOT of the other. The logic works out through De Morgan’s laws such that the PMOS transistors in parallel have corresponding NMOS transistors in series while the PMOS transistors in series have corresponding NMOS transistors in parallel. Logic: More complex logic functions such as those involving AND and OR gates require manipulating the paths between gates to represent the logic. When a path consists of two transistors in series, then both transistors must have low resistance for voltage to pass, modelling an AND. When a path consists of two transistors in parallel, then either one or both of the transistors must have low resistance for voltage to pass, modelling an OR. 4 CMOS NAND GATE A circuit diagram shown above is a NAND gate in CMOS logic. If both of the A and B inputs are high, then both the NMOS transistors (bottom half of the diagram) will conduct, neither of the PMOS transistors (top half) will conduct, and a conductive path will be established between the output and Vss (ground), bringing the output low. If either of the A or B inputs is low, one of the NMOS transistors will not conduct, one of the PMOS transistors will, and a conductive path will be established between the output and Vdd (voltage source), bringing the output high. An advantage of CMOS over NMOS is that both low-to-high and high-to-low output transitions are fast since the pull-up transistors have low resistance when switched on, unlike the load resistors in NMOS logic. In addition, the output signal swings the full voltage between the low and high rails. This strong, more nearly symmetric response also makes CMOS more resistant to noise. Future of CMOS Technology: The key to understanding the future of CMOS technology is to understand the factors influencing the cost per function. CMOS will continue to dominate and evolve as long as the net cost per function drops. This paper therefore considers the key elements behind this trend: 1. Lithography to enable the manufacturing of components with smaller dimensions. As Moore pointed out, this is the single greatest factor in increasing the number of components per chip. 2. Proper transistor design to achieve higher performance at smaller dimensions as well as innovative layout to gain density. 3. More effective interconnections to increase the component density. 4. New circuit families. 5. Innovative, denser memory cells. 6. More productive design processes. 7. Manageable capital costs Layout: layout is the process of defining the geometry of various masks required for fabrication of microcircuit. After a circuit is laid out, the circuit elements such as transistors, parasitic capacitances, and resistances are extracted and used in two types of simulations: a transistor-level simulation using SPICE variants, and a switch-level simulation using programs such as IRSIM. The former is suitable for determining accurate dynamic characteristics of a small circuit, whereas the latter is a more feasible in verifying the logic functionality of a large digital circuit. 5 Block Diagram of hamming Encoder and Decoder [Peter minns & E ion illots] Here the above figure shows us procedure diagram for hamming code encoder and decoder. First a code is taken, encoded, after this before decoding we just add an error through an Error injector. This injects an error to which the code to be decoded. Hamming detects and corrects single errors, but it can only detect double error and cannot correct the code. It is main limitation of Hamming code. If we introduced double error then it simply generates a show in detection “0” waveform which indicates no operation is done. The simulating programs are shown for each sections. Code for verilog Design Code for Hamming Encoder: module Hamenc8(Data, Parout); input [7:0] Data; output [4:0] Parout; //define masks to select bits to xor for each parity localparam MaskP1 = 8'b01011011; localparam MaskP2 = 8'b01101101; localparam MaskP4 = 8'b10001110; localparam MaskP8 = 8'b11110000; assign Parout[4:1] = {^(Data & MaskP8), ^(Data & MaskP4), ^(Data & MaskP2), ^(Data & MaskP1)}; assign Parout[0] = ^{Parout[4:1], Data}; endmodule 6 Code Error injecting code: module InjectError(Din,Pin,Dout,Pout,Ein); input [7:0] Din; input [4:0] Pin; output [7:0] Dout; output [4:0] Pout; input [12:0] Ein; assign {Dout, Pout} = {Din, Pin} ^ Ein; endmodule Code for Hamming Decoder: module Hamdec8(Datain, Parin, Dataout, Parout, NE, DED, SEC); input [7:0] Datain; input [4:0] Parin; output [7:0] Dataout; reg [7:0] Dataout; output [4:0] Parout; reg [4:0] Parout; output NE, DED, SEC; reg NE, DED, SEC; //define masks to select bits to xor for each parity parameter MaskP1 = 8'b01011011; parameter MaskP2 = 8'b01101101; parameter MaskP4 = 8'b10001110; parameter MaskP8 = 8'b11110000; reg [4:1] synd; reg P0; always @(Datain or Parin) begin //assign default outputs (assumes no errors) NE = 1'b1; DED = 1'b0; SEC = 1'b0; Dataout = Datain; Parout = Parin; P0 = ^{Parin, Datain}; //overall parity 7 //generate syndrome bits synd[4] = (^(Datain & MaskP8))^Parin[4]; synd[3] = (^(Datain & MaskP4))^Parin[3]; synd[2] = (^(Datain & MaskP2))^Parin[2]; synd[1] = (^(Datain & MaskP1))^Parin[1]; if ((synd == 0) && (P0 == 1'b0)) //no errors ; //accept default o/p else if (P0 == 1'b1) //single error (or odd no of errors!) begin NE = 1'b0; SEC = 1'b1; //correct single error case (synd) 0 : Parout[0] = ~Parin[0]; 1 : Parout[1] = ~Parin[1]; 2 : Parout[2] = ~Parin[2]; 3 : Dataout[0] = ~Datain[0]; 4 : Parout[3] = ~Parin[3]; 5 : Dataout[1] = ~Datain[1]; 6 : Dataout[2] = ~Datain[2]; 7 : Dataout[3] = ~Datain[3]; 8 : Parout[4] = ~Parin[4]; 9 : Dataout[4] = ~Datain[4]; 10 : Dataout[5] = ~Datain[5]; 11 : Dataout[6] = ~Datain[6]; 12 : Dataout[7] = ~Datain[7]; default : begin Dataout = 8'b00000000; Parout = 5'b00000; end endcase end else if ((P0 == 0) && (synd != 4'b0000)) //double error begin NE = 1'b0; DED = 1'b1; Dataout = 8'b00000000; Parout = 5'b00000; end end //always endmodule 8 Code for Test Bench: `timescale 1ns / 1ps module test_hamming(); // Inputs to encoder reg [7:0] Data; //output of encoder wire [4:0] Par; //error injector input and outputs reg [12:0] Error; wire [7:0] EData; wire [4:0] EPar; // Outputs from decoder wire DED; wire NE; wire SEC; wire [7:0] Dataout; wire [4:0] Parout; // Instantiate the modules Hamenc8 U1 (.Data(Data), .Parout(Par)); InjectError U3 (.Din(Data), .Ein(Error), .Pin(Par), .Dout(EData), .Pout(EPar)); Hamdec8 U2 (.Datain(EData), .Parin(EPar), .Dataout(Dataout), .DED(DED), .NE(NE), .Parout(Parout), .SEC(SEC)); initial //apply inputs begin Data = 0; repeat (256) #100 Data = Data + 1; stop; 9 end initial //inject errors begin Error = 13'b0000000000000; #200; Error = 13'b0000000000001; #200; forever #200 Error = {Error[11:0], Error[12]}; end endmodule Explanation of Encoder code: In the operation of encoder here we are using 8-bit encoder. The code module hammenc8 is provided to generate parity check bits from an incoming 8-bit data. The check bits attached are 13 bits, this gives us error correcting and detecting. From the program Line2 and 3 defines module header for the encoder, the output parout is asset of five parity check bit generated by performing the ex-or operation on the subsets of the incoming 8-bit data value appearing on input port Data. The bits of the input data that are to be ex-or together are defined by a set of marks declared as local parameters on line 5 to 8. The local param key word allows the definition of parameters or constant values that are local to the enclosing module , i.e they cannot be overridden by external values. 10 Simulation Waveform of result: Code for Gate level Implantation: //gate level logic circuit code module Hamenc(Data, Parout); input [7:0] Data; output [4:0] Parout; wire A1,A2,A3,A4,A5,A6,B1,B2,B3,B4,B5,B6,B7,B8,C1,C2,C3,C4,C5;//signals xor x1(A1,Data[0],Data[1]); xor x2(A2,Data[3],Data[6]); xor x3(A3,Data[2],Data[5]); xor x4(A4,B2,B6); xor x5(A5,Parout[3],Parout[4]); xor x6(A6,Parout[1],Parout[2]); xor x7(B1,Data[6],Data[5]); xor x8(B2,Data[4],Data[7]); xor x9(B3,Data[1],Data[7]); xor x10(B4,Data[2],Data[3]); xor x11(B5,Data[0],B1); xor x12(B6,A1,A2); 11 xor x13(B7,A4,A3); xor x14(B8,A5,A6); xor x15(Parout[4],B1,B2); xor x16(Parout[3],B3,B4); xor x17(Parout[2],B5,B4); xor x18(Parout[1],Data[4],B6); xor x19(Parout[0],B7,B8); endmodule Simulation results for Gate Level: 12 Schematic Diagram for Gate level implementation: Code for switch level //gate level logic circuit code module Hamenc(Data, Parout); input [7:0] Data; output [4:0] Parout; wire A1,A2,A3,A4,A5,A6,B1,B2,B3,B4,B5,B6,B7,B8,C1,C2,C3,C4,C5;//signals xor1 x1(A1,Data[0],Data[1]); xor1 x2(A2,Data[3],Data[6]); xor1 x3(A3,Data[2],Data[5]); xor1 x4(A4,B2,B6); xor1 x5(A5,Parout[3],Parout[4]); xor1 x6(A6,Parout[1],Parout[2]); xor1 x7(B1,Data[6],Data[5]); xor1 x8(B2,Data[4],Data[7]); xor1 x9(B3,Data[1],Data[7]); xor1 x10(B4,Data[2],Data[3]); xor1 x11(B5,Data[0],B1); xor1 x12(B6,A1,A2); xor1 x13(B7,A4,A3); xor1 x14(B8,A5,A6); xor1 x15(Parout[4],B1,B2); xor1 x16(Parout[3],B3,B4); 13 xor1 x17(Parout[2],B5,B4); xor1 x18(Parout[1],Data[4],B6); xor1 x19(Parout[0],B7,B8); endmodule code for calling functions nand and x-or: Nand: module nand1(output C3, input C,Ci); wire q1; supply0 gnd supply1 vdd pmos n1(C3,vdd,C); pmos n1(C3,vdd,Ci); nmos n2(C3,q1,C); nmos n2(q1,gnd,Ci); endmodule X-OR module xor1(output c, input a,b); wire d1,d2,d3; nand1 a1(d1,a,b); nand1 a2(d2,d1,a); nand1 a3(d3,d1,b); nand1 a4(c,a,b); endmodule In the switch level coding to convert the gate level into switch level coding , I just converted X-or and Nand gate operations into switch i.e. I written switch level description to them then the I called these two gates to the main program , so thus the whole program Is converted to the switch level. 14 Simulation results for switch level : By comparing the all (test bench hamming encoder and Gate level code and switch level code) results, I observed that they all are same. Propagation Delay: The propagation delay of a gate is the average transition delay-time for the signal to propagate from input to the output , when the binary signal changes in value .The signal through gate take a certain amount of time to propagate from inputs to output. This interval of time is define as the propagation delay of the gate. Propagation delay is measured in nanoseconds .The signal that travel from the input of a digital circuit to its outputs pass through a series of gates. The sum of the propagation delays through the gates is the total delay of the circuit. When speed of operation is important, each gate must have a short propagation delay and digital circuit must have a min number of gates b/w inputs and outputs. The average propagation delay of the gate is calculated from the input and output waveforms. The signal-delay time b/w the input and output when the output changes from low to high level , the delay is t. It is customary to measure the time b/w 50% point on the 15 input and output transitions. The average propagation time delay is calculated by taking the average of the two delays. Conclusion: In this assignment we simulated, (i)Verilog design (ii)Gate level design (iii) Converted the gate level into switch level and simulated this switch level description and discussed the propagation delay of the gates. Finally we can conclude that all the simulation results are the same. From all these results we have seen that How Hamming encoder works and I came to know that Hamming code can only detect and correct the single errors , but cannot correct double error , even though it can detect the error. References: (1) Morris mano et al.,(2007),Digital design;4th edn,Prentis hall,London. (2) Peter Minns and Ian Elliot ,(2008);FSM based Digital design using verilog HDL,John willy&sons .U.S.A (3) Wakerly .J (1990); Digital design –Principals and practices,4th edn, (4) Hamming R,(1950).Error correcting and detecting codes 16