diff --git a/fpga/Makefile b/fpga/Makefile index c4b9f88..7f9f66f 100644 --- a/fpga/Makefile +++ b/fpga/Makefile @@ -166,13 +166,13 @@ isimgui: build/isim_$(TB)$(EXE) GHDL_FLAGS=--mb-comments %_syntax: %.vhd - ghdl -s --mb-comments "$<" + ghdl -s $(GHDL_FLAGS) "$<" build/%.o: %.vhd ghdl -a $(GHDL_FLAGS) --workdir="$(shell dirname "$@")" "$<" build/%_tb: build/%_tb.o $(addprefix build/,$(subst .vhd,.o,$(VHDSOURCE))) - ghdl -e --workdir="$(shell dirname "$@")" -o "$(shell echo "$@" | tr A-Z a-z)" "$(basename $(notdir $<))" + ghdl -e $(GHDL_FLAGS) --workdir="$(shell dirname "$@")" -o "$(shell echo "$@" | tr A-Z a-z)" "$(basename $(notdir $<))" build/%_tb.vcd: build/%_tb (cd "$(shell dirname "$<")"; time ghdl -r "$(basename $(notdir $<))" --vcd="../$@" ) diff --git a/fpga/Principal.vhd b/fpga/Principal.vhd index 2731d66..55855b8 100644 --- a/fpga/Principal.vhd +++ b/fpga/Principal.vhd @@ -44,9 +44,13 @@ architecture Behavioral of Principal is ); end component; - -- Sensors + -- Distance sensors signal front : integer := 0; + signal frontRaw : integer := 0; + signal frontFinished : std_logic; signal back : integer := 0; + signal backRaw : integer := 0; + signal backFinished : std_logic; component hcsr04 IS generic( fFpga : INTEGER := fFpga @@ -61,6 +65,16 @@ architecture Behavioral of Principal is finished : OUT STD_LOGIC ); end component; + component fir is + Port ( + clock : in STD_LOGIC; + reset : in STD_LOGIC; + signalIn : in INTEGER; + signalOut : out INTEGER; + start : in STD_LOGIC; + done : out STD_LOGIC + ); + end component; -- AF component uart is @@ -127,25 +141,44 @@ begin zero => zerocoder, counts => right ); + frontCapt: hcsr04 port map ( clk => CLK, reset => reset, echo => FRONTECHO, - distance => front, + distance => frontRaw, trigger => FRONTTRIGGER, - start => '1' - -- finished => + start => '1', + finished => frontFinished + ); + frontFilter : FIR port map ( + clock => CLK, + reset => reset, + signalIn => frontRaw, + signalOut => front, + start => frontFinished + -- done => done ); backCapt: hcsr04 port map ( clk => CLK, reset => reset, echo => BACKECHO, - distance => back, + distance => backRaw, trigger => BACKTRIGGER, - start => '1' - -- finished => + start => '1', + finished => backFinished ); + backFilter : FIR port map ( + clock => CLK, + reset => reset, + signalIn => backRaw, + signalOut => back, + start => backFinished + -- done => done + ); + + FA: uart port map( clock => CLK, diff --git a/fpga/fir.vhd b/fpga/fir.vhd new file mode 100644 index 0000000..2955433 --- /dev/null +++ b/fpga/fir.vhd @@ -0,0 +1,72 @@ +-- Code original écrit par Geoffrey Preud'homme et Eloi Zalczer +-- dans le cadre du tutorat de Circuits Numériques Programmables du S7 + +-- Filtre à réponse impulsionelle finie + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; + +entity fir is + Port ( + clock : in STD_LOGIC; -- Afin de générer l'impulsion terminée + reset : in STD_LOGIC; + signalIn : in INTEGER; -- Signal d'entrée (un à la fois) + signalOut : out INTEGER := 0; -- Signal filtré de sortie + start : in STD_LOGIC; -- Lance une étape de filtrage + done : out STD_LOGIC -- Signale la fin de l'étape de filtrage + ); +end fir; + +architecture Behavioral of fir is + + constant N : INTEGER := 4; -- Nombre de coefficients + constant M : INTEGER := 2**6; -- Facteur multiplicatif + type INT_ARRAY is array (N-1 downto 0) of integer; + constant coefficients : INT_ARRAY := (16,16,16,16); + -- ↑ Coefficients du fir multipliés par M + + signal echantillons : INT_ARRAY := (others => 0); -- stockage des entrées retardées + type fir_states is (waiting, calculating); -- machine à états finis + signal state : fir_states := waiting; + signal k : integer := 0; + signal somme : integer := 0; +begin + filter: PROCESS(clock) + begin + if reset = '1' then + done <= '0'; + state <= waiting; + echantillons <= (others => 0); + + elsif rising_edge(clock) then + + if state = waiting then + done <= '0'; + + -- Quand start est à 1, on lance le filtre + if start = '1' then + -- Décalage + echantillons(N-1 downto 1) <= echantillons(N-2 downto 0); + echantillons(0) <= signalIn; + k <= 0; + somme <= 0; + state <= calculating; + end if; + + elsif state = calculating then + -- Calcul de la somme + somme <= somme + echantillons(k) * coefficients(k); + k <= k + 1; + + if k = N-1 then + -- Division par le facteur + signalOut <= somme / M; + done <= '1'; + state <= waiting; + end if; + end if; + end if; + end process; + +end Behavioral; diff --git a/fpga/fir_tb.gtkw b/fpga/fir_tb.gtkw new file mode 100644 index 0000000..bedd1b8 --- /dev/null +++ b/fpga/fir_tb.gtkw @@ -0,0 +1,43 @@ +[*] +[*] GTKWave Analyzer v3.3.86 (w)1999-2017 BSI +[*] Wed Feb 28 09:53:14 2018 +[*] +[dumpfile] "/home/geoffrey/Documents/Polytech/Robotech/2017-2018/CdF/cdf2018-principal/fpga/build/fir_tb.ghw" +[dumpfile_mtime] "Wed Feb 28 09:53:10 2018" +[dumpfile_size] 595494 +[savefile] "/home/geoffrey/Documents/Polytech/Robotech/2017-2018/CdF/cdf2018-principal/fpga/fir_tb.gtkw" +[timestart] 0 +[size] 1600 862 +[pos] -1 -1 +*-36.330536 375700000000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[treeopen] top. +[treeopen] top.fir_tb. +[sst_width] 213 +[signals_width] 177 +[sst_expanded] 1 +[sst_vpaned_height] 244 +@28 +top.fir_tb.clock +top.fir_tb.reset +[color] 1 +top.fir_tb.start +@8420 +[color] 1 +top.fir_tb.signalin +@420 +[color] 2 +top.fir_tb.dut.state +@8420 +[color] 2 +top.fir_tb.dut.k +@8421 +[color] 2 +top.fir_tb.dut.somme +@28 +[color] 1 +top.fir_tb.done +@8420 +[color] 1 +top.fir_tb.signalout +[pattern_trace] 1 +[pattern_trace] 0 diff --git a/fpga/fir_tb.vhd b/fpga/fir_tb.vhd new file mode 100644 index 0000000..d6a999d --- /dev/null +++ b/fpga/fir_tb.vhd @@ -0,0 +1,92 @@ +-- Testbench automatically generated online +-- at http://vhdl.lapinoo.net +-- Generation date : 28.2.2018 08:45:52 GMT + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; + +entity fir_tb is + end fir_tb; + +architecture tb of fir_tb is + + component FIR + port (clock : in std_logic; + reset : in std_logic; + signalIn : in integer; + signalOut : out integer; + start : in std_logic; + done : out std_logic); + end component; + + signal clock : std_logic; + signal reset : std_logic; + signal signalIn : integer; + signal signalOut : integer; + signal start : std_logic; + signal done : std_logic; + + constant TbPeriod : time := 20 ns; + signal TbClock : std_logic := '0'; + signal TbSimEnded : std_logic := '0'; + + constant SignalPeriod : time := 100 us; + constant SignalAmpl : integer := 1000; + constant SamplingPeriod : time := TbPeriod * 150; + constant TimeBase : time := 1 ns; -- For working with integers when generating the signal + +begin + + dut : FIR + port map (clock => clock, + reset => reset, + signalIn => signalIn, + signalOut => signalOut, + start => start, + done => done); + + -- Clock generation + TbClock <= not TbClock after TbPeriod/2 when TbSimEnded /= '1' else '0'; + + clock <= TbClock; + + sampling : process + variable nowI : integer; + variable SignalPeriodI : integer; + variable x : integer; + variable y : integer; + variable z : integer; + begin + while TbSimEnded = '0' loop + -- Not optimised at all... No worries though it's just a testbench + nowI := now / TimeBase; + SignalPeriodI := SignalPeriod / TimeBase; + x := nowI rem SignalPeriodI; + y := x * SignalAmpl; + z := y / SignalPeriodI; + signalIn <= z; + start <= '1'; + wait for TbPeriod; + start <= '0'; + wait for SamplingPeriod - TbPeriod; + end loop; + wait; + end process; + + stimuli : process + begin + -- Reset generation + reset <= '1'; + wait for 100 ns; + reset <= '0'; + wait for 100 ns; + + wait for 5 * SignalPeriod; + + -- Stop the clock and hence terminate the simulation + TbSimEnded <= '1'; + wait; + end process; + +end tb; diff --git a/fpga/project.cfg b/fpga/project.cfg index 6622ec0..41c1623 100644 --- a/fpga/project.cfg +++ b/fpga/project.cfg @@ -5,5 +5,5 @@ PROGRAMMER = mercpcl TOPLEVEL = Principal # Prod -VHDSOURCE = $(TOPLEVEL).vhd communication.vhd uart.vhd hedm.vhd hcsr04.vhd +VHDSOURCE = $(TOPLEVEL).vhd communication.vhd uart.vhd hedm.vhd hcsr04.vhd fir.vhd CONSTRAINTS = principal.ucf