Skip to content

Customized IP Guidelines #3

@BernardoMadeira

Description

@BernardoMadeira

Hello everyone.

I am a user of the OscimpDigital framework and I would like to start by thanking you guys all the good work.

I use a 14b RedPitaya to do some signal processing on my sensors and wanted to implement a biquad structured IIR lpf with coefficients that could be accessed externally by the user and injected through the add_const IP. There would be no need to add these to the libOscimpDig libraries since I could change the coefficients in such a simple way like in the FIR IP.

I saw an (unfinished?) implementation of the IIR lpf (https://github.com/oscimp/fpga_ip/blob/master/iir_lpf_complex/hdl/iir_lpf_complex.vhd). I have tried to adapt this script (annexed) for my implementation, but when I tried connecting it to the other IPs the connections did not match.


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

entity iir_lpf_complex is 
	generic (
		DATA_WIDTH : natural := 16
	);
	port (
		data_i_i   : in std_logic_vector(DATA_WIDTH-1 downto 0);
		data_q_i   : in std_logic_vector(DATA_WIDTH-1 downto 0);
		data_en_i  : in std_logic;
		data_clk_i : in std_logic;
		data_rst_i : in std_logic;
		data_i_o   : out std_logic_vector(DATA_WIDTH-1 downto 0);
		data_q_o   : out std_logic_vector(DATA_WIDTH-1 downto 0);
		data_en_o  : out std_logic;
		data_clk_o : out std_logic;
		data_rst_o : out std_logic;
		a0         : in signed(DATA_WIDTH-1 downto 0); -- Biquad filter coefficients
		a1         : in signed(DATA_WIDTH-1 downto 0);
		b0         : in signed(DATA_WIDTH-1 downto 0);
		b1         : in signed(DATA_WIDTH-1 downto 0);
		b2         : in signed(DATA_WIDTH-1 downto 0)
	);
end entity;

architecture bhv of iir_lpf_complex is
	signal data_i_1, data_i_2, data_i_3 : signed(DATA_WIDTH+1 downto 0) := (others => '0');
	signal data_q_1, data_q_2, data_q_3 : signed(DATA_WIDTH+1 downto 0) := (others => '0');
	signal en_i_1 : std_logic := '0';
begin
	data_i_2 <= to_signed(0, DATA_WIDTH+2) when data_rst_i = '1' else data_i_1 - b1 * data_i_3 - b2 * data_i_2;
	data_q_2 <= to_signed(0, DATA_WIDTH+2) when data_rst_i = '1' else data_q_1 - b1 * data_q_3 - b2 * data_q_2;
	data_i_3 <= to_signed(0, DATA_WIDTH+2) when data_rst_i = '1' else data_i_1 - a1 * data_i_3 - a0 * data_i_2;
	data_q_3 <= to_signed(0, DATA_WIDTH+2) when data_rst_i = '1' else data_q_1 - a1 * data_q_3 - a0 * data_q_2;

	data_i_o <= std_logic_vector(data_i_1(DATA_WIDTH-1 downto 0));
	data_q_o <= std_logic_vector(data_q_1(DATA_WIDTH-1 downto 0));
	data_en_o <= en_i_1;
	data_clk_o <= data_clk_i;
	data_rst_o <= data_rst_i;

	process(data_clk_i) is
	begin 
		if rising_edge(data_clk_i) then
			en_i_1 <= data_en_i;
			if (data_rst_i = '1') then 
				en_i_1 <= '0';
				data_i_1 <= (others => '0');
				data_q_1 <= (others => '0');
				data_i_2 <= (others => '0');
				data_q_2 <= (others => '0');
				data_i_3 <= (others => '0');
				data_q_3 <= (others => '0');
			end if;

			if (data_en_i = '1') then
				data_i_1 <= signed(data_i_i);
				data_q_1 <= signed(data_q_i);
			else 
				data_i_1 <= data_i_1;
				data_q_1 <= data_q_1;
			end if;

			if (en_i_1 = '1') then
				data_i_1 <= data_i_3;
				data_q_1 <= data_q_3;
			else	
				data_i_1 <= data_i_1;
				data_q_1 <= data_q_1;
			end if;
		end if;
	end process;
end architecture bhv;

I used Vivado's IP Packager.

Are there guidelines to make customized IP compatible with the OscimpDigital library? Or could you point me in a direction where I could make this specific source compatible?

Thank you!

Bernardo

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions