%% HDL Optimized QPSK Transmitter
% This example shows how to optimize the QPSK transmitter modeled in the
% <matlab:showdemo('commqpsktxrx') QPSK Transmitter and Receiver example>
% for HDL code generation and hardware implementation.

% Copyright 2014-2018 The MathWorks, Inc.

%% Introduction
%%
% 
% The HDL Optimized QPSK Transmitter example shows how Simulink blocks that support HDL code generation can be used to 
% implement the baseband processing of a digital communications
% transmitter.
% 
% The HDLTx subsystem can be cascaded with the HDLRx subsystem given in the
% <matlab:showdemo('hdlcoder_commqpskrx') HDL Optimized QPSK Receiver example>, in order to form a complete QPSK
% transmitter-receiver chain from which HDL code can be generated.
%
% At the top level of hierarchy, there are two components: HDLTx and Signal Quality
% Measurement. The HDLTx subsystem has been optimized for HDL code
% generation by using hardware friendly blocks and design practices.
%
% The HDLTx subsystem generates the In-phase (I) and Quadrature (Q)
% channels representing a  QPSK (Quaternary-Phase-Shift-Keying) symbol
% mapping. This is sent in as a complex valued vector to the Root Raised
% Cosine (RRC) transmit pulse shaping filter. The output of the HDLTx subsystem therefore consists
% of the pulse shaped and upsampled symbols.
% 
% The Signal Quality Measurement subsystem is intended for software based validation
% of the design and is therefore not supported for HDL code generation.
% 
% The Signal Quality Measurement component consists of the matching
% RRC receive filter and a Constellation Diagram scope. The purpose of the
% scope is twofold. It both displays the output data, and calculates the 
% Error Vector Magnitude (EVM) and Modulation Error Ratio (MER) values. This
% allows the designer to investigate the noise introduced
% into the system from the RRC filter design. This will arise from two sources -
% (a) the quantization of the coefficient values in the RRC filter and (b) 
% the truncated impulse response of the RRC filter (roll-off factor 0.5). The EVM can therefore
% be improved by either increasing the number of fractional bits for the
% coefficient values or by redesigning the RRC filter to give an improved response. 

  modelname = 'hdlcoder_commqpsktx';
  open_system(modelname);
  close_system('hdlcoder_commqpsktx/Signal Quality Measurement/Constellation Diagram');
  set_param(modelname, 'Open', 'on');
%% Overview of HDL Optimized QPSK Tx
%
% The HDLTx component is composed of three subsystems - 
%
% * Data Generation & Packetization
% * Symbol Mapping 
% * Pulse Shaping
%
% Pipeline registers are inserted between the subsystems in order to minimize the combinatorial path delay 
% between components and therefore maximize the achievable clock frequency
% (i.e. minimizing the critical path delay).
% The Data Generation & Packetization subsystem contains several
% sub-components, which are also pipelined. There is, therefore, a fixed latency
% before valid data appears at the input to the Pulse Shaping component.
% To ensure that only valid data is transmitted, valid out and valid in ports are
% included which are used to control a 2:1 Multiplexer (Input Mux).
%

  set_param(modelname, 'Open', 'off'); 
  set_param([modelname '/HDLTx'], 'Open', 'on'); 

  
%%
% The Data Generation & Packetization, Symbol Mapping, and Pulse Shaping subsystems are
% further described in the following sections.
%
% 1 - *Data Generation & Packetization*
%
% The following figure illustrates the top level hierarchy of the
% component. 
% The Packetizer FSM and Data Source generate both the preamble and data
% bits, and perform scrambling and packetization. The packets consist of a
% 26 bit Barker code preamble and 174 bits of scrambled data. The Barker code
% preamble is used in the <matlab:showdemo('hdlcoder_commqpskrx') HDL Optimized QPSK Receiver Example> for autocorrelation based packet detection 
% via the use of a matched filter. The Bit Pairing subsystem converts
% the single bit serial data input into a two bit output of half the sampling rate,
% providing the correct data format for the symbol mapper. Internally, the
% data source block has a pipeline delay of 2 samples. In addition, there
% is a pipeline delay between the data source and the bit pairing
% subsystem. The valid signal is therefore delayed to match the
% pipeline delay of the data path. The Bit Pairing subsystem reduces the
% sample rate by a factor of 2. Placing a downsample by two in the valid
% control path ensures that the
% sample rate of the valid control path matches that of the signal path.

  set_param(modelname, 'Open', 'off'); 
  set_param([modelname '/HDLTx/Data Generation & Packetization'], 'Open', 'on'); 
  
%%
% * *Packetizer FSM* - 
% The Packetizer FSM component consists of a Moore machine, created using a MATLAB(TM) function block.
% The FSM has two states - Pack_Preamble, and Append_Data. The  Pack_Preamble state serves to
% enable the preamble counter via the load_preamble output. The preamble counter
% generates the address signal for the preamble Lookup Table (LUT), incrementing from 0 --> 25. Following
% this, the FSM moves into the Append_Data state, asserting the load_data signal, where it shall
% remain for 174 cycles. During this time, the reset_preamble output is
% held high, while the load_preamble output is held low. 
% The FSM shall sequentially switch between the two states
% in turn.
  
