mirror of
https://github.com/jhshi/openofdm.git
synced 2024-12-21 06:33:48 +00:00
160 lines
3.6 KiB
Verilog
160 lines
3.6 KiB
Verilog
/*
|
|
* OFDM deinterleaver
|
|
*/
|
|
module deinterleave
|
|
(
|
|
input clock,
|
|
input reset,
|
|
input enable,
|
|
|
|
input [7:0] rate,
|
|
input [5:0] in_bits,
|
|
input input_strobe,
|
|
|
|
output [1:0] out_bits,
|
|
output [1:0] erase,
|
|
output output_strobe
|
|
);
|
|
|
|
wire ht = rate[7];
|
|
|
|
wire [5:0] num_data_carrier = ht? 52: 48;
|
|
wire [5:0] half_data_carrier = ht? 26: 24;
|
|
|
|
reg [5:0] addra;
|
|
reg [5:0] addrb;
|
|
|
|
reg [10:0] lut_key;
|
|
wire [21:0] lut_out;
|
|
wire [21:0] lut_out_delayed;
|
|
|
|
reg lut_valid;
|
|
wire lut_valid_delayed;
|
|
|
|
assign erase[0] = lut_out_delayed[21];
|
|
assign erase[1] = lut_out_delayed[20];
|
|
|
|
wire [2:0] lut_bita = lut_out_delayed[7:5];
|
|
wire [2:0] lut_bitb = lut_out_delayed[4:2];
|
|
|
|
wire [5:0] bit_outa;
|
|
wire [5:0] bit_outb;
|
|
|
|
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];
|
|
wire [5:0] lut_addrb = lut_out[13:8];
|
|
wire lut_done = lut_out[0];
|
|
|
|
reg ram_delay;
|
|
reg ht_delayed;
|
|
|
|
ram_2port #(.DWIDTH(6), .AWIDTH(6)) ram_inst (
|
|
.clka(clock),
|
|
.ena(1),
|
|
.wea(input_strobe),
|
|
.addra(addra),
|
|
.dia(in_bits),
|
|
.doa(bit_outa),
|
|
.clkb(clock),
|
|
.enb(1),
|
|
.web(0),
|
|
.addrb(addrb),
|
|
.dib(32'hFFFF),
|
|
.dob(bit_outb)
|
|
);
|
|
|
|
deinter_lut lut_inst (
|
|
.clka(clock),
|
|
.addra(lut_key),
|
|
.douta(lut_out)
|
|
);
|
|
|
|
delayT #(.DATA_WIDTH(23), .DELAY(2)) delay_inst (
|
|
.clock(clock),
|
|
.reset(reset),
|
|
|
|
.data_in({lut_valid, lut_out}),
|
|
.data_out({lut_valid_delayed, lut_out_delayed})
|
|
);
|
|
|
|
|
|
localparam S_INPUT = 0;
|
|
localparam S_GET_BASE = 1;
|
|
localparam S_OUTPUT = 2;
|
|
|
|
reg [1:0] state;
|
|
|
|
always @(posedge clock) begin
|
|
if (reset) begin
|
|
addra <= num_data_carrier>>1;
|
|
addrb <= 0;
|
|
|
|
lut_key <= 0;
|
|
lut_valid <= 0;
|
|
ht_delayed <= 0;
|
|
|
|
ram_delay <= 0;
|
|
state <= S_INPUT;
|
|
end else if (enable) begin
|
|
ht_delayed <= ht;
|
|
if (ht != ht_delayed) begin
|
|
addra <= num_data_carrier>>1;
|
|
end
|
|
|
|
case(state)
|
|
S_INPUT: begin
|
|
if (input_strobe) begin
|
|
if (addra == half_data_carrier-1) begin
|
|
lut_key <= {6'b0, ht, rate[3:0]};
|
|
ram_delay <= 0;
|
|
lut_valid <= 0;
|
|
state <= S_GET_BASE;
|
|
end else begin
|
|
if (addra == num_data_carrier-1) begin
|
|
addra <= 0;
|
|
end else begin
|
|
addra <= addra + 1;
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
S_GET_BASE: begin
|
|
if (ram_delay) begin
|
|
lut_key <= lut_out;
|
|
ram_delay <= 0;
|
|
state <= S_OUTPUT;
|
|
end else begin
|
|
ram_delay <= 1;
|
|
end
|
|
end
|
|
|
|
S_OUTPUT: begin
|
|
if (ram_delay) begin
|
|
addra <= lut_addra;
|
|
addrb <= lut_addrb;
|
|
if (lut_done) begin
|
|
lut_key <= 0;
|
|
lut_valid <= 0;
|
|
state <= S_INPUT;
|
|
end else begin
|
|
lut_valid <= 1;
|
|
lut_key <= lut_key + 1;
|
|
end
|
|
end else begin
|
|
ram_delay <= 1;
|
|
lut_valid <= 1;
|
|
lut_key <= lut_key + 1;
|
|
end
|
|
end
|
|
default: begin
|
|
end
|
|
endcase
|
|
end
|
|
end
|
|
|
|
endmodule
|