diff --git a/LAB3/design/diligent_jstk/diligent_jstk.bd b/LAB3/design/diligent_jstk/diligent_jstk.bd
index ced2b7f..45a1dc3 100644
--- a/LAB3/design/diligent_jstk/diligent_jstk.bd
+++ b/LAB3/design/diligent_jstk/diligent_jstk.bd
@@ -13,9 +13,9 @@
"proc_sys_reset_0": "",
"clk_wiz_0": "",
"AXI4Stream_UART_0": "",
- "digilent_jstk2_0": "",
"jstk_uart_bridge_0": "",
- "axi4stream_spi_master_0": ""
+ "axi4stream_spi_master_0": "",
+ "digilent_jstk2_0": ""
},
"interface_ports": {
"usb_uart": {
@@ -101,6 +101,9 @@
"xci_path": "ip\\diligent_jstk_AXI4Stream_UART_0_0\\diligent_jstk_AXI4Stream_UART_0_0.xci",
"inst_hier_path": "AXI4Stream_UART_0",
"parameters": {
+ "UART_BAUD_RATE": {
+ "value": "115200"
+ },
"UART_BOARD_INTERFACE": {
"value": "usb_uart"
},
@@ -109,216 +112,6 @@
}
}
},
- "digilent_jstk2_0": {
- "vlnv": "xilinx.com:module_ref:digilent_jstk2:1.0",
- "xci_name": "diligent_jstk_digilent_jstk2_0_0",
- "xci_path": "ip\\diligent_jstk_digilent_jstk2_0_0\\diligent_jstk_digilent_jstk2_0_0.xci",
- "inst_hier_path": "digilent_jstk2_0",
- "reference_info": {
- "ref_type": "hdl",
- "ref_name": "digilent_jstk2",
- "boundary_crc": "0x0"
- },
- "interface_ports": {
- "m_axis": {
- "mode": "Master",
- "vlnv": "xilinx.com:interface:axis_rtl:1.0",
- "parameters": {
- "TDATA_NUM_BYTES": {
- "value": "1",
- "value_src": "constant"
- },
- "TDEST_WIDTH": {
- "value": "0",
- "value_src": "constant"
- },
- "TID_WIDTH": {
- "value": "0",
- "value_src": "constant"
- },
- "TUSER_WIDTH": {
- "value": "0",
- "value_src": "constant"
- },
- "HAS_TREADY": {
- "value": "1",
- "value_src": "constant"
- },
- "HAS_TSTRB": {
- "value": "0",
- "value_src": "constant"
- },
- "HAS_TKEEP": {
- "value": "0",
- "value_src": "constant"
- },
- "HAS_TLAST": {
- "value": "0",
- "value_src": "constant"
- },
- "FREQ_HZ": {
- "value": "100000000",
- "value_src": "ip_prop"
- },
- "PHASE": {
- "value": "0.0",
- "value_src": "ip_prop"
- },
- "CLK_DOMAIN": {
- "value": "/clk_wiz_0_clk_out1",
- "value_src": "ip_prop"
- }
- },
- "port_maps": {
- "TDATA": {
- "physical_name": "m_axis_tdata",
- "direction": "O",
- "left": "7",
- "right": "0"
- },
- "TVALID": {
- "physical_name": "m_axis_tvalid",
- "direction": "O"
- },
- "TREADY": {
- "physical_name": "m_axis_tready",
- "direction": "I"
- }
- }
- },
- "s_axis": {
- "mode": "Slave",
- "vlnv": "xilinx.com:interface:axis_rtl:1.0",
- "parameters": {
- "TDATA_NUM_BYTES": {
- "value": "1",
- "value_src": "constant"
- },
- "TDEST_WIDTH": {
- "value": "0",
- "value_src": "constant"
- },
- "TID_WIDTH": {
- "value": "0",
- "value_src": "constant"
- },
- "TUSER_WIDTH": {
- "value": "0",
- "value_src": "constant"
- },
- "HAS_TREADY": {
- "value": "0",
- "value_src": "constant"
- },
- "HAS_TSTRB": {
- "value": "0",
- "value_src": "constant"
- },
- "HAS_TKEEP": {
- "value": "0",
- "value_src": "constant"
- },
- "HAS_TLAST": {
- "value": "0",
- "value_src": "constant"
- },
- "FREQ_HZ": {
- "value": "100000000",
- "value_src": "ip_prop"
- },
- "PHASE": {
- "value": "0.0",
- "value_src": "ip_prop"
- },
- "CLK_DOMAIN": {
- "value": "/clk_wiz_0_clk_out1",
- "value_src": "ip_prop"
- }
- },
- "port_maps": {
- "TDATA": {
- "physical_name": "s_axis_tdata",
- "direction": "I",
- "left": "7",
- "right": "0"
- },
- "TVALID": {
- "physical_name": "s_axis_tvalid",
- "direction": "I"
- }
- }
- }
- },
- "ports": {
- "aclk": {
- "type": "clk",
- "direction": "I",
- "parameters": {
- "ASSOCIATED_BUSIF": {
- "value": "m_axis:s_axis",
- "value_src": "constant"
- },
- "ASSOCIATED_RESET": {
- "value": "aresetn",
- "value_src": "constant"
- },
- "FREQ_HZ": {
- "value": "100000000",
- "value_src": "ip_prop"
- },
- "PHASE": {
- "value": "0.0",
- "value_src": "ip_prop"
- },
- "CLK_DOMAIN": {
- "value": "/clk_wiz_0_clk_out1",
- "value_src": "ip_prop"
- }
- }
- },
- "aresetn": {
- "type": "rst",
- "direction": "I",
- "parameters": {
- "POLARITY": {
- "value": "ACTIVE_LOW",
- "value_src": "constant"
- }
- }
- },
- "jstk_x": {
- "direction": "O",
- "left": "9",
- "right": "0"
- },
- "jstk_y": {
- "direction": "O",
- "left": "9",
- "right": "0"
- },
- "btn_jstk": {
- "direction": "O"
- },
- "btn_trigger": {
- "direction": "O"
- },
- "led_r": {
- "direction": "I",
- "left": "7",
- "right": "0"
- },
- "led_g": {
- "direction": "I",
- "left": "7",
- "right": "0"
- },
- "led_b": {
- "direction": "I",
- "left": "7",
- "right": "0"
- }
- }
- },
"jstk_uart_bridge_0": {
"vlnv": "xilinx.com:module_ref:jstk_uart_bridge:1.0",
"xci_name": "diligent_jstk_jstk_uart_bridge_0_0",
@@ -537,22 +330,242 @@
"vlnv": "DigiLAB:ip:axi4stream_spi_master:1.0",
"xci_name": "diligent_jstk_axi4stream_spi_master_0_0",
"xci_path": "ip\\diligent_jstk_axi4stream_spi_master_0_0\\diligent_jstk_axi4stream_spi_master_0_0.xci",
- "inst_hier_path": "axi4stream_spi_master_0"
+ "inst_hier_path": "axi4stream_spi_master_0",
+ "parameters": {
+ "c_sclkfreq": {
+ "value": "5000"
+ }
+ }
+ },
+ "digilent_jstk2_0": {
+ "vlnv": "xilinx.com:module_ref:digilent_jstk2:1.0",
+ "xci_name": "diligent_jstk_digilent_jstk2_0_0",
+ "xci_path": "ip\\diligent_jstk_digilent_jstk2_0_0\\diligent_jstk_digilent_jstk2_0_0.xci",
+ "inst_hier_path": "digilent_jstk2_0",
+ "parameters": {
+ "SPI_SCLKFREQ": {
+ "value": "5000"
+ }
+ },
+ "reference_info": {
+ "ref_type": "hdl",
+ "ref_name": "digilent_jstk2",
+ "boundary_crc": "0x0"
+ },
+ "interface_ports": {
+ "m_axis": {
+ "mode": "Master",
+ "vlnv": "xilinx.com:interface:axis_rtl:1.0",
+ "parameters": {
+ "TDATA_NUM_BYTES": {
+ "value": "1",
+ "value_src": "constant"
+ },
+ "TDEST_WIDTH": {
+ "value": "0",
+ "value_src": "constant"
+ },
+ "TID_WIDTH": {
+ "value": "0",
+ "value_src": "constant"
+ },
+ "TUSER_WIDTH": {
+ "value": "0",
+ "value_src": "constant"
+ },
+ "HAS_TREADY": {
+ "value": "1",
+ "value_src": "constant"
+ },
+ "HAS_TSTRB": {
+ "value": "0",
+ "value_src": "constant"
+ },
+ "HAS_TKEEP": {
+ "value": "0",
+ "value_src": "constant"
+ },
+ "HAS_TLAST": {
+ "value": "0",
+ "value_src": "constant"
+ },
+ "FREQ_HZ": {
+ "value": "100000000",
+ "value_src": "ip_prop"
+ },
+ "PHASE": {
+ "value": "0.0",
+ "value_src": "ip_prop"
+ },
+ "CLK_DOMAIN": {
+ "value": "/clk_wiz_0_clk_out1",
+ "value_src": "ip_prop"
+ }
+ },
+ "port_maps": {
+ "TDATA": {
+ "physical_name": "m_axis_tdata",
+ "direction": "O",
+ "left": "7",
+ "right": "0"
+ },
+ "TVALID": {
+ "physical_name": "m_axis_tvalid",
+ "direction": "O"
+ },
+ "TREADY": {
+ "physical_name": "m_axis_tready",
+ "direction": "I"
+ }
+ }
+ },
+ "s_axis": {
+ "mode": "Slave",
+ "vlnv": "xilinx.com:interface:axis_rtl:1.0",
+ "parameters": {
+ "TDATA_NUM_BYTES": {
+ "value": "1",
+ "value_src": "constant"
+ },
+ "TDEST_WIDTH": {
+ "value": "0",
+ "value_src": "constant"
+ },
+ "TID_WIDTH": {
+ "value": "0",
+ "value_src": "constant"
+ },
+ "TUSER_WIDTH": {
+ "value": "0",
+ "value_src": "constant"
+ },
+ "HAS_TREADY": {
+ "value": "0",
+ "value_src": "constant"
+ },
+ "HAS_TSTRB": {
+ "value": "0",
+ "value_src": "constant"
+ },
+ "HAS_TKEEP": {
+ "value": "0",
+ "value_src": "constant"
+ },
+ "HAS_TLAST": {
+ "value": "0",
+ "value_src": "constant"
+ },
+ "FREQ_HZ": {
+ "value": "100000000",
+ "value_src": "ip_prop"
+ },
+ "PHASE": {
+ "value": "0.0",
+ "value_src": "ip_prop"
+ },
+ "CLK_DOMAIN": {
+ "value": "/clk_wiz_0_clk_out1",
+ "value_src": "ip_prop"
+ }
+ },
+ "port_maps": {
+ "TDATA": {
+ "physical_name": "s_axis_tdata",
+ "direction": "I",
+ "left": "7",
+ "right": "0"
+ },
+ "TVALID": {
+ "physical_name": "s_axis_tvalid",
+ "direction": "I"
+ }
+ }
+ }
+ },
+ "ports": {
+ "aclk": {
+ "type": "clk",
+ "direction": "I",
+ "parameters": {
+ "ASSOCIATED_BUSIF": {
+ "value": "m_axis:s_axis",
+ "value_src": "constant"
+ },
+ "ASSOCIATED_RESET": {
+ "value": "aresetn",
+ "value_src": "constant"
+ },
+ "FREQ_HZ": {
+ "value": "100000000",
+ "value_src": "ip_prop"
+ },
+ "PHASE": {
+ "value": "0.0",
+ "value_src": "ip_prop"
+ },
+ "CLK_DOMAIN": {
+ "value": "/clk_wiz_0_clk_out1",
+ "value_src": "ip_prop"
+ }
+ }
+ },
+ "aresetn": {
+ "type": "rst",
+ "direction": "I",
+ "parameters": {
+ "POLARITY": {
+ "value": "ACTIVE_LOW",
+ "value_src": "constant"
+ }
+ }
+ },
+ "jstk_x": {
+ "direction": "O",
+ "left": "9",
+ "right": "0"
+ },
+ "jstk_y": {
+ "direction": "O",
+ "left": "9",
+ "right": "0"
+ },
+ "btn_jstk": {
+ "direction": "O"
+ },
+ "btn_trigger": {
+ "direction": "O"
+ },
+ "led_r": {
+ "direction": "I",
+ "left": "7",
+ "right": "0"
+ },
+ "led_g": {
+ "direction": "I",
+ "left": "7",
+ "right": "0"
+ },
+ "led_b": {
+ "direction": "I",
+ "left": "7",
+ "right": "0"
+ }
+ }
}
},
"interface_nets": {
- "jstk_uart_bridge_0_m_axis": {
- "interface_ports": [
- "AXI4Stream_UART_0/S00_AXIS_TX",
- "jstk_uart_bridge_0/m_axis"
- ]
- },
"axi4stream_spi_master_0_M_AXIS": {
"interface_ports": [
"axi4stream_spi_master_0/M_AXIS",
"digilent_jstk2_0/s_axis"
]
},
+ "jstk_uart_bridge_0_m_axis": {
+ "interface_ports": [
+ "AXI4Stream_UART_0/S00_AXIS_TX",
+ "jstk_uart_bridge_0/m_axis"
+ ]
+ },
"digilent_jstk2_0_m_axis": {
"interface_ports": [
"digilent_jstk2_0/m_axis",
@@ -565,17 +578,17 @@
"AXI4Stream_UART_0/UART"
]
},
- "AXI4Stream_UART_0_M00_AXIS_RX": {
- "interface_ports": [
- "AXI4Stream_UART_0/M00_AXIS_RX",
- "jstk_uart_bridge_0/s_axis"
- ]
- },
"axi4stream_spi_master_0_SPI_M": {
"interface_ports": [
"SPI_M_0",
"axi4stream_spi_master_0/SPI_M"
]
+ },
+ "AXI4Stream_UART_0_M00_AXIS_RX": {
+ "interface_ports": [
+ "AXI4Stream_UART_0/M00_AXIS_RX",
+ "jstk_uart_bridge_0/s_axis"
+ ]
}
},
"nets": {
@@ -603,11 +616,11 @@
"clk_wiz_0/clk_out1",
"proc_sys_reset_0/slowest_sync_clk",
"axi4stream_spi_master_0/aclk",
- "digilent_jstk2_0/aclk",
"AXI4Stream_UART_0/clk_uart",
"AXI4Stream_UART_0/m00_axis_rx_aclk",
"jstk_uart_bridge_0/aclk",
- "AXI4Stream_UART_0/s00_axis_tx_aclk"
+ "AXI4Stream_UART_0/s00_axis_tx_aclk",
+ "digilent_jstk2_0/aclk"
]
},
"digilent_jstk2_0_btn_trigger": {
@@ -655,11 +668,11 @@
"proc_sys_reset_0_peripheral_aresetn": {
"ports": [
"proc_sys_reset_0/peripheral_aresetn",
- "digilent_jstk2_0/aresetn",
"AXI4Stream_UART_0/m00_axis_rx_aresetn",
"jstk_uart_bridge_0/aresetn",
"AXI4Stream_UART_0/s00_axis_tx_aresetn",
- "axi4stream_spi_master_0/aresetn"
+ "axi4stream_spi_master_0/aresetn",
+ "digilent_jstk2_0/aresetn"
]
},
"proc_sys_reset_0_peripheral_reset": {
diff --git a/LAB3/design/diligent_jstk/hdl/diligent_jstk_wrapper.vhd b/LAB3/design/diligent_jstk/hdl/diligent_jstk_wrapper.vhd
index 9c30c60..7fff9d5 100644
--- a/LAB3/design/diligent_jstk/hdl/diligent_jstk_wrapper.vhd
+++ b/LAB3/design/diligent_jstk/hdl/diligent_jstk_wrapper.vhd
@@ -1,7 +1,7 @@
--Copyright 1986-2020 Xilinx, Inc. All Rights Reserved.
----------------------------------------------------------------------------------
--Tool Version: Vivado v.2020.2 (win64) Build 3064766 Wed Nov 18 09:12:45 MST 2020
---Date : Mon May 12 15:44:44 2025
+--Date : Wed May 14 13:59:17 2025
--Host : Davide-Samsung running 64-bit major release (build 9200)
--Command : generate_target diligent_jstk_wrapper.bd
--Design : diligent_jstk_wrapper
@@ -29,8 +29,6 @@ architecture STRUCTURE of diligent_jstk_wrapper is
port (
reset : in STD_LOGIC;
sys_clock : in STD_LOGIC;
- usb_uart_txd : out STD_LOGIC;
- usb_uart_rxd : in STD_LOGIC;
SPI_M_0_sck_t : out STD_LOGIC;
SPI_M_0_io1_o : out STD_LOGIC;
SPI_M_0_ss_t : out STD_LOGIC;
@@ -42,7 +40,9 @@ architecture STRUCTURE of diligent_jstk_wrapper is
SPI_M_0_sck_o : out STD_LOGIC;
SPI_M_0_ss_i : in STD_LOGIC;
SPI_M_0_io1_i : in STD_LOGIC;
- SPI_M_0_io0_i : in STD_LOGIC
+ SPI_M_0_io0_i : in STD_LOGIC;
+ usb_uart_txd : out STD_LOGIC;
+ usb_uart_rxd : in STD_LOGIC
);
end component diligent_jstk;
component IOBUF is
diff --git a/LAB3/sim/ReadMe.md b/LAB3/sim/ReadMe.md
deleted file mode 100644
index 0f8aee3..0000000
--- a/LAB3/sim/ReadMe.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Placeholder
-
-This is a placeholder.
\ No newline at end of file
diff --git a/LAB3/sim/tb_digilent_jstk2.vhd b/LAB3/sim/tb_digilent_jstk2.vhd
new file mode 100644
index 0000000..f5ae1fa
--- /dev/null
+++ b/LAB3/sim/tb_digilent_jstk2.vhd
@@ -0,0 +1,154 @@
+----------------------------------------------------------------------------------
+-- Company:
+-- Engineer:
+--
+-- Create Date: 05/13/2025
+-- Design Name:
+-- Module Name: tb_digilent_jstk2 - sim
+-- Project Name:
+-- Target Devices:
+-- Tool Versions:
+-- Description: Testbench for digilent_jstk2, sends data only after CMDSETLEDRGB is received
+--
+-- Dependencies:
+--
+-- Revision:
+-- Revision 0.01 - File Created
+-- Additional Comments:
+--
+----------------------------------------------------------------------------------
+
+LIBRARY ieee;
+USE ieee.std_logic_1164.ALL;
+USE ieee.numeric_std.ALL;
+
+ENTITY tb_digilent_jstk2 IS
+END tb_digilent_jstk2;
+
+ARCHITECTURE sim OF tb_digilent_jstk2 IS
+
+ -- Testbench constants
+ CONSTANT CLKFREQ : INTEGER := 100_000_000;
+ CONSTANT DELAY_US : INTEGER := 25;
+ CONSTANT SPI_SCLKFREQ : INTEGER := 66_666;
+ CONSTANT CMDSETLEDRGB : STD_LOGIC_VECTOR(7 DOWNTO 0) := x"84";
+
+ -- Component declaration for digilent_jstk2
+ COMPONENT digilent_jstk2 IS
+ GENERIC (
+ DELAY_US : INTEGER;
+ CLKFREQ : INTEGER;
+ SPI_SCLKFREQ : INTEGER
+ );
+ PORT (
+ aclk : IN STD_LOGIC;
+ aresetn : IN STD_LOGIC;
+ m_axis_tvalid : OUT STD_LOGIC;
+ m_axis_tdata : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
+ m_axis_tready : IN STD_LOGIC;
+ s_axis_tvalid : IN STD_LOGIC;
+ s_axis_tdata : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
+ 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_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 COMPONENT;
+
+ -- Signals for DUT
+ SIGNAL aclk : STD_LOGIC := '0';
+ SIGNAL aresetn : STD_LOGIC := '0';
+ SIGNAL m_axis_tvalid : STD_LOGIC;
+ SIGNAL m_axis_tdata : STD_LOGIC_VECTOR(7 DOWNTO 0);
+ SIGNAL m_axis_tready : STD_LOGIC := '1'; -- Always ready in TB
+ SIGNAL s_axis_tvalid : STD_LOGIC := '0';
+ SIGNAL s_axis_tdata : STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => '0');
+ SIGNAL jstk_x : STD_LOGIC_VECTOR(9 DOWNTO 0);
+ SIGNAL jstk_y : STD_LOGIC_VECTOR(9 DOWNTO 0);
+ SIGNAL btn_jstk : STD_LOGIC;
+ SIGNAL btn_trigger : STD_LOGIC;
+ SIGNAL led_r : STD_LOGIC_VECTOR(7 DOWNTO 0) := x"AA";
+ SIGNAL led_g : STD_LOGIC_VECTOR(7 DOWNTO 0) := x"55";
+ SIGNAL led_b : STD_LOGIC_VECTOR(7 DOWNTO 0) := x"FF";
+
+ -- Stimulus memory for SPI responses (simulate JSTK2 module)
+ TYPE spi_mem_type IS ARRAY(0 TO 4) OF STD_LOGIC_VECTOR(7 DOWNTO 0);
+ SIGNAL spi_mem : spi_mem_type := (
+ 0 => x"34", -- JSTK_X_LOW
+ 1 => x"02", -- JSTK_X_HIGH (2 LSBs used)
+ 2 => x"56", -- JSTK_Y_LOW
+ 3 => x"01", -- JSTK_Y_HIGH (2 LSBs used)
+ 4 => "00000011" -- BUTTONS: btn_jstk='1', btn_trigger='1'
+ );
+
+BEGIN
+
+ -- Clock generation
+ aclk <= NOT aclk AFTER 5 ns;
+
+ -- DUT instantiation
+ uut : digilent_jstk2
+ GENERIC MAP(
+ DELAY_US => DELAY_US,
+ CLKFREQ => CLKFREQ,
+ SPI_SCLKFREQ => SPI_SCLKFREQ
+ )
+ PORT MAP(
+ aclk => aclk,
+ aresetn => aresetn,
+ m_axis_tvalid => m_axis_tvalid,
+ m_axis_tdata => m_axis_tdata,
+ m_axis_tready => m_axis_tready,
+ s_axis_tvalid => s_axis_tvalid,
+ s_axis_tdata => s_axis_tdata,
+ jstk_x => jstk_x,
+ jstk_y => jstk_y,
+ btn_jstk => btn_jstk,
+ btn_trigger => btn_trigger,
+ led_r => led_r,
+ led_g => led_g,
+ led_b => led_b
+ );
+
+ -- Stimulus process
+ stimulus : PROCESS
+ VARIABLE send_data : BOOLEAN := FALSE;
+ VARIABLE mem_idx : INTEGER := 0;
+ BEGIN
+ -- Reset
+ aresetn <= '0';
+ WAIT FOR 20 ns;
+ aresetn <= '1';
+ WAIT UNTIL rising_edge(aclk);
+
+ -- Wait for the DUT to start sending SPI packets
+ WAIT FOR 1000 ns;
+
+ -- Main loop: wait for CMDSETLEDRGB, then send mem bytes for each byte received
+ WHILE TRUE LOOP
+ WAIT UNTIL rising_edge(aclk);
+ IF m_axis_tvalid = '1' THEN
+ IF m_axis_tdata = CMDSETLEDRGB THEN
+ send_data := TRUE;
+ mem_idx := 0;
+ END IF;
+
+ IF send_data THEN
+ IF mem_idx <= 4 THEN
+ s_axis_tdata <= spi_mem(mem_idx);
+ s_axis_tvalid <= '1';
+ mem_idx := mem_idx + 1;
+ ELSE
+ send_data := FALSE;
+ END IF;
+ END IF;
+ ELSE
+ s_axis_tvalid <= '0';
+ END IF;
+ END LOOP;
+ END PROCESS;
+
+END sim;
\ No newline at end of file
diff --git a/LAB3/src/digilent_jstk2.vhd b/LAB3/src/digilent_jstk2.vhd
index 9194ef3..356632e 100644
--- a/LAB3/src/digilent_jstk2.vhd
+++ b/LAB3/src/digilent_jstk2.vhd
@@ -1,49 +1,193 @@
-library IEEE;
-use IEEE.STD_LOGIC_1164.ALL;
+LIBRARY IEEE;
+USE IEEE.STD_LOGIC_1164.ALL;
-entity digilent_jstk2 is
- generic (
- DELAY_US : integer := 25; -- Delay (in us) between two packets
- CLKFREQ : integer := 100_000_000; -- Frequency of the aclk signal (in Hz)
- SPI_SCLKFREQ : integer := 66_666 -- Frequency of the SPI SCLK clock signal (in Hz)
+ENTITY digilent_jstk2 IS
+ GENERIC (
+ DELAY_US : INTEGER := 25; -- Delay (in us) between two packets
+ CLKFREQ : INTEGER := 100_000_000; -- Frequency of the aclk signal (in Hz)
+ SPI_SCLKFREQ : INTEGER := 66_666 -- Frequency of the SPI SCLK clock signal (in Hz)
);
- Port (
- aclk : in STD_LOGIC;
- aresetn : in STD_LOGIC;
+ 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;
+ 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);
+ 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;
+ 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_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;
+END digilent_jstk2;
-architecture Behavioral of digilent_jstk2 is
+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";
+ 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).
------------------------------------------------------------
-begin
+ CONSTANT DELAY_CLK_CYCLES : INTEGER := DELAY_US * (CLKFREQ / 1_000_000) - 1;
- -- ...
+ -- 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);
-end architecture;
+ SIGNAL tx_state : tx_state_type;
+ SIGNAL rx_state : rx_state_type;
+
+ SIGNAL rx_cache : STD_LOGIC_VECTOR(7 DOWNTO 0);
+ SIGNAL tx_delay_counter : INTEGER := 0;
+
+ SIGNAL m_axis_tvalid_int : STD_LOGIC := '0';
+
+BEGIN
+
+ m_axis_tvalid <= m_axis_tvalid_int;
+
+ -- Send the data to the SPI IP-Core
+ TX : PROCESS (aclk)
+ BEGIN
+ IF rising_edge(aclk) THEN
+ IF aresetn = '0' THEN
+ -- Reset the state machine
+ tx_state <= DELAY;
+
+ m_axis_tvalid_int <= '0';
+ m_axis_tdata <= (OTHERS => '0');
+
+ tx_delay_counter <= 0;
+
+ ELSE
+ -- Clear valid flag when master interface is ready
+ IF m_axis_tready = '1' THEN
+ m_axis_tvalid_int <= '0';
+ END IF;
+
+ -- State machine for sending data to the SPI IP-Core
+ CASE tx_state IS
+
+ WHEN DELAY =>
+ m_axis_tvalid_int <= '0';
+ m_axis_tdata <= (OTHERS => '0');
+
+ 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_CMD =>
+ IF (m_axis_tvalid_int = '0' OR m_axis_tready = '1') THEN
+ m_axis_tdata <= CMDSETLEDRGB;
+ m_axis_tvalid_int <= '1';
+ tx_state <= SEND_RED;
+ END IF;
+
+ WHEN SEND_RED =>
+ IF (m_axis_tvalid_int = '0' OR m_axis_tready = '1') THEN
+ m_axis_tdata <= led_r;
+ m_axis_tvalid_int <= '1';
+ tx_state <= SEND_GREEN;
+ END IF;
+
+ WHEN SEND_GREEN =>
+ IF (m_axis_tvalid_int = '0' OR m_axis_tready = '1') THEN
+ m_axis_tdata <= led_g;
+ m_axis_tvalid_int <= '1';
+ tx_state <= SEND_BLUE;
+ END IF;
+
+ WHEN SEND_BLUE =>
+ IF (m_axis_tvalid_int = '0' OR m_axis_tready = '1') THEN
+ m_axis_tdata <= led_b;
+ m_axis_tvalid_int <= '1';
+ tx_state <= SEND_DUMMY;
+ END IF;
+
+ WHEN SEND_DUMMY =>
+ IF (m_axis_tvalid_int = '0' OR m_axis_tready = '1') THEN
+ m_axis_tdata <= (OTHERS => '0');
+ m_axis_tvalid_int <= '1';
+ tx_state <= DELAY;
+ END IF;
+
+ END CASE;
+
+ END IF;
+ END IF;
+
+ END PROCESS TX;
+
+ -- Receive the data from the SPI IP-Core
+ RX : PROCESS (aclk)
+ BEGIN
+ IF rising_edge(aclk) THEN
+ IF aresetn = '0' THEN
+ -- Reset the state machine
+ rx_state <= JSTK_X_LOW;
+
+ -- jstk_x <= (others => '0');
+ -- jstk_y <= (others => '0');
+ btn_jstk <= '0';
+ btn_trigger <= '0';
+
+ rx_cache <= (OTHERS => '0');
+ ELSE
+ -- State machine for receiving data from the SPI IP-Core
+ CASE rx_state IS
+
+ WHEN JSTK_X_LOW =>
+ IF s_axis_tvalid = '1' THEN
+ rx_cache(7 DOWNTO 0) <= s_axis_tdata;
+ rx_state <= JSTK_X_HIGH;
+ END IF;
+
+ WHEN JSTK_X_HIGH =>
+ IF s_axis_tvalid = '1' THEN
+ jstk_x(9 DOWNTO 0) <= s_axis_tdata(1 DOWNTO 0) & rx_cache(7 DOWNTO 0);
+ rx_state <= JSTK_Y_LOW;
+ END IF;
+
+ WHEN JSTK_Y_LOW =>
+ IF s_axis_tvalid = '1' THEN
+ rx_cache(7 DOWNTO 0) <= s_axis_tdata;
+ rx_state <= JSTK_Y_HIGH;
+ END IF;
+
+ WHEN JSTK_Y_HIGH =>
+ IF s_axis_tvalid = '1' THEN
+ jstk_y(9 DOWNTO 0) <= s_axis_tdata(1 DOWNTO 0) & rx_cache(7 DOWNTO 0);
+ rx_state <= BUTTONS;
+ 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;
+
+ END CASE;
+ END IF;
+ END IF;
+
+ END PROCESS RX;
+
+END ARCHITECTURE;
\ No newline at end of file
diff --git a/LAB3/test/uart_viewer.py b/LAB3/test/uart_viewer.py
new file mode 100644
index 0000000..07b2d2d
--- /dev/null
+++ b/LAB3/test/uart_viewer.py
@@ -0,0 +1,61 @@
+import serial
+import time
+
+# CONFIGURAZIONE
+PORT = 'COM4' # Cambia con la tua porta: es. 'COM3' su Windows o '/dev/ttyUSB0' su Linux
+BAUDRATE = 115200 # Imposta la tua velocità
+CHUNK_SIZE = 4 # 4 byte per riga
+
+def receive_mode(ser):
+ print("Modalità ricezione. Premi Ctrl+C per uscire.\n")
+ while True:
+ if ser.in_waiting >= CHUNK_SIZE:
+ data = ser.read(CHUNK_SIZE)
+ hex_bytes = ' '.join(f"{b:02X}" for b in data)
+ print(f"HH | {hex_bytes}")
+
+def send_mode(ser):
+ print("Modalità invio. Inserisci 3 byte in esadecimale (il primo sarà sempre 'C0').")
+ print("Formato: XX XX XX (dove XX è tra 00 e FF). Premi Ctrl+C per uscire.\n")
+ while True:
+ try:
+ user_input = input("Inserisci 3 byte (es: 12 34 AB): ").strip()
+ parts = user_input.split()
+ if len(parts) != 3:
+ print("Devi inserire esattamente 3 byte.")
+ continue
+ try:
+ bytes_to_send = [0xC0] # Primo byte fisso
+ for part in parts:
+ val = int(part, 16)
+ if not (0x00 <= val <= 0xFF):
+ raise ValueError
+ bytes_to_send.append(val)
+ ser.write(bytearray(bytes_to_send))
+ print(f"Inviato: {' '.join(f'{b:02X}' for b in bytes_to_send)}")
+ except ValueError:
+ print("Valori non validi. Usa solo byte esadecimali tra 00 e FF.")
+ except KeyboardInterrupt:
+ print("\nChiusura modalità invio...")
+ break
+
+try:
+ mode = ""
+ while mode not in ["r", "s"]:
+ mode = input("Vuoi ricevere (r) o inviare (s) dati? [r/s]: ").strip().lower()
+
+ ser = serial.Serial(PORT, BAUDRATE, timeout=1)
+ print(f"Aperta porta seriale: {PORT} a {BAUDRATE} baud.\n")
+
+ if mode == "r":
+ receive_mode(ser)
+ else:
+ send_mode(ser)
+
+except KeyboardInterrupt:
+ print("\nChiusura programma...")
+except serial.SerialException as e:
+ print(f"Errore nella connessione seriale: {e}")
+finally:
+ if 'ser' in locals() and ser.is_open:
+ ser.close()
diff --git a/LAB3/vivado/diligent_jstk/diligent_jstk.xpr b/LAB3/vivado/diligent_jstk/diligent_jstk.xpr
index 68f7553..b670b84 100644
--- a/LAB3/vivado/diligent_jstk/diligent_jstk.xpr
+++ b/LAB3/vivado/diligent_jstk/diligent_jstk.xpr
@@ -48,20 +48,20 @@
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
@@ -77,13 +77,13 @@
-
+
-
+
@@ -121,6 +121,7 @@
+
@@ -162,22 +163,19 @@
-
+
-
- Vivado Synthesis Defaults
-
+
+
-
+
-
- Default settings for Implementation.
-
+
@@ -188,6 +186,7 @@
+