Update design files for diligent_jstk: change synthesis flow mode to Hierarchical, adjust XCI paths, and enhance UART viewer for real-time coordinate visualization with updated axis limits.

This commit is contained in:
2025-05-17 13:29:40 +02:00
parent 8fd7db7575
commit 1eb2181d1d
5 changed files with 173 additions and 168 deletions

View File

@@ -2,173 +2,178 @@ LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY digilent_jstk2 IS
GENERIC (
DELAY_US : INTEGER := 100; -- Delay (in us) between two packets - Required by the SPI IP-Core tested with 25us doesn't work
CLKFREQ : INTEGER := 100_000_000; -- Frequency of the aclk signal (in Hz)
SPI_SCLKFREQ : INTEGER := 5_000 -- Frequency of the SPI SCLK clock signal (in Hz)
);
PORT (
aclk : IN STD_LOGIC;
aresetn : IN STD_LOGIC;
GENERIC (
DELAY_US : INTEGER := 100; -- Delay (in us) between two packets - Required by the SPI IP-Core tested with 25us doesn't work
CLKFREQ : INTEGER := 100_000_000; -- Frequency of the aclk signal (in Hz)
SPI_SCLKFREQ : INTEGER := 5_000 -- Frequency of the SPI SCLK clock signal (in Hz)
);
PORT (
aclk : IN STD_LOGIC;
aresetn : IN STD_LOGIC;
-- Data going TO the SPI IP-Core (and so, to the JSTK2 module)
m_axis_tvalid : OUT STD_LOGIC;
m_axis_tdata : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
m_axis_tready : IN STD_LOGIC;
-- Data going TO the SPI IP-Core (and so, to the JSTK2 module)
m_axis_tvalid : OUT STD_LOGIC;
m_axis_tdata : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
m_axis_tready : IN STD_LOGIC;
-- Data coming FROM the SPI IP-Core (and so, from the JSTK2 module)
-- There is no tready signal, so you must be always ready to accept and use the incoming data, or it will be lost!
s_axis_tvalid : IN STD_LOGIC;
s_axis_tdata : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
-- Data coming FROM the SPI IP-Core (and so, from the JSTK2 module)
-- There is no tready signal, so you must be always ready to accept and use the incoming data, or it will be lost!
s_axis_tvalid : IN STD_LOGIC;
s_axis_tdata : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
-- Joystick and button values read from the module
jstk_x : OUT STD_LOGIC_VECTOR(9 DOWNTO 0);
jstk_y : OUT STD_LOGIC_VECTOR(9 DOWNTO 0);
btn_jstk : OUT STD_LOGIC;
btn_trigger : OUT STD_LOGIC;
-- Joystick and button values read from the module
jstk_x : OUT STD_LOGIC_VECTOR(9 DOWNTO 0);
jstk_y : OUT STD_LOGIC_VECTOR(9 DOWNTO 0);
btn_jstk : OUT STD_LOGIC;
btn_trigger : OUT STD_LOGIC;
-- LED color to send to the module
led_r : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
led_g : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
led_b : IN STD_LOGIC_VECTOR(7 DOWNTO 0)
);
-- LED color to send to the module
led_r : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
led_g : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
led_b : IN STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END digilent_jstk2;
ARCHITECTURE Behavioral OF digilent_jstk2 IS
-- Code for the SetLEDRGB command, see the JSTK2 datasheet.
CONSTANT CMDSETLEDRGB : STD_LOGIC_VECTOR(7 DOWNTO 0) := x"84";
-- Code for the SetLEDRGB command, see the JSTK2 datasheet.
CONSTANT CMDSETLEDRGB : STD_LOGIC_VECTOR(7 DOWNTO 0) := x"84";
-- Do not forget that you MUST wait a bit between two packets. See the JSTK2 datasheet (and the SPI IP-Core README).
------------------------------------------------------------
-- Do not forget that you MUST wait a bit between two packets. See the JSTK2 datasheet (and the SPI IP-Core README).
------------------------------------------------------------
CONSTANT DELAY_CLK_CYCLES : INTEGER := DELAY_US * (CLKFREQ / 1_000_000);
CONSTANT DELAY_CLK_CYCLES : INTEGER := DELAY_US * (CLKFREQ / 1_000_000);
-- State machine states
TYPE tx_state_type IS (DELAY, SEND_CMD, SEND_RED, SEND_GREEN, SEND_BLUE, SEND_DUMMY, WAIT_READY);
TYPE rx_state_type IS (JSTK_X_LOW, JSTK_X_HIGH, JSTK_Y_LOW, JSTK_Y_HIGH, BUTTONS);
-- State machine states
TYPE tx_state_type IS (DELAY, SEND_CMD, SEND_RED, SEND_GREEN, SEND_BLUE, SEND_DUMMY);
TYPE rx_state_type IS (JSTK_X_LOW, JSTK_X_HIGH, JSTK_Y_LOW, JSTK_Y_HIGH, BUTTONS);
SIGNAL tx_state : tx_state_type := DELAY;
SIGNAL rx_state : rx_state_type := JSTK_X_LOW;
SIGNAL tx_state : tx_state_type := DELAY;
SIGNAL rx_state : rx_state_type := JSTK_X_LOW;
SIGNAL tx_delay_counter : INTEGER := 0;
SIGNAL tx_delay_counter : INTEGER := 0;
SIGNAL rx_cache : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL rx_cache : STD_LOGIC_VECTOR(7 DOWNTO 0);
BEGIN
-- The SPI IP-Core is a slave, so we must set the m_axis_tvalid signal to '1' when we want to send data to it.
WITH tx_state SELECT m_axis_tvalid <=
'0' WHEN DELAY,
'1' WHEN OTHERS;
-- The SPI IP-Core is a slave, so we must set the m_axis_tvalid signal to '1' when we want to send data to it.
WITH tx_state SELECT m_axis_tvalid <=
'0' WHEN DELAY,
'1' WHEN SEND_CMD,
'1' WHEN SEND_RED,
'1' WHEN SEND_GREEN,
'1' WHEN SEND_BLUE,
'1' WHEN SEND_DUMMY;
-- TX FSM: invia un nuovo comando solo dopo che la risposta precedente <20> stata ricevuta (rx_done = '1')
TX : PROCESS (aclk)
BEGIN
IF rising_edge(aclk) THEN
IF aresetn = '0' THEN
tx_state <= DELAY;
m_axis_tdata <= (OTHERS => '0');
tx_delay_counter <= 0;
-- Send the data to the SPI IP-Core based on the current state of the TX FSM
WITH tx_state SELECT m_axis_tdata <=
(OTHERS => '0') WHEN DELAY,
CMDSETLEDRGB WHEN SEND_CMD,
led_r WHEN SEND_RED,
led_g WHEN SEND_GREEN,
led_b WHEN SEND_BLUE,
"01101000" WHEN SEND_DUMMY; -- Dummy byte
ELSE
-- TX FSM: invia un nuovo comando solo dopo che la risposta precedente <20> stata ricevuta (rx_done = '1')
TX : PROCESS (aclk)
BEGIN
IF rising_edge(aclk) THEN
IF aresetn = '0' THEN
CASE tx_state IS
tx_state <= DELAY;
m_axis_tdata <= (OTHERS => '0');
tx_delay_counter <= 0;
WHEN DELAY =>
IF tx_delay_counter >= DELAY_CLK_CYCLES THEN
tx_delay_counter <= 0;
tx_state <= SEND_CMD;
ELSE
tx_delay_counter <= tx_delay_counter + 1;
END IF;
ELSE
WHEN SEND_CMD =>
tx_state <= SEND_RED;
m_axis_tdata <= CMDSETLEDRGB;
CASE tx_state IS
WHEN SEND_RED =>
IF m_axis_tready = '1' THEN
m_axis_tdata <= led_r;
tx_state <= SEND_GREEN;
END IF;
WHEN DELAY =>
IF tx_delay_counter >= DELAY_CLK_CYCLES THEN
tx_delay_counter <= 0;
tx_state <= SEND_CMD;
ELSE
tx_delay_counter <= tx_delay_counter + 1;
END IF;
WHEN SEND_GREEN =>
IF m_axis_tready = '1' THEN
m_axis_tdata <= led_g;
tx_state <= SEND_BLUE;
END IF;
WHEN SEND_CMD =>
IF m_axis_tready = '1' THEN
tx_state <= SEND_RED;
END IF;
WHEN SEND_BLUE =>
IF m_axis_tready = '1' THEN
m_axis_tdata <= led_b;
tx_state <= SEND_DUMMY;
END IF;
WHEN SEND_RED =>
IF m_axis_tready = '1' THEN
tx_state <= SEND_GREEN;
END IF;
WHEN SEND_DUMMY =>
IF m_axis_tready = '1' THEN
m_axis_tdata <= "01101000"; -- Dummy byte
tx_state <= WAIT_READY;
END IF;
WHEN SEND_GREEN =>
IF m_axis_tready = '1' THEN
tx_state <= SEND_BLUE;
END IF;
WHEN WAIT_READY =>
IF m_axis_tready = '1' THEN
m_axis_tdata <= "01000101"; -- Dummy byte not readed
tx_state <= DELAY;
END IF;
WHEN SEND_BLUE =>
IF m_axis_tready = '1' THEN
tx_state <= SEND_DUMMY;
END IF;
END CASE;
END IF;
END IF;
END PROCESS TX;
WHEN SEND_DUMMY =>
IF m_axis_tready = '1' THEN
tx_state <= DELAY;
END IF;
-- RX FSM: riceve 5 byte, aggiorna le uscite e segnala a TX FSM quando la risposta <20> completa
RX : PROCESS (aclk)
BEGIN
IF rising_edge(aclk) THEN
END CASE;
END IF;
END IF;
END PROCESS TX;
IF aresetn = '0' THEN
-- RX FSM: riceve 5 byte, aggiorna le uscite e segnala a TX FSM quando la risposta <20> completa
RX : PROCESS (aclk)
BEGIN
IF rising_edge(aclk) THEN
rx_state <= JSTK_X_LOW;
rx_cache <= (OTHERS => '0');
IF aresetn = '0' THEN
ELSE
rx_state <= JSTK_X_LOW;
rx_cache <= (OTHERS => '0');
CASE rx_state IS
ELSE
WHEN JSTK_X_LOW =>
IF s_axis_tvalid = '1' THEN
rx_cache <= s_axis_tdata;
rx_state <= JSTK_X_HIGH;
END IF;
CASE rx_state IS
WHEN JSTK_X_HIGH =>
IF s_axis_tvalid = '1' THEN
jstk_x <= s_axis_tdata(1 DOWNTO 0) & rx_cache;
rx_state <= JSTK_Y_LOW;
END IF;
WHEN JSTK_X_LOW =>
IF s_axis_tvalid = '1' THEN
rx_cache <= s_axis_tdata;
rx_state <= JSTK_X_HIGH;
END IF;
WHEN JSTK_Y_LOW =>
IF s_axis_tvalid = '1' THEN
rx_cache <= s_axis_tdata;
rx_state <= JSTK_Y_HIGH;
END IF;
WHEN JSTK_X_HIGH =>
IF s_axis_tvalid = '1' THEN
jstk_x <= s_axis_tdata(1 DOWNTO 0) & rx_cache;
rx_state <= JSTK_Y_LOW;
END IF;
WHEN JSTK_Y_HIGH =>
IF s_axis_tvalid = '1' THEN
jstk_y <= s_axis_tdata(1 DOWNTO 0) & rx_cache;
rx_state <= BUTTONS;
END IF;
WHEN JSTK_Y_LOW =>
IF s_axis_tvalid = '1' THEN
rx_cache <= s_axis_tdata;
rx_state <= JSTK_Y_HIGH;
END IF;
WHEN BUTTONS =>
IF s_axis_tvalid = '1' THEN
btn_jstk <= s_axis_tdata(0);
btn_trigger <= s_axis_tdata(1);
rx_state <= JSTK_X_LOW;
END IF;
WHEN JSTK_Y_HIGH =>
IF s_axis_tvalid = '1' THEN
jstk_y <= s_axis_tdata(1 DOWNTO 0) & rx_cache;
rx_state <= BUTTONS;
END IF;
END CASE;
END IF;
END IF;
END PROCESS RX;
WHEN BUTTONS =>
IF s_axis_tvalid = '1' THEN
btn_jstk <= s_axis_tdata(0);
btn_trigger <= s_axis_tdata(1);
rx_state <= JSTK_X_LOW;
END IF;
END CASE;
END IF;
END IF;
END PROCESS RX;
END ARCHITECTURE;