mirror of
https://github.com/Nuand/bladeRF-wiphy.git
synced 2024-12-29 18:19:10 +00:00
234 lines
6.8 KiB
VHDL
234 lines
6.8 KiB
VHDL
-- This file is part of bladeRF-wiphy.
|
|
--
|
|
-- Copyright (C) 2020 Nuand, LLC.
|
|
--
|
|
-- This program is free software; you can redistribute it and/or modify
|
|
-- it under the terms of the GNU General Public License as published by
|
|
-- the Free Software Foundation; either version 2 of the License, or
|
|
-- (at your option) any later version.
|
|
--
|
|
-- This program is distributed in the hope that it will be useful,
|
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
-- GNU General Public License for more details.
|
|
--
|
|
-- You should have received a copy of the GNU General Public License along
|
|
-- with this program; if not, write to the Free Software Foundation, Inc.,
|
|
-- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
library ieee ;
|
|
use ieee.std_logic_1164.all ;
|
|
use ieee.numeric_std.all ;
|
|
|
|
library work ;
|
|
use work.wlan_p.all ;
|
|
use work.wlan_tx_p.all ;
|
|
|
|
entity wlan_tx_controller is
|
|
port (
|
|
clock : in std_logic ;
|
|
reset : in std_logic ;
|
|
|
|
-- Control from the MAC
|
|
tx_vector : in wlan_tx_vector_t ;
|
|
tx_vector_valid : in std_logic ;
|
|
|
|
-- Caculated parameters
|
|
params : out wlan_tx_params_t ;
|
|
params_valid : out std_logic ;
|
|
|
|
-- TX status generation
|
|
status : out wlan_tx_status_t ;
|
|
status_valid : out std_logic ;
|
|
|
|
-- Encoder from MAC
|
|
encoder_start : out std_logic ;
|
|
encoder_done : in std_logic ;
|
|
|
|
-- Short preamble control and status
|
|
short_start : out std_logic ;
|
|
short_done : in std_logic ;
|
|
|
|
-- Long preamble control and status
|
|
long_done : in std_logic ;
|
|
|
|
-- Modulator control and status
|
|
mod_init : out std_logic ;
|
|
mod_end : in std_logic ;
|
|
|
|
-- TX done
|
|
tx_done : in std_logic
|
|
) ;
|
|
end entity ;
|
|
|
|
architecture arch of wlan_tx_controller is
|
|
|
|
type fsm_t is (IDLE, START_TRANSMISSION, START_ENCODING_DATA, WAIT_FOR_PREAMBLE_DONE, WAIT_FOR_TX_DONE) ;
|
|
|
|
type state_t is record
|
|
fsm : fsm_t ;
|
|
params : wlan_tx_params_t ;
|
|
params_valid : std_logic ;
|
|
short_start : std_logic ;
|
|
encoder_start : std_logic ;
|
|
mod_init : std_logic ;
|
|
status_valid : std_logic ;
|
|
end record ;
|
|
|
|
function calculate_params( x : wlan_tx_vector_t ) return wlan_tx_params_t is
|
|
variable rv : wlan_tx_params_t ;
|
|
begin
|
|
rv.datarate := x.datarate ;
|
|
rv.length := x.length ;
|
|
rv.lfsr_init := "1011101" ;
|
|
|
|
case x.datarate is
|
|
when WLAN_RATE_6 =>
|
|
-- BPSK R=1/2
|
|
rv.n_bpsc := 1 ;
|
|
rv.n_dbps := 24 ;
|
|
rv.n_cbps := 48 ;
|
|
rv.modulation := WLAN_BPSK ;
|
|
|
|
when WLAN_RATE_9 =>
|
|
-- BPSK R=3/4
|
|
rv.n_bpsc := 1 ;
|
|
rv.n_dbps := 36 ;
|
|
rv.n_cbps := 48 ;
|
|
rv.modulation := WLAN_BPSK ;
|
|
|
|
when WLAN_RATE_12 =>
|
|
-- QPSK R=1/2
|
|
rv.n_bpsc := 2 ;
|
|
rv.n_dbps := 48 ;
|
|
rv.n_cbps := 96 ;
|
|
rv.modulation := WLAN_QPSK ;
|
|
|
|
when WLAN_RATE_18 =>
|
|
-- QPSK R=3/4
|
|
rv.n_bpsc := 2 ;
|
|
rv.n_dbps := 72 ;
|
|
rv.n_cbps := 96 ;
|
|
rv.modulation := WLAN_QPSK ;
|
|
|
|
when WLAN_RATE_24 =>
|
|
-- 16-QAM R=1/2
|
|
rv.n_bpsc := 4 ;
|
|
rv.n_dbps := 96 ;
|
|
rv.n_cbps := 192 ;
|
|
rv.modulation := WLAN_16QAM ;
|
|
|
|
when WLAN_RATE_36 =>
|
|
-- 16-QAM R=3/4
|
|
rv.n_bpsc := 4 ;
|
|
rv.n_dbps := 144 ;
|
|
rv.n_cbps := 192 ;
|
|
rv.modulation := WLAN_16QAM ;
|
|
|
|
when WLAN_RATE_48 =>
|
|
-- 64-QAM R=2/3
|
|
rv.n_bpsc := 6 ;
|
|
rv.n_dbps := 192 ;
|
|
rv.n_cbps := 288 ;
|
|
rv.modulation := WLAN_64QAM ;
|
|
|
|
when WLAN_RATE_54 =>
|
|
-- 64-QAM R=3/4
|
|
rv.n_bpsc := 6 ;
|
|
rv.n_dbps := 216 ;
|
|
rv.n_cbps := 288;
|
|
rv.modulation := WLAN_64QAM ;
|
|
|
|
when others =>
|
|
report "Invalid params" severity failure ;
|
|
end case ;
|
|
|
|
case x.bandwidth is
|
|
when WLAN_BW_5 =>
|
|
null ;
|
|
|
|
when WLAN_BW_10 =>
|
|
null ;
|
|
|
|
when WLAN_BW_20 =>
|
|
null ;
|
|
|
|
when others =>
|
|
report "Invalid bandwidth" severity failure ;
|
|
end case ;
|
|
|
|
return rv ;
|
|
end function ;
|
|
|
|
function NULL_STATE return state_t is
|
|
variable rv : state_t ;
|
|
begin
|
|
rv.fsm := IDLE ;
|
|
rv.params_valid := '0' ;
|
|
rv.short_start := '0' ;
|
|
rv.encoder_start := '0' ;
|
|
rv.mod_init := '0' ;
|
|
rv.status_valid := '0' ;
|
|
return rv ;
|
|
end function ;
|
|
|
|
signal current, future : state_t := NULL_STATE ;
|
|
|
|
begin
|
|
|
|
params <= current.params ;
|
|
params_valid <= current.params_valid ;
|
|
short_start <= current.short_start ;
|
|
encoder_start <= current.encoder_start ;
|
|
mod_init <= current.mod_init ;
|
|
|
|
sync : process(clock, reset)
|
|
begin
|
|
if( reset = '1' ) then
|
|
current <= NULL_STATE ;
|
|
elsif( rising_edge(clock) ) then
|
|
current <= future ;
|
|
end if ;
|
|
end process ;
|
|
|
|
comb : process(all)
|
|
begin
|
|
future <= current ;
|
|
future.params_valid <= '0' ;
|
|
future.short_start <= '0' ;
|
|
future.encoder_start <= '0' ;
|
|
future.mod_init <= '0' ;
|
|
future.status_valid <= '0' ;
|
|
case current.fsm is
|
|
when IDLE =>
|
|
future.params_valid <= tx_vector_valid ;
|
|
if( tx_vector_valid = '1' ) then
|
|
future.params <= calculate_params(tx_vector) ;
|
|
future.fsm <= START_TRANSMISSION ;
|
|
end if ;
|
|
|
|
when START_TRANSMISSION =>
|
|
future.short_start <= '1' ;
|
|
future.fsm <= START_ENCODING_DATA ;
|
|
|
|
when START_ENCODING_DATA =>
|
|
future.fsm <= WAIT_FOR_PREAMBLE_DONE ;
|
|
|
|
when WAIT_FOR_PREAMBLE_DONE =>
|
|
if( long_done = '1' ) then
|
|
future.fsm <= WAIT_FOR_TX_DONE ;
|
|
future.encoder_start <= '1' ;
|
|
future.mod_init <= '1' ;
|
|
end if ;
|
|
|
|
when WAIT_FOR_TX_DONE =>
|
|
if( tx_done = '1' ) then
|
|
future.fsm <= IDLE ;
|
|
end if ;
|
|
|
|
end case ;
|
|
end process ;
|
|
|
|
end architecture ;
|
|
|