diff --git a/README.md b/README.md index 33b1ff3a686246f439aa5b79d464712416b26922..37391b3726c3da4a57e4d4f28bb6501a32613d84 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # TP filtre audio -[ ] Comment utiliser Git et Gitlab : [https://tp-vhdl.gitlab-pages.imt-atlantique.fr/gitlab/](https://tp-vhdl.gitlab-pages.imt-atlantique.fr/gitlab/) -[ ] Énoncé du TP : [https://tp-vhdl.gitlab-pages.imt-atlantique.fr/filtre/](https://tp-vhdl.gitlab-pages.imt-atlantique.fr/filtre/) +- Comment utiliser Git et Gitlab : [https://mee-labs.gitlab-pages.imt-atlantique.fr/gitlab/](https://mee-labs.gitlab-pages.imt-atlantique.fr/gitlab/) +- Énoncé du TP : [https://mee-labs.gitlab-pages.imt-atlantique.fr/vhdl/filter/](https://mee-labs.gitlab-pages.imt-atlantique.fr/vhdl/filter/) ## Questions diff --git a/src/hdl/operativeUnit.vhd b/src/hdl/operativeUnit.vhd index 1286aff5a65b975b333b4136df7781bb98c0742e..7d08c1bb8592058ee92cb298cc40e7d82cc104cf 100644 --- a/src/hdl/operativeUnit.vhd +++ b/src/hdl/operativeUnit.vhd @@ -6,7 +6,7 @@ -- Author : Jean-Noel BAZIN <jnbazin@pc-disi-026.enst-bretagne.fr> -- Company : -- Created : 2018-04-11 --- Last update: 2019-02-13 +-- Last update: 2025-03-28 -- Platform : -- Standard : VHDL'93/02 ------------------------------------------------------------------------------- @@ -31,99 +31,102 @@ use ieee.numeric_std.all; entity operativeUnit is - port ( - I_clock : in std_logic; -- global clock - I_reset : in std_logic; -- asynchronous global reset - I_inputSample : in std_logic_vector(7 downto 0); -- 8 bit input sample - I_loadShift : in std_logic; -- Control signal to load the input sample in the sample shift register and shift the register - I_initAddress : in std_logic; -- Control signal to initialize register read address - I_incrAddress : in std_logic; -- Control signal to increment register read address - I_initSum : in std_logic; -- Control signal to initialize the MAC register - I_loadSum : in std_logic; -- Control signal to load the MAC register; - I_loadY : in std_logic; -- Control signal to load Y register - O_processingDone : out std_logic; -- Indicate that processing is done - O_Y : out std_logic_vector(7 downto 0) -- filtered sample - ); + port ( + I_clock : in std_logic; -- global clock + I_reset : in std_logic; -- asynchronous global reset + I_inputSample : in std_logic_vector(7 downto 0); -- 8 bit input sample + I_loadShift : in std_logic; -- Control signal to load the input sample in the sample shift register and shift the register + I_initAddress : in std_logic; -- Control signal to initialize register read address + I_incrAddress : in std_logic; -- Control signal to increment register read address + I_initSum : in std_logic; -- Control signal to initialize the MAC register + I_loadSum : in std_logic; -- Control signal to load the MAC register; + I_loadY : in std_logic; -- Control signal to load Y register + O_processingDone : out std_logic; -- Indicate that processing is done + O_Y : out std_logic_vector(7 downto 0) -- filtered sample + ); end entity operativeUnit; architecture arch_operativeUnit of operativeUnit is - type registerFile is array(0 to 15) of signed(7 downto 0); - signal SR_coefRegister : registerFile; + type registerFile is array(0 to 15) of signed(7 downto 0); + signal SR_coefRegister : registerFile; - signal SR_shiftRegister : registerFile; -- shift register file used to store and shift input samples - signal SC_multOperand1 : signed(7 downto 0); - signal SC_multOperand2 : signed(7 downto 0); - signal SC_MultResult : signed(15 downto 0); -- Result of the multiplication Xi*Hi - signal SC_addResult : signed(19 downto 0); -- result of the accumulation addition - signal SR_sum : signed(19 downto 0); -- Accumulation register - signal SR_Y : signed(7 downto 0); -- filtered sample storage register - signal SR_readAddress : integer range 0 to 15; -- register files read address + signal SR_shiftRegister : registerFile; -- shift register file used to store and shift input samples + signal SC_multOperand1 : signed(7 downto 0); + signal SC_multOperand2 : signed(7 downto 0); + signal SC_MultResult : signed(15 downto 0); -- Result of the multiplication Xi*Hi + signal SC_addResult : signed(19 downto 0); -- result of the accumulation addition + signal SR_sum : signed(19 downto 0); -- Accumulation register + signal SR_Y : signed(7 downto 0); -- filtered sample storage register + signal SR_readAddress : integer range 0 to 15; -- register files read address begin --- Low-pass filter provided with octave (or Matlab ;)) command ---fir1(15, .001)/sqrt(sum(fir1(15, .001).^2))*2^6 - SR_coefRegister <= (to_signed(2, 8), -- ROM register used file to store FIR coefficients - to_signed(3, 8), - to_signed(6, 8), - to_signed(10, 8), - to_signed(15, 8), - to_signed(20, 8), - to_signed(24, 8), - to_signed(26, 8), - to_signed(26, 8), - to_signed(24, 8), - to_signed(20, 8), - to_signed(15, 8), - to_signed(10, 8), - to_signed(6, 8), - to_signed(3, 8), - to_signed(2, 8) - ); - - shift : process (_BLANK_) is - begin -- process shift - if I_reset = '1' then -- asynchronous reset (active high) - SR_shiftRegister <= (others => (others => '0')); - elsif _BLANK_ - - end if; - end process shift; - - incr_address : process (_BLANK_) is - begin - if I_reset = '1' then -- asynchronous reset (active high) - SR_readAddress <= 0; - elsif _BLANK_ - - end if; - end process incr_address; - - O_processingDone <= '1' when _BLANK_ ; - - SC_multOperand1 <= _BLANK_ ; -- 8 bits - SC_multOperand2 <= _BLANK_ ; -- 8 bits - SC_MultResult <= _BLANK_ ; -- 16 bits - SC_addResult <= resize(SC_MultResult, SC_addResult'length) + SR_sum; - - sum_acc : process (_BLANK_) is - begin - if I_reset = '1' then -- asynchronous reset (active high) - SR_sum <= (others => '0'); - elsif _BLANK_ - end if; - end process sum_acc; - - store_result : process (_BLANK_) is - begin - _BLANK_ - - end process store_result; - - O_Y <= std_logic_vector(SR_Y); + -- Low-pass filter provided with octave (or Matlab ;)) command + -- fir1(15, .001)/sqrt(sum(fir1(15, .001).^2))*2^6 + -- Or python with (import signal from scipy and math) + -- [round(elem/math.sqrt(sum(signal.firwin(16, .001)**2)) * 2**6) for elem in signal.firwin(16, .001)] + + SR_coefRegister <= (to_signed(2, 8), -- ROM register used file to store FIR coefficients + to_signed(3, 8), + to_signed(6, 8), + to_signed(10, 8), + to_signed(15, 8), + to_signed(20, 8), + to_signed(24, 8), + to_signed(26, 8), + to_signed(26, 8), + to_signed(24, 8), + to_signed(20, 8), + to_signed(15, 8), + to_signed(10, 8), + to_signed(6, 8), + to_signed(3, 8), + to_signed(2, 8) + ); + + shift : process (_BLANK_) is + begin -- process shift + if I_reset = '1' then -- asynchronous reset (active high) + SR_shiftRegister <= (others => (others => '0')); + elsif _BLANK_ + + end if; + end process shift; + + incr_address : process (_BLANK_) is + begin + if I_reset = '1' then -- asynchronous reset (active high) + SR_readAddress <= 0; + elsif _BLANK_ + + end if; + end process incr_address; + + O_processingDone <= '1' when _BLANK_; + + SC_multOperand1 <= _BLANK_; -- 8 bits + SC_multOperand2 <= _BLANK_; -- 8 bits + SC_MultResult <= _BLANK_; -- 16 bits + SC_addResult <= resize(SC_MultResult, SC_addResult'length) + SR_sum; + + sum_acc : process (_BLANK_) is + begin + if I_reset = '1' then -- asynchronous reset (active high) + SR_sum <= (others => '0'); + elsif _BLANK_ + end if; + end process sum_acc; + + store_result : process (_BLANK_) is + begin + _BLANK_ + + end process store_result; + + O_Y <= std_logic_vector(SR_Y); end architecture arch_operativeUnit; diff --git a/src/hdl/tb_firUnit.vhd b/src/hdl/tb_firUnit.vhd index e19d713585d5121f39e78cd67ed5edb8a48f4ed0..b33e962b4631a3043f2383bdd97b591c60d1f52c 100644 --- a/src/hdl/tb_firUnit.vhd +++ b/src/hdl/tb_firUnit.vhd @@ -1,23 +1,23 @@ ------------------------------------------------------------------------------- -- Title : FirUnit --- Project : +-- Project : ------------------------------------------------------------------------------- -- File : operativeUnit.vhd -- Author : Jean-Noel BAZIN <jnbazin@pc-disi-026.enst-bretagne.fr> --- Company : +-- Company : -- Created : 2018-04-11 --- Last update: 2019-02-26 --- Platform : +-- Last update: 2025-03-28 +-- Platform : -- Standard : VHDL'93/02 ------------------------------------------------------------------------------- -- Description: 8 bit FIR ------------------------------------------------------------------------------- --- Copyright (c) 2018 +-- Copyright (c) 2018 ------------------------------------------------------------------------------- -- Revisions : -- Date Version Author Description -- 2018-04-11 1.0 jnbazin Created --- 2018-04-18 1.1 marzel Modified to add more test inputs +-- 2018-04-18 1.1 marzel Modified to add more test inputs -- 2019-02-26 1.1 marzel Adapted to 16-tap filtering ------------------------------------------------------------------------------- @@ -29,59 +29,59 @@ entity tb_firUnit is end entity tb_firUnit; architecture archi_tb_firUnit of tb_firUnit is - component firUnit is - port ( - I_clock : in std_logic; - I_reset : in std_logic; - I_inputSample : in std_logic_vector(7 downto 0); - I_inputSampleValid : in std_logic; - O_filteredSample : out std_logic_vector(7 downto 0); - O_filteredSampleValid : out std_logic); - end component firUnit; + component firUnit is + port ( + I_clock : in std_logic; + I_reset : in std_logic; + I_inputSample : in std_logic_vector(7 downto 0); + I_inputSampleValid : in std_logic; + O_filteredSample : out std_logic_vector(7 downto 0); + O_filteredSampleValid : out std_logic); + end component firUnit; - signal SC_clock : std_logic := '0'; - signal SC_reset : std_logic; - signal SC_inputSample : std_logic_vector(7 downto 0); - signal SC_inputSampleValid : std_logic:='0'; - signal SC_filteredSample : std_logic_vector(7 downto 0); - signal SC_filteredSampleValid : std_logic; + signal SC_clock : std_logic := '0'; + signal SC_reset : std_logic; + signal SC_inputSample : std_logic_vector(7 downto 0); + signal SC_inputSampleValid : std_logic := '0'; + signal SC_filteredSample : std_logic_vector(7 downto 0); + signal SC_filteredSampleValid : std_logic; begin - SC_clock <= not SC_clock after 5 ns; - SC_reset <= '0', '1' after 19 ns, '0' after 57 ns; + SC_clock <= not SC_clock after 5 ns; + SC_reset <= '0', '1' after 19 ns, '0' after 57 ns; - -- Sample period = 20 clk period - SC_inputSampleValid <= not SC_inputSampleValid after 100 ns; + -- Sample period = 20 clk period + SC_inputSampleValid <= not SC_inputSampleValid after 100 ns; - -- Null signal followed by a Dirac and then an arbitrary sequence - SC_inputSample <= "00000000", - "01111111" after 401 ns, - "00000000" after 601 ns, - "00100100" after 4201 ns, - "01100100" after 4401 ns, - "10100010" after 4601 ns, - "11011011" after 4801 ns, - "00001011" after 5001 ns, - "10000000" after 5201 ns, - "01111111" after 5401 ns, - "10111010" after 5601 ns; + -- Null signal followed by a Dirac and then an arbitrary sequence + SC_inputSample <= "00000000", + "01111111" after 401 ns, + "00000000" after 601 ns, + "00100100" after 4201 ns, + "01100100" after 4401 ns, + "10100010" after 4601 ns, + "11011011" after 4801 ns, + "00001011" after 5001 ns, + "10000000" after 5201 ns, + "01111111" after 5401 ns, + "10111010" after 5601 ns; --- the filter output on 8 bits is a sequence of signed numbers (with the assumption --- of rounding the output, so the accuracy can be slightly different depending --- on your final stage): - -- 0 2 3 6 10 15 20 24 26 26 24 20 15 10 6 3 2 0 0 0 1 2 3 5 7 7 8 4 -1 -8 - -- -17 -27 -38 -49 -61 -71 -82 -93 -101 -107 -112 -113 -116 - + -- the filter output on 8 bits is a sequence of signed numbers (with the assumption + -- of rounding the output, so the accuracy can be slightly different depending + -- on your final stage): + -- 0 2 3 6 10 15 20 24 26 26 24 20 15 10 6 3 2 0 0 0 1 2 3 5 7 7 8 4 -1 -8 + -- -17 -27 -38 -49 -61 -71 -82 -93 -101 -107 -112 -113 -116 - firUnit_1 : entity work.firUnit - port map ( - I_clock => SC_clock, - I_reset => SC_reset, - I_inputSample => SC_inputSample, - I_inputSampleValid => SC_inputSampleValid, - O_filteredSample => SC_filteredSample, - O_filteredSampleValid => SC_filteredSampleValid); + + firUnit_1 : entity work.firUnit + port map ( + I_clock => SC_clock, + I_reset => SC_reset, + I_inputSample => SC_inputSample, + I_inputSampleValid => SC_inputSampleValid, + O_filteredSample => SC_filteredSample, + O_filteredSampleValid => SC_filteredSampleValid); end architecture archi_tb_firUnit;