From 9f4bb046b876d2e373e491356d01a1310f44b420 Mon Sep 17 00:00:00 2001
From: KAMMOUN Yanis <yanis.kammoun@imt-atlantique.net>
Date: Wed, 26 Mar 2025 11:20:28 +0000
Subject: [PATCH] Upload New File

---
 VHDL/operativeUnit.vhd | 255 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 255 insertions(+)
 create mode 100644 VHDL/operativeUnit.vhd

diff --git a/VHDL/operativeUnit.vhd b/VHDL/operativeUnit.vhd
new file mode 100644
index 0000000..2fba240
--- /dev/null
+++ b/VHDL/operativeUnit.vhd
@@ -0,0 +1,255 @@
+-------------------------------------------------------------------------------
+-- Title      : operativeUnit
+-- Project    :
+-------------------------------------------------------------------------------
+-- File       : operativeUnit.vhd
+-- Author     : Jean-Noel BAZIN  <jnbazin@pc-disi-026.enst-bretagne.fr>
+-- Company    :
+-- Created    : 2018-04-11
+-- Last update: 2019-02-13
+-- Platform   :
+-- Standard   : VHDL'93/02
+-------------------------------------------------------------------------------
+-- Description: Operative unit of a sequential FIR filter. Including shift
+-- register for samples, registers for coefficients, a MAC and a register to
+-- store the result
+-------------------------------------------------------------------------------
+-- Copyright (c) 2018
+-------------------------------------------------------------------------------
+-- Revisions  :
+-- Date        Version  Author  Description
+-- 2019-02-13  1.1      marzel  Update to provide a 16-tap filter and improve
+--                              the user experience ;)
+-- 2018-04-11  1.0      jnbazin Created
+-- 2018-04-18  1.0      marzel  Modification of SR_Y assignment to a round
+--                              instead of a trunc
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+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(10 downto 0);  -- 8 bit input sample
+    I_loadShiftX          : in  std_logic;  -- filtered sample
+    I_loadShiftY          : in  std_logic;  -- filtered sample
+    I_loadShiftz          : in  std_logic;  -- filtered sample    
+    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
+    I_samples             : in  std_logic_vector(1 to 0);  -- Data signal to select X or Y samples (and B or A coefficients)
+    I_coeffs              : in  std_logic_vector(1 to 0); -- Data signal to select coefficients
+    O_GprocessingDone     : out std_logic;
+    O_BprocessingDone     : out std_logic;
+    O_AprocessingDone     : out std_logic;
+    O_HprocessingDone     : out std_logic;
+    O_Y                   : out std_logic_vector(10 downto 0)   -- filtered sample
+    );
+
+end entity operativeUnit;
+
+architecture arch_operativeUnit of operativeUnit is
+  type registerFileG is array(0 to 95) of signed(10 downto 0) ;
+  type registerFileB is array(0 to 2) of signed(10 downto 0);
+  type registerFileA is array(0 to 1) of signed(10 downto 0);
+  type registerFileH is array(0 to 10) of signed(10 downto 0) ;
+  signal SR_GcoefRegister : registerFileG;
+  signal SR_BcoefRegister : registerFileB;
+  signal SR_AcoefRegister : registerFileA;
+  signal SR_HcoefRegister : registerFileH;
+
+
+
+  signal SR_XshiftRegister : registerFileG := (others => (others => '0')); -- shift register file used to store and shift input samples
+  signal SR_YshiftRegister : registerFileB := (others => (others => '0'));  -- Initialisation à 0;  -- shift register file used to store and shift output samples
+  signal SR_ZshiftRegister : registerFileH := (others => (others => '0'));  -- Initialisation à 0;  -- shift register file used to store and shift output samples
+  signal SC_multOperand1  : signed(10 downto 0);
+  signal SC_multOperand2  : signed(10 downto 0);
+  signal SC_MultResult    : signed(20 downto 0);  -- Result of the multiplication Xi*Hi
+  signal SC_addResult     : signed(25 downto 0);  -- result of the accumulation addition
+  signal SR_sum           : signed(25 downto 0);  -- Accumulation register
+  signal SR_Y             : signed(10 downto 0);  -- filtered sample storage register
+  signal SR_readAddress   : integer range 0 to 95;  -- 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_GcoefRegister <= (to_signed(-1, 11), to_signed(-1, 11), to_signed(-1, 11), to_signed(-1, 11),
+        to_signed(-1, 11), to_signed(-1, 11), to_signed(-2, 11), to_signed(-2, 11),
+        to_signed(-2, 11), to_signed(-3, 11), to_signed(-3, 11), to_signed(-3, 11),
+        to_signed(-4, 11), to_signed(-4, 11), to_signed(-5, 11), to_signed(-5, 11),
+        to_signed(-6, 11), to_signed(-6, 11), to_signed(-7, 11), to_signed(-7, 11),
+        to_signed(-8, 11), to_signed(-8, 11), to_signed(-9, 11), to_signed(-10, 11),
+        to_signed(-10, 11), to_signed(-11, 11), to_signed(-11, 11), to_signed(-12, 11),
+        to_signed(-13, 11), to_signed(-13, 11), to_signed(-14, 11), to_signed(-14, 11),
+        to_signed(-15, 11), to_signed(-15, 11), to_signed(-16, 11), to_signed(-16, 11),
+        to_signed(-17, 11), to_signed(-17, 11), to_signed(-18, 11), to_signed(-18, 11),
+        to_signed(-18, 11), to_signed(-19, 11), to_signed(-19, 11), to_signed(-19, 11),
+        to_signed(-19, 11), to_signed(-19, 11), to_signed(-19, 11), to_signed(1004, 11),
+        to_signed(-19, 11), to_signed(-19, 11), to_signed(-19, 11), to_signed(-19, 11),
+        to_signed(-19, 11), to_signed(-19, 11), to_signed(-18, 11), to_signed(-18, 11),
+        to_signed(-18, 11), to_signed(-17, 11), to_signed(-17, 11), to_signed(-16, 11),
+        to_signed(-16, 11), to_signed(-15, 11), to_signed(-15, 11), to_signed(-14, 11),
+        to_signed(-14, 11), to_signed(-13, 11), to_signed(-13, 11), to_signed(-12, 11),
+        to_signed(-11, 11), to_signed(-11, 11), to_signed(-10, 11), to_signed(-10, 11),
+        to_signed(-9, 11), to_signed(-8, 11), to_signed(-8, 11), to_signed(-7, 11),
+        to_signed(-7, 11), to_signed(-6, 11), to_signed(-6, 11), to_signed(-5, 11),
+        to_signed(-5, 11), to_signed(-4, 11), to_signed(-4, 11), to_signed(-3, 11),
+        to_signed(-3, 11), to_signed(-3, 11), to_signed(-2, 11), to_signed(-2, 11),
+        to_signed(-2, 11), to_signed(-1, 11), to_signed(-1, 11), to_signed(-1, 11),
+        to_signed(-1, 11), to_signed(-1, 11), to_signed(-1, 11)
+        );
+        
+  SR_BcoefRegister <= (to_signed(480, 11), 
+                       to_signed(-777, 11), 
+                       to_signed(480, 11)
+                       ); 
+        
+  SR_AcoefRegister <= (to_signed(512, 11), 
+                       to_signed(-777, 11), 
+                       to_signed(449, 11)
+                       );  
+                                    
+  SR_HcoefRegister <= (to_signed(-119, 11),
+        to_signed(122, 11),
+        to_signed(149, 11),
+        to_signed(191, 11),
+        to_signed(226, 11),
+        to_signed(239, 11),
+        to_signed(226, 11),
+        to_signed(191, 11),
+        to_signed(149, 11),
+        to_signed(122, 11),
+        to_signed(-119, 11)
+        );   
+                       
+
+  shiftX : process (I_reset, I_clock) is
+  begin  -- process shift
+    if I_reset = '1' then               -- asynchronous reset (active high)
+      SR_XshiftRegister <= (others => (others => '0'));
+    elsif Rising_edge(I_clock) then
+      if I_loadShiftX = '1' then
+        SR_XshiftRegister(0) <= signed(I_inputSample);
+        SR_XshiftRegister(1 to 95) <= SR_XshiftRegister(0 to 94);
+      end if;
+    end if;
+  end process shiftX ;
+  
+  shiftY : process (I_reset, I_clock) is
+  begin  -- process shift
+    if I_reset = '1' then               -- asynchronous reset (active high)
+      SR_YshiftRegister <= (others => (others => '0'));
+    elsif Rising_edge(I_clock) then
+      if I_loadShiftY = '1' then
+        if SC_addResult(9) = '1' then                                   --cas ou on arrondi à l'entier supérieur
+            SR_Y <= SC_addResult(20 downto 10) + 1;
+            SR_YshiftRegister(0) <= signed(SC_addResult(20 downto 10) + 1);
+        else                                                            -- cas ou on arrondi à l'entier inférieur
+            SR_Y <= SC_addResult(20 downto 10); 
+            SR_YshiftRegister(0) <= signed(SC_addResult(20 downto 10));
+        end if;
+        SR_YshiftRegister(1 to 2) <= SR_YshiftRegister(0 to 1);
+      end if;
+    end if;
+  end process shiftY ;
+  
+  shiftZ : process (I_reset, I_clock) is  
+  begin  -- process shift
+    if I_reset = '1' then               -- asynchronous reset (active high)
+      SR_ZshiftRegister <= (others => (others => '0'));
+    elsif Rising_edge(I_clock) then
+      if I_loadShiftZ = '1' then
+        if SC_addResult(8) = '1' then                                   --cas ou on arrondi à l'entier supérieur
+            SR_Y <= SC_addResult(19 downto 9) + 1;
+            SR_ZshiftRegister(0) <= signed(SC_addResult(19 downto 9) + 1);
+        else                                                            -- cas ou on arrondi à l'entier inférieur
+            SR_Y <= SC_addResult(20 downto 10); 
+            SR_ZshiftRegister(0) <= signed(SC_addResult(19 downto 9));
+        end if;
+        SR_ZshiftRegister(1 to 10) <= SR_ZshiftRegister(0 to 9);
+      end if;
+    end if;
+  end process shiftZ ;
+
+  
+
+  incr_address : process (I_reset, I_clock) is
+  begin
+    if I_reset = '1' then               -- asynchronous reset (active high)
+      SR_readAddress <= 0;
+    elsif Rising_edge(I_clock) then
+      if I_initAddress = '1' then
+       SR_readAddress <= 0;
+      elsif I_incrAddress = '1' and SR_readAddress <= 93 then
+       SR_readAddress <= SR_readAddress + 1;    
+--      elsif I_coeffs = "00" then
+--        if I_incrAddress = '1' and SR_readAddress <= 93 then
+--            SR_readAddress <= SR_readAddress + 1;
+--        end if;
+--      elsif I_coeffs = "01" then 
+--        if I_incrAddress = '1' and SR_readAddress <= 2 then
+--            SR_readAddress <= SR_readAddress + 1;        
+--        end if;
+      end if;
+    end if;
+  end process incr_address;
+
+  O_GprocessingDone <= '1' when SR_readAddress = 94 else '0';
+  O_BprocessingDone <= '1' when SR_readAddress = 1 else '0';
+  O_AprocessingDone <= '1' when SR_readAddress = 0 else '0';
+  O_HprocessingDone <= '1' when SR_readAddress = 9 else '0';
+
+
+  SC_multOperand1 <= SR_XshiftRegister(SR_readAddress) when I_samples = "00" else 
+  SR_YshiftRegister(SR_readAddress) when I_samples = "01" else
+  SR_ZshiftRegister(SR_readAddress) when I_samples = "10" or I_samples = "11";
+     
+  SC_multOperand2 <= SR_GcoefRegister(SR_readAddress) when I_coeffs = "00" else 
+  SR_BcoefRegister(SR_readAddress) when I_coeffs ="01" else
+  SR_AcoefRegister(SR_readAddress) when I_coeffs ="10" else
+  SR_HcoefRegister(SR_readAddress) when I_coeffs ="11";
+
+
+  SC_MultResult   <= SC_multOperand1 * SC_multOperand2;                                                           
+  SC_addResult    <= resize(SC_MultResult, SC_addResult'length) + SR_sum;                                       
+
+  sum_acc : process (I_reset, I_clock) is
+  begin
+    if I_reset = '1' then               -- asynchronous reset (active high)
+      SR_sum <= (others => '0');
+    elsif Rising_edge(I_clock) then
+      if I_initSum = '1' then
+        SR_sum <= (others => '0');
+      elsif I_loadSum = '1' then
+        SR_sum <= SC_addResult;
+      end if;
+    end if;
+  end process sum_acc;
+
+  store_result : process (I_clock) is
+  begin
+    if Rising_edge(I_clock) then
+      if I_loadY = '1' then
+        if SC_addResult(9) = '1' then
+            SR_Y <= SC_addResult(20 downto 10) + 1;
+        else 
+            SR_Y <= SC_addResult(20 downto 10);
+        end if;
+      end if;
+    end if;
+
+  end process store_result;
+
+  O_Y <= std_logic_vector(SR_Y);
+
+end architecture arch_operativeUnit;
-- 
GitLab