Radical Computer Technologies
DSP / entity

raddsp_axis_am_iq_modulator

Documentation version: 0.2.1 / Subpackage: dsp_comms / Source package: raddsp

Register-controlled AXI-stream AM IQ modulator. Multiplies a signed envelope stream by either externally supplied carrier samples or an internal phase-accumulator DDS carrier. The output is packed I/Q with I in the low word and Q in the high word. A RADIF-style register interface controls enable, bypass, internal carrier selection, phase reset, carrier phase increment, and phase offset.

Use Cases

Block Diagram

raddsp_axis_am_iq_modulator radhdl entity S_AXIS clk rst carrier_i_i carrier_q_i reg_wr_addr reg_rd_addr reg_wr_en reg_rd_en reg_data_in M_AXIS reg_data_out reg_wr_rdy reg_rd_rdy reg_wr_valid reg_rd_valid reg_error
VHDL Include And Instantiation Template

File Header

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library radhdl;
-- Direct entity instantiation below does not require importing the entity name.
use radhdl.dsp.all;
-- Narrower alternative: use radhdl.dsp_comms.all;

Component Declaration

component raddsp_axis_am_iq_modulator is
  generic (
    SAMPLE_WIDTH : positive := 16;
    FRAC_BITS : natural := 14;
    PHASE_WIDTH : positive := 32;
    REG_DATA_WIDTH : positive := 32;
    REG_ADDR_WIDTH : positive := 16;
    DEFAULT_PHASE_INC : natural := 16#01000000#;
    DEFAULT_INTERNAL_DDS : boolean := true;
    DEFAULT_ENABLE : boolean := true;
    VENDOR : string := "GENERIC";
    DEVICE_FAMILY : string := "GENERIC"
  );
  port (
    m_axis_tvalid : out std_logic;
    m_axis_tready : in std_logic;
    m_axis_tdata : out std_logic_vector((2 * SAMPLE_WIDTH) - 1 downto 0);
    m_axis_tlast : out std_logic;
    s_axis_tvalid : in std_logic;
    s_axis_tready : out std_logic;
    s_axis_tdata : in std_logic_vector(SAMPLE_WIDTH - 1 downto 0);
    s_axis_tlast : in std_logic;
    clk : in std_logic;
    rst : in std_logic;
    carrier_i_i : in std_logic_vector(SAMPLE_WIDTH - 1 downto 0);
    carrier_q_i : in std_logic_vector(SAMPLE_WIDTH - 1 downto 0);
    reg_wr_addr : in std_logic_vector(REG_ADDR_WIDTH - 1 downto 0);
    reg_rd_addr : in std_logic_vector(REG_ADDR_WIDTH - 1 downto 0);
    reg_wr_en : in std_logic;
    reg_rd_en : in std_logic;
    reg_data_in : in std_logic_vector(REG_DATA_WIDTH - 1 downto 0);
    reg_data_out : out std_logic_vector(REG_DATA_WIDTH - 1 downto 0);
    reg_wr_rdy : out std_logic;
    reg_rd_rdy : out std_logic;
    reg_wr_valid : out std_logic;
    reg_rd_valid : out std_logic;
    reg_error : out std_logic
  );
end component;

Direct Entity Instantiation

