Use Cases
- AXI-Stream datapath integration where module boundaries need explicit ready/valid behavior.
- Reusable FPGA DSP pipelines that need fixed-point, timing-aware implementation.
- Memory-mapped control/status integration with software-visible register maps.
Block Diagram
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
| Name | Type | Default | Description |
|---|---|---|---|
| SAMPLE_WIDTH | positive | 16 | Sample width for envelope, carrier, and I/Q output lanes. |
| FRAC_BITS | natural | 14 | Number of fractional bits used by carrier and envelope fixed-point values. |
| PHASE_WIDTH | positive | 32 | Internal DDS phase accumulator width. The register interface supports up to 32 bits. |
| REG_DATA_WIDTH | positive | 32 | Width of the RADIF register data path. |
| REG_ADDR_WIDTH | positive | 16 | Width of the RADIF byte address path. |
| DEFAULT_PHASE_INC | natural | 16#01000000# | Reset value for carrier phase increment. |
| DEFAULT_INTERNAL_DDS | boolean | true | Reset value for internal DDS carrier selection. |
| DEFAULT_ENABLE | boolean | true | Reset value for stream processing enable. |
| VENDOR | string | "GENERIC" | Vendor selector retained for generated package consistency. |
| DEVICE_FAMILY | string | "GENERIC" | Device-family selector retained for generated package consistency. |
Ports
| Name | Direction | Type | Description |
|---|---|---|---|
| m_axis_tvalid | out | std_logic | Packed I/Q output valid. |
| m_axis_tready | in | std_logic | Packed I/Q output ready. |
| m_axis_tdata | out | std_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_tlast | out | std_logic | Output frame marker aligned with output sample. |
| s_axis_tvalid | in | std_logic | Envelope stream valid. |
| s_axis_tready | out | std_logic | Envelope stream ready. |
| s_axis_tdata | in | std_logic_vector(SAMPLE_WIDTH - 1 downto 0) | Signed fixed-point envelope sample. |
| s_axis_tlast | in | std_logic | Envelope stream frame marker. |
| clk | in | std_logic | Stream and register clock. |
| rst | in | std_logic | Active-high synchronous reset. |
| carrier_i_i | in | std_logic_vector(SAMPLE_WIDTH - 1 downto 0) | Signed fixed-point external carrier cosine sample. |
| carrier_q_i | in | std_logic_vector(SAMPLE_WIDTH - 1 downto 0) | Signed fixed-point external carrier sine sample. |
| reg_wr_addr | in | std_logic_vector(REG_ADDR_WIDTH - 1 downto 0) | Register write address. |
| reg_rd_addr | in | std_logic_vector(REG_ADDR_WIDTH - 1 downto 0) | Register read address. |
| reg_wr_en | in | std_logic | One-cycle register write request. |
| reg_rd_en | in | std_logic | One-cycle register read request. |
| reg_data_in | in | std_logic_vector(REG_DATA_WIDTH - 1 downto 0) | Register write data. |
| reg_data_out | out | std_logic_vector(REG_DATA_WIDTH - 1 downto 0) | Register read data. |
| reg_wr_rdy | out | std_logic | Register write ready. |
| reg_rd_rdy | out | std_logic | Register read ready. |
| reg_wr_valid | out | std_logic | Register write response valid. |
| reg_rd_valid | out | std_logic | Register read response valid. |
| reg_error | out | std_logic | Register transaction error. |
Register Interfaces
Static register maps are rendered below for this module.
| Interface | Directions | Signals | Representative ports |
|---|---|---|---|
| M_AXIS | in, out | 4 | m_axis_tvalid, m_axis_tready, m_axis_tdata, m_axis_tlast |
| S_AXIS | in, out | 4 | s_axis_tvalid, s_axis_tready, s_axis_tdata, s_axis_tlast |
| Register control/status | in, out | 11 | reg_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
Controls AM envelope modulation, internal/external carrier selection, DDS tuning, and sample-count observation.
| Register | Offset | Access | Reset | Description |
|---|---|---|---|---|
| control | 0x00 | rw | 0x00000003 | Controls stream processing and carrier source selection. |
| status | 0x04 | ro | 0x00000002 | Reports output-valid and input-ready status. |
| phase_inc | 0x08 | rw | 0x01000000 | Internal DDS phase increment applied after each accepted sample. |
| phase_offset | 0x0C | rw | 0x00000000 | Static phase offset added to the accumulator before carrier lookup. |
| phase | 0x10 | ro | 0x00000000 | Current internal DDS phase accumulator value. |
| sample_count | 0x14 | rw | 0x00000000 | Counts accepted and emitted samples. Write bit 0 as one to clear the counter. |
control
Controls stream processing and carrier source selection.
| Name | Register bit(s) | Description |
|---|---|---|
| PH RST | Control[3] | Write-one strobe that clears the internal DDS phase accumulator. |
| BYPASS | Control[2] | Passes the envelope to the I lane and drives Q to zero without carrier multiplication. |
| INT DDS | Control[1] | Selects the internal DDS carrier. When clear, carrier_i_i and carrier_q_i provide the carrier samples. |
| EN | Control[0] | Enables stream processing. When clear, accepted input samples are dropped and no output samples are emitted. |
status
Reports output-valid and input-ready status.
| Name | Register bit(s) | Description |
|---|---|---|
| READY | Status[1] | Set when the block can accept an input envelope sample. |
| VALID | Status[0] | Set when an output I/Q sample is currently valid. |
phase_inc
Internal DDS phase increment applied after each accepted sample.
| Name | Register bit(s) | Description |
|---|---|---|
| PH INC | PhaseInc[31:0] | Unsigned phase tuning word. Larger values increase carrier frequency; one full accumulator wrap equals one carrier cycle. |
phase_offset
Static phase offset added to the accumulator before carrier lookup.
| Name | Register bit(s) | Description |
|---|---|---|
| PH OFFS | PhaseOffset[31:0] | Unsigned phase offset added to the DDS accumulator before sine/cosine lookup. |
phase
Current internal DDS phase accumulator value.
| Name | Register bit(s) | Description |
|---|---|---|
| PHASE | Phase[31:0] | Current unsigned DDS phase accumulator value. |
sample_count
Counts accepted and emitted samples. Write bit 0 as one to clear the counter.
| Name | Register bit(s) | Description |
|---|---|---|
| COUNT | SampleCount[31:0] | Current emitted-sample count. Writing bit 0 as one clears the counter. |
Testbenches
tb_raddsp_axis_am_iq
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.
Interface Timing Diagram
M_AXIS interface signals
M_AXIS Interface Waveform
S_AXIS interface signals
S_AXIS Interface Waveform
Sources
- dsp/hdl/raddsp/src/raddsp_axis_am_iq_modulator.vhd
