Skip to content
Snippets Groups Projects
Commit c209e7fd authored by fibonup's avatar fibonup
Browse files

codes vhdl

parent 5e96f1f5
No related branches found
No related tags found
No related merge requests found
-------------------------------------------------------------------------------
-- Title : controlUnit
-- 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: Control unit of a sequential FIR filter.
-------------------------------------------------------------------------------
-- Copyright (c) 2018
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2018-04-11 1.0 jnbazin Created
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity controlUnit is
port (
I_clock : in std_logic; -- global clock
I_reset : in std_logic; -- asynchronous global reset
I_inputSampleValid : in std_logic; -- Control signal to load the input sample in the sample shift register and shift the register
I_processingDone1 : in std_logic;
I_processingDone2_1 : in std_logic;
I_processingDone2_2 : in std_logic;
I_processingDone3 : in std_logic;
O_loadShift : out std_logic_vector(1 downto 0); -- filtered sample
O_initAddress : out std_logic; -- Control signal to initialize register read address
O_incrAddress : out std_logic; -- Control signal to increment register read address
O_initSum : out std_logic; -- Control signal to initialize the MAC register
O_loadSum : out std_logic; -- Control signal to load the MAC register;
O_loadOutput : out std_logic; -- Control signal to load Y register
O_Selector : out std_logic_vector(1 downto 0)
--O_FilteredSampleValid : out std_logic -- Data valid signal for filtered sample
);
end entity controlUnit;
architecture archi_operativeUnit of controlUnit is
type T_state is (WAIT_SAMPLE, STORE1, STORE2, STORE3, PROCESSING_LOOP1,PROCESSING_LOOP2_1,PROCESSING_LOOP2_2,PROCESSING_LOOP3, OUTPUT, WAIT_END_SAMPLE); -- state list
signal SR_presentState : T_state;
signal SR_futurState : T_state;
begin
process (I_clock, I_reset) is
begin
if I_reset = '1' then -- asynchronous reset (active high)
SR_presentState <= WAIT_SAMPLE;
elsif rising_edge(I_clock) then -- rising clock edge
SR_presentState <= SR_futurState;
end if;
end process;
process (I_inputSampleValid, I_processingDone1, I_processingDone2_1, I_processingDone2_2, I_processingDone3, SR_presentState) is
begin
case SR_presentState is
when WAIT_SAMPLE =>
if I_inputSampleValid = '1' then
SR_futurState <= STORE1;
else
SR_futurState <= WAIT_SAMPLE;
end if;
when STORE1 =>
SR_futurState <= PROCESSING_LOOP1;
when PROCESSING_LOOP1 =>
if I_processingDone1 = '1' then
SR_futurState <= STORE2;
else
SR_futurState <= PROCESSING_LOOP1;
end if;
when STORE2 =>
SR_futurState <= PROCESSING_LOOP2_1;
when PROCESSING_LOOP2_1 =>
if I_processingDone2_1 = '1' then
SR_futurState <= PROCESSING_LOOP2_2;
else
SR_futurState <= PROCESSING_LOOP2_1;
end if;
when PROCESSING_LOOP2_2 =>
if I_processingDone2_2 = '1' then
SR_futurState <= STORE3;
else
SR_futurState <= PROCESSING_LOOP2_2;
end if;
when STORE3 =>
SR_futurState <= PROCESSING_LOOP3;
when PROCESSING_LOOP3 =>
if I_processingDone3 = '1' then
SR_futurState <= OUTPUT;
else
SR_futurState <= PROCESSING_LOOP3;
end if;
when OUTPUT =>
SR_futurState <= WAIT_END_SAMPLE;
when others => ---WAIT_END_SAMPLE
if I_inputSampleValid = '1' then
SR_futurState <= WAIT_SAMPLE;
else
SR_futurState <= WAIT_END_SAMPLE;
end if;
end case;
end process;
O_loadShift <= "01" when SR_presentState = STORE1 else
"10" when SR_presentState = STORE2 else
"11" when SR_presentState = STORE3 else
"00";
O_initAddress <= '1' when SR_presentState = STORE1 or SR_presentState = STORE2 or SR_presentState = STORE3 else '0';
O_incrAddress <= '1' when SR_presentState = PROCESSING_LOOP1 or SR_presentState = PROCESSING_LOOP2_1 or SR_presentState = PROCESSING_LOOP2_2 or SR_presentState = PROCESSING_LOOP3 else '0';
O_initSum <= '1' when SR_presentState = STORE1 or SR_presentState = STORE2 or SR_presentState = STORE3 else '0';
O_loadSum <= '1' when SR_presentState = PROCESSING_LOOP1 or SR_presentState = PROCESSING_LOOP2_1 or SR_presentState = PROCESSING_LOOP2_2 or SR_presentState = PROCESSING_LOOP3 else '0';
O_loadOutput <= '1' when SR_presentState = OUTPUT else '0' ;
O_Selector <= "01" when SR_presentState = STORE2 or SR_presentState = PROCESSING_LOOP2_1 else
"10" when SR_presentState = PROCESSING_LOOP2_2 else
"11" when SR_presentState = STORE3 or SR_presentState = PROCESSING_LOOP3 else
"00";
--O_FilteredSampleValid <= '1' when SR_presentState = WAIT_END_SAMPLE else '0' ;
end architecture archi_operativeUnit;
-------------------------------------------------------------------------------
-- 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(7 downto 0); -- 8 bit input sample
I_loadShift : in std_logic_vector(1 downto 0); -- 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_loadOutput : in std_logic; -- Control signal to load Y register
I_Selector : in std_logic_vector(1 downto 0);
O_processingDone1 : out std_logic; -- Indicate that processing is done
O_processingDone2_1 : out std_logic; -- Indicate that processing is done
O_processingDone2_2 : out std_logic; -- Indicate that processing is done
O_processingDone3 : 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_coefRegisterH : registerFile;
signal SR_coefRegisterB : registerFile;
signal SR_coefRegisterA : registerFile;
signal SR_coefRegisterG : registerFile;
signal SR_shiftRegisterX : registerFile; -- shift register file used to store and shift input samples
signal SR_shiftRegisterY : registerFile; -- shift register file used to store and shift input samples
signal SR_shiftRegisterZ : registerFile; -- shift register file used to store and shift input samples
signal SC_multOperandX : signed(10 downto 0);
signal SC_multOperandY : signed(10 downto 0);
signal SC_multOperandZ : signed(10 downto 0);
signal SC_multOperandH : signed(10 downto 0);
signal SC_multOperandB : signed(10 downto 0);
signal SC_multOperandA : signed(10 downto 0);
signal SC_multOperandG : signed(10 downto 0);
signal SC_multOperandCoef : signed(10 downto 0);
signal SC_multOperandShift : signed(10 downto 0);
signal SC_MultResult : signed(21 downto 0); -- Result of the multiplication Xi*Hi
signal SC_addResult : signed(28 downto 0); -- result of the accumulation addition
signal SR_sum : signed(28 downto 0); -- Accumulation register
signal SR_Y : signed(7 downto 0); -- filtered sample storage register
signal SR_readAddress : integer range 0 to 128; -- register files read address
-- Coefficients des filtres
begin
-- Low-pass filter provided with octave (or Matlab ;)) command
--fir1(15, .001)/sqrt(sum(fir1(15, .001).^2))*2^6
-- BaseLine filter provided with octave (or Matlab ;)) command
-- fir1(128, 1/100, 'high')*2^10
SR_coefRegisterH <= (to_signed(-1, 11), -- ROM register used file to store FIR coefficients
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)
);
-- Pei Tseng Notch filter provided by octave
-- [b, a] = pei_tseng_notch(1/5, 1/25)*2^9
SR_coefRegisterB <= (
to_signed(480, 11),
to_signed(-777, 11),
to_signed(480, 11)
);
SR_coefRegisterA <= (
to_signed(512, 11),
to_signed(-777, 11),
to_signed(449, 11)
);
-- Parks McClellan filter provided by octave
-- fLP = remez(10, [0 50 60 250]/250, [1 1 0 0])*2^10
SR_coefRegisterG <= (
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)
);
shift : process (I_clock, I_reset) is
begin -- process shift
if I_reset = '1' then -- asynchronous reset (active high)
SR_shiftRegisterX <= (others => (others => '0'));
SR_shiftRegisterY <= (others => (others => '0'));
SR_shiftRegisterZ <= (others => (others => '0'));
elsif rising_edge(I_clock) then
if I_loadShift = "01" then
for i in 128 downto 1 loop
SR_shiftRegisterX(i) <= SR_shiftRegisterX(i-1);
end loop;
SR_shiftRegisterX(0) <= signed(I_inputSample);
end if;
if I_loadShift = "10" then
for i in 2 downto 1 loop
SR_shiftRegisterY(i) <= SR_shiftRegisterY(i-1);
end loop;
SR_shiftRegisterY(0) <= signed(SC_addResult);
end if;
if I_loadShift = "11" then
for i in 10 downto 1 loop
SR_shiftRegisterZ(i) <= SR_shiftRegisterZ(i-1);
end loop;
SR_shiftRegisterZ(0) <= signed(SC_addResult);
end if;
end if;
end process shift;
-- Definition AdressGenerator
incr_address : process (I_clock, I_reset) 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') then
if SR_readAddress < 128 then
SR_readAddress <= SR_readAddress + 1;
else
SR_readAddress <= 0;
end if;
end if;
end if;
end process incr_address;
-- Definition des ProcessingDone
O_processingDone1 <= '1' when SR_readAddress = 128 else '0';
O_processingDone2_1 <= '1' when SR_readAddress >= 2 else '0';
O_processingDone2_2 <= '1' when SR_readAddress >= 2 else '0'; --penser à commencer la 3eme boucle a 1
O_processingDone3 <= '1' when SR_readAddress >= 11 else '0';
-- Definition des multiplexeurs
SC_multOperandX <= SR_shiftRegisterX(SR_readAddress); -- 11 bits
SC_multOperandY <= SR_shiftRegisterY(SR_readAddress) when (SR_readAddress <= 2) else (others => '0');
SC_multOperandZ <= SR_shiftRegisterZ(SR_readAddress) when (SR_readAddress <= 10) else (others => '0');
SC_multOperandH <= SR_coefRegisterH(SR_readAddress) ; -- 11 bits
SC_multOperandB <= SR_coefRegisterB(SR_readAddress) when (SR_readAddress >= 1 and SR_readAddress <= 2) else (others => '0');
SC_multOperandA <= SR_coefRegisterA(SR_readAddress) when (SR_readAddress <= 2) else (others => '0');
SC_multOperandG <= SR_coefRegisterG(SR_readAddress) when (SR_readAddress <= 10) else (others => '0');
SC_multOperandCoef <= SC_multOperandX when I_Selector = "00" else
SC_multOperandY when I_Selector = "01" else
SC_multOperandZ;
SC_multOperandShift <= SC_multOperandH when I_Selector = "00" else
SC_multOperandB when I_Selector = "01" else
SC_multOperandA when I_Selector = "10" else
SC_multOperandG;
SC_MultResult <= SC_multOperandCoef * SC_multOperandShift ; -- 22 bits
SC_addResult <= resize(SC_MultResult, SC_addResult'length) + SR_sum; -- 28 bits
-- Definition du registre sommateur
sum_acc : process (I_clock, I_reset) 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;
-- Definition du registre de sortie
store_result : process (I_clock) is
begin
if rising_edge(I_clock) then
if (I_loadOutput = '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;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment