I am trying to implement Digilent Parallel Interface from their SDK. You can specifically read up on the interface in this manual. I am using the Basys 2 250k board.
I am trying to figure out what I am I doing wrong which I think is just an issue with timing in my VHDL.
Here is a timing diagram to read data from the FPGA:
The VHDL looks like:
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;
After simulation with this test bench stimulus I get these results:
-- insert stimulus here
EppWR <= '1';
EppDstb <= '1';
sw <= "00001111";
wait for 4 ns;
EppDstb <= '0';
wait for 50 ns;
EppDstb <= '1';
My C++ project compiles just fine and I used Hamsters EPP Performace project as my base (which I got working just fine) and then went into the demo file of the SDK download and grabbed the DoGetReg()
function to start reading bytes.
Whenever I run the program I get...
Opening
Enabling
Getting
DeppGetReg failed
Here is the code:
// DeppSwitches.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include
#include
#include
#include
#include
#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);
}
Answer
Thanks to some help from Hamster I managed to get it working.
My code had many problems but the main thing I was doing wrong was not supporting write
commands.
Here is my 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;
My C++ program was just fine. You can see the code in the main post.
No comments:
Post a Comment