fpga4fun.com - where FPGAs are fun.
Home
Welcome
Information


FPGA projects
Music box
Pong game
R/C servos
Text LCD module
Quadrature decoder
PWM and one-bit DAC
Debouncer
LED displays
Crossing clock domains
External contributions

FPGA interface projects
RS-232
JTAG
I2C
EPP
SPI
CNC steppers

FPGA advanced projects
Graphic LCD panel
Digital oscilloscope
10BASE-T interface
PCI interface
Spoc CPU core

Hands-on
A simple oscilloscope


FPGA introduction
What are FPGAs?
How FPGAs work
FPGA pins
Clocks and global lines
Download cables
Configuration
Learn more

FPGA software
Design software
Pin assignment
Design-entry/HDL
Simulation/HDL
Synthesis and P&R

FPGA electronic
SMD technology
Crystals and oscillators

HDL info
HDL tutorials
Verilog tips
VHDL tips

Quick-start guides
ISE
Quartus

Site
News
FPGA links
HDL tutorials
Forum


EPP - The HDL

Let's see how easy it is to implement an EPP port in an FPGA.

First let's create a few signals from the parallel port signals. We invert some signals to make all new signals active high.

// Let's create a few signals from the "PP" parallel port pins
// first for the EPP outputs (i.e. outputs from the PC, inputs for us)
wire EPP_write = ~PP[1];
wire EPP_addr_strobe = ~PP[17];
wire EPP_data_strobe = ~PP[14];
wire [7:0] EPP_datain = PP[9:2];

// now for the EPP inputs
wire EPP_wait;			assign PP[11] = EPP_wait;
wire [7:0] EPP_dataout;		assign PP[9:2] = EPP_dataout;

Now most FPGA designs use their own clock. Let's call our clock "clk" and synchronize the strobe signals to our clock.

// Use a 3-taps shift register to synchronize EPP_strobe to our clock
wire EPP_strobe = EPP_data_strobe | EPP_addr_strobe;  // only one is active at a time
reg [2:0] EPP_strobe_reg;
always @(posedge clk) EPP_strobe_reg <= {EPP_strobe_reg[1:0], EPP_strobe};

// detect the strobe edges
wire EPP_strobe_edge1 = (EPP_strobe_reg[2:1]==2'b01);
wire EPP_strobe_edge2 = (EPP_strobe_reg[2:1]==2'b10);

// respond right away to a transaction
assign EPP_wait = EPP_strobe_reg[1];

Now we can handle the EPP writes. Let's store the received values into registers.

// EPP writes
reg [7:0] addr_reg, data_reg;
always @(posedge clk) if(EPP_strobe_edge1 & EPP_write & EPP_addr_strobe) addr_reg <= EPP_datain;
always @(posedge clk) if(EPP_strobe_edge1 & EPP_write & EPP_data_strobe) data_reg <= EPP_datain;

EPP reads now. Let's just read back what are stored in the registers...

// EPP reads
wire EPP_read = ~EPP_write;
wire [7:0] EPP_data_mux = EPP_addr_strobe ? addr_reg : data_reg;
assign EPP_dataout = (EPP_read & EPP_wait) ? EPP_data_mux : 8'hZZ;

That's it.
Congratulations! You can now read and write into your FPGA using EPP.

What to try next?

Your turn to experiment!






This page was last updated on September 12 2006.