Files
DEPP/code/DEPP.vhd
Max P 2b2fdd3867 dev (#1)
* Enhanced edge detection in DEPP

Updated the DEPP VHDL component with clearer comment annotations and modified edge detection logic for address and data enable signals. Additionally, refined the main state machine by explicitly adding states for edge waiting periods and defining behaviors for each state, specifically regarding the handling of output FIFO signals and cycle initiation. Updated the edge detection mechanism within the address and data processing workflows, improving cycle handling for idle, address, and data states to better signal the transitions and manage the bus as well as the request and write enable signals.

* Implement FIFO compatible interface and update waveforms

Enhanced DEPP documentation and diagrams to reflect a transition to FIFO compatible interfaces for data traffic efficiency. Updated waveforms depict the revised cycle timings for data/address commands and address acknowledgment, ensuring clarity on the implemented protocol changes.

* Refine DEPP VHDL port naming for clarity

Updated the DEPP VHDL entity's port naming convention to enhance readability and consistency across data and address lines. Introduced clear "Fifo" and "AddressOut" prefixes as per FIFO compatible interfaces, replacing generic data and address signal names. This renaming also strengthens the association between ports and their respective data flow. Additional changes include:
- Replaced 'DataAviable' with a negated 'DataInFifo_EmptyFlag' for immediate data availability check.
- Streamlined write enable signals alignment with the new naming convention.
- Redesigned read-enable logic to minimize latency in 'RequestActive' mode by directly relaying the 'DataInFifo_DataAviable' status.
- Simplified and restructured bus wait management states to reflect the updated port names and signal handling improvements.
- Removed obsolete comments and updated documentation to accurately reflect the current interface functionality and structure.

* Enhanced DEPP module docs and waveform references

- Updated the DEPP module documentation to improve clarity and readability.
- Refactoring included renaming of waveform files for consistency and eliminating unnecessary whitespace.
- Revised virtual bus interface descriptions for better accuracy and cleared up the ambiguity in port names and their corresponding descriptions.
- Streamlined the ports and signals tables to enhance document structure and coherence.
- Modified the state machine SVG file for an up-to-date representation of the module design.
- Integrated additional waveform diagrams to detail the EPP (Enhanced Parallel Port) bus cycles within the documentation.

* Optimized EPP state machine timing

Refactored the EPP (Enhanced Parallel Port) VHDL state machine to streamline the signal handling for different operating states. This optimization includes removing redundant assignments to the `DEPP_Wait` signal in intermediary states and ensuring it is only held high for a minimum of one cycle where necessary. These modifications enhance the clarity of state transitions and may improve the system's timing performance, particularly for the start of read, write, and address cycles.

Additionally, the documentation is updated to include measured data rates, aiding in setting performance expectations.

* Enhanced UCF readability and added LA constraints

Reformatted the pin constraints section in Nexys2Test.ucf to improve readability, adding descriptive comments for RST, DataOutFullFlag, and RequestFullFlag signals. Removed unnecessary net constraints related to DEPP interface signals. Extended the UCF to include configuration for the Logic Analyzer (LA), specifying appropriate locations and providing comments linking net names to their corresponding physical connectors.

* Refactor signal handling and add Logic Analyzer output

Updated the Nexys2Test VHDL entity to streamline signal handling and add support for a Logic Analyzer interface. Removed commented-out attributes for virtual bus and related signals, which simplifies the interface section. Introduced new outputs for the Logic Analyzer to monitor various signals such as address, data enable, write enable, and wait signals, which improves debug and testing capabilities. In the architecture, redundant process handling DEPP_Wait has been removed to reduce complexity, and DEPP_Bus is now directly assigned. Updated the main process to simplify LED assignments and fixed an incorrect value for DataInFifo_EmptyFlag, enhancing signal accuracy and conforming to expected logic levels. These changes contribute to a more maintainable and understandable codebase.

* Update EPP documentation with data rate and refreshed diagrams

- Added the measured data transfer rate to the DEPP documentation.
- Replaced EPP bus waveform diagrams with updated versions.
- Resized and restructured the DEPP FSM SVG for better legibility, including adjustments to cluster dimensions, node positions, edges, and transitions.
- Renamed waveform SVG files for a consistent naming convention.

* Added logic analyzer capture visuals for documentation

* Added MIT License and enhanced README for DEPP module

Implemented an MIT License file and updated the README to provide comprehensive documentation for the VHDL Module designed for the Digilent Asynchronous Parallel Port Interface. The README now includes an overview of the module's purpose, features such as the measured data rate, visual diagrams for bus cycles, a detailed port definition table, module dependencies, contribution guidelines, licensing information, and acknowledgments, improving clarity and usability for end-users and contributors.
Co-authored-by: Max P <Mail@MPassarello.de>
Co-committed-by: Max P <Mail@MPassarello.de>
2024-03-08 23:52:17 +01:00

357 lines
15 KiB
VHDL

----------------------------------------------------------------------------------
-- @name Digilent EPP Interface
-- @version 0.3.1
-- @author Maximilian Passarello (mpassarello.de)
--@ An EPP interface for Digilent FPGA boards
--@ This interface is designed to be used with the Digilent EPP interface
--@ and the Digilent Adept software.
--@
--@ **Measured data rate ≈ 4.68 kByte/s**
--@
--@ Below are diagrams of the EPP bus:
-- @history
-- - 0.2.0 (2010.05.30) Initial version
-- - 0.3.0 (2024.03.06) Refactored and commented
-- - 0.3.1 (2024.03.07) TODO
----------------------------------------------------------------------------------
-- Timing Diagram's
-- EPP Address Write
--@ {
--@ "signal": [
--@ { "name": "DEPP_Bus", "wave": "xx3....xxx", "data": ["Adress"] },
--@ { "name": "DEPP_WriteEnable", "wave": "1.0....1.." },
--@ { "node": "...A...B", "phase": 0.15 },
--@ { "name": "DEPP_AddressEnable", "wave": "1..0...1.." },
--@ { "node": "...E.F.H.I", "phase": 0.15 },
--@ { "node": ".C.D.G", "phase": 0.15 },
--@ { "name": "DEPP_Wait", "wave": "x0...1...0" }
--@ ],
--@ "head": {
--@ "text": "EPP Address Write"
--@ },
--@ "foot": {
--@ "text": "EPP Address Write Cycle Timing Diagram"
--@ },
--@ "edge": ["A+B min. 80 ns", "C+D min. 40ns", "E+F 0 to 10ms", "H+I 0 to 10ms"]
--@ }
-- EPP Data Write
--@ {
--@ "signal": [
--@ { "name": "DEPP_Bus", "wave": "xx3....xxx", "data": ["Data"] },
--@ { "name": "DEPP_WriteEnable", "wave": "1.0....1.." },
--@ { "node": "...A...B", "phase": 0.15 },
--@ { "name": "DEPP_DataEnable", "wave": "1..0...1.." },
--@ { "node": "...E.F.H.I", "phase": 0.15 },
--@ { "node": ".C.D.G", "phase": 0.15 },
--@ { "name": "DEPP_Wait", "wave": "x0...1...0" }
--@ ],
--@ "head": {
--@ "text": "EPP Data Write"
--@ },
--@ "foot": {
--@ "text": "EPP Data Write Cycle Timing Diagram"
--@ },
--@ "edge": ["A+B min. 80 ns", "C+D min. 40ns", "E+F 0 to 10ms", "H+I 0 to 10ms"]
--@ }
-- EPP Data Read
--@ {
--@ "signal": [
--@ { "name": "DEPP_Bus", "wave": "zz...3...x", "data": ["Data"] },
--@ { "node": "...J.K.L.M", "phase": 0.15 },
--@ { "name": "DEPP_WriteEnable", "wave": "x1........" },
--@ { "node": "...A...B", "phase": 0.15 },
--@ { "name": "DEPP_DataEnable", "wave": "1..0...1.." },
--@ { "node": "...E..FH.I", "phase": 0.15 },
--@ { "node": ".C.D.G", "phase": 0.15 },
--@ { "name": "DEPP_Wait", "wave": "x0....1..0" }
--@ ],
--@ "head": {
--@ "text": "EPP Data Read"
--@ },
--@ "foot": {
--@ "text": "EPP Data Read Cycle Timing Diagram"
--@ },
--@ "edge": ["A+B min. 80 ns", "C+D min. 40 ns", "E+F 0 to 10 ms", "H+I 0 to 10 ms", "J+K max. 20 ns", "L+M min. 20 ns"
--@ ]
--@ }
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
entity DEPP is
port (
--@ Clock signal
--@ Rising edge triggered
CLK : in std_logic;
--@ Chip enable
--@ `1` = enabled, `0` = disabled
CE : in std_logic;
--@ Reset signal
--@ `1` = reset, `0` = normal operation
RST : in std_logic;
--@ @virtualbus EPP-Interface @dir out EPP Interface
--@ Address strobe
DEPP_AddressEnable : in std_logic;
--@ Data strobe
DEPP_DataEnable : in std_logic;
--@ Transfer direction control
--@
--@ `1` = read (Host from DEPP);
--@ `0` = write (Host to DEPP)
DEPP_WriteEnable : in std_logic;
--@ Handshake signal
--@
--@ `0` = ready for new cycle;
--@ `1` = closing current cycle and not ready for new cycle
--@
--@ Keep the signal low to delay the cycle length
DEPP_Wait : out std_logic := '1';
--@ Data/Adress bus;
--@ Tri-state
DEPP_Bus : inout std_logic_vector(7 downto 0) := (others => 'Z');
--@ @end
--@ @virtualbus FIFO-Data-Out @dir out Data & Address Output. FIFO compatible interface
--@ Data output corosponding to the address
DataOutFifo_Data : out std_logic_vector(7 downto 0);
--@ Address output
DataOutFifo_Address : out std_logic_vector(7 downto 0);
--@ Valid data & adress output if `1`. Is only 1 cycle valid
DataOutFifo_WriteEnable : out std_logic;
--@ If `1` the module delays the bus
--@ and dont rise the `WriteEnable` signal
DataOutFifo_FullFlag : in std_logic;
--@ @end
--@ @virtualbus FIFO-Data-In Data input. FIFO compatible interface
--@ Data input
DataInFifo_Data : in std_logic_vector(7 downto 0);
--@ If the fifo is not empty, the module will read the data
DataInFifo_EmptyFlag : in std_logic;
--@ Is one cycle `1` to indicate that the data is read
DataInFifo_ReadEnable : out std_logic;
--@ @end
--@ @virtualbus FIFO-Address-Out @dir out Request address output. FIFO compatible interface
--@ Address output for read requests
AddressOutFifo_Data : out std_logic_vector(7 downto 0);
--@ Valid address output if `1`. Is only 1 cycle valid
AddressOutFifo_WriteEnable : out std_logic;
--@ If `1` the module delays the bus
--@ and dont rise the `RequestEnable` signal
AddressOutFifo_FullFlag : in std_logic
--@ @end
);
end DEPP;
architecture Behavioral of DEPP is
--@ Catch the address as long as the mode (read/write) has not yet been decided.
signal TempAddressRegister : std_logic_vector(7 downto 0) := (others => '0');
--@ Shift register for the rising/falling edge detection of the `DEPP_AddressEnable` signal
signal EPP_AddressEnableShiftRegister : std_logic_vector(1 downto 0) := (others => '0');
--@ Shift register for the rising/falling edge detection of the `DEPP_DataEnable` signal
signal EPP_DataEnableShiftRegister : std_logic_vector(1 downto 0) := (others => '0');
--@ The states of the main state machine
type ModeType is (Idle, RequestActive, SetData, WriteActive, WaitForFallingDataEnable, WaitingForFallingAddressEnable, AdressActive);
--@ The current state of the main state machine
signal Mode : ModeType := Idle;
--@ The output signals for the output data fifo
signal InterWriteEnableOut : std_logic := '0';
--@ The output signals for the output address fifo
signal InterRequestEnable : std_logic := '0';
--@ Intermediary signal to start the address write cycle
signal InterAddressEnable : std_logic := '0';
--@ Negated `DataInFifo_EmptyFlag` signal
signal DataInFifo_DataAviable : std_logic;
begin
DataInFifo_DataAviable <= not DataInFifo_EmptyFlag;
DataOutFifo_WriteEnable <= InterWriteEnableOut;
AddressOutFifo_WriteEnable <= InterRequestEnable;
--@ Shifts the value from the `DEPP_AddressEnable` signal into the `EPP_AddressEnableShiftRegister`
--@ for the rising/falling edge detection.
EPP_AddressEnableCatch : process (CLK)
begin
if rising_edge(CLK) then
if RST = '1' then
EPP_AddressEnableShiftRegister <= (others => '0');
elsif CE = '1' then
EPP_AddressEnableShiftRegister <= EPP_AddressEnableShiftRegister(0) & DEPP_AddressEnable;
end if;
end if;
end process;
--@ Shifts the value from the `DEPP_DataEnable` signal into the `EPP_DataEnableShiftRegister`.
--@ for the rising/falling edge detection.
EPP_DataEnableCatch : process (CLK)
begin
if rising_edge(CLK) then
if RST = '1' then
EPP_DataEnableShiftRegister <= (others => '0');
elsif CE = '1' then
EPP_DataEnableShiftRegister <= EPP_DataEnableShiftRegister(0) & DEPP_DataEnable;
end if;
end if;
end process;
--@ Redirection of the `DataInFifo_EmptyFlag` signal to the `DataInFifo_ReadEnable` signal
--@ if in the `RequestActive` mode: Minimize the latency of the data read.
DataInFIFOMinimizeLatency : process (Mode, DataInFifo_DataAviable)
begin
if Mode = RequestActive then
DataInFifo_ReadEnable <= DataInFifo_DataAviable;
else
DataInFifo_ReadEnable <= '0';
end if;
end process;
EPP_WaitManagement : process (CLK)
begin
if rising_edge(CLK) then
if RST = '1' then
DEPP_Wait <= '1';
DEPP_Bus <= (others => 'Z');
Mode <= Idle;
elsif CE = '1' then
case Mode is
when Idle =>
--@ In idle state the module waits for the beginning of a new cycle
--@ like write address, write data or read data.
--@ A new cycle is signaled via the signals `InterRequestEnable`,
--@ `InterWriteEnableOut` and `InterAddressEnable` provided by the
--@ `EPP_AddressCatch`, `EPP_ReciveData` and `EPP_ReciveRequest` processes.
DEPP_Bus <= (others => 'Z');
--@ If the data or address output fifo is full the module signals the host to wait.
DEPP_Wait <= DataOutFifo_FullFlag or AddressOutFifo_FullFlag;
if InterRequestEnable = '1' then
--@ Start the read cycle
Mode <= RequestActive;
DEPP_Wait <= '0';
elsif InterWriteEnableOut = '1' then
--@ Start the write cycle
Mode <= WaitForFallingDataEnable;
elsif InterAddressEnable = '1' then
--@ Start the address write cycle
Mode <= WaitingForFallingAddressEnable;
end if;
when AdressActive =>
--@ Intermediary state to hold the `DEPP_Wait` minimum one cycle high.
Mode <= WaitingForFallingAddressEnable;
when WriteActive =>
--@ Intermediary state to hold the `DEPP_Wait` minimum one cycle high.
Mode <= WaitForFallingDataEnable;
when RequestActive =>
DEPP_Wait <= '0';
if DataInFifo_DataAviable = '1' then
Mode <= SetData;
end if;
when SetData =>
DEPP_Bus <= DataInFifo_Data;
Mode <= WaitForFallingDataEnable;
when WaitForFallingDataEnable =>
DEPP_Wait <= '1';
if EPP_DataEnableShiftRegister = "01" then
Mode <= Idle;
elsif (EPP_DataEnableShiftRegister = "11") and (EPP_AddressEnableShiftRegister = "11") then
Mode <= Idle;
end if;
when WaitingForFallingAddressEnable =>
DEPP_Wait <= '1';
if EPP_AddressEnableShiftRegister = "01" then
Mode <= Idle;
elsif (EPP_DataEnableShiftRegister = "11") and (EPP_AddressEnableShiftRegister = "11") then
Mode <= Idle;
end if;
when others =>
DEPP_Wait <= '1';
DEPP_Bus <= (others => 'Z');
Mode <= Idle;
end case;
end if;
end if;
end process;
--@ Address write cycle:
--@ If the `DEPP_AddressEnable` signal rises,
--@ he `DEPP_WriteEnable` signal is low and the module is in idle state
--@ the `DEPP_Bus` is stored in the `TempAddressRegister`.
EPP_AddressCatch : process (CLK)
begin
if rising_edge(CLK) then
if RST = '1' then
TempAddressRegister <= (others => '0');
InterAddressEnable <= '0';
elsif CE = '1' then
-- Self reset the `InterAddressEnableRst` signal after one cycle high.
if InterAddressEnable = '1' then
InterAddressEnable <= '0';
end if;
if (EPP_AddressEnableShiftRegister = "10") and (DEPP_WriteEnable = '0') and (Mode = Idle) then
TempAddressRegister <= DEPP_Bus;
InterAddressEnable <= '1';
end if;
end if;
end if;
end process;
--@ Data write cycle:
--@ If the `DEPP_DataEnable` signal rises,
--@ the `DEPP_WriteEnable` signal is low
--@ and the module is in idle state
--@ the `DEPP_Bus` is stored in the `DataOut`,
--@ the `TempAddressRegister` is stored in the `AddressOut`
--@ and the `WriteEnableOut` signal is set to `1`.
EPP_ReciveData : process (CLK)
begin
if rising_edge(CLK) then
if RST = '1' then
DataOutFifo_Address <= (others => '0');
DataOutFifo_Data <= (others => '0');
InterWriteEnableOut <= '0';
elsif CE = '1' then
-- Self reset the `WriteEnableOut` signal after one cycle high.
if InterWriteEnableOut = '1' then
InterWriteEnableOut <= '0';
end if;
if (EPP_DataEnableShiftRegister = "10") and (DEPP_WriteEnable = '0') and (Mode = Idle) then
DataOutFifo_Address <= TempAddressRegister;
DataOutFifo_Data <= DEPP_Bus;
InterWriteEnableOut <= '1';
end if;
end if;
end if;
end process;
--@ Data read cycle:
--@ If the `DEPP_DataEnable` signal rises,
--@ the `DEPP_WriteEnable` signal is high (read)
--@ and the module is in idle state
--@ the `TempAddressRegister` is stored in the `RequestAddress`
--@ and the `RequestEnable` signal is set to `1`.
EPP_ReciveRequest : process (CLK)
begin
if rising_edge(CLK) then
if RST = '1' then
AddressOutFifo_Data <= (others => '0');
InterRequestEnable <= '0';
elsif CE = '1' then
-- Self reset the `RequestEnable` signal after one cycle high.
if InterRequestEnable = '1' then
InterRequestEnable <= '0';
end if;
if (EPP_DataEnableShiftRegister = "10") and (DEPP_WriteEnable = '1') and (Mode = Idle) then
AddressOutFifo_Data <= TempAddressRegister;
InterRequestEnable <= '1';
end if;
end if;
end if;
end process;
end Behavioral;