%%
% * *Data Source* - 
% As shown in the following figure, the Data Source component contains two
% LUTs, containing the preamble and data bits. The
% preamble bits are invariant between packets, and so the counter used to address the preamble
% LUT is reset after the loading of each preamble. The counter used to address the
% data LUT is allowed to wrap around after reaching the maximum address value,
% which corresponds to the final character of the packet body string "Hello World 099".
% Each of the LUTs is zero
% padded in order to ensure that the number of data entries is of a power of two
% length. In addition to enabling the counter for the data
% LUT, the load data input is used to control when the data scrambler
% component should be enabled, and to control whether the preamble or data
% bits should be passed to the output via the 2:1 Preamble Data Mux.

set_param([modelname '/HDLTx/Data Generation & Packetization/PacketizerFSM'], 'Open', 'off'); 
set_param([modelname '/HDLTx/Data Generation & Packetization/Data Source'], 'Open' ,'on'); 


%%
% * *Data Scrambler* -
% The data scrambler is detailed in the following figure. The scrambler is 
% built from first principles using XOR gates (for modulo 2 addition) and registers. By using
% an enabled subsystem, it is ensured that the scrambler is only enabled
% when there is new input data to be processed.
%

set_param([modelname '/HDLTx/Data Generation & Packetization/Data Source'], 'Open', 'off'); 
set_param([modelname '/HDLTx/Data Generation & Packetization/Data Source/HDL Data Scrambler'], 'Open' ,'on');

%%
% * *Bit Pairing*-
% The purpose of the Bit Pairing subsystem is to group pairs of bits into an 
% unsigned two bit output - the input format expected by the symbol mapping component. To achieve this, a pair of
% downsamplers are used to reduce the sample rate by a factor of two, with
% the first downsampler selecting the second phase and the second downsampler selecting
% the first phase. The Bit Concat block concatenates the single bit
% inputs into an unsigned two bit output.


set_param([modelname '/HDLTx/Data Generation & Packetization/Data Source/HDL Data Scrambler'], 'Open', 'off'); 
set_param([modelname '/HDLTx/Data Generation & Packetization/Bit Pairing'], 'Open' ,'on');

%%
% 2 -  *Symbol Mapper* 
%
% The Symbol Mapper uses the QPSK Modulator Baseband block from the
% Communications Toolbox(TM) in order to map the integer input value
% [0,1,2,3] onto the appropriate complex valued symbol [1 + 1i, -1 + 1i, 1 - 1i, -1 - 1i].
% Mapping the symbols in this manner allows for a 2 bit value to be used to represent each symbol. 
% This allows the wordlengths in the RRC transmit filter for the product and accumulator
% datapaths to be optimized. The block uses a
% Gray Mapping scheme.
% 

set_param([modelname '/HDLTx/Data Generation & Packetization/Bit Pairing'], 'Open', 'off'); 
set_param([modelname '/HDLTx/Symbol Mapping'], 'Open' ,'on');

%%
% 3 -  *Pulse Shaping*
%
% The Pulse Shaping component uses an FIR Interpolation filter, featuring an
% upsampling factor of four, and a Root Raised Cosine impulse
% response. The receive filter in the HDL optimized QPSK Receiver demo
% forms a matched filter to this transmit filter. The filter is pipelined
% (see HDL Block Properties) in order to ensure that the combinatorial
% delay is minimized throughout the design. 
%

set_param([modelname '/HDLTx/Symbol Mapping'], 'Open', 'off'); 
set_param([modelname '/HDLTx/Pulse Shaping'], 'Open' ,'on');

%% Results and Displays
% During simulation, the constellation obtained after passing the signal
% through the transmit and receive filter chain is displayed via the Constellation
% Diagram Scope (contained within the Signal Quality Measurement component). In addition,
% the scope displays the calculated EVM and MER via the *Tools --> Measurements --> Signal Quality* option.

set_param([modelname '/HDLTx/Pulse Shaping'], 'Open' ,'off');

%%
% The EVM is the calculated magnitude of the error vector between the ideal
% constellation point (given by the immediate symbol mapper output) and the
% constellation point obtained after transmit and 
% receive pulse shape filtering has been performed. The EVM gives a figure of
% merit regarding the distortion introduced by the transmit and receive filtering.
% In this case, the EVM allows the system designer to determine if the
% distortion introduced by the pulse shaping filters due to the effects of fixed point
% quantization and non-ideal (truncated) impulse responses is acceptable or
% otherwise. For further information, please refer to the EVM Measurement block
% documentation.
%
% The MER is a measure of the signal-to-noise ratio in digital modulation
% applications. It is the ratio of the average reference signal power to
% the mean square error. For further information, please refer to the MER
% Measurement block documentation.
%
% Shown below is a snapshot from the Constellation Diagram
% scope output.
%
% <<hdlcoder_commqpsktx_Constellation_Diagram.png>>
%


%% HDL Code Generation
% The HDL code generated  from the *HDLTx* subsystem has been synthesized using
% Xilinx(R) ISE on a Virtex6 (XC6VLX240T) FPGA, and ran at around 300 MHz.
% When operating the RRC transmit filter at maximum rate, the QPSK
% input symbols are generated at 75M symbols/second. The resulting theoretical
% maximum data rate is therefore
% 150M samples/second, taking into account the data transmitted over both the I and the
% Q channels.
%
% You can use the commands *makehdl* and
% *makehdltb* to generate HDL code and testbench for
% subsystems in *HDLTx*. To generate the HDL code, use the following command:
%
%     makehdl(subsystemname)
%
% To generate a testbench, use the following command:
%
%     makehdltb(subsystemname)
%
% When generating the testbench, a validation model will be created which
% includes the internal pipeline delay of the RRC transmit filter. The second constellation
% diagram which is invoked illustrates the output of the validation model. 

