soft decoding support for BPSK, QPSK, 16-QAM and 64-QAM

This commit is contained in:
mmehari 2019-12-10 13:45:43 +01:00
parent 2643844f2f
commit 1f8bb83587
5 changed files with 515 additions and 14 deletions

View File

@ -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 (

View File

@ -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

View File

@ -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),

View File

@ -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

View File

@ -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;