Simtec Electronics


EB675001DIP User CPLD Guide

ProductEB675001DIP
Date12/04/2007
ReferenceCPLDGD001
AuthorBJD
Revision1.1

Contents

©2007 Simtec Electronics


Introduction

This document describes the CPLD example projects provided and how to use the programmable logic on the Simtec EB675001DIP.

Bus Interface

Name From Description
nrst_i CPU Active low reset
cko_i CPU CPU generated clock, default 58.976MHz
nxcs_i CPU Chip select for areas 2 and 3
nxoe_i CPU Output enable, active for read cycles
nxwe_i CPU Write strobe, active during write cycles
nubs_i CPU Upper byte (D8..D15) enable
nlbs_i CPU Lower byte (D0..D7) enable
xa_i CPU Address lines A23 to A21
xa0_i CPU Address line A0 1
ncplden_i CPU Unused portion chip-select for area 0
xd Both Data bus
nbufen_io Both Off board address buffer enable
nwait_i Onboard Bus wait input
xwait_o CPLD Bus wait output to CPU
a CPLD GPIO pins bank A
b CPLD GPIO pins bank B
c CPLD GPIO pins bank C
d CPLD GPIO pins bank D
d_18 CPLD GPIO pin D 181
d_19 CPLD GPIO pin D 191
d_20 CPLD GPIO pin D 201
d_29 CPLD GPIO pin D 291

1VHDL does not allow for more than one range in a vector, so these pins have been split

All signals that are input only are postfixed with _i, and any that are output only are postfixed with _o. Active low signals are prefixed with n.

nrst_i

The nrst_i signal is is generated from the CPU, and should be active for at least 1ms during any reset cycle. It should be used to reset any internal state that the CPLD may carry.

xd

The CPU databus. This bus is shared between all the peripherals and memory (including the SDRAM) on the system, so should be left tristate when the CPLD is not being accessed.

CPLD Accesses

Three chip select lines are provided, nxcs_i carries the CPU's select lines for areas 2 and 3 directly, nxcs_i(2) is XIOCS_N[2] and nxcs_i(3) is XIOCS_N[3] from the CPU. ncplden_i is the portion of chip select area 0 that is not used by the on-board peripherals.

ncplden_i is provided for any applications that require wait to be honoured, as area 0 is the only area with support for stretched IO cycles. See notes on processing the wait line for more information.

Any access cycle must be checked with the appropriate chip select signal as the CPLD is not the only device on the bus.

The chip selects are accessed via the following addresses in the CPU:

Chip SelectCPU Address
00xF0000000
20xF8000000
30xFC000000

For chip select 0, only 0xF0000000 to 0xF0DFFFFF is available to the CPLD due to usage by other onboard peripherals. This also means that the configuration of this chip select should not be altered if these peripherals are needed. This chip select is configured for 16 bit accesses.

If chip select 0 is being used in the design, ensure that the section on the the wait line is obeyed, otherwise there may be problems with other onboard systems.

Note, due to decoding logic for ncplden_i, there may be small (sub 10ns) glitches on this line, these should not overlap the read or write strobe, but any logic using ncplden_i edges should take care to ignore these.

Chip selects 2 and 3 share configuration.

For more details on how to configure the bus width and access timings for these regions, see the Oki ML675001 manual.

Byte lane enables

The nubs_i and nlbs_i signals indicate which part of the databus (xd) is active during a read or write cycle. nlbs_i indicates that D0 through D7 are valid (or to be driven) and nubs_i indicates D8 through D15 are active.

For write, these signals indicate which data lines have been driven onto the bus. In read cycles, these indicates which lines the processor is expecting to see valid data on.

If the CPLD is only configure for 8bit, or if the CPLD is using a 16bit databus and does not use 8bit read/writes then these signals can be ignored.

Note, 8bit read/writes to a sixteen bit area may not produce a valid A0 signal.

Wait line

To allow the interception of the wait signal to the CPU, it is passed through the CPLD, from nwait_i to xwait_o. To ensure that the rest of the system functions correctly, any design must ensure this signal is passed through in the correct matter even if there is no other usage for wait.

For example:

xwait_o    <= not(nwait_i);

or if wait is needed in the design:

signal user_wait: std_logic;

xwait_o	<= not(nwait_i) or user_wait;

The CPU only uses wait for chip select area 0 and ignores it on areas 2 and 3.

Examples

Writable register

This example shows a writable register in chip select 2, address 0, using all 16 data bits. Note, this does not take into account the byte-selects, so 8bit writes to this register will act as 16 bit writes.

signal reg_val: std_logic_vector(15 downto 0);

my_reg: process(nrst_i, nxcs_i, nxwe_i, xd, xa_i)
begin
	if (nrst_i = '0') then
		reg_val <= X"0000";	-- register default at reset 
	else
		if (nxcs_i(2)='0' and xa_i = "000" and nxwe_i='0') then
			reg_val <= xd;
		end if;
	end if;
end if;

This could also be written as so, using the rising edge of nxwe_i as a clock into the register (using the rising edge gives the best data setup time):

signal reg_val: std_logic_vector(15 downto 0);

my_reg: process(nrst_i, nxcs_i, nxwe_i, xd, xa_i)
begin
	if (nrst_i = '0') then
		reg_val <= X"0000";	-- register default at reset 
	else
		if (nxcs_i(2)='0' and xa_i = "000") then
			if (rising_edge(nxwe_i)) then
				reg_val <= xd;
			end if;
		end if;
	end if;
