Gray code is a binary code where each successive value differs from the previous value by only one bit.

## Implementation #1

```
module bin2gray #(parameter N=4) ( input [N-1:0] bin,
output [N-1:0] gray);
genvar i;
generate
for(i = 0; i < N-1; i = i + 1) begin
assign gray[i] = bin[i] ^ bin[i+1];
end
endgenerate
assign gray[N-1] = bin[N-1];
endmodule
```

Gray code, also known as Gray binary code or reflected binary code, is a binary numeral system where adjacent values differ by only one bit. In other words, Gray code is a binary code where each successive value differs from the previous value by only one bit.

For example, the binary representation of decimal numbers 1 and 2 is 0001 and 0010 respectively. Note that two LSB bits (bit#0 and bit#1) have to change for the transition from 1 to 2. In Gray code, 1 and 2 are represented by 0001 and 0011 respectively but the same transition now requires only a change of one bit (bit#1 from LSB).

A shift register is a sequential digital circuit that is used to store and transfer binary data. It consists of a series of flip-flops connected in a chain, with each flip-flop holding a single bit of data. The input data is shifted through the register one bit at a time, either left or right, depending on the design.

A T flip-flop can be implemented using NAND logic gates by performing the following steps:

- Use two NAND gates in a feedback loop where the output of one NAND gate connects to one of the inputs of the other NAND gate.
- Connect a T input to one of the inputs of each NAND gate.
- Connect an enable input to both NAND gates' inputs, with the enable signal flipped by an inverter to one of the inputs.
- Connect a clock input inverted to either one of the two inputs of each NAND gate.

A JK flip-flop can also be implemented using NAND logic gates by performing the following steps:

- Use two NAND gates in a feedback loop where the output of one NAND gate connects to one of the inputs of the other NAND gate.
- Connect a J and a K input to the inputs of the two NAND gates, respectively.
- Connect an enable input to both NAND gates' inputs, with the enable signal flipped by an inverter to one of the inputs.
- Connect a clock input inverted to either one of the two inputs of each NAND gate.