source: ResearchApps/PHY/MIMO_OFDM/fec_decoder_top.v

Last change on this file was 1729, checked in by murphpo, 12 years ago

Adding Sysgen 13.4 version of coded OFDM PHY; includes temporary fix for crash during simulation (bbReplace.m)

File size: 8.7 KB
Line 
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//********************************************************************************************
14module fec_decoder_top (
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       
35input           clk ;
36input           ce ;
37input           nrst ;
38input   [31:0]  fec_reg ;
39input           start ;
40input           vin ;
41input   [5:0]   xk_index ;
42input   [3:0]   mod_level ;     
43input   [15:0]  rx_i ;
44input   [15:0]  rx_q ;
45output          rx_we ;
46output  [13:0]  rx_addr ;
47output  [7:0]   rx_data ;
48output          rx_done ;
49output          rx_we_2 ;
50output  [13:0]  rx_addr_2 ;
51output  [7:0]   rx_data_2 ;
52output          rx_done_2 ;
53
54//==============================
55//Internal signal
56//==============================
57wire            sym_start ;
58wire    [3:0]   llr_a ;
59wire    [3:0]   llr_b ;
60wire            dec_vout ;
61
62wire    [7:0]   dec_dout ;
63
64wire    [13:0]  nbyte ;
65wire    [13:0]  byte_cnt ;
66wire            rx_packet_done ;
67reg             rx_packet_done_s0 ;
68reg             rx_packet_done_s1 ;
69
70wire            demapper_vld ;
71wire            coding_en ;
72wire            zero_tail ;
73wire            soft_decoding ;
74wire    [3:0]   scale_qpsk ;
75wire    [4:0]   scale_16qam ;
76
77wire            depunct_dav ;
78wire    [7:0]   iq_data ;
79wire    [7:0]   iq_data_buf ;
80wire            llr_buf_empty ;
81wire            buf_full ;
82wire    [3:0]   llr_i_depunc ;
83wire    [3:0]   llr_q_depunc ;
84wire            llr_valid ;
85wire            llr_buf_rd ;
86
87wire            ack_pkt ;
88
89wire    [1:0]   cc_rate ;
90
91reg     [23:0]  timeout_reg ;
92reg             in_dec ;
93wire            timeout ;
94reg             timeout_s1 ;
95wire            timeout_pls ;
96wire            depunt_buf_rd ;
97wire            in_fullrate ;
98wire            unc_buf_rd ;
99wire            data_coded ;
100wire    [3:0]   hdr_mod_level ;
101
102wire            we_1x ;
103wire    [7:0]   data_1x ;
104
105wire            we_down2 ;
106wire    [7:0]   data_down2 ;
107wire    [13:0]  addr_down2 ;
108reg             rx_done_d ;
109wire            rx_done_i ;
110reg     [15:0]   rx_done_dly ;
111
112//=========================================
113// Main body of code
114//=========================================
115assign rx_done = (rx_packet_done_s0 & ~rx_packet_done_s1) | timeout_pls ;
116assign rx_addr = byte_cnt ;
117assign rx_data = dec_dout ;
118assign rx_we = dec_vout & ~rx_packet_done ;
119
120assign rx_addr_2 = addr_down2 ;
121assign rx_we_2 = we_down2 ;
122assign rx_data_2 = data_down2 ;
123assign rx_done_2 = rx_done_dly[15] ;
124
125
126assign we_1x = dec_vout & ~rx_packet_done ;
127assign data_1x = dec_dout ;
128
129assign coding_en = fec_reg [0] ;
130assign soft_decoding = fec_reg [1] ;
131assign zero_tail = fec_reg [2] ;
132assign scale_qpsk = fec_reg [7:4] ;
133assign scale_16qam = fec_reg [12:8] ;
134
135
136always @(posedge clk or negedge nrst)
137  if(~nrst)
138    rx_done_d <= 1'b0 ;
139  else
140    rx_done_d <= rx_done ;
141
142assign rx_done_i = rx_done | rx_done_d ;
143
144always @(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//==============================
153soft_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
174assign iq_data = {llr_a, llr_b} ;
175assign llr_buf_rd = (in_fullrate & ~data_coded) ? unc_buf_rd : depunt_buf_rd ;
176
177//==============================
178// LLR buffer
179//==============================
180llr_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
192assign depunct_dav = ~llr_buf_empty ;
193//==============================
194// depuncture
195//==============================
196depunc 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//==============================
212decoder_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
235out_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
248assign rx_packet_done = byte_cnt >= nbyte ;
249always @ (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
262assign ack_pkt = (nbyte == 24) ;
263
264always @(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
272assign timeout = timeout_reg == 24'h40000 ;
273always @(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 
284assign timeout_pls = ~timeout_s1 & timeout ;
285always @(posedge clk or negedge nrst)
286  if (~nrst)
287    timeout_s1 <= 1'b0 ;
288  else
289    timeout_s1 <= timeout ; 
290     
291endmodule
Note: See TracBrowser for help on using the repository browser.