oscimpDigital icon indicating copy to clipboard operation
oscimpDigital copied to clipboard

Customized IP Guidelines

Open BernardoMadeira opened this issue 1 year ago • 3 comments

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

BernardoMadeira avatar Jul 20 '23 13:07 BernardoMadeira