u_raddsp_axis_am_iq_modulator : entity radhdl.raddsp_axis_am_iq_modulator
  generic map (
    SAMPLE_WIDTH         => 16,
    FRAC_BITS            => 14,
    PHASE_WIDTH          => 32,
    REG_DATA_WIDTH       => 32,
    REG_ADDR_WIDTH       => 16,
    DEFAULT_PHASE_INC    => 16#01000000#,
    DEFAULT_INTERNAL_DDS => true,
    DEFAULT_ENABLE       => true,
    VENDOR               => "GENERIC",
    DEVICE_FAMILY        => "GENERIC"
  )
  port map (
    m_axis_tvalid => <m_axis_tvalid_signal>,
    m_axis_tready => <m_axis_tready_signal>,
    m_axis_tdata  => <m_axis_tdata_signal>,
    m_axis_tlast  => <m_axis_tlast_signal>,
    s_axis_tvalid => <s_axis_tvalid_signal>,
    s_axis_tready => <s_axis_tready_signal>,
    s_axis_tdata  => <s_axis_tdata_signal>,
    s_axis_tlast  => <s_axis_tlast_signal>,
    clk           => <clk_signal>,
    rst           => <rst_signal>,
    carrier_i_i   => <carrier_i_i_signal>,
    carrier_q_i   => <carrier_q_i_signal>,
    reg_wr_addr   => <reg_wr_addr_signal>,
    reg_rd_addr   => <reg_rd_addr_signal>,
    reg_wr_en     => <reg_wr_en_signal>,
    reg_rd_en     => <reg_rd_en_signal>,
    reg_data_in   => <reg_data_in_signal>,
    reg_data_out  => <reg_data_out_signal>,
    reg_wr_rdy    => <reg_wr_rdy_signal>,
    reg_rd_rdy    => <reg_rd_rdy_signal>,
    reg_wr_valid  => <reg_wr_valid_signal>,
    reg_rd_valid  => <reg_rd_valid_signal>,
    reg_error     => <reg_error_signal>
  );

Generics

NameTypeDefaultDescription
SAMPLE_WIDTHpositive16Sample width for envelope, carrier, and I/Q output lanes.
FRAC_BITSnatural14Number of fractional bits used by carrier and envelope fixed-point values.
PHASE_WIDTHpositive32Internal DDS phase accumulator width. The register interface supports up to 32 bits.
REG_DATA_WIDTHpositive32Width of the RADIF register data path.
REG_ADDR_WIDTHpositive16Width of the RADIF byte address path.
DEFAULT_PHASE_INCnatural16#01000000#Reset value for carrier phase increment.
DEFAULT_INTERNAL_DDSbooleantrueReset value for internal DDS carrier selection.
DEFAULT_ENABLEbooleantrueReset value for stream processing enable.
VENDORstring"GENERIC"Vendor selector retained for generated package consistency.
DEVICE_FAMILYstring"GENERIC"Device-family selector retained for generated package consistency.

Ports

NameDirectionTypeDescription
m_axis_tvalidoutstd_logicPacked I/Q output valid.
m_axis_treadyinstd_logicPacked I/Q output ready.
m_axis_tdataoutstd_logic_vector((2 * SAMPLE_WIDTH) - 1 downto 0)Packed I/Q output, I in bits SAMPLE_WIDTH-1:0 and Q above it.
m_axis_tlastoutstd_logicOutput frame marker aligned with output sample.
s_axis_tvalidinstd_logicEnvelope stream valid.
s_axis_treadyoutstd_logicEnvelope stream ready.
s_axis_tdatainstd_logic_vector(SAMPLE_WIDTH - 1 downto 0)Signed fixed-point envelope sample.
s_axis_tlastinstd_logicEnvelope stream frame marker.
clkinstd_logicStream and register clock.
rstinstd_logicActive-high synchronous reset.
carrier_i_iinstd_logic_vector(SAMPLE_WIDTH - 1 downto 0)Signed fixed-point external carrier cosine sample.
carrier_q_iinstd_logic_vector(SAMPLE_WIDTH - 1 downto 0)Signed fixed-point external carrier sine sample.
reg_wr_addrinstd_logic_vector(REG_ADDR_WIDTH - 1 downto 0)Register write address.
reg_rd_addrinstd_logic_vector(REG_ADDR_WIDTH - 1 downto 0)Register read address.
reg_wr_eninstd_logicOne-cycle register write request.
reg_rd_eninstd_logicOne-cycle register read request.
reg_data_ininstd_logic_vector(REG_DATA_WIDTH - 1 downto 0)Register write data.
reg_data_outoutstd_logic_vector(REG_DATA_WIDTH - 1 downto 0)Register read data.
reg_wr_rdyoutstd_logicRegister write ready.
reg_rd_rdyoutstd_logicRegister read ready.
reg_wr_validoutstd_logicRegister write response valid.
reg_rd_validoutstd_logicRegister read response valid.
reg_erroroutstd_logicRegister transaction error.

