gtx_10x8dec.v 5.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/*******************************************************************************
 * Module: gtx_10x8dec
 * Date: 2015-07-11  
 * Author: Alexey     
 * Description: 8x10 encoder implementation
 *
 * Copyright (c) 2015 Elphel, Inc.
 * gtx_10x8dec.v is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * gtx_10x8dec.v file 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/> .
20 21 22 23 24 25 26 27 28 29 30 31 32
 *
 * Additional permission under GNU GPL version 3 section 7:
 * If you modify this Program, or any covered work, by linking or combining it
 * with independent modules provided by the FPGA vendor only (this permission
 * does not extend to any 3-rd party modules, "soft cores" or macros) under
 * different license terms solely for the purpose of generating binary "bitstream"
 * files and/or simulating the code, the copyright holders of this Program give
 * you the right to distribute the covered work without those independent modules
 * as long as the source code for them is available from the FPGA vendor free of
 * charge, and there is no dependence on any encrypted modules for simulating of
 * the combined code. This permission applies to you if the distributed code
 * contains all the components and scripts required to completely simulate it
 * with at least one of the Free Software programs.
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
 *******************************************************************************/
module gtx_10x8dec(
    input   wire    rst,
    input   wire    clk,
    input   wire    [19:0]  indata,
    output  wire    [15:0]  outdata,
    output  wire    [1:0]   outisk,
    output  wire    [1:0]   notintable,
    output  wire    [1:0]   disperror
/* uncomment if necessary
    input   wire    [0:0]   inaux,
    output  wire    [0:0]   outaux, */
);
/*
uncomment if necessary
// bypass auxilary informational signals
reg [0:0] aux_r;
reg [0:0] aux_rr;
always @ (posedge clk)
begin
    aux_r   <= inaux;
    aux_rr  <= aux_r;
end
assign  outaux = aux_rr;
*/
// split incoming data in 2 bytes
wire    [9:0]   addr0;
wire    [9:0]   addr1;

assign  addr0 = indata[9:0];
assign  addr1 = indata[19:10];

// get decoded values after 2 clock cycles, all '1's = cannot be decoded
wire    [15:0]  table0_out;
wire    [15:0]  table1_out;
68 69 70 71
wire    [10:0]   table0;
wire    [10:0]   table1;
assign  table0 = table0_out[10:0];
assign  table1 = table1_out[10:0];
72 73 74

assign  outdata = {table1[7:0], table0[7:0]};
assign  outisk  = {table1[8], table0[8]};
75
assign  notintable = {&table1, &table0};
76 77 78 79 80 81 82 83

// disparity control
// last clock disparity
reg     disparity;
// disparity after 1st byte
wire    disparity_interm;
// delayed ones
reg     disp0_r;
84
reg     disp0_rr;
85 86 87 88 89
reg     disp1_r;
reg     disp1_rr;
always @ (posedge clk)
begin
    disp0_r     <= disparity;
90
    disp0_rr    <= disp0_r;
91 92 93 94 95
    disp1_r     <= disparity_interm;
    disp1_rr    <= disp1_r;
end
// overall expected disparity when the table values would apper - disp0_r. 
// disp1_rr shows expected after 0st byte would be considered
96
reg     correct_table_disp;
97 98 99
wire    expected_disparity;
wire    expected_disparity_interm;

100 101
assign  expected_disparity = disp0_rr ^ correct_table_disp;
assign  expected_disparity_interm = disp1_rr ^ correct_table_disp;
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116

// invert disparity after a byte
// if current encoded word containg an equal amount of 1s and 0s (i.e. 5 x '1'), disp shall stay the same
// if amounts are unequal, there are either 4 or 6 '1's. in either case disp shall be inverted
wire    inv_disp0;
wire    inv_disp1;
assign  inv_disp0 = ~^(indata[9:0]);
assign  inv_disp1 = ~^(indata[19:10]);

assign  disparity_interm = inv_disp0 ? ~disparity : disparity;
always @ (posedge clk)
    disparity <= rst ? 1'b0 : inv_disp1 ^ inv_disp0 ? ~disparity : disparity;

// to correct disparity if once an error occured
always @ (posedge clk)
117
    correct_table_disp   <= rst ? 1'b0 : disperror[1] ? ~correct_table_disp : correct_table_disp;
118 119

// calculate disparity on table values
120 121 122 123 124 125 126 127 128 129 130
wire    table_pos_disp0;
wire    table_neg_disp0;
wire    table_pos_disp1;
wire    table_neg_disp1;
// table_pos_disp - for current 10-bit word disparity can be positive
// _neg_ - can be negative
// neg & pos - can be either of them
assign  table_pos_disp0 = table0[10];
assign  table_neg_disp0 = table0[9];
assign  table_pos_disp1 = table1[10];
assign  table_neg_disp1 = table1[9];
131

132
assign  disperror = ~{table_pos_disp0 & expected_disparity | table_neg_disp0 & ~expected_disparity, table_pos_disp1 & expected_disparity_interm | table_neg_disp1 & ~expected_disparity_interm};
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159

// TODO change mem to 18 instead of 36, so the highest address bit could be dropped
ramt_var_w_var_r #(
    .REGISTERS_A    (1),
    .REGISTERS_B    (1),
    .LOG2WIDTH_A    (4),
    .LOG2WIDTH_B    (4)
`include "gtx_10x8dec_init.v"
)
decoding_table(
    .clk_a       (clk),
    .addr_a      ({1'b0, addr0}),
    .en_a        (1'b1),
    .regen_a     (1'b1),
    .we_a        (1'b0),
    .data_out_a  (table0_out),
    .data_in_a   (16'h0),
    .clk_b       (clk),
    .addr_b      ({1'b0, addr1}),
    .en_b        (1'b1),
    .regen_b     (1'b1),
    .we_b        (1'b0),
    .data_out_b  (table1_out),
    .data_in_b   (16'h0)
);

endmodule