EB675001DIP User CPLD Guide |
|
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 Select | CPU Address |
---|---|
0 | 0xF0000000 |
2 | 0xF8000000 |
3 | 0xFC000000 |
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:
Register | Address |
---|---|
reg_000 | 0xF8000000 |
reg_001 | 0xF8200000 |
reg_010 | 0xF8400000 |
reg_011 | 0xF8600000 |
reg_100 | 0xF8800000 |
reg_101 | 0xF8A00000 |
reg_110 | 0xF8C00000 |
reg_111 | 0xF8E00000 |
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.