1
0
Fork 0
mirror of https://github.com/RobotechLille/cdf2018-principal synced 2024-11-24 17:16:04 +01:00

FPGA : Filtre

This commit is contained in:
Geoffrey Frogeye 2018-02-28 12:06:11 +01:00
parent 63b89e64b2
commit 68c7223fe4
6 changed files with 250 additions and 10 deletions

View file

@ -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="../$@" )

View file

@ -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,

72
fpga/fir.vhd Normal file
View file

@ -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;

43
fpga/fir_tb.gtkw Normal file
View file

@ -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

92
fpga/fir_tb.vhd Normal file
View file

@ -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;

View file

@ -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