diff --git a/verilog/deinterleave.v b/verilog/deinterleave.v index d485286..0dfc1e0 100644 --- a/verilog/deinterleave.v +++ b/verilog/deinterleave.v @@ -9,9 +9,12 @@ module deinterleave input [7:0] rate, input [5:0] in_bits, + input [5:0] soft_in_bits, + input [3:0] soft_in_bits_pos, input input_strobe, + input soft_decoding, - output [1:0] out_bits, + output reg [5:0] out_bits, output [1:0] erase, output output_strobe ); @@ -39,9 +42,85 @@ wire [2:0] lut_bitb = lut_out_delayed[4:2]; wire [5:0] bit_outa; wire [5:0] bit_outb; +wire [5:0] soft_bit_outa; +wire [5:0] soft_bit_outb; +wire [3:0] soft_bit_outa_pos; +wire [3:0] soft_bit_outb_pos; -assign out_bits[0] = lut_valid_delayed? bit_outa[lut_bita]: 0; -assign out_bits[1] = lut_valid_delayed? bit_outb[lut_bitb]: 0; +// Soft and hard decoding +wire [4:0] MOD_TYPE = {rate[7], rate[3:0]}; +wire BPSK = MOD_TYPE == 5'b01011 || MOD_TYPE == 5'b01111 || MOD_TYPE == 5'b10000; +wire QPSK = MOD_TYPE == 5'b01010 || MOD_TYPE == 5'b01110 || MOD_TYPE == 5'b10001 || MOD_TYPE == 5'b10010; +wire QAM_16 = MOD_TYPE == 5'b01001 || MOD_TYPE == 5'b01101 || MOD_TYPE == 5'b10011 || MOD_TYPE == 5'b10100; +wire QAM_64 = MOD_TYPE == 5'b01000 || MOD_TYPE == 5'b01100 || MOD_TYPE == 5'b10101 || MOD_TYPE == 5'b10110 || MOD_TYPE == 5'b10111; + +wire [2:0] N_BPSC_DIV_2 = BPSK ? 3'b000 : (QPSK ? 3'b001 : (QAM_16 ? 3'b010: (QAM_64 ? 3'b011 : 3'b111))); + +always @* begin + if(lut_valid_delayed == 1'b1) begin + + // Soft decoding + if(soft_decoding && (BPSK || QPSK || QAM_16 || QAM_64)) begin + if(BPSK || lut_bita < N_BPSC_DIV_2) begin + if(lut_bita[1:0] == soft_bit_outa_pos[1:0]) begin + out_bits[2:0] = soft_bit_outa[2:0]; + end else begin + if(bit_outa[lut_bita] == 1'b1) + out_bits[2:0] = 3'b111; + else + out_bits[2:0] = 3'b011; + end + end else begin + if(lut_bita == ({1'b0,soft_bit_outa_pos[3:2]} + N_BPSC_DIV_2)) begin + out_bits[2:0] = soft_bit_outa[5:3]; + end else begin + if(bit_outa[lut_bita] == 1'b1) + out_bits[2:0] = 3'b111; + else + out_bits[2:0] = 3'b011; + end + end + + if(BPSK || lut_bitb < N_BPSC_DIV_2) begin + if(lut_bitb[1:0] == soft_bit_outb_pos[1:0]) begin + out_bits[5:3] = soft_bit_outb[2:0]; + end else begin + if(bit_outb[lut_bitb] == 1'b1) + out_bits[5:3] = 3'b111; + else + out_bits[5:3] = 3'b011; + end + end else begin + if(lut_bitb == ({1'b0,soft_bit_outb_pos[3:2]} + N_BPSC_DIV_2)) begin + out_bits[5:3] = soft_bit_outb[5:3]; + end else begin + if(bit_outb[lut_bitb] == 1'b1) + out_bits[5:3] = 3'b111; + else + out_bits[5:3] = 3'b011; + end + end + + // Hard decoding + end else begin + if(bit_outa[lut_bita] == 1'b1) + out_bits[2:0] = 3'b111; + else + out_bits[2:0] = 3'b011; + + if(bit_outb[lut_bitb] == 1'b1) + out_bits[5:3] = 3'b111; + else + out_bits[5:3] = 3'b011; + end + end else begin + out_bits[2:0] = 0; + out_bits[5:3] = 0; + end +end + +//assign out_bits[0] = lut_valid_delayed? bit_outa[lut_bita]: 0; +//assign out_bits[1] = lut_valid_delayed? bit_outb[lut_bitb]: 0; assign output_strobe = enable & lut_valid_delayed & lut_out_delayed[1]; wire [5:0] lut_addra = lut_out[19:14]; @@ -51,19 +130,19 @@ wire lut_done = lut_out[0]; reg ram_delay; reg ht_delayed; -ram_2port #(.DWIDTH(6), .AWIDTH(6)) ram_inst ( +ram_2port #(.DWIDTH(16), .AWIDTH(6)) ram_inst ( .clka(clock), .ena(1), .wea(input_strobe), .addra(addra), - .dia(in_bits), - .doa(bit_outa), + .dia({in_bits, soft_in_bits, soft_in_bits_pos}), + .doa({bit_outa,soft_bit_outa,soft_bit_outa_pos}), .clkb(clock), .enb(1), .web(0), .addrb(addrb), .dib(32'hFFFF), - .dob(bit_outb) + .dob({bit_outb,soft_bit_outb,soft_bit_outb_pos}) ); deinter_lut lut_inst ( diff --git a/verilog/demodulate.v b/verilog/demodulate.v index 2145b9a..8a151b2 100644 --- a/verilog/demodulate.v +++ b/verilog/demodulate.v @@ -11,6 +11,8 @@ module demodulate ( input input_strobe, output reg [5:0] bits, + output reg [5:0] soft_bits, + output reg [3:0] soft_bits_pos, output output_strobe ); @@ -22,6 +24,62 @@ localparam QAM_64_DIV_0 = MAX*2/7; localparam QAM_64_DIV_1 = MAX*4/7; localparam QAM_64_DIV_2 = MAX*6/7; +localparam BPSK_SOFT_4 = MAX; +localparam BPSK_SOFT_3 = MAX*3/4; +localparam BPSK_SOFT_2 = MAX*2/4; +localparam BPSK_SOFT_1 = MAX*1/4; +localparam BPSK_SOFT_0 = 0; + +localparam QPSK_SOFT_4 = MAX; +localparam QPSK_SOFT_3 = MAX*3/4; +localparam QPSK_SOFT_2 = MAX*2/4; +localparam QPSK_SOFT_1 = MAX*1/4; +localparam QPSK_SOFT_0 = 0; + +localparam QAM_16_SOFT_12 = MAX; +localparam QAM_16_SOFT_11 = MAX*11/12; +localparam QAM_16_SOFT_10 = MAX*10/12; +localparam QAM_16_SOFT_9 = MAX*9/12; +localparam QAM_16_SOFT_8 = MAX*8/12; +localparam QAM_16_SOFT_7 = MAX*7/12; +localparam QAM_16_SOFT_6 = MAX*6/12; +localparam QAM_16_SOFT_5 = MAX*5/12; +localparam QAM_16_SOFT_4 = MAX*4/12; +localparam QAM_16_SOFT_3 = MAX*3/12; +localparam QAM_16_SOFT_2 = MAX*2/12; +localparam QAM_16_SOFT_1 = MAX*1/12; +localparam QAM_16_SOFT_0 = 0; + +localparam QAM_64_SOFT_28 = MAX; +localparam QAM_64_SOFT_27 = MAX*27/28; +localparam QAM_64_SOFT_26 = MAX*26/28; +localparam QAM_64_SOFT_25 = MAX*25/28; +localparam QAM_64_SOFT_24 = MAX*24/28; +localparam QAM_64_SOFT_23 = MAX*23/28; +localparam QAM_64_SOFT_22 = MAX*22/28; +localparam QAM_64_SOFT_21 = MAX*21/28; +localparam QAM_64_SOFT_20 = MAX*20/28; +localparam QAM_64_SOFT_19 = MAX*19/28; +localparam QAM_64_SOFT_18 = MAX*18/28; +localparam QAM_64_SOFT_17 = MAX*17/28; +localparam QAM_64_SOFT_16 = MAX*16/28; +localparam QAM_64_SOFT_15 = MAX*15/28; +localparam QAM_64_SOFT_14 = MAX*14/28; +localparam QAM_64_SOFT_13 = MAX*13/28; +localparam QAM_64_SOFT_12 = MAX*12/28; +localparam QAM_64_SOFT_11 = MAX*11/28; +localparam QAM_64_SOFT_10 = MAX*10/28; +localparam QAM_64_SOFT_9 = MAX*9/28; +localparam QAM_64_SOFT_8 = MAX*8/28; +localparam QAM_64_SOFT_7 = MAX*7/28; +localparam QAM_64_SOFT_6 = MAX*6/28; +localparam QAM_64_SOFT_5 = MAX*5/28; +localparam QAM_64_SOFT_4 = MAX*4/28; +localparam QAM_64_SOFT_3 = MAX*3/28; +localparam QAM_64_SOFT_2 = MAX*2/28; +localparam QAM_64_SOFT_1 = MAX*1/28; +localparam QAM_64_SOFT_0 = 0; + localparam BPSK = 1; localparam QPSK = 2; localparam QAM_16 = 3; @@ -47,6 +105,8 @@ delayT #(.DATA_WIDTH(1), .DELAY(2)) stb_delay_inst ( always @(posedge clock) begin if (reset) begin bits <= 0; + soft_bits <= 0; + soft_bits_pos <= 4'b1111; abs_cons_i <= 0; abs_cons_q <= 0; cons_i_delayed <= 0; @@ -84,22 +144,205 @@ always @(posedge clock) begin case(mod) BPSK: begin + // Hard decoded bits bits[0] <= ~cons_i_delayed[15]; bits[5:1] <= 0; + + // Inphase soft decoded bits + if(cons_i_delayed[15] == 0 && abs_cons_i >= BPSK_SOFT_3) + soft_bits[2:0] <= 3'b111; + else if(cons_i_delayed[15] == 0 && abs_cons_i < BPSK_SOFT_3 && abs_cons_i >= BPSK_SOFT_2) + soft_bits[2:0] <= 3'b110; + else if(cons_i_delayed[15] == 0 && abs_cons_i < BPSK_SOFT_2 && abs_cons_i >= BPSK_SOFT_1) + soft_bits[2:0] <= 3'b101; + else if(cons_i_delayed[15] == 0 && abs_cons_i < BPSK_SOFT_1 && abs_cons_i >= BPSK_SOFT_0) + soft_bits[2:0] <= 3'b100; + else if(cons_i_delayed[15] == 1 && abs_cons_i < BPSK_SOFT_1 && abs_cons_i >= BPSK_SOFT_0) + soft_bits[2:0] <= 3'b000; + else if(cons_i_delayed[15] == 1 && abs_cons_i < BPSK_SOFT_2 && abs_cons_i >= BPSK_SOFT_1) + soft_bits[2:0] <= 3'b001; + else if(cons_i_delayed[15] == 1 && abs_cons_i < BPSK_SOFT_3 && abs_cons_i >= BPSK_SOFT_2) + soft_bits[2:0] <= 3'b010; + else if(cons_i_delayed[15] == 1 && abs_cons_i < BPSK_SOFT_4 && abs_cons_i >= BPSK_SOFT_3) + soft_bits[2:0] <= 3'b011; + // + else + soft_bits[2:0] <= 3'b011; + + // Quadrature soft decoded bits + soft_bits[5:3] <= 3'b000; + + // Inphase soft decoded bit positions + if(abs_cons_i < BPSK_SOFT_4) + soft_bits_pos[1:0] <= 2'b00; + else + soft_bits_pos[1:0] <= 2'b11; + + // Quadrature soft decoded bit positions + soft_bits_pos[3:2] <= 2'b11; end QPSK: begin + // Hard decoded bits bits[0] <= ~cons_i_delayed[15]; bits[1] <= ~cons_q_delayed[15]; bits[5:2] <= 0; + + // Inphase soft decoded bits + if(cons_i_delayed[15] == 0 && abs_cons_i >= QPSK_SOFT_3) + soft_bits[2:0] <= 3'b111; + else if(cons_i_delayed[15] == 0 && abs_cons_i < QPSK_SOFT_3 && abs_cons_i >= QPSK_SOFT_2) + soft_bits[2:0] <= 3'b110; + else if(cons_i_delayed[15] == 0 && abs_cons_i < QPSK_SOFT_2 && abs_cons_i >= QPSK_SOFT_1) + soft_bits[2:0] <= 3'b101; + else if(cons_i_delayed[15] == 0 && abs_cons_i < QPSK_SOFT_1 && abs_cons_i >= QPSK_SOFT_0) + soft_bits[2:0] <= 3'b100; + else if(cons_i_delayed[15] == 1 && abs_cons_i < QPSK_SOFT_1 && abs_cons_i >= QPSK_SOFT_0) + soft_bits[2:0] <= 3'b000; + else if(cons_i_delayed[15] == 1 && abs_cons_i < QPSK_SOFT_2 && abs_cons_i >= QPSK_SOFT_1) + soft_bits[2:0] <= 3'b001; + else if(cons_i_delayed[15] == 1 && abs_cons_i < QPSK_SOFT_3 && abs_cons_i >= QPSK_SOFT_2) + soft_bits[2:0] <= 3'b010; + else if(cons_i_delayed[15] == 1 && abs_cons_i < QPSK_SOFT_4 && abs_cons_i >= QPSK_SOFT_3) + soft_bits[2:0] <= 3'b011; + // + else + soft_bits[2:0] <= 3'b011; + + // Quadrature soft decoded bits + if(cons_q_delayed[15] == 0 && abs_cons_q >= QPSK_SOFT_3) + soft_bits[5:3] <= 3'b111; + else if(cons_q_delayed[15] == 0 && abs_cons_q < QPSK_SOFT_3 && abs_cons_q >= QPSK_SOFT_2) + soft_bits[5:3] <= 3'b110; + else if(cons_q_delayed[15] == 0 && abs_cons_q < QPSK_SOFT_2 && abs_cons_q >= QPSK_SOFT_1) + soft_bits[5:3] <= 3'b101; + else if(cons_q_delayed[15] == 0 && abs_cons_q < QPSK_SOFT_1 && abs_cons_q >= QPSK_SOFT_0) + soft_bits[5:3] <= 3'b100; + else if(cons_q_delayed[15] == 1 && abs_cons_q < QPSK_SOFT_1 && abs_cons_q >= QPSK_SOFT_0) + soft_bits[5:3] <= 3'b000; + else if(cons_q_delayed[15] == 1 && abs_cons_q < QPSK_SOFT_2 && abs_cons_q >= QPSK_SOFT_1) + soft_bits[5:3] <= 3'b001; + else if(cons_q_delayed[15] == 1 && abs_cons_q < QPSK_SOFT_3 && abs_cons_q >= QPSK_SOFT_2) + soft_bits[5:3] <= 3'b010; + else if(cons_q_delayed[15] == 1 && abs_cons_q < QPSK_SOFT_4 && abs_cons_q >= QPSK_SOFT_3) + soft_bits[5:3] <= 3'b011; + // + else + soft_bits[5:3] <= 3'b011; + + // Inphase soft decoded bit positions + if(abs_cons_i < QPSK_SOFT_4) + soft_bits_pos[1:0] <= 2'b00; + else + soft_bits_pos[1:0] <= 2'b11; + + // Quadrature soft decoded bit positions + if(abs_cons_q < QPSK_SOFT_4) + soft_bits_pos[3:2] <= 2'b00; + else + soft_bits_pos[3:2] <= 2'b11; end QAM_16: begin + // Hard decoded bits bits[0] <= ~cons_i_delayed[15]; bits[1] <= abs_cons_i < QAM_16_DIV? 1: 0; bits[2] <= ~cons_q_delayed[15]; bits[3] <= abs_cons_q < QAM_16_DIV? 1: 0; bits[5:4] <= 0; + + // Inphase soft decoded bits + if(abs_cons_i < QAM_16_SOFT_12 && abs_cons_i >= QAM_16_SOFT_11) + soft_bits[2:0] <= 3'b011; + else if(abs_cons_i < QAM_16_SOFT_11 && abs_cons_i >= QAM_16_SOFT_10) + soft_bits[2:0] <= 3'b010; + else if(abs_cons_i < QAM_16_SOFT_10 && abs_cons_i >= QAM_16_SOFT_9) + soft_bits[2:0] <= 3'b001; + else if(abs_cons_i < QAM_16_SOFT_9 && abs_cons_i >= QAM_16_SOFT_8) + soft_bits[2:0] <= 3'b000; + else if(abs_cons_i < QAM_16_SOFT_8 && abs_cons_i >= QAM_16_SOFT_7) + soft_bits[2:0] <= 3'b100; + else if(abs_cons_i < QAM_16_SOFT_7 && abs_cons_i >= QAM_16_SOFT_6) + soft_bits[2:0] <= 3'b101; + else if(abs_cons_i < QAM_16_SOFT_6 && abs_cons_i >= QAM_16_SOFT_5) + soft_bits[2:0] <= 3'b110; + else if(abs_cons_i < QAM_16_SOFT_5 && abs_cons_i >= QAM_16_SOFT_4) + soft_bits[2:0] <= 3'b111; + // + else if(cons_i_delayed[15] == 0 && abs_cons_i < QAM_16_SOFT_4 && abs_cons_i >= QAM_16_SOFT_3) + soft_bits[2:0] <= 3'b111; + else if(cons_i_delayed[15] == 0 && abs_cons_i < QAM_16_SOFT_3 && abs_cons_i >= QAM_16_SOFT_2) + soft_bits[2:0] <= 3'b110; + else if(cons_i_delayed[15] == 0 && abs_cons_i < QAM_16_SOFT_2 && abs_cons_i >= QAM_16_SOFT_1) + soft_bits[2:0] <= 3'b101; + else if(cons_i_delayed[15] == 0 && abs_cons_i < QAM_16_SOFT_1 && abs_cons_i >= QAM_16_SOFT_0) + soft_bits[2:0] <= 3'b100; + else if(cons_i_delayed[15] == 1 && abs_cons_i < QAM_16_SOFT_1 && abs_cons_i >= QAM_16_SOFT_0) + soft_bits[2:0] <= 3'b000; + else if(cons_i_delayed[15] == 1 && abs_cons_i < QAM_16_SOFT_2 && abs_cons_i >= QAM_16_SOFT_1) + soft_bits[2:0] <= 3'b001; + else if(cons_i_delayed[15] == 1 && abs_cons_i < QAM_16_SOFT_3 && abs_cons_i >= QAM_16_SOFT_2) + soft_bits[2:0] <= 3'b010; + else if(cons_i_delayed[15] == 1 && abs_cons_i < QAM_16_SOFT_4 && abs_cons_i >= QAM_16_SOFT_3) + soft_bits[2:0] <= 3'b011; + // + else + soft_bits[2:0] <= 3'b011; + + // Quadrature soft decoded bits + if(abs_cons_q < QAM_16_SOFT_12 && abs_cons_q >= QAM_16_SOFT_11) + soft_bits[5:3] <= 3'b011; + else if(abs_cons_q < QAM_16_SOFT_11 && abs_cons_q >= QAM_16_SOFT_10) + soft_bits[5:3] <= 3'b010; + else if(abs_cons_q < QAM_16_SOFT_10 && abs_cons_q >= QAM_16_SOFT_9) + soft_bits[5:3] <= 3'b001; + else if(abs_cons_q < QAM_16_SOFT_9 && abs_cons_q >= QAM_16_SOFT_8) + soft_bits[5:3] <= 3'b000; + else if(abs_cons_q < QAM_16_SOFT_8 && abs_cons_q >= QAM_16_SOFT_7) + soft_bits[5:3] <= 3'b100; + else if(abs_cons_q < QAM_16_SOFT_7 && abs_cons_q >= QAM_16_SOFT_6) + soft_bits[5:3] <= 3'b101; + else if(abs_cons_q < QAM_16_SOFT_6 && abs_cons_q >= QAM_16_SOFT_5) + soft_bits[5:3] <= 3'b110; + else if(abs_cons_q < QAM_16_SOFT_5 && abs_cons_q >= QAM_16_SOFT_4) + soft_bits[5:3] <= 3'b111; + // + else if(cons_q_delayed[15] == 0 && abs_cons_q < QAM_16_SOFT_4 && abs_cons_q >= QAM_16_SOFT_3) + soft_bits[5:3] <= 3'b111; + else if(cons_q_delayed[15] == 0 && abs_cons_q < QAM_16_SOFT_3 && abs_cons_q >= QAM_16_SOFT_2) + soft_bits[5:3] <= 3'b110; + else if(cons_q_delayed[15] == 0 && abs_cons_q < QAM_16_SOFT_2 && abs_cons_q >= QAM_16_SOFT_1) + soft_bits[5:3] <= 3'b101; + else if(cons_q_delayed[15] == 0 && abs_cons_q < QAM_16_SOFT_1 && abs_cons_q >= QAM_16_SOFT_0) + soft_bits[5:3] <= 3'b100; + else if(cons_q_delayed[15] == 1 && abs_cons_q < QAM_16_SOFT_1 && abs_cons_q >= QAM_16_SOFT_0) + soft_bits[5:3] <= 3'b000; + else if(cons_q_delayed[15] == 1 && abs_cons_q < QAM_16_SOFT_2 && abs_cons_q >= QAM_16_SOFT_1) + soft_bits[5:3] <= 3'b001; + else if(cons_q_delayed[15] == 1 && abs_cons_q < QAM_16_SOFT_3 && abs_cons_q >= QAM_16_SOFT_2) + soft_bits[5:3] <= 3'b010; + else if(cons_q_delayed[15] == 1 && abs_cons_q < QAM_16_SOFT_4 && abs_cons_q >= QAM_16_SOFT_3) + soft_bits[5:3] <= 3'b011; + // + else + soft_bits[5:3] <= 3'b011; + + // Inphase soft decoded bit positions + if(abs_cons_i < QAM_16_SOFT_12 && abs_cons_i >= QAM_16_SOFT_4) + soft_bits_pos[1:0] <= 2'b01; + else if(abs_cons_i < QAM_16_SOFT_4) + soft_bits_pos[1:0] <= 2'b00; + else + soft_bits_pos[1:0] <= 2'b11; + + // Quadrature soft decoded bit positions + if(abs_cons_q < QAM_16_SOFT_12 && abs_cons_q >= QAM_16_SOFT_4) + soft_bits_pos[3:2] <= 2'b01; + else if(abs_cons_q < QAM_16_SOFT_4) + soft_bits_pos[3:2] <= 2'b00; + else + soft_bits_pos[3:2] <= 2'b11; end QAM_64: begin + // Hard decoded bits bits[0] <= ~cons_i_delayed[15]; bits[1] <= abs_cons_i < QAM_64_DIV_1? 1: 0; bits[2] <= abs_cons_i > QAM_64_DIV_0 && @@ -108,6 +351,174 @@ always @(posedge clock) begin bits[4] <= abs_cons_q < QAM_64_DIV_1? 1: 0; bits[5] <= abs_cons_q > QAM_64_DIV_0 && abs_cons_q < QAM_64_DIV_2? 1: 0; + + // Inphase soft decoded bits + if(abs_cons_i < QAM_64_SOFT_28 && abs_cons_i >= QAM_64_SOFT_27) + soft_bits[2:0] <= 3'b011; + else if(abs_cons_i < QAM_64_SOFT_27 && abs_cons_i >= QAM_64_SOFT_26) + soft_bits[2:0] <= 3'b010; + else if(abs_cons_i < QAM_64_SOFT_26 && abs_cons_i >= QAM_64_SOFT_25) + soft_bits[2:0] <= 3'b001; + else if(abs_cons_i < QAM_64_SOFT_25 && abs_cons_i >= QAM_64_SOFT_24) + soft_bits[2:0] <= 3'b000; + else if(abs_cons_i < QAM_64_SOFT_24 && abs_cons_i >= QAM_64_SOFT_23) + soft_bits[2:0] <= 3'b100; + else if(abs_cons_i < QAM_64_SOFT_23 && abs_cons_i >= QAM_64_SOFT_22) + soft_bits[2:0] <= 3'b101; + else if(abs_cons_i < QAM_64_SOFT_22 && abs_cons_i >= QAM_64_SOFT_21) + soft_bits[2:0] <= 3'b110; + else if(abs_cons_i < QAM_64_SOFT_21 && abs_cons_i >= QAM_64_SOFT_20) + soft_bits[2:0] <= 3'b111; + // + else if(abs_cons_i < QAM_64_SOFT_20 && abs_cons_i >= QAM_64_SOFT_19) + soft_bits[2:0] <= 3'b010; + else if(abs_cons_i < QAM_64_SOFT_19 && abs_cons_i >= QAM_64_SOFT_18) + soft_bits[2:0] <= 3'b010; + else if(abs_cons_i < QAM_64_SOFT_18 && abs_cons_i >= QAM_64_SOFT_17) + soft_bits[2:0] <= 3'b001; + else if(abs_cons_i < QAM_64_SOFT_17 && abs_cons_i >= QAM_64_SOFT_16) + soft_bits[2:0] <= 3'b000; + else if(abs_cons_i < QAM_64_SOFT_16 && abs_cons_i >= QAM_64_SOFT_15) + soft_bits[2:0] <= 3'b100; + else if(abs_cons_i < QAM_64_SOFT_15 && abs_cons_i >= QAM_64_SOFT_14) + soft_bits[2:0] <= 3'b101; + else if(abs_cons_i < QAM_64_SOFT_14 && abs_cons_i >= QAM_64_SOFT_13) + soft_bits[2:0] <= 3'b110; + else if(abs_cons_i < QAM_64_SOFT_13 && abs_cons_i >= QAM_64_SOFT_12) + soft_bits[2:0] <= 3'b111; + // + else if(abs_cons_i < QAM_64_SOFT_12 && abs_cons_i >= QAM_64_SOFT_11) + soft_bits[2:0] <= 3'b111; + else if(abs_cons_i < QAM_64_SOFT_11 && abs_cons_i >= QAM_64_SOFT_10) + soft_bits[2:0] <= 3'b110; + else if(abs_cons_i < QAM_64_SOFT_10 && abs_cons_i >= QAM_64_SOFT_9) + soft_bits[2:0] <= 3'b101; + else if(abs_cons_i < QAM_64_SOFT_9 && abs_cons_i >= QAM_64_SOFT_8) + soft_bits[2:0] <= 3'b100; + else if(abs_cons_i < QAM_64_SOFT_8 && abs_cons_i >= QAM_64_SOFT_7) + soft_bits[2:0] <= 3'b000; + else if(abs_cons_i < QAM_64_SOFT_7 && abs_cons_i >= QAM_64_SOFT_6) + soft_bits[2:0] <= 3'b001; + else if(abs_cons_i < QAM_64_SOFT_6 && abs_cons_i >= QAM_64_SOFT_5) + soft_bits[2:0] <= 3'b010; + else if(abs_cons_i < QAM_64_SOFT_5 && abs_cons_i >= QAM_64_SOFT_4) + soft_bits[2:0] <= 3'b011; + // + else if(cons_i_delayed[15] == 0 && abs_cons_i < QAM_64_SOFT_4 && abs_cons_i >= QAM_64_SOFT_3) + soft_bits[2:0] <= 3'b111; + else if(cons_i_delayed[15] == 0 && abs_cons_i < QAM_64_SOFT_3 && abs_cons_i >= QAM_64_SOFT_2) + soft_bits[2:0] <= 3'b110; + else if(cons_i_delayed[15] == 0 && abs_cons_i < QAM_64_SOFT_2 && abs_cons_i >= QAM_64_SOFT_1) + soft_bits[2:0] <= 3'b101; + else if(cons_i_delayed[15] == 0 && abs_cons_i < QAM_64_SOFT_1 && abs_cons_i >= QAM_64_SOFT_0) + soft_bits[2:0] <= 3'b100; + else if(cons_i_delayed[15] == 1 && abs_cons_i < QAM_64_SOFT_1 && abs_cons_i >= QAM_64_SOFT_0) + soft_bits[2:0] <= 3'b000; + else if(cons_i_delayed[15] == 1 && abs_cons_i < QAM_64_SOFT_2 && abs_cons_i >= QAM_64_SOFT_1) + soft_bits[2:0] <= 3'b001; + else if(cons_i_delayed[15] == 1 && abs_cons_i < QAM_64_SOFT_3 && abs_cons_i >= QAM_64_SOFT_2) + soft_bits[2:0] <= 3'b010; + else if(cons_i_delayed[15] == 1 && abs_cons_i < QAM_64_SOFT_4 && abs_cons_i >= QAM_64_SOFT_3) + soft_bits[2:0] <= 3'b011; + // + else + soft_bits[2:0] <= 3'b011; + + // Quadrature soft decoded bits + if(abs_cons_q < QAM_64_SOFT_28 && abs_cons_q >= QAM_64_SOFT_27) + soft_bits[5:3] <= 3'b011; + else if(abs_cons_q < QAM_64_SOFT_27 && abs_cons_q >= QAM_64_SOFT_26) + soft_bits[5:3] <= 3'b010; + else if(abs_cons_q < QAM_64_SOFT_26 && abs_cons_q >= QAM_64_SOFT_25) + soft_bits[5:3] <= 3'b001; + else if(abs_cons_q < QAM_64_SOFT_25 && abs_cons_q >= QAM_64_SOFT_24) + soft_bits[5:3] <= 3'b000; + else if(abs_cons_q < QAM_64_SOFT_24 && abs_cons_q >= QAM_64_SOFT_23) + soft_bits[5:3] <= 3'b100; + else if(abs_cons_q < QAM_64_SOFT_23 && abs_cons_q >= QAM_64_SOFT_22) + soft_bits[5:3] <= 3'b101; + else if(abs_cons_q < QAM_64_SOFT_22 && abs_cons_q >= QAM_64_SOFT_21) + soft_bits[5:3] <= 3'b110; + else if(abs_cons_q < QAM_64_SOFT_21 && abs_cons_q >= QAM_64_SOFT_20) + soft_bits[5:3] <= 3'b111; + // + else if(abs_cons_q < QAM_64_SOFT_20 && abs_cons_q >= QAM_64_SOFT_19) + soft_bits[5:3] <= 3'b010; + else if(abs_cons_q < QAM_64_SOFT_19 && abs_cons_q >= QAM_64_SOFT_18) + soft_bits[5:3] <= 3'b010; + else if(abs_cons_q < QAM_64_SOFT_18 && abs_cons_q >= QAM_64_SOFT_17) + soft_bits[5:3] <= 3'b001; + else if(abs_cons_q < QAM_64_SOFT_17 && abs_cons_q >= QAM_64_SOFT_16) + soft_bits[5:3] <= 3'b000; + else if(abs_cons_q < QAM_64_SOFT_16 && abs_cons_q >= QAM_64_SOFT_15) + soft_bits[5:3] <= 3'b100; + else if(abs_cons_q < QAM_64_SOFT_15 && abs_cons_q >= QAM_64_SOFT_14) + soft_bits[5:3] <= 3'b101; + else if(abs_cons_q < QAM_64_SOFT_14 && abs_cons_q >= QAM_64_SOFT_13) + soft_bits[5:3] <= 3'b110; + else if(abs_cons_q < QAM_64_SOFT_13 && abs_cons_q >= QAM_64_SOFT_12) + soft_bits[5:3] <= 3'b111; + // + else if(abs_cons_q < QAM_64_SOFT_12 && abs_cons_q >= QAM_64_SOFT_11) + soft_bits[5:3] <= 3'b111; + else if(abs_cons_q < QAM_64_SOFT_11 && abs_cons_q >= QAM_64_SOFT_10) + soft_bits[5:3] <= 3'b110; + else if(abs_cons_q < QAM_64_SOFT_10 && abs_cons_q >= QAM_64_SOFT_9) + soft_bits[5:3] <= 3'b101; + else if(abs_cons_q < QAM_64_SOFT_9 && abs_cons_q >= QAM_64_SOFT_8) + soft_bits[5:3] <= 3'b100; + else if(abs_cons_q < QAM_64_SOFT_8 && abs_cons_q >= QAM_64_SOFT_7) + soft_bits[5:3] <= 3'b000; + else if(abs_cons_q < QAM_64_SOFT_7 && abs_cons_q >= QAM_64_SOFT_6) + soft_bits[5:3] <= 3'b001; + else if(abs_cons_q < QAM_64_SOFT_6 && abs_cons_q >= QAM_64_SOFT_5) + soft_bits[5:3] <= 3'b010; + else if(abs_cons_q < QAM_64_SOFT_5 && abs_cons_q >= QAM_64_SOFT_4) + soft_bits[5:3] <= 3'b011; + // + else if(cons_q_delayed[15] == 0 && abs_cons_q < QAM_64_SOFT_4 && abs_cons_q >= QAM_64_SOFT_3) + soft_bits[5:3] <= 3'b111; + else if(cons_q_delayed[15] == 0 && abs_cons_q < QAM_64_SOFT_3 && abs_cons_q >= QAM_64_SOFT_2) + soft_bits[5:3] <= 3'b110; + else if(cons_q_delayed[15] == 0 && abs_cons_q < QAM_64_SOFT_2 && abs_cons_q >= QAM_64_SOFT_1) + soft_bits[5:3] <= 3'b101; + else if(cons_q_delayed[15] == 0 && abs_cons_q < QAM_64_SOFT_1 && abs_cons_q >= QAM_64_SOFT_0) + soft_bits[5:3] <= 3'b100; + else if(cons_q_delayed[15] == 1 && abs_cons_q < QAM_64_SOFT_1 && abs_cons_q >= QAM_64_SOFT_0) + soft_bits[5:3] <= 3'b000; + else if(cons_q_delayed[15] == 1 && abs_cons_q < QAM_64_SOFT_2 && abs_cons_q >= QAM_64_SOFT_1) + soft_bits[5:3] <= 3'b001; + else if(cons_q_delayed[15] == 1 && abs_cons_q < QAM_64_SOFT_3 && abs_cons_q >= QAM_64_SOFT_2) + soft_bits[5:3] <= 3'b010; + else if(cons_q_delayed[15] == 1 && abs_cons_q < QAM_64_SOFT_4 && abs_cons_q >= QAM_64_SOFT_3) + soft_bits[5:3] <= 3'b011; + // + else + soft_bits[5:3] <= 3'b011; + + // Inphase soft decoded bit positions + if(abs_cons_i < QAM_64_SOFT_28 && abs_cons_i >= QAM_64_SOFT_20) + soft_bits_pos[1:0] <= 2'b10; + else if(abs_cons_i < QAM_64_SOFT_20 && abs_cons_i >= QAM_64_SOFT_12) + soft_bits_pos[1:0] <= 2'b01; + else if(abs_cons_i < QAM_64_SOFT_12 && abs_cons_i >= QAM_64_SOFT_4) + soft_bits_pos[1:0] <= 2'b10; + else if(abs_cons_i < QAM_64_SOFT_4) + soft_bits_pos[1:0] <= 2'b00; + else + soft_bits_pos[1:0] <= 2'b11; + + // Quadrature soft decoded bit positions + if(abs_cons_q < QAM_64_SOFT_28 && abs_cons_q >= QAM_64_SOFT_20) + soft_bits_pos[3:2] <= 2'b10; + else if(abs_cons_q < QAM_64_SOFT_20 && abs_cons_q >= QAM_64_SOFT_12) + soft_bits_pos[3:2] <= 2'b01; + else if(abs_cons_q < QAM_64_SOFT_12 && abs_cons_q >= QAM_64_SOFT_4) + soft_bits_pos[3:2] <= 2'b10; + else if(abs_cons_q < QAM_64_SOFT_4) + soft_bits_pos[3:2] <= 2'b00; + else + soft_bits_pos[3:2] <= 2'b11; end endcase end diff --git a/verilog/dot11.v b/verilog/dot11.v index c051b22..c1f0106 100644 --- a/verilog/dot11.v +++ b/verilog/dot11.v @@ -19,6 +19,7 @@ module dot11 ( // INPUT: I/Q sample (* mark_debug = "true" *) input [31:0] sample_in, (* mark_debug = "true" *) input sample_in_strobe, + (* mark_debug = "true" *) input soft_decoding, // OUTPUT: bytes and FCS status (* mark_debug = "true" *) output reg demod_is_ongoing, @@ -93,7 +94,7 @@ module dot11 ( output [5:0] demod_out, output demod_out_strobe, - output [3:0] deinterleave_erase_out, + output [7:0] deinterleave_erase_out, output deinterleave_erase_out_strobe, output conv_decoder_out, @@ -369,6 +370,7 @@ ofdm_decoder ofdm_decoder_inst ( .sample_in({ofdm_in_i, ofdm_in_q}), .sample_in_strobe(ofdm_in_stb), + .soft_decoding(soft_decoding), .do_descramble(do_descramble), .num_bits_to_decode(num_bits_to_decode), diff --git a/verilog/dot11_tb.v b/verilog/dot11_tb.v index 7c5d651..f95ad6b 100644 --- a/verilog/dot11_tb.v +++ b/verilog/dot11_tb.v @@ -29,7 +29,7 @@ wire equalizer_out_strobe; wire [5:0] demod_out; wire demod_out_strobe; -wire [3:0] deinterleave_erase_out; +wire [7:0] deinterleave_erase_out; wire deinterleave_erase_out_strobe; wire conv_decoder_out; @@ -234,7 +234,7 @@ always @(posedge clock) begin end if (dot11_state == S_DECODE_DATA && deinterleave_erase_out_strobe) begin - $fwrite(deinterleave_erase_out_fd, "%b %b %b %b\n", deinterleave_erase_out[0], deinterleave_erase_out[1], deinterleave_erase_out[2], deinterleave_erase_out[3]); + $fwrite(deinterleave_erase_out_fd, "%b %b %b %b %b %b %b %b\n", deinterleave_erase_out[0], deinterleave_erase_out[1], deinterleave_erase_out[2], deinterleave_erase_out[3], deinterleave_erase_out[4], deinterleave_erase_out[5], deinterleave_erase_out[6], deinterleave_erase_out[7]); $fflush(deinterleave_erase_out_fd); end diff --git a/verilog/ofdm_decoder.v b/verilog/ofdm_decoder.v index 8ef27ae..71f160e 100644 --- a/verilog/ofdm_decoder.v +++ b/verilog/ofdm_decoder.v @@ -6,6 +6,7 @@ module ofdm_decoder input [31:0] sample_in, input sample_in_strobe, + input soft_decoding, // decode instructions input [7:0] rate, @@ -15,7 +16,7 @@ module ofdm_decoder (* mark_debug = "false" *) output [5:0] demod_out, (* mark_debug = "false" *) output demod_out_strobe, - (* mark_debug = "false" *) output [3:0] deinterleave_erase_out, + (* mark_debug = "false" *) output [7:0] deinterleave_erase_out, (* mark_debug = "false" *) output deinterleave_erase_out_strobe, (* mark_debug = "false" *) output conv_decoder_out, @@ -28,6 +29,9 @@ module ofdm_decoder output byte_out_strobe ); +wire [5:0] demod_soft_bits; +wire [3:0] demod_soft_bits_pos; + reg conv_in_stb, conv_in_stb_dly, do_descramble_dly; reg [2:0] conv_in0, conv_in0_dly; reg [2:0] conv_in1, conv_in1_dly; @@ -42,7 +46,7 @@ wire vit_clr = reset; reg vit_clr_dly; wire vit_rdy; -wire [1:0] deinterleave_out; +wire [5:0] deinterleave_out; wire deinterleave_out_strobe; wire [1:0] erase; @@ -67,6 +71,8 @@ demodulate demod_inst ( .cons_q(input_q), .input_strobe(sample_in_strobe), .bits(demod_out), + .soft_bits(demod_soft_bits), + .soft_bits_pos(demod_soft_bits_pos), .output_strobe(demod_out_strobe) ); @@ -77,7 +83,10 @@ deinterleave deinterleave_inst ( .rate(rate), .in_bits(demod_out), + .soft_in_bits(demod_soft_bits), + .soft_in_bits_pos(demod_soft_bits_pos), .input_strobe(demod_out_strobe), + .soft_decoding(soft_decoding), .out_bits(deinterleave_out), .output_strobe(deinterleave_out_strobe), @@ -164,8 +173,8 @@ always @(posedge clock) begin //if (!flush) begin if (!(deinter_out_count >= num_bits_to_decode)) begin conv_in_stb <= deinterleave_out_strobe; - conv_in0 <= deinterleave_out[0]? 3'b111: 3'b011; - conv_in1 <= deinterleave_out[1]? 3'b111: 3'b011; + conv_in0 <= deinterleave_out[2:0]; + conv_in1 <= deinterleave_out[5:3]; conv_erase <= erase; end else begin conv_in_stb <= 1;