end if;

If we are using the byte selects to control which part of the register gets written, then the first example becomes:

signal reg_val: std_logic_vector(15 downto 0);

my_reg: process(nrst_i, nxcs_i, nxwe_i, xd, xa_i, nubs_i, nlbs_i)
begin
	if (nrst_i = '0') then
		reg_val <= X"0000";	-- register default at reset 
	else
		if (nxcs_i(2)='0' and xa_i = "000" and nxwe_i='0') then
			if (nlbs_i='0') then
				reg_val(7 downto 0) <= xd(7 downto 0);
			end if;

			if (nubs_i='0') then
				reg_val(15 downto 8) <= xd(15 downto 8);
			end if;
		end if;
	end if;
end if;

This register would be accessed by writing to address 0xF8000000

Internal bus

This example shows a user bus which takes a set of registers and outputs the register selected by address when chip select 2 is active. It does not take into account the nlbs_i or nubs_i signals.

-- our internal data bus
signal user_bus: std_logic_vector(15 downto 0);

-- our internal registers
signal reg_000: std_logic_vector(15 downto 0);
signal reg_001: std_logic_vector(15 downto 0);
signal reg_010: std_logic_vector(15 downto 0);
signal reg_011: std_logic_vector(15 downto 0);
signal reg_100: std_logic_vector(15 downto 0);
signal reg_101: std_logic_vector(15 downto 0);
signal reg_110: std_logic_vector(15 downto 0);
signal reg_111: std_logic_vector(15 downto 0);

-- output our bus when we are selected for read

xd <= user_bus when (nxoe_i='0' and ncs_i(2)='0') else (others => 'Z');

-- create our bus mux

user_bus <= reg_000 when (xa_i = "000") else
	    reg_001 when (xa_i = "001") else
	    reg_010 when (xa_i = "010") else
	    reg_011 when (xa_i = "011") else
	    reg_100 when (xa_i = "100") else
	    reg_101 when (xa_i = "101") else
	    reg_110 when (xa_i = "110") else
	    reg_111 when (xa_i = "111") else
	    X"0000";	       -- keep the compiler happy

The bus would turn up in the 0xF8000000 region, and the registers would have the following addresses:

RegisterAddress
reg_0000xF8000000
reg_0010xF8200000
reg_0100xF8400000
reg_0110xF8600000
reg_1000xF8800000
reg_1010xF8A00000
reg_1100xF8C00000
reg_1110xF8E00000

This example uses the byte select signals to control which byte lane is output. As above it is for chip select 2 only:

-- our internal data bus
signal user_bus: std_logic_vector(15 downto 0);

-- our internal registers
signal reg_000: std_logic_vector(15 downto 0);
signal reg_001: std_logic_vector(15 downto 0);
signal reg_010: std_logic_vector(15 downto 0);
signal reg_011: std_logic_vector(15 downto 0);
signal reg_100: std_logic_vector(15 downto 0);
signal reg_101: std_logic_vector(15 downto 0);
signal reg_110: std_logic_vector(15 downto 0);
signal reg_111: std_logic_vector(15 downto 0);

-- output our bus when we are selected for read

xd(15 downto 8) <= user_bus (15 downto 8) when (nxoe_i='0' and ncs_i(2)='0' and nubs_i='0') else (others => 'Z');
xd(7 downto 0) <= user_bus(7 downto 0) when (nxoe_i='0' and ncs_i(2)='0' and nlbs_i='0') else (others => 'Z');

-- create our bus mux

user_bus <= reg_000 when (xa_i = "000") else
	    reg_001 when (xa_i = "001") else
	    reg_010 when (xa_i = "010") else
	    reg_011 when (xa_i = "011") else
	    reg_100 when (xa_i = "100") else
	    reg_101 when (xa_i = "101") else
	    reg_110 when (xa_i = "110") else
	    reg_111 when (xa_i = "111") else
	    X"0000";	       -- keep the compiler happy

To extend the bus to any of the chip-selects the CPLD is on, then the following from the example project can be used:

signal ncs: std_logic;   
signal user_bus: std_logic_vector(15 downto 0);

-- create a single, active low, internal chip select signal
ncs <= cs_n_i(2) and cs_n_i(3) and ncplden_i;

-- output our databus during our chipselect
xd(7 downto 0) <= user_bus(7 downto 0) when nxoe_i='0' and ncs='0' and nlbs_i='0' else (others=>'Z')  ;
xd(15 downto 8) <= user_bus(15 downto 8) when nxoe_i='0' and ncs='0' and nubs_i='0' else (others=>'Z')  ;

Enabling off-board address buffers

The off-board address lines A1 through A23 are passed through a set of buffers to ensure that no noise from SDRAM accesses is allowed to leak off-board. The CPLD has access to the enable pins for these buffers via the nbufen_io pin.

This line is driven from more than one source, so must be left tri-state when not being used. If the CPLD wishes to enable the buffers, the line should be driven low.

An example driving the buffers if chip select 2 is active:

nbufen_io <= '0' when (nxcs_i(2)='0') else 'Z';

The example project creates an internal signal called nbufen which can be permanently driven.

Simtec Electronics

Web http://www.simtec.co.uk/
Email info@simtec.co.uk
Telephone +44 (0)1772 978010
Fax +44 (0)1772 816426
Mail Simtec Electronics,
Avondale Drive,
Tarleton,
Preston,
Lancs
PR4 6AX
United Kingdom