diff --git a/fpga/Principal.vhd b/fpga/Principal.vhd index 69866e4..281fb32 100644 --- a/fpga/Principal.vhd +++ b/fpga/Principal.vhd @@ -3,19 +3,148 @@ use IEEE.STD_LOGIC_1164.ALL; entity Principal is - Port ( CLK : in STD_LOGIC; - LED : out STD_LOGIC_VECTOR (3 downto 0)); + Port ( CLK : in STD_LOGIC; -- Clock + BTN : in STD_LOGIC; -- Reset + -- FA + IO : inout STD_LOGIC_VECTOR (21 downto 20); + -- Debug + LED : out STD_LOGIC_VECTOR (3 downto 0); + AN : out STD_LOGIC_VECTOR (3 downto 0); + A_TO_G : out STD_LOGIC_VECTOR (6 downto 0); + DOT : out STD_LOGIC + ); end Principal; architecture Behavioral of Principal is + -- Blink led signal pulse : std_logic := '0'; - signal count : integer range 0 to 49999999 := 0; + signal count : integer := 0; + + -- General + signal reset : std_logic := '0'; + + -- Encoder + signal left : integer; + signal right : integer; + + -- Sensors + signal front : integer; + signal back : integer; + signal frontTrigger : integer := 0; + signal backTrigger : integer := 0; + + -- AF + component uart is + generic ( + baud : positive := 9600; + clock_frequency : positive := 50_000_000 + ); + port ( + clock : in std_logic; + reset : in std_logic; + data_stream_in : in std_logic_vector(7 downto 0); + data_stream_in_stb : in std_logic; + data_stream_in_ack : out std_logic; + data_stream_out : out std_logic_vector(7 downto 0); + data_stream_out_stb : out std_logic; + tx : out std_logic; + rx : in std_logic + ); + end component; + + constant BAUD_COUNT: std_logic_vector := x"1458"; -- 96000 Baud at 50 MHz + + signal txData : std_logic_vector(7 downto 0); + signal txStb : std_logic := '0'; + signal txAck : std_logic := '0'; + + signal rxData : std_logic_vector(7 downto 0); + signal rxStb : std_logic := '0'; + + constant A2FD_PING : std_logic_vector := x"50"; -- 'P' + + type readStates is (readIdle); + signal readState : readStates := readIdle; + + type sendMessages is (none, A2FD_PINGs); + signal resetSendMessageRead : std_logic := '0'; + signal resetSendMessageSend : std_logic := '0'; + signal sendMessage : sendMessages := none; + signal sendOffset : integer := 0; + + -- Debug + component sevenseg is + Port ( + data : in STD_LOGIC_VECTOR (15 downto 0); + clock : in STD_LOGIC; + anode : out STD_LOGIC_VECTOR (3 downto 0); + segment : out STD_LOGIC_VECTOR (6 downto 0); + dot : out STD_LOGIC + ); + end component; + signal sevensegdata: std_logic_vector(15 downto 0); + signal fullseg: std_logic_vector(7 downto 0); begin - counter : process(CLK) + reset <= BTN; + + FA: uart port map( + clock => CLK, + reset => reset, + data_stream_in => txData, + data_stream_in_stb => txStb, + data_stream_in_ack => txAck, + data_stream_out => rxData, + data_stream_out_stb => rxStb, + tx => IO(21), + rx => IO(20) + ); + + readsendFA : process(reset, rxStb, txAck) begin - if CLK'event and CLK = '1' then - if count = 49999999 then + if reset = '1' then + readState <= readIdle; + sendMessage <= none; + txStb <= '0'; + sendOffset <= 0; + else + -- If read something + if rxStb = '1' then + if readState = readIdle then + case rxData is + when A2FD_PING => -- 'P' + sendMessage <= A2FD_PINGs; -- TODO Not so brutal + when others => + end case; + end if; + end if; + + -- Reset sending if UART module has begun sending (and has a copy of the byte) + if txAck = '1' then + txStb <= '0'; + end if; + + -- If what was sent is acknowledged and there is still something to send + if txStb = '0' then + case sendMessage is + when none => + when A2FD_PINGs => + txData <= A2FD_PING; + txStb <= '1'; + sendMessage <= none; + end case; + end if; + end if; + end process; + + -- Debug + blinkled : process(CLK, reset) + begin + if reset = '1' then + count <= 0; + pulse <= '0'; + elsif CLK'event and CLK = '1' then + if count = 9999999 then count <= 0; pulse <= not pulse; else @@ -23,7 +152,21 @@ begin end if; end if; end process; + LED(3) <= pulse; + + LED(2) <= txStb; + LED(1) <= rxStb; + LED(0) <= txAck; + + debugSeg: sevenseg port map( + data => sevensegdata, + clock => CLK, + anode => AN, + segment => A_TO_G, + dot => DOT + ); + sevensegdata(15 downto 8) <= rxData; + sevensegdata(7 downto 0) <= txData; - LED(3 downto 0) <= (others => pulse); end Behavioral; diff --git a/fpga/debug.ucf b/fpga/debug.ucf new file mode 100644 index 0000000..b707d17 --- /dev/null +++ b/fpga/debug.ucf @@ -0,0 +1,179 @@ +# __ ____ _ __ +# / |/ (_)_____________ / | / /___ _ ______ _ +# / /|_/ / / ___/ ___/ __ \/ |/ / __ \ | / / __ `/ +# / / / / / /__/ / / /_/ / /| / /_/ / |/ / /_/ / +# /_/ /_/_/\___/_/ \____/_/ |_/\____/|___/\__,_/ +# +# Mercury BASEBOARD User Constraints File +# Revision 1.0.0 (03/25/2015) +# Copyright (c) 2015 MicroNova, LLC +# www.micro-nova.com + +# system oscillators +NET "EXT_CLK" LOC = "P44" | IOSTANDARD = LVTTL ; +NET "CLK" LOC = "P43" | IOSTANDARD = LVTTL ; +NET "CLK" TNM_NET = "CLK"; +TIMESPEC "TS_CLK" = PERIOD "CLK" 20 ns HIGH 50 %; + +# PS/2 +NET "PS2_DATA" LOC = "P13" | IOSTANDARD = LVTTL ; +NET "PS2_CLK" LOC = "P15" | IOSTANDARD = LVTTL ; + +# Buttons +NET "USR_BTN" LOC = "P41" | IOSTANDARD = LVTTL ; +NET "BTN<0>" LOC = "P68" | IOSTANDARD = LVTTL ; +NET "BTN<1>" LOC = "P97" | IOSTANDARD = LVTTL ; +NET "BTN<2>" LOC = "P7" | IOSTANDARD = LVTTL ; +NET "BTN<3>" LOC = "P82" | IOSTANDARD = LVTTL ; + +# VGA +NET "RED<0>" LOC = "P20" | IOSTANDARD = LVTTL ; +NET "RED<1>" LOC = "P32" | IOSTANDARD = LVTTL ; +NET "RED<2>" LOC = "P33" | IOSTANDARD = LVTTL ; +NET "GRN<0>" LOC = "P34" | IOSTANDARD = LVTTL ; +NET "GRN<1>" LOC = "P35" | IOSTANDARD = LVTTL ; +NET "GRN<2>" LOC = "P36" | IOSTANDARD = LVTTL ; +NET "BLU<0>" LOC = "P37" | IOSTANDARD = LVTTL ; +NET "BLU<1>" LOC = "P40" | IOSTANDARD = LVTTL ; +NET "HSYNC" LOC = "P16" | IOSTANDARD = LVTTL ; +NET "VSYNC" LOC = "P19" | IOSTANDARD = LVTTL ; + +# SWITCHES +NET "SW<0>" LOC = "P59" | IOSTANDARD = LVTTL ; +NET "SW<1>" LOC = "P60" | IOSTANDARD = LVTTL ; +NET "SW<2>" LOC = "P61" | IOSTANDARD = LVTTL ; +NET "SW<3>" LOC = "P62" | IOSTANDARD = LVTTL ; +NET "SW<4>" LOC = "P64" | IOSTANDARD = LVTTL ; +NET "SW<5>" LOC = "P57" | IOSTANDARD = LVTTL ; +NET "SW<6>" LOC = "P56" | IOSTANDARD = LVTTL ; +NET "SW<7>" LOC = "P52" | IOSTANDARD = LVTTL ; + +# 7 SEG +NET "AN<0>" LOC = "P50" | IOSTANDARD = LVTTL ; +NET "AN<1>" LOC = "P49" | IOSTANDARD = LVTTL ; +NET "AN<2>" LOC = "P85" | IOSTANDARD = LVTTL ; +NET "AN<3>" LOC = "P84" | IOSTANDARD = LVTTL ; +NET "A_TO_G<0>" LOC = "P72" | IOSTANDARD = LVTTL ; +NET "A_TO_G<1>" LOC = "P71" | IOSTANDARD = LVTTL ; +NET "A_TO_G<2>" LOC = "P70" | IOSTANDARD = LVTTL ; +NET "A_TO_G<3>" LOC = "P65" | IOSTANDARD = LVTTL ; +NET "A_TO_G<4>" LOC = "P77" | IOSTANDARD = LVTTL ; +NET "A_TO_G<5>" LOC = "P78" | IOSTANDARD = LVTTL ; +NET "A_TO_G<6>" LOC = "P83" | IOSTANDARD = LVTTL ; +NET "DOT" LOC = "P73" | IOSTANDARD = LVTTL ; + +# PMOD +NET "PMOD<0>" LOC = "P5" | IOSTANDARD = LVTTL ; +NET "PMOD<1>" LOC = "P4" | IOSTANDARD = LVTTL ; +NET "PMOD<2>" LOC = "P6" | IOSTANDARD = LVTTL ; +NET "PMOD<3>" LOC = "P98" | IOSTANDARD = LVTTL ; +NET "PMOD<4>" LOC = "P94" | IOSTANDARD = LVTTL ; +NET "PMOD<5>" LOC = "P93" | IOSTANDARD = LVTTL ; +NET "PMOD<6>" LOC = "P90" | IOSTANDARD = LVTTL ; +NET "PMOD<7>" LOC = "P89" | IOSTANDARD = LVTTL ; + +# AUDIO OUT +NET "AUDIO_OUT_R" LOC = "P88" | IOSTANDARD = LVTTL ; +NET "AUDIO_OUT_L" LOC = "P86" | IOSTANDARD = LVTTL ; + +# memory & bus-switch +NET "SWITCH_OEN" LOC = "P3" | IOSTANDARD = LVTTL ; +NET "MEMORY_OEN" LOC = "P30" | IOSTANDARD = LVTTL ; + +# flash/usb interface +NET "FPGA_CSN" LOC = "P39" | IOSTANDARD = LVTTL ; +NET "FLASH_CSN" LOC = "P27" | IOSTANDARD = LVTTL ; +NET "SPI_MOSI" LOC = "P46" | IOSTANDARD = LVTTL ; +NET "SPI_MISO" LOC = "P51" | IOSTANDARD = LVTTL ; +NET "SPI_SCK" LOC = "P53" | IOSTANDARD = LVTTL ; + +# ADC interface +NET "ADC_MISO" LOC = "P21" | IOSTANDARD = LVTTL ; +NET "ADC_MOSI" LOC = "P10" | IOSTANDARD = LVTTL ; +NET "ADC_SCK" LOC = "P9" | IOSTANDARD = LVTTL ; +NET "ADC_CSN" LOC = "P12" | IOSTANDARD = LVTTL ; +# __ ____ _ __ +# / |/ (_)_____________ / | / /___ _ ______ _ +# / /|_/ / / ___/ ___/ __ \/ |/ / __ \ | / / __ `/ +# / / / / / /__/ / / /_/ / /| / /_/ / |/ / /_/ / +# /_/ /_/_/\___/_/ \____/_/ |_/\____/|___/\__,_/ +# +# Mercury User Constraints File +# Revision 1.0.142 (10/24/2012) +# Copyright (c) 2012 MicroNova, LLC +# www.micro-nova.com + +# user LEDs and button +NET "LED<0>" LOC = "P13" | IOSTANDARD = LVTTL ; +NET "LED<1>" LOC = "P15" | IOSTANDARD = LVTTL ; +NET "LED<2>" LOC = "P16" | IOSTANDARD = LVTTL ; +NET "LED<3>" LOC = "P19" | IOSTANDARD = LVTTL ; +NET "BTN" LOC = "P41" | IOSTANDARD = LVTTL ; + +# direct and global-clock I/O +NET "DIO<0>" LOC = "P20" | IOSTANDARD = LVTTL ; +NET "DIO<1>" LOC = "P32" | IOSTANDARD = LVTTL ; +NET "DIO<2>" LOC = "P33" | IOSTANDARD = LVTTL ; +NET "DIO<3>" LOC = "P34" | IOSTANDARD = LVTTL ; +NET "DIO<4>" LOC = "P35" | IOSTANDARD = LVTTL ; +NET "DIO<5>" LOC = "P36" | IOSTANDARD = LVTTL ; +NET "DIO<6>" LOC = "P37" | IOSTANDARD = LVTTL ; +NET "CIO<0>" LOC = "P40" | IOSTANDARD = LVTTL ; +NET "CIO<1>" LOC = "P44" | IOSTANDARD = LVTTL ; + +# in-only pins +NET "INPIN<0>" LOC = "P68" | IOSTANDARD = LVTTL ; +NET "INPIN<1>" LOC = "P97" | IOSTANDARD = LVTTL ; +NET "INPIN<2>" LOC = "P7" | IOSTANDARD = LVTTL ; +NET "INPIN<3>" LOC = "P82" | IOSTANDARD = LVTTL ; + +# level-shifted I/O +NET "IO<0>" LOC = "P59" | IOSTANDARD = LVTTL ; +NET "IO<1>" LOC = "P60" | IOSTANDARD = LVTTL ; +NET "IO<2>" LOC = "P61" | IOSTANDARD = LVTTL ; +NET "IO<3>" LOC = "P62" | IOSTANDARD = LVTTL ; +NET "IO<4>" LOC = "P64" | IOSTANDARD = LVTTL ; +NET "IO<5>" LOC = "P57" | IOSTANDARD = LVTTL ; +NET "IO<6>" LOC = "P56" | IOSTANDARD = LVTTL ; +NET "IO<7>" LOC = "P52" | IOSTANDARD = LVTTL ; +NET "IO<8>" LOC = "P50" | IOSTANDARD = LVTTL ; +NET "IO<9>" LOC = "P49" | IOSTANDARD = LVTTL ; +NET "IO<10>" LOC = "P85" | IOSTANDARD = LVTTL ; +NET "IO<11>" LOC = "P84" | IOSTANDARD = LVTTL ; +NET "IO<12>" LOC = "P83" | IOSTANDARD = LVTTL ; +NET "IO<13>" LOC = "P78" | IOSTANDARD = LVTTL ; +NET "IO<14>" LOC = "P77" | IOSTANDARD = LVTTL ; +NET "IO<15>" LOC = "P65" | IOSTANDARD = LVTTL ; +NET "IO<16>" LOC = "P70" | IOSTANDARD = LVTTL ; +NET "IO<17>" LOC = "P71" | IOSTANDARD = LVTTL ; +NET "IO<18>" LOC = "P72" | IOSTANDARD = LVTTL ; +NET "IO<19>" LOC = "P73" | IOSTANDARD = LVTTL ; +NET "IO<20>" LOC = "P5" | IOSTANDARD = LVTTL ; +NET "IO<21>" LOC = "P4" | IOSTANDARD = LVTTL ; +NET "IO<22>" LOC = "P6" | IOSTANDARD = LVTTL ; +NET "IO<23>" LOC = "P98" | IOSTANDARD = LVTTL ; +NET "IO<24>" LOC = "P94" | IOSTANDARD = LVTTL ; +NET "IO<25>" LOC = "P93" | IOSTANDARD = LVTTL ; +NET "IO<26>" LOC = "P90" | IOSTANDARD = LVTTL ; +NET "IO<27>" LOC = "P89" | IOSTANDARD = LVTTL ; +NET "IO<28>" LOC = "P88" | IOSTANDARD = LVTTL ; +NET "IO<29>" LOC = "P86" | IOSTANDARD = LVTTL ; + +# memory & bus-switch +NET "switch_oen" LOC = "P3" | IOSTANDARD = LVTTL ; +NET "memory_oen" LOC = "P30" | IOSTANDARD = LVTTL ; + +# flash/usb interface +NET "fpga_csn" LOC = "P39" | IOSTANDARD = LVTTL ; +NET "flash_csn" LOC = "P27" | IOSTANDARD = LVTTL ; +NET "spi_mosi" LOC = "P46" | IOSTANDARD = LVTTL ; +NET "spi_miso" LOC = "P51" | IOSTANDARD = LVTTL ; +NET "spi_sck" LOC = "P53" | IOSTANDARD = LVTTL ; + +# ADC interface +NET "adc_miso" LOC = "P21" | IOSTANDARD = LVTTL ; +NET "adc_mosi" LOC = "P10" | IOSTANDARD = LVTTL ; +NET "adc_sck" LOC = "P9" | IOSTANDARD = LVTTL ; +NET "adc_csn" LOC = "P12" | IOSTANDARD = LVTTL ; + +# CLOCK timing diff --git a/fpga/hedm.vhd b/fpga/hedm.vhd index d106dbf..1f52bd8 100644 --- a/fpga/hedm.vhd +++ b/fpga/hedm.vhd @@ -13,7 +13,7 @@ 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 - counts : out -- Integer; + counts : out integer ); end hedm; @@ -29,8 +29,8 @@ begin Ap <= An; Bp <= Bn; - An <= A; - Bn <= B; + 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 diff --git a/fpga/project.cfg b/fpga/project.cfg index e0228e8..119cd88 100644 --- a/fpga/project.cfg +++ b/fpga/project.cfg @@ -4,8 +4,13 @@ XILINX = /opt/Xilinx/14.7/ISE_DS/ISE PROGRAMMER = mercpcl TOPLEVEL = Principal -VHDSOURCE = $(TOPLEVEL).vhd -CONSTRAINTS = mercury.ucf +# Prod +# VHDSOURCE = $(TOPLEVEL).vhd uart.vhd +# CONSTRAINTS = mercury.ucf +# Debug +VHDSOURCE = $(TOPLEVEL).vhd $(wildcard *.vhd) +CONSTRAINTS = debug.ucf + # Implement design # Allow unmatched LOC Constraints diff --git a/fpga/sevenseg.vhd b/fpga/sevenseg.vhd new file mode 100644 index 0000000..c10b2d9 --- /dev/null +++ b/fpga/sevenseg.vhd @@ -0,0 +1,68 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; + +entity sevenseg is + Port ( + data : in STD_LOGIC_VECTOR (15 downto 0); + clock : in STD_LOGIC; + anode : out STD_LOGIC_VECTOR (3 downto 0); + segment : out STD_LOGIC_VECTOR (6 downto 0); + dot : out STD_LOGIC + ); +end sevenseg; + +architecture structural of sevenseg is + + signal digit: std_logic_vector(3 downto 0); + signal selector: integer range 0 to 3 := 0; + signal counter : integer range 0 to 199999 := 0; + +begin + with selector select + anode <= "1110" when 0, + "1101" when 1, + "1011" when 2, + "0111" when 3, + "0000" when others; + + with selector select + digit <= data(3 downto 0) when 0, + data(7 downto 4) when 1, + data(11 downto 8) when 2, + data(15 downto 12) when 3, + "0000" when others; + + with digit select + segment <= "0000001" when "0000", -- 0 + "1001111" when "0001", -- 1 + "0010010" when "0010", -- 2 + "0000110" when "0011", -- 3 + "1001100" when "0100", -- 4 + "0100100" when "0101", -- 5 + "0100000" when "0110", -- 6 + "0001111" when "0111", -- 7 + "0000000" when "1000", -- 8 + "0000100" when "1001", -- 9 + "0001000" when "1010", -- A + "1100000" when "1011", -- b + "0110001" when "1100", -- C + "1000010" when "1101", -- d + "0110000" when "1110", -- E + "0111000" when "1111", -- F + "0000000" when others; + + dot <= '1'; + + alternateur : process(clock) + begin + if clock'event and clock = '1' then + if counter = 0 then + selector <= selector + 1; + end if; + counter <= counter + 1; + end if; + end process; + + +end structural; +