Register Interfaces

Static register maps are rendered below for this module.

InterfaceDirectionsSignalsRepresentative ports
M_AXISin, out4m_axis_tvalid, m_axis_tready, m_axis_tdata, m_axis_tlast
S_AXISin, out4s_axis_tvalid, s_axis_tready, s_axis_tdata, s_axis_tlast
Register control/statusin, out11reg_wr_addr, reg_rd_addr, reg_wr_en, reg_rd_en, reg_data_in, reg_data_out, reg_wr_rdy, reg_rd_rdy, +3 more

Register Maps

raddsp_axis_am_iq_modulator

Source: dsp/hdl/raddsp/register_maps/raddsp_axis_am_iq_modulator.map.json

Controls AM envelope modulation, internal/external carrier selection, DDS tuning, and sample-count observation.

RegisterOffsetAccessResetDescription
control0x00rw0x00000003Controls stream processing and carrier source selection.
status0x04ro0x00000002Reports output-valid and input-ready status.
phase_inc0x08rw0x01000000Internal DDS phase increment applied after each accepted sample.
phase_offset0x0Crw0x00000000Static phase offset added to the accumulator before carrier lookup.
phase0x10ro0x00000000Current internal DDS phase accumulator value.
sample_count0x14rw0x00000000Counts accepted and emitted samples. Write bit 0 as one to clear the counter.

control

Offset 0x00 / Access rw / Reset 0x00000003

Controls stream processing and carrier source selection.

Control[15:0]
1514131211109876543210
RSVD [15:4]
PH RST
BYPASS
INT DDS
EN
Control[31:16]
31302928272625242322212019181716
RSVD [31:16]
NameRegister bit(s)Description
PH RSTControl[3]Write-one strobe that clears the internal DDS phase accumulator.
BYPASSControl[2]Passes the envelope to the I lane and drives Q to zero without carrier multiplication.
INT DDSControl[1]Selects the internal DDS carrier. When clear, carrier_i_i and carrier_q_i provide the carrier samples.
ENControl[0]Enables stream processing. When clear, accepted input samples are dropped and no output samples are emitted.

status

Offset 0x04 / Access ro / Reset 0x00000002

Reports output-valid and input-ready status.

Status[15:0]
1514131211109876543210
RSVD [15:2]
READY
VALID
Status[31:16]
31302928272625242322212019181716
RSVD [31:16]
NameRegister bit(s)Description
READYStatus[1]Set when the block can accept an input envelope sample.
VALIDStatus[0]Set when an output I/Q sample is currently valid.

phase_inc

Offset 0x08 / Access rw / Reset 0x01000000

Internal DDS phase increment applied after each accepted sample.

PhaseInc[15:0]
1514131211109876543210
PH INC [15:0]
PhaseInc[31:16]
31302928272625242322212019181716
PH INC [31:16]
NameRegister bit(s)Description
PH INCPhaseInc[31:0]Unsigned phase tuning word. Larger values increase carrier frequency; one full accumulator wrap equals one carrier cycle.

phase_offset

Offset 0x0C / Access rw / Reset 0x00000000

Static phase offset added to the accumulator before carrier lookup.

PhaseOffset[15:0]
1514131211109876543210
PH OFFS [15:0]
PhaseOffset[31:16]
31302928272625242322212019181716
PH OFFS [31:16]
NameRegister bit(s)Description
PH OFFSPhaseOffset[31:0]Unsigned phase offset added to the DDS accumulator before sine/cosine lookup.

phase

Offset 0x10 / Access ro / Reset 0x00000000

Current internal DDS phase accumulator value.

