├── 3b-4b_5b-6b_Encoding.PNG ├── 8b-10b.png ├── README.md ├── decoder_10b_8b.v ├── encoder_8b_10b.v ├── latch_8bit.v ├── piso_10bit.v ├── serdes_top.v └── sipo_10bit.v /3b-4b_5b-6b_Encoding.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ishfaqahmed29/SerDes/f9c5b0c06506d27741625fe32cbca941a43f1c38/3b-4b_5b-6b_Encoding.PNG -------------------------------------------------------------------------------- /8b-10b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ishfaqahmed29/SerDes/f9c5b0c06506d27741625fe32cbca941a43f1c38/8b-10b.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Serializer-Deserializer 2 | A simple implementation of a SerDes module, typically used in high-speed communication protocols like PCIe, DisplayPort, Gigabit Ethernet, USB etc. 3 | 4 | ![SerDes Block Diagram](https://user-images.githubusercontent.com/34355989/132104019-276ba8cd-9032-41ae-b1d5-96f2250137d3.jpg) 5 | 6 | - RTL Design has basic modules like Latches, Encoder, Decoder, Shift Registers -> Parallel-In-Serial-Out, Serial-In-Parallel-Out 7 | 8 | - Serializer latches onto 8-bit Parallel data input, encodes to 10-bit, and converts to Serial bits 9 | 10 | - Deserializer converts incoming Serial bits to Parallel data using 10-bit latches, decodes and outputs back as 8-bit 11 | 12 | - Followed [specifications](http://www.latticesemi.com/products/designsoftwareandip/intellectualproperty/referencedesigns/referencedesigns01/8b10bencoderdecoder) to implement 3b/4b & 5b/6b encoding schemes and maintain a DC-balance data stream 13 | 14 | ![8b_10b Encoding](https://user-images.githubusercontent.com/34355989/132104163-17ad4b67-e369-4525-8d83-15a4f6f04605.jpg) 15 | -------------------------------------------------------------------------------- /decoder_10b_8b.v: -------------------------------------------------------------------------------- 1 | module decoder_10b_8b( 2 | input clk, 3 | input rst_n, 4 | input [9:0] data_10b_in, 5 | input par_en, 6 | output [7:0] data_8b_out 7 | ); 8 | 9 | reg [3:0] temp_3b; 10 | reg [5:0] temp_5b; 11 | 12 | always @ (posedge clk) begin 13 | if (!rst_n) begin 14 | temp_3b <= 4'b0000; 15 | temp_5b <= 6'b000000; 16 | end 17 | else begin 18 | if (par_en) begin 19 | case (data_10b_in[9:6]) 20 | 4'b0100: temp_3b <= 3'b000; 21 | 4'b1001: temp_3b <= 3'b001; 22 | 4'b0101: temp_3b <= 3'b010; 23 | 4'b0011: temp_3b <= 3'b011; 24 | 4'b0010: temp_3b <= 3'b100; 25 | 4'b1010: temp_3b <= 3'b101; 26 | 4'b0110: temp_3b <= 3'b110; 27 | 4'b0001: temp_3b <= 3'b111; 28 | default: temp_3b <= 3'b000; 29 | endcase 30 | case (data_10b_in[5:0]) 31 | 6'b011000: temp_5b <= 5'b00000; 32 | 6'b011101: temp_5b <= 5'b00001; 33 | 6'b010010: temp_5b <= 5'b00010; 34 | 6'b110001: temp_5b <= 5'b00011; 35 | 6'b110101: temp_5b <= 5'b00100; 36 | 6'b101001: temp_5b <= 5'b00101; 37 | 6'b011001: temp_5b <= 5'b00110; 38 | 6'b111000: temp_5b <= 5'b00111; 39 | 6'b111001: temp_5b <= 5'b01000; 40 | 6'b100101: temp_5b <= 5'b01001; 41 | 6'b010101: temp_5b <= 5'b01010; 42 | 6'b110100: temp_5b <= 5'b01011; 43 | 6'b001101: temp_5b <= 5'b01100; 44 | 6'b101100: temp_5b <= 5'b01101; 45 | 6'b011100: temp_5b <= 5'b01110; 46 | 6'b010111: temp_5b <= 5'b01111; 47 | 6'b011011: temp_5b <= 5'b10000; 48 | 6'b100011: temp_5b <= 5'b10001; 49 | 6'b010011: temp_5b <= 5'b10010; 50 | 6'b110010: temp_5b <= 5'b10011; 51 | 6'b001011: temp_5b <= 5'b10100; 52 | 6'b101010: temp_5b <= 5'b10101; 53 | 6'b011010: temp_5b <= 5'b10110; 54 | 6'b111010: temp_5b <= 5'b10111; 55 | 6'b110011: temp_5b <= 5'b11000; 56 | 6'b100110: temp_5b <= 5'b11001; 57 | 6'b010110: temp_5b <= 5'b11010; 58 | 6'b110110: temp_5b <= 5'b11011; 59 | 6'b001110: temp_5b <= 5'b11100; 60 | 6'b101110: temp_5b <= 5'b11101; 61 | 6'b011110: temp_5b <= 5'b11110; 62 | 6'b101011: temp_5b <= 5'b11111; 63 | default: temp_5b <= 5'b00000; 64 | endcase 65 | end 66 | else data_8b_out <= {temp_5b, temp_3b}; 67 | end 68 | end 69 | 70 | endmodule -------------------------------------------------------------------------------- /encoder_8b_10b.v: -------------------------------------------------------------------------------- 1 | module encoder_8b_10b( 2 | input clk, 3 | input rst_n, 4 | input [7:0] data_8b_in, 5 | input ser_en, 6 | output [9:0] data_10b_out 7 | ); 8 | 9 | reg [3:0] temp_4b; 10 | reg [5:0] temp_6b; 11 | 12 | always @ (posedge clk) begin 13 | if (!rst_n) begin 14 | temp_4b <= 4'b0000; 15 | temp_6b <= 6'b000000; 16 | end 17 | else begin 18 | if (ser_en) begin 19 | case (data_8b_in[7:5]) 20 | 3'b000: temp_4b <= 4'b0100; 21 | 3'b001: temp_4b <= 4'b1001; 22 | 3'b010: temp_4b <= 4'b0101; 23 | 3'b011: temp_4b <= 4'b0011; 24 | 3'b100: temp_4b <= 4'b0010; 25 | 3'b101: temp_4b <= 4'b1010; 26 | 3'b110: temp_4b <= 4'b0110; 27 | 3'b111: temp_4b <= 4'b0001; 28 | default: temp_4b <= 4'b0000; 29 | endcase 30 | case (data_8b_in[4:0]) 31 | 5'b00000: temp_6b <= 6'b011000; 32 | 5'b00001: temp_6b <= 6'b011101; 33 | 5'b00010: temp_6b <= 6'b010010; 34 | 5'b00011: temp_6b <= 6'b110001; 35 | 5'b00100: temp_6b <= 6'b110101; 36 | 5'b00101: temp_6b <= 6'b101001; 37 | 5'b00110: temp_6b <= 6'b011001; 38 | 5'b00111: temp_6b <= 6'b111000; 39 | 5'b01000: temp_6b <= 6'b111001; 40 | 5'b01001: temp_6b <= 6'b100101; 41 | 5'b01010: temp_6b <= 6'b010101; 42 | 5'b01011: temp_6b <= 6'b110100; 43 | 5'b01100: temp_6b <= 6'b001101; 44 | 5'b01101: temp_6b <= 6'b101100; 45 | 5'b01110: temp_6b <= 6'b011100; 46 | 5'b01111: temp_6b <= 6'b010111; 47 | 5'b10000: temp_6b <= 6'b011011; 48 | 5'b10001: temp_6b <= 6'b100011; 49 | 5'b10010: temp_6b <= 6'b010011; 50 | 5'b10011: temp_6b <= 6'b110010; 51 | 5'b10100: temp_6b <= 6'b001011; 52 | 5'b10101: temp_6b <= 6'b101010; 53 | 5'b10110: temp_6b <= 6'b011010; 54 | 5'b10111: temp_6b <= 6'b111010; 55 | 5'b11000: temp_6b <= 6'b110011; 56 | 5'b11001: temp_6b <= 6'b100110; 57 | 5'b11010: temp_6b <= 6'b010110; 58 | 5'b11011: temp_6b <= 6'b110110; 59 | 5'b11100: temp_6b <= 6'b001110; 60 | 5'b11101: temp_6b <= 6'b101110; 61 | 5'b11110: temp_6b <= 6'b011110; 62 | 5'b11111: temp_6b <= 6'b101011; 63 | default: temp_6b <= 6'b000000; 64 | endcase 65 | end 66 | else data_10b_out <= {temp_4b, temp_6b}; 67 | end 68 | end 69 | endmodule 70 | -------------------------------------------------------------------------------- /latch_8bit.v: -------------------------------------------------------------------------------- 1 | module latch_8bit( 2 | input clk, 3 | input rst_n, 4 | input [7:0] data_8b_in, 5 | input data_en, 6 | output [7:0] data_8b_out 7 | ); 8 | 9 | always @ (rst_n or data_en or data_8b_in) begin 10 | if (!rst_n) begin 11 | data_8b_out <= 8'h00; 12 | end 13 | else begin 14 | if (data_en) begin 15 | data_8b_out <= data_8b_in; 16 | end 17 | else data_8b_out <= data_8b_out; 18 | end 19 | end 20 | 21 | endmodule -------------------------------------------------------------------------------- /piso_10bit.v: -------------------------------------------------------------------------------- 1 | module piso_10bit( 2 | input clk, 3 | input rst_n, 4 | input [9:0] par_in, 5 | input load_en, 6 | output reg ser_out 7 | ); 8 | 9 | reg [9:0] shift_reg; 10 | 11 | always @ (posedge clk)begin 12 | if (!rst_n) begin 13 | shift_reg <= 10'b0000000000; 14 | end 15 | else begin 16 | if (load_en) begin 17 | shift_reg <= par_in; 18 | end 19 | else 20 | ser_out <= shift_reg[0]; 21 | shift_reg <= {1'b0, shift_reg[9:1]}; 22 | end 23 | end 24 | 25 | endmodule -------------------------------------------------------------------------------- /serdes_top.v: -------------------------------------------------------------------------------- 1 | module serdes_top( 2 | input clk, 3 | input rst_n, 4 | input [7:0] parallel_data_in, 5 | output [7:0] parallel_data_out 6 | ); 7 | 8 | wire [7:0] parallel_data_in = 8'b11010101; 9 | 10 | reg [7:0] parallel_data_out; 11 | 12 | latch_8bit data_in_latch( 13 | .clk(clk), 14 | .rst_n(rst_n), 15 | .data_8b_in(parallel_data), 16 | .data_en(data_en), 17 | .data_8b_out(data_8b_out) 18 | ); 19 | 20 | encoder_8b_10b encode_data( 21 | .clk(clk), 22 | .rst_n(rst_n), 23 | .data_8b_in(data_8b_in), 24 | .ser_en(ser_en), 25 | .data_10b_out(data_10b_out) 26 | ); 27 | 28 | piso_10bit par_to_ser( 29 | .clk(clk), 30 | .rst_n(rst_n), 31 | .par_in(data_10b_out), 32 | .load_en(load_en), 33 | .ser_out(ser_out) 34 | ); 35 | 36 | sipo_10bit ser_to_par( 37 | .clk(clk), 38 | .rst_n(rst_n), 39 | .ser_in(ser_out), 40 | .shift_en(shift_en), 41 | .par_out(par_out) 42 | ); 43 | 44 | decoder_10b_8b decode_data( 45 | .clk(clk), 46 | .rst_n(rst_n), 47 | .data_10b_in(par_out), 48 | .par_en(par_en), 49 | .data_8b_out(data_8b_out) 50 | ); 51 | 52 | always @ (posedge clk) begin 53 | if (!rst_n) begin 54 | parallel_data_out <= 0; 55 | end 56 | else parallel_data_out <= data_8b_out; 57 | end 58 | 59 | endmodule -------------------------------------------------------------------------------- /sipo_10bit.v: -------------------------------------------------------------------------------- 1 | module sipo_10bit( 2 | input clk, 3 | input rst_n, 4 | input ser_in, 5 | input shift_en, 6 | output [9:0] par_out 7 | ); 8 | 9 | reg [9:0] shift_reg; 10 | 11 | always @ (posedge clk)begin 12 | if (!rst_n) begin 13 | shift_reg <= 10'b0000000000; 14 | end 15 | else begin 16 | if (shift_en) begin 17 | par_out <= shift_reg; 18 | end 19 | else shift_reg <= {shift_reg[8:0], ser_in}; 20 | end 21 | end 22 | 23 | endmodule --------------------------------------------------------------------------------