mirror of
https://github.com/RobotechLille/cdf2018-principal
synced 2024-11-13 03:46:12 +01:00
FPGA: Ajout de simulations
This commit is contained in:
parent
00fe416933
commit
39154e4f5e
|
@ -87,7 +87,7 @@ export XILINX
|
|||
default: $(BITFILE)
|
||||
|
||||
clean:
|
||||
rm -rf build
|
||||
rm -rf build/*
|
||||
|
||||
build/$(PROJECT).prj: project.cfg
|
||||
@echo "Updating $@"
|
||||
|
@ -159,6 +159,24 @@ isimgui: build/isim_$(TB)$(EXE)
|
|||
@echo "run all" >> build/isim_$(TB).cmd
|
||||
cd build ; ./isim_$(TB)$(EXE) -gui -tclbatch isim_$(TB).cmd
|
||||
|
||||
###########################################################################
|
||||
# Testing (using ghdl and gtkwave)
|
||||
###########################################################################
|
||||
|
||||
%_syntax: %.vhd
|
||||
ghdl -s --mb-comments "$<"
|
||||
|
||||
build/%.o: %.vhd
|
||||
ghdl -a --mb-comments --workdir="$(shell dirname "$@")" "$<"
|
||||
|
||||
build/%_tb: build/%_tb.o $(addprefix build/,$(subst .vhd,.o,$(VHDSOURCE)))
|
||||
ghdl -e --workdir="$(shell dirname "$@")" -o "$@" "$(basename $(notdir $<))"
|
||||
|
||||
build/%_tb.vcd: build/%_tb
|
||||
(cd "$(shell dirname "$<")"; ghdl -r "$(basename $(notdir $<))" --vcd="../$@" )
|
||||
|
||||
%_wave: build/%_tb.vcd
|
||||
gtkwave --save "$(notdir $(basename $<)).gtkw" "$<"
|
||||
|
||||
###########################################################################
|
||||
# Programming
|
||||
|
|
12
fpga/generateConstants.sh
Executable file
12
fpga/generateConstants.sh
Executable file
|
@ -0,0 +1,12 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
cd "$(dirname "${BASH_SOURCE[0]}")"
|
||||
|
||||
grep "#define [A-Z0-9_]\+ '[a-zA-Z]'" ../arduino/AFsignals.h | while read line
|
||||
do
|
||||
name="$(echo "$line" | cut -d ' ' -f 2)"
|
||||
letter="$(echo "$line" | cut -d ' ' -f 3 | cut -d "'" -f 2)"
|
||||
hex="$(python -c "print(hex(ord('$letter'))[2:])")"
|
||||
|
||||
echo " constant $name : std_logic_vector(7 downto 0) := x\"$hex\"; -- '$letter'"
|
||||
done
|
|
@ -13,18 +13,25 @@ entity hedm is
|
|||
clk : in STD_LOGIC; -- Horloge, la fréquence n'importe pas
|
||||
chA : in STD_LOGIC; -- Canal A
|
||||
chB : in STD_LOGIC; -- Canal B
|
||||
reset : in STD_LOGIC;
|
||||
counts : out integer
|
||||
);
|
||||
end hedm;
|
||||
|
||||
architecture Behavioral of hedm is
|
||||
signal counter : integer;
|
||||
signal An, Bn : STD_LOGIC; -- Nouvelles valeurs de A et B stockées pour que les entrées soient lues une seule fois en début de cycle
|
||||
signal Ap, Bp : STD_LOGIC; -- Précédentes valeurs de A et B pour détecter les front montant
|
||||
signal counter : integer := 0;
|
||||
signal An, Bn : STD_LOGIC := '0'; -- Nouvelles valeurs de A et B stockées pour que les entrées soient lues une seule fois en début de cycle
|
||||
signal Ap, Bp : STD_LOGIC := '0'; -- Précédentes valeurs de A et B pour détecter les front montant
|
||||
begin
|
||||
processInput : process(clk)
|
||||
processInput : process(clk, reset)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if reset = '1' then
|
||||
counter <= 0;
|
||||
An <= '0';
|
||||
Bn <= '0';
|
||||
Ap <= '0';
|
||||
Bp <= '0';
|
||||
elsif rising_edge(clk) then
|
||||
|
||||
Ap <= An;
|
||||
Bp <= Bn;
|
||||
|
@ -32,9 +39,9 @@ begin
|
|||
An <= chA;
|
||||
Bn <= chB;
|
||||
|
||||
-- On pourrait optimiser la logique avec un tableau de Karnaugh ou autres méthodes
|
||||
-- de simplification d'algèbre de Boole, mais le "compilateur" pour FPGA fera un
|
||||
-- tout aussi bon travail, on garde donc le code suivant pour la lisibilité
|
||||
-- On pourrait optimiser la logique avec un tableau de Karnaugh ou autres méthodes
|
||||
-- de simplification d'algèbre de Boole, mais le "compilateur" pour FPGA fera un
|
||||
-- tout aussi bon travail, on garde donc le code suivant pour la lisibilité
|
||||
|
||||
if (Ap = '0' and An = '1') then -- Front montant A
|
||||
if (Bn = '0') then
|
||||
|
|
25
fpga/hedm_tb.gtkw
Normal file
25
fpga/hedm_tb.gtkw
Normal file
|
@ -0,0 +1,25 @@
|
|||
[*]
|
||||
[*] GTKWave Analyzer v3.3.86 (w)1999-2017 BSI
|
||||
[*] Sat Feb 24 16:20:02 2018
|
||||
[*]
|
||||
[dumpfile] "/home/geoffrey/Documents/Polytech/Robotech/2017-2018/CdF/cdf2018-principal/fpga/build/hedm_tb.vcd"
|
||||
[dumpfile_mtime] "Sat Feb 24 16:19:31 2018"
|
||||
[dumpfile_size] 10717
|
||||
[savefile] "/home/geoffrey/Documents/Polytech/Robotech/2017-2018/CdF/cdf2018-principal/fpga/build/hedm_tb.gtkw"
|
||||
[timestart] 0
|
||||
[size] 1600 862
|
||||
[pos] -1 -1
|
||||
*-28.000000 -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 -1
|
||||
[sst_width] 213
|
||||
[signals_width] 78
|
||||
[sst_expanded] 1
|
||||
[sst_vpaned_height] 244
|
||||
@28
|
||||
clk
|
||||
reset
|
||||
cha
|
||||
chb
|
||||
@421
|
||||
counts
|
||||
[pattern_trace] 1
|
||||
[pattern_trace] 0
|
110
fpga/hedm_tb.vhd
Normal file
110
fpga/hedm_tb.vhd
Normal file
|
@ -0,0 +1,110 @@
|
|||
-- Testbench automatically generated online
|
||||
-- at http://vhdl.lapinoo.net
|
||||
-- Generation date : 24.2.2018 15:15:56 GMT
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
entity hedm_tb is
|
||||
end hedm_tb;
|
||||
|
||||
architecture tb of hedm_tb is
|
||||
|
||||
component hedm
|
||||
port (clk : in std_logic;
|
||||
chA : in std_logic;
|
||||
chB : in std_logic;
|
||||
reset : in std_logic;
|
||||
counts : out integer);
|
||||
end component;
|
||||
|
||||
signal clk : std_logic;
|
||||
signal chA : std_logic;
|
||||
signal chB : std_logic;
|
||||
signal reset : std_logic;
|
||||
signal counts : integer;
|
||||
|
||||
constant TbPeriod : time := 20 ns;
|
||||
signal TbClock : std_logic := '0';
|
||||
signal TbSimEnded : std_logic := '0';
|
||||
|
||||
begin
|
||||
|
||||
dut : hedm
|
||||
port map (clk => clk,
|
||||
chA => chA,
|
||||
chB => chB,
|
||||
reset => reset,
|
||||
counts => counts);
|
||||
|
||||
-- Clock generation
|
||||
TbClock <= not TbClock after TbPeriod/2 when TbSimEnded /= '1' else '0';
|
||||
|
||||
clk <= TbClock;
|
||||
|
||||
stimuli : process
|
||||
variable tour : integer;
|
||||
constant nbTours : integer := 10;
|
||||
begin
|
||||
chA <= '0';
|
||||
chB <= '0';
|
||||
|
||||
-- Reset generation
|
||||
reset <= '1';
|
||||
wait for 100 ns;
|
||||
reset <= '0';
|
||||
wait for 100 ns;
|
||||
|
||||
-- Test sens avant
|
||||
for I in 0 to nbTours-1 loop
|
||||
chA <= '1';
|
||||
wait for TbPeriod;
|
||||
chB <= '1';
|
||||
wait for TbPeriod;
|
||||
chA <= '0';
|
||||
wait for TbPeriod;
|
||||
chB <= '0';
|
||||
wait for TbPeriod;
|
||||
end loop;
|
||||
|
||||
wait for 5 * TbPeriod;
|
||||
assert counts = nbTours * 4 report "Sens avant faux, reçu " & integer'image(counts) severity error;
|
||||
|
||||
|
||||
-- Test sens avant
|
||||
for I in 0 to nbTours-1 loop
|
||||
chB <= '1';
|
||||
wait for TbPeriod;
|
||||
chA <= '1';
|
||||
wait for TbPeriod;
|
||||
chB <= '0';
|
||||
wait for TbPeriod;
|
||||
chA <= '0';
|
||||
wait for TbPeriod;
|
||||
end loop;
|
||||
|
||||
wait for 5 * TbPeriod;
|
||||
assert counts = 0 report "Sens arrière faux, reçu " & integer'image(counts) severity error;
|
||||
|
||||
-- Test aller-retours
|
||||
for I in 0 to nbTours-1 loop
|
||||
chA <= '1';
|
||||
wait for TbPeriod;
|
||||
chB <= '1';
|
||||
wait for TbPeriod;
|
||||
chB <= '0';
|
||||
wait for TbPeriod;
|
||||
chA <= '0';
|
||||
wait for TbPeriod;
|
||||
end loop;
|
||||
|
||||
wait for 5 * TbPeriod;
|
||||
assert counts = 0 report "Aller-retours faux, reçu " & integer'image(counts) severity error;
|
||||
|
||||
|
||||
-- Stop the clock and hence terminate the simulation
|
||||
TbSimEnded <= '1';
|
||||
wait;
|
||||
end process;
|
||||
|
||||
end tb;
|
Loading…
Reference in a new issue