Phase[15:0]
1514131211109876543210
PHASE [15:0]
Phase[31:16]
31302928272625242322212019181716
PHASE [31:16]
NameRegister bit(s)Description
PHASEPhase[31:0]Current unsigned DDS phase accumulator value.

sample_count

Offset 0x14 / Access rw / Reset 0x00000000

Counts accepted and emitted samples. Write bit 0 as one to clear the counter.

SampleCount[15:0]
1514131211109876543210
COUNT [15:0]
SampleCount[31:16]
31302928272625242322212019181716
COUNT [31:16]
NameRegister bit(s)Description
COUNTSampleCount[31:0]Current emitted-sample count. Writing bit 0 as one clears the counter.

Testbenches

tb_raddsp_axis_am_iq captured waveform

Source: dsp/hdl/testbenches/tb_raddsp_axis_am_iq.vhd

Verifies the register-controlled AM IQ modulator and demodulator with a 2048-sample amplitude envelope. The test programs both internal DDS mixers to the same carrier tuning word, streams a sinusoidal envelope through the modulator, demodulates it back to baseband, and exposes plot_* signals for datasheet analog plots.

Artifacts: status, vcd

Data Plots

AM IQ Input Envelope

Input amplitude envelope streamed into the AM IQ modulator over the full 2048-sample frame.

04098191.23e+031.64e+0320471400010500700035000Q14 amplitude vs SampleEnvelope In

AM IQ Recovered Envelope

Envelope recovered by the demodulator after IQ modulation and DDS-based baseband rotation.

04098191.23e+031.64e+0320471400010500700035000Q14 amplitude vs SampleEnvelope Out

AM IQ Carrier Components

Modulated I and Q carrier components generated by the internal DDS-controlled mixer.

04098191.23e+031.64e+0320471400070000-7000-14000Signed Q14 amplitude vs SampleIQ

Captured GHDL Waveform

Source: dsp/hdl/testbenches/tb_raddsp_axis_am_iq.vhd

clk
rst
carrier_i[15:0]
carrier_q[15:0]
in_valid
in_ready
in_data[15:0]
in_last
iq_valid
iq_ready
iq_data[31:0]
iq_last
env_valid
env_ready
env_data[15:0]
env_last
reg_wr_addr[15:0]
reg_rd_addr[15:0]
reg_wr_en
reg_rd_en
reg_data_in[31:0]
mod_reg_data[31:0]
dem_reg_data[31:0]
mod_wr_valid
mod_rd_valid
dem_wr_valid
dem_rd_valid
mod_error
dem_error
sent_count
received_count
last_seen
plot_index[15:0]
plot_env_in[15:0]
plot_i[15:0]
plot_q[15:0]
plot_env_out[15:0]
carrier_i_i[15:0]
carrier_q_i[15:0]
reg_data_out[31:0]
reg_wr_rdy
reg_rd_rdy
reg_wr_valid
reg_rd_valid
reg_error
out_valid_r
out_data_r[31:0]
out_last_r
ready_i
enable_r
internal_dds_r
bypass_r
phase_r[31:0]
phase_inc_r[31:0]
phase_offset_r[31:0]
sample_count_r[31:0]
rd_data_r[31:0]
wr_valid_r
rd_valid_r
error_r
out_data_r[15:0]
S_AXIS
M_AXIS
M_AXIS interface signals

M_AXIS Interface Waveform

Source: dsp/hdl/testbenches/tb_raddsp_axis_am_iq.vhd

m_axis_tvalid
m_axis_tready
m_axis_tdata[31:0]
m_axis_tlast
m_axis_tdata[15:0]
S_AXIS interface signals

S_AXIS Interface Waveform

Source: dsp/hdl/testbenches/tb_raddsp_axis_am_iq.vhd

s_axis_tvalid
s_axis_tready
s_axis_tdata[15:0]
s_axis_tlast
s_axis_tdata[31:0]

Sources