Ich versuche, Digilent Parallel Interface aus ihrem SDK zu implementieren . In diesem Handbuch können Sie sich speziell über die Schnittstelle informieren . Ich verwende das Basys 2 250k Board.
Ich versuche herauszufinden, was ich falsch mache, was meiner Meinung nach nur ein Problem mit dem Timing in meinem VHDL ist.
Hier ist ein Zeitdiagramm zum Lesen von Daten aus dem FPGA:
Das VHDL sieht so aus:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity DeppSwitches is
Port(
mclk : in std_logic;
EppDB : inout std_logic_vector(7 downto 0);
EppAstb : in std_logic;
EppDstb : in std_logic;
EppWR : in std_logic;
EppWait : out std_logic;
Led : out std_logic_vector(7 downto 0);
sw : in std_logic_vector(7 downto 0);
btn : in std_logic_vector(4 downto 0);
stepCurrOutDebug : out std_logic_vector(7 downto 0);
stepNextOutDebug : out std_logic_vector(7 downto 0)
);
end DeppSwitches;
architecture Behavioral of DeppSwitches is
signal busEppOut: std_logic_vector(7 downto 0); -- Channel to send bits to pc
signal busEppIn: std_logic_vector(7 downto 0); -- Address that the pc sends to fpga
signal busEppData: std_logic_vector(7 downto 0); -- Bits to send to PC
signal peripheralWait: std_logic := '0';
constant stepIdle: std_logic_vector(7 downto 0) := "0001" & "0000";
constant stepRead: std_logic_vector(7 downto 0) := "0010" & "0000"; -- PC Read from FPGA
constant stepRead2: std_logic_vector(7 downto 0) := "0100" & "0000"; -- PC Read from FPGA
signal stepCurr: std_logic_vector(7 downto 0) := stepIdle;
signal stepNext: std_logic_vector(7 downto 0);
begin
Led <= sw;
-- Handshake signal used to indicate when the peripheral is ready to accept data or has data available.
EppWait <= peripheralWait;
-- Data bus direction control. The internal input data bus always
-- gets the port data bus. The port data bus drives the internal
-- output data bus onto the pins when the interface says we are doing
-- a read cycle and we are in one of the read cycles states in the
-- state machine.
busEppIn <= EppDB;
EppDB <= busEppOut;
-- Hook the data bits to the switches
busEppData <= sw;
-- We need this to see the state when debugging
stepCurrOutDebug <= stepCurr;
stepNextOutDebug <= stepNext;
-- Advance the state machine
process(mclk)
begin
if rising_edge(mclk) then
stepCurr <= stepNext;
end if;
end process;
process(mclk)
begin
if rising_edge(mclk) then
case stepCurr is
when stepIdle =>
peripheralWait <= '0';
busEppOut <= "ZZZZZZZZ";
if EppWR = '1' then
stepNext <= stepRead;
else
stepNext <= stepIdle;
end if;
when stepRead =>
if EppDstb = '0' then
busEppOut <= busEppData;
peripheralWait <= '1';
stepNext <= stepRead2;
end if;
when stepRead2 =>
if EppDstb = '1' then
busEppOut <= "ZZZZZZZZ";
stepNext <= stepIdle;
else
stepNext <= stepRead2;
end if;
when others => stepNext <= stepIdle;
end case;
end if;
end process;
end Behavioral;
Nach der Simulation mit diesem Testbench-Stimulus erhalte ich diese Ergebnisse:
-- insert stimulus here
EppWR <= '1';
EppDstb <= '1';
sw <= "00001111";
wait for 4 ns;
EppDstb <= '0';
wait for 50 ns;
EppDstb <= '1';
Mein C++-Projekt lässt sich problemlos kompilieren, und ich habe das EPP-Performace-Projekt von Hamster als Basis verwendet (das problemlos funktionierte) und bin dann in die Demodatei des SDK-Downloads gegangen und habe die DoGetReg()
Funktion aufgerufen, um mit dem Lesen von Bytes zu beginnen.
Immer wenn ich das Programm starte bekomme ich...
Opening
Enabling
Getting
DeppGetReg failed
Hier ist der Code:
// DeppSwitches.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "dpcdecl.h"
#include "depp.h"
#include "dmgr.h"
static HIF hif = hifInvalid;
void ErrorExit();
void DoGetReg();
int main(int cszArg, char * rgszArg[])
{
fprintf(stderr,"Opening\n");
if(!DmgrOpen(&hif, "Basys2")) // Change to Basys2 for the other board.
{
printf("DmgrOpen failed (check the device name you provided)\n");
return 0;
}
fprintf(stderr,"Enabling\n");
if(!DeppEnable(hif))
{
printf("DeppEnable failed\n");
return 0;
}
fprintf(stderr,"Getting\n");
DoGetReg();
if( hif != hifInvalid )
{
DeppDisable(hif);
DmgrClose(hif);
}
return 0;
}
void DoGetReg()
{
BYTE idReg;
BYTE idData;
idReg = (BYTE)0;
// DEPP API Call: DeppGetReg
if(!DeppGetReg(hif, idReg, &idData, fFalse)) {
printf("DeppGetReg failed\n");
ErrorExit();
}
printf("Complete. Recieved data %d\n", idData);
return;
}
/* ------------------------------------------------------------ */
/*** ErrorExit
**
** Parameters:
** none
**
** Return Value:
** none
**
** Errors:
** none
**
** Description:
** Disables DEPP, closes the device, close any open files, and exits the program
*/
void ErrorExit() {
if( hif != hifInvalid ) {
// DEPP API Call: DeppDisable
DeppDisable(hif);
// DMGR API Call: DmgrClose
DmgrClose(hif);
}
exit(1);
}
Dank etwas Hilfe von Hamster habe ich es geschafft, es zum Laufen zu bringen.
Mein Code hatte viele Probleme, aber die Hauptsache, die ich falsch gemacht habe, war, keine write
Befehle zu unterstützen.
Hier ist mein VHDL:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity DeppSwitches is
Port(
mclk : in std_logic;
EppDB : inout std_logic_vector(7 downto 0);
EppAstb : in std_logic;
EppDstb : in std_logic;
EppWR : in std_logic;
EppWait : out std_logic;
Led : out std_logic_vector(7 downto 0);
sw : in std_logic_vector(7 downto 0);
btn : in std_logic_vector(4 downto 0);
stepCurrOutDebug : out std_logic_vector(7 downto 0);
stepNextOutDebug : out std_logic_vector(7 downto 0)
);
end DeppSwitches;
architecture Behavioral of DeppSwitches is
signal busEppOut: std_logic_vector(7 downto 0); -- Channel to send bits to pc
signal busEppIn: std_logic_vector(7 downto 0); -- Address that the pc sends to fpga
signal busEppData: std_logic_vector(7 downto 0); -- Bits to send to PC
signal peripheralWait: std_logic := '0';
constant stepIdle: std_logic_vector(7 downto 0) := "0000" & "0000";
constant stepReadA: std_logic_vector(7 downto 0) := "0001" & "0000"; -- PC Read from FPGA Address
constant stepReadD: std_logic_vector(7 downto 0) := "0010" & "0000"; -- PC Read from FPGA Data
constant stepWriteA: std_logic_vector(7 downto 0) := "0100" & "0000"; -- PC Write to FPGA Address
constant stepWriteD: std_logic_vector(7 downto 0) := "1000" & "0000"; -- PC Write to FPGA Data
signal stepCurr: std_logic_vector(7 downto 0) := stepIdle;
signal stepNext: std_logic_vector(7 downto 0);
begin
Led <= sw;
-- Handshake signal used to indicate when the peripheral is ready to accept data or has data available.
EppWait <= peripheralWait;
-- Data bus direction control. The internal input data bus always
-- gets the port data bus. The port data bus drives the internal
-- output data bus onto the pins when the interface says we are doing
-- a read cycle and we are in one of the read cycles states in the
-- state machine.
busEppIn <= EppDB;
EppDB <= busEppOut;
-- Hook the data bits to the switches
busEppData <= sw;
-- We need this to see the state when debugging
stepCurrOutDebug <= stepCurr;
stepNextOutDebug <= stepNext;
-- Advance the state machine
process(mclk)
begin
if rising_edge(mclk) then
stepCurr <= stepNext;
end if;
end process;
process(mclk)
begin
if rising_edge(mclk) then
case stepCurr is
when stepIdle =>
peripheralWait <= '0';
busEppOut <= "ZZZZZZZZ";
if EppDstb = '0' then
if EppWr = '0' then
stepNext <= stepWriteD; -- PC Write to FPGA Data
else
stepNext <= stepReadD; -- PC Read from FPGA Data
end if;
end if;
if EppAstb = '0' then
if EppWr = '0' then
stepNext <= stepWriteA; -- PC Write to FPGA Address
else
stepNext <= stepReadA; -- PC Read from FPGA Address
end if;
end if;
-------------------------------------------------
when stepReadD | stepReadA =>
busEppOut <= busEppData;
peripheralWait <= '1';
if EppDstb = '1' then
stepNext <= stepIdle;
end if;
-------------------------------------------------
when stepWriteD | stepWriteA =>
peripheralWait <= '1';
if EppDstb = '1' then
stepNext <= stepIdle;
end if;
when others => stepNext <= stepIdle;
end case;
end if;
end process;
end Behavioral;
Mein C++-Programm war in Ordnung. Sie können den Code im Hauptpost sehen.
EppAstb = '1'
den Koffer brauchen ?when stepWriteD | stepWriteA
if EppDstb = '1' or EppAstb = '1' then
user_1818839