[1609] | 1 | //******************************************************************************************** |
---|
| 2 | // File: fec_decoder |
---|
| 3 | // Author: Yang Sun (ysun@rice.edu) |
---|
| 4 | // Birth: $ 4/26/07 |
---|
| 5 | // Des: This module integreated a Viterbi decoder |
---|
| 6 | // History: $ 04/26/07: Init coding for QPSK CC coding |
---|
| 7 | // $ 11/25/07: Updated for uncodede system |
---|
| 8 | // $ 04/16/08: Added 16-QAM support |
---|
| 9 | // $ 09/27/08: Added dec-puncture |
---|
| 10 | // $ 09/27/08: Added dec-puncture |
---|
| 11 | // $ 10/11/08, Added uncodeded and BPSK |
---|
| 12 | // $ 10/10/10, OFDM reference design v15.0 |
---|
| 13 | //******************************************************************************************** |
---|
[1729] | 14 | module fec_decoder_top ( |
---|
[1609] | 15 | clk , // I, clock |
---|
| 16 | ce , // I, clock enable |
---|
| 17 | nrst , // I, n reset |
---|
| 18 | fec_reg , // I, controll register |
---|
| 19 | start , // I, packet start pulse |
---|
| 20 | vin , // I, data valid input |
---|
| 21 | xk_index , // I, FFT index |
---|
| 22 | mod_level , // I, 0=Invalid, 1=BPSK, 2=QPSK, 4=16-QAM |
---|
| 23 | rx_i , // I, RX I |
---|
| 24 | rx_q , // I, RX Q |
---|
| 25 | rx_we , // O, buffer write enable |
---|
| 26 | rx_addr , // O, buffer write address |
---|
| 27 | rx_data , // O, buffer write data |
---|
| 28 | rx_done , // O, RX done pulse |
---|
| 29 | rx_we_2 , // O, buffer write enable in clk/2 domain |
---|
| 30 | rx_addr_2 , // O, buffer write address in clk/2 domain |
---|
| 31 | rx_data_2 , // O, buffer write data in clk/2 domain |
---|
| 32 | rx_done_2 // O, RX done pulse in clk/2 domain |
---|
| 33 | ) ; |
---|
| 34 | |
---|
| 35 | input clk ; |
---|
| 36 | input ce ; |
---|
| 37 | input nrst ; |
---|
| 38 | input [31:0] fec_reg ; |
---|
| 39 | input start ; |
---|
| 40 | input vin ; |
---|
| 41 | input [5:0] xk_index ; |
---|
| 42 | input [3:0] mod_level ; |
---|
| 43 | input [15:0] rx_i ; |
---|
| 44 | input [15:0] rx_q ; |
---|
| 45 | output rx_we ; |
---|
| 46 | output [13:0] rx_addr ; |
---|
| 47 | output [7:0] rx_data ; |
---|
| 48 | output rx_done ; |
---|
| 49 | output rx_we_2 ; |
---|
| 50 | output [13:0] rx_addr_2 ; |
---|
| 51 | output [7:0] rx_data_2 ; |
---|
| 52 | output rx_done_2 ; |
---|
| 53 | |
---|
| 54 | //============================== |
---|
| 55 | //Internal signal |
---|
| 56 | //============================== |
---|
| 57 | wire sym_start ; |
---|
| 58 | wire [3:0] llr_a ; |
---|
| 59 | wire [3:0] llr_b ; |
---|
| 60 | wire dec_vout ; |
---|
| 61 | |
---|
| 62 | wire [7:0] dec_dout ; |
---|
| 63 | |
---|
| 64 | wire [13:0] nbyte ; |
---|
| 65 | wire [13:0] byte_cnt ; |
---|
| 66 | wire rx_packet_done ; |
---|
| 67 | reg rx_packet_done_s0 ; |
---|
| 68 | reg rx_packet_done_s1 ; |
---|
| 69 | |
---|
| 70 | wire demapper_vld ; |
---|
| 71 | wire coding_en ; |
---|
| 72 | wire zero_tail ; |
---|
| 73 | wire soft_decoding ; |
---|
| 74 | wire [3:0] scale_qpsk ; |
---|
| 75 | wire [4:0] scale_16qam ; |
---|
| 76 | |
---|
| 77 | wire depunct_dav ; |
---|
| 78 | wire [7:0] iq_data ; |
---|
| 79 | wire [7:0] iq_data_buf ; |
---|
| 80 | wire llr_buf_empty ; |
---|
| 81 | wire buf_full ; |
---|
| 82 | wire [3:0] llr_i_depunc ; |
---|
| 83 | wire [3:0] llr_q_depunc ; |
---|
| 84 | wire llr_valid ; |
---|
| 85 | wire llr_buf_rd ; |
---|
| 86 | |
---|
| 87 | wire ack_pkt ; |
---|
| 88 | |
---|
| 89 | wire [1:0] cc_rate ; |
---|
| 90 | |
---|
| 91 | reg [23:0] timeout_reg ; |
---|
| 92 | reg in_dec ; |
---|
| 93 | wire timeout ; |
---|
| 94 | reg timeout_s1 ; |
---|
| 95 | wire timeout_pls ; |
---|
| 96 | wire depunt_buf_rd ; |
---|
| 97 | wire in_fullrate ; |
---|
| 98 | wire unc_buf_rd ; |
---|
| 99 | wire data_coded ; |
---|
| 100 | wire [3:0] hdr_mod_level ; |
---|
| 101 | |
---|
| 102 | wire we_1x ; |
---|
| 103 | wire [7:0] data_1x ; |
---|
| 104 | |
---|
| 105 | wire we_down2 ; |
---|
| 106 | wire [7:0] data_down2 ; |
---|
| 107 | wire [13:0] addr_down2 ; |
---|
| 108 | reg rx_done_d ; |
---|
| 109 | wire rx_done_i ; |
---|
| 110 | reg [15:0] rx_done_dly ; |
---|
| 111 | |
---|
| 112 | //========================================= |
---|
| 113 | // Main body of code |
---|
| 114 | //========================================= |
---|
| 115 | assign rx_done = (rx_packet_done_s0 & ~rx_packet_done_s1) | timeout_pls ; |
---|
| 116 | assign rx_addr = byte_cnt ; |
---|
| 117 | assign rx_data = dec_dout ; |
---|
| 118 | assign rx_we = dec_vout & ~rx_packet_done ; |
---|
| 119 | |
---|
| 120 | assign rx_addr_2 = addr_down2 ; |
---|
| 121 | assign rx_we_2 = we_down2 ; |
---|
| 122 | assign rx_data_2 = data_down2 ; |
---|
| 123 | assign rx_done_2 = rx_done_dly[15] ; |
---|
| 124 | |
---|
| 125 | |
---|
| 126 | assign we_1x = dec_vout & ~rx_packet_done ; |
---|
| 127 | assign data_1x = dec_dout ; |
---|
| 128 | |
---|
| 129 | assign coding_en = fec_reg [0] ; |
---|
| 130 | assign soft_decoding = fec_reg [1] ; |
---|
| 131 | assign zero_tail = fec_reg [2] ; |
---|
| 132 | assign scale_qpsk = fec_reg [7:4] ; |
---|
| 133 | assign scale_16qam = fec_reg [12:8] ; |
---|
| 134 | |
---|
| 135 | |
---|
| 136 | always @(posedge clk or negedge nrst) |
---|
| 137 | if(~nrst) |
---|
| 138 | rx_done_d <= 1'b0 ; |
---|
| 139 | else |
---|
| 140 | rx_done_d <= rx_done ; |
---|
| 141 | |
---|
| 142 | assign rx_done_i = rx_done | rx_done_d ; |
---|
| 143 | |
---|
| 144 | always @(posedge clk or negedge nrst) |
---|
| 145 | if(~nrst) |
---|
| 146 | rx_done_dly <= 0 ; |
---|
| 147 | else |
---|
| 148 | rx_done_dly <= {rx_done_dly[14:0], rx_done_i} ; |
---|
| 149 | |
---|
| 150 | //============================== |
---|
| 151 | // soft_demapper |
---|
| 152 | //============================== |
---|
| 153 | soft_demapper soft_demapper ( |
---|
| 154 | .clk (clk ), |
---|
| 155 | .nrst (nrst ), |
---|
| 156 | .start (start ), |
---|
| 157 | .coding_en (coding_en ), |
---|
| 158 | .vin (vin ), |
---|
| 159 | .xk_index (xk_index ), |
---|
| 160 | .mod_level (mod_level ), |
---|
| 161 | .rx_i (rx_i ), |
---|
| 162 | .rx_q (rx_q ), |
---|
| 163 | .scale_qpsk (scale_qpsk ), |
---|
| 164 | .scale_16qam (scale_16qam ), |
---|
| 165 | .in_fullrate (in_fullrate ), |
---|
| 166 | .sym_start (sym_start ), |
---|
| 167 | .hdr_mod_level (hdr_mod_level ), |
---|
| 168 | .vout (demapper_vld ), |
---|
| 169 | .soft_decoding (soft_decoding ), |
---|
| 170 | .llr_a (llr_a ), |
---|
| 171 | .llr_b (llr_b ) |
---|
| 172 | ) ; |
---|
| 173 | |
---|
| 174 | assign iq_data = {llr_a, llr_b} ; |
---|
| 175 | assign llr_buf_rd = (in_fullrate & ~data_coded) ? unc_buf_rd : depunt_buf_rd ; |
---|
| 176 | |
---|
| 177 | //============================== |
---|
| 178 | // LLR buffer |
---|
| 179 | //============================== |
---|
| 180 | llr_buffer llr_buffer ( |
---|
| 181 | .clk (clk ), |
---|
| 182 | .nrst (nrst ), |
---|
| 183 | .reset (start ), |
---|
| 184 | .din (iq_data ), |
---|
| 185 | .dout (iq_data_buf ), |
---|
| 186 | .wr (demapper_vld ), |
---|
| 187 | .rd (llr_buf_rd ), |
---|
| 188 | .empty (llr_buf_empty ), |
---|
| 189 | .full (buf_full ) |
---|
| 190 | ) ; |
---|
| 191 | |
---|
| 192 | assign depunct_dav = ~llr_buf_empty ; |
---|
| 193 | //============================== |
---|
| 194 | // depuncture |
---|
| 195 | //============================== |
---|
| 196 | depunc depunc ( |
---|
| 197 | .clk (clk ), |
---|
| 198 | .nrst (nrst ), |
---|
| 199 | .start (start ), |
---|
| 200 | .dav (depunct_dav ), |
---|
| 201 | .rate (cc_rate ), |
---|
| 202 | .din (iq_data_buf ), |
---|
| 203 | .vout (llr_valid ), |
---|
| 204 | .dout_a (llr_i_depunc ), |
---|
| 205 | .dout_b (llr_q_depunc ), |
---|
| 206 | .buf_rd (depunt_buf_rd ) |
---|
| 207 | ) ; |
---|
| 208 | |
---|
| 209 | //============================== |
---|
| 210 | // decoder_system |
---|
| 211 | //============================== |
---|
| 212 | decoder_system decoder_system ( |
---|
| 213 | .clk (clk ), // I, clock |
---|
| 214 | .nrst (nrst ), // I, n reset |
---|
| 215 | .start (start ), // I, start pulse |
---|
| 216 | .in_dec (in_dec ), |
---|
| 217 | .coding_en (coding_en ), |
---|
| 218 | .zero_tail (zero_tail ), |
---|
| 219 | .sym_start (sym_start ), // I, sym start |
---|
| 220 | .hdr_mod_level (hdr_mod_level ), |
---|
| 221 | .unc_buf_rd (unc_buf_rd ), // I, LLR buffer read by unc |
---|
| 222 | .vin (llr_valid ), // I, data valid input |
---|
| 223 | .llr_buf_empty (llr_buf_empty ), // I, LLR buffer empty |
---|
| 224 | .llr_a (llr_i_depunc ), // I, LLR I channel |
---|
| 225 | .llr_b (llr_q_depunc ), // I, LLR Q channel |
---|
| 226 | .vout (dec_vout ), // O, data valid output |
---|
| 227 | .dout (dec_dout ), // O, byte data output |
---|
| 228 | .nbyte (nbyte ), // O, num of bytes |
---|
| 229 | .byte_cnt (byte_cnt ), // O, byte cnt |
---|
| 230 | .cc_rate (cc_rate ), // O, code rate |
---|
| 231 | .data_coded (data_coded ), // O, coded system |
---|
| 232 | .in_fullrate (in_fullrate ) // O, in full rate |
---|
| 233 | ) ; |
---|
| 234 | |
---|
| 235 | out_ctrl out_ctrl ( |
---|
| 236 | .clk (clk ), |
---|
| 237 | .nrst (nrst ), |
---|
| 238 | .start (start ), |
---|
| 239 | .vin (we_1x ), |
---|
| 240 | .din (data_1x ), |
---|
| 241 | .vout (we_down2 ), |
---|
| 242 | .dout (data_down2 ), |
---|
| 243 | .idx_out (addr_down2 ) |
---|
| 244 | ) ; |
---|
| 245 | |
---|
| 246 | |
---|
| 247 | |
---|
| 248 | assign rx_packet_done = byte_cnt >= nbyte ; |
---|
| 249 | always @ (posedge clk or negedge nrst) |
---|
| 250 | if (~nrst) |
---|
| 251 | begin |
---|
| 252 | rx_packet_done_s0 <= 1'b0 ; |
---|
| 253 | rx_packet_done_s1 <= 1'b0 ; |
---|
| 254 | end |
---|
| 255 | else |
---|
| 256 | begin |
---|
| 257 | rx_packet_done_s0 <= rx_packet_done ; |
---|
| 258 | rx_packet_done_s1 <= rx_packet_done_s0 ; |
---|
| 259 | end |
---|
| 260 | |
---|
| 261 | |
---|
| 262 | assign ack_pkt = (nbyte == 24) ; |
---|
| 263 | |
---|
| 264 | always @(posedge clk or negedge nrst) |
---|
| 265 | if (~nrst) |
---|
| 266 | in_dec <= 1'b0 ; |
---|
| 267 | else if (start) |
---|
| 268 | in_dec <= 1'b1 ; |
---|
| 269 | else if (rx_done) |
---|
| 270 | in_dec <= 1'b0 ; |
---|
| 271 | |
---|
| 272 | assign timeout = timeout_reg == 24'h40000 ; |
---|
| 273 | always @(posedge clk or negedge nrst) |
---|
| 274 | if (~nrst) |
---|
| 275 | timeout_reg <= 0 ; |
---|
| 276 | else if (start) |
---|
| 277 | timeout_reg <= 0 ; |
---|
| 278 | else if (in_dec) |
---|
| 279 | begin |
---|
| 280 | if (~timeout) |
---|
| 281 | timeout_reg <= timeout_reg +1 ; |
---|
| 282 | end |
---|
| 283 | |
---|
| 284 | assign timeout_pls = ~timeout_s1 & timeout ; |
---|
| 285 | always @(posedge clk or negedge nrst) |
---|
| 286 | if (~nrst) |
---|
| 287 | timeout_s1 <= 1'b0 ; |
---|
| 288 | else |
---|
| 289 | timeout_s1 <= timeout ; |
---|
| 290 | |
---|
| 291 | endmodule |
---|