summaryrefslogtreecommitdiff
path: root/tormenta2.vhd
diff options
context:
space:
mode:
authormarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2001-10-22 23:39:42 +0000
committermarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2001-10-22 23:39:42 +0000
commit7c41810692ed90ece40bf4b2f125f441e2187ac5 (patch)
tree573b8c4e629e7b944f0c1a518caff9a260864610 /tormenta2.vhd
parent3e1750439e2671d398506d06841aaf84a7ef67e4 (diff)
Version 0.1.0 from FTP
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@15 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'tormenta2.vhd')
-rwxr-xr-xtormenta2.vhd588
1 files changed, 588 insertions, 0 deletions
diff --git a/tormenta2.vhd b/tormenta2.vhd
new file mode 100755
index 0000000..19b23bb
--- /dev/null
+++ b/tormenta2.vhd
@@ -0,0 +1,588 @@
+-- Tormenta2 -- PCI Telephony Interface Card -- VHDL for Xilinx Part
+-- version 1.1, 10/22/2001.
+-- Copyright (c) 2001, Jim Dixon.
+--
+-- Jim Dixon <jim@lambdatel.com>
+-- Mark Spencer <mark@linux-support.net>
+--
+-- This program is free software, and the design, schematics, layout,
+-- and artwork for the hardware on which it runs is free, and all are
+-- distributed under the terms of the GNU General Public License.
+--
+-- Thanks to Mark and the gang at Linux Support Services for the contribution
+-- of the initial buffering code.
+--
+--
+
+-- The A4 die of the Dallas 21Q352 chip has a bug in it (well, it has several actually,
+-- but this is the one that effects us the most) where when you have it in IBO mode
+-- (where all 4 framers are combined into 1 8.192 Mhz backplane), the receive data
+-- comes out of the chip late. So late, in fact, that its an entire HALF clock cycle
+-- off. So what we had to do is have a separate RSYSCLK signal (which was the TSYSCLK
+-- signal inverted) and a separate RSYNC signal (which corresponds to the RSYSCLK inverted
+-- signal as opposed to the TSYSCLK) that was 1/2 clock cycle early, so that the data comes
+-- out at the correct time.
+
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL;
+use IEEE.STD_LOGIC_ARITH.ALL;
+use IEEE.STD_LOGIC_UNSIGNED.ALL;
+
+entity tormenta2 is
+ Port (
+-- GCK0 signal (Local bus clock)
+ CLK : in std_logic;
+-- GCK1 signal 8.192 Mhz clock from mk1574 and drives SYSCLK's on Dallas chip
+ CLK8192 : in std_logic;
+-- Tx Framing Pulse to Dallas chip
+ TSSYNC : out std_logic;
+-- Rx Framing Pulse to Dallas chip
+ RSYNC : out std_logic;
+-- 8 Khz square wave for input to mk1574 (RCLKO divided by 193)
+ KHZ8000 : out std_logic;
+-- RSER from Dallas chip (received serial data)
+ RSER : in std_logic;
+-- TSER to Dallas chip (transmitted serial data)
+ TSER : out std_logic;
+-- RCLK output to Dallas chip (TCLK) (1.544 Mhz)
+ RCLKO : out std_logic;
+-- RCLK 1-4 are RCLK inputs from SCT's, 0 is 1.544 Mhz oscillator
+ RCLK : in std_logic_vector(4 downto 0);
+-- LCLK is tied to GCK0, so you dont specify it here.
+-- CCLK, CPROGRAM, and CDONE are tied to dedicated pins, so you dont either.
+-- Local bus Data Bus
+ D : inout std_logic_vector(31 downto 0);
+-- Local bus Address Bus
+ ADDR : in std_logic_vector(11 downto 2);
+-- Local bus Byte Enable lines (also BE0 is A0 and BE1 is A1 for 8 bit operations)
+ BE : in std_logic_vector(3 downto 0);
+-- Local bus "WR" signal
+ WR : in std_logic;
+-- Local bus "RD" signal
+ RD : in std_logic;
+-- Local bus READY signal out (also Configuration BUSY signal)
+ READY : out std_logic;
+-- Local bus INTerrupt signal
+ INT : out std_logic;
+-- Chip selects for Dallas chip SCT's 1 thru 4
+ CS : out std_logic_vector(4 downto 1);
+-- Dallas chip WRite signal
+ DWR : out std_logic;
+-- Dallas chip ReaD signal
+ DRD : out std_logic;
+-- Dallas chip INTerrupt signal in
+ DINT : in std_logic;
+-- LED's output
+ LEDS : out std_logic_vector(7 downto 0);
+-- Board ID input
+ BOARDID : in std_logic_vector(3 downto 0);
+-- TEST pins
+ TEST1 : inout std_logic;
+ TEST2 : inout std_logic;
+ TEST3 : inout std_logic;
+ TEST4 : inout std_logic;
+-- BTERM output
+ BTERM : out std_logic;
+-- MASTER output
+ MASTER : out std_logic;
+-- XSYNCIN input
+ XSYNCIN: in std_logic;
+-- XSYNCOUT output
+ XSYNCOUT: out std_logic);
+end tormenta2;
+
+architecture behavioral of tormenta2 is
+
+component RAMB4_S1_S16
+ port (
+ ADDRA: IN std_logic_vector(11 downto 0);
+ ADDRB: IN std_logic_vector(7 downto 0);
+ DIA: IN std_logic_vector(0 downto 0);
+ DIB: IN std_logic_vector(15 downto 0);
+ WEA: IN std_logic;
+ WEB: IN std_logic;
+ CLKA: IN std_logic;
+ CLKB: IN std_logic;
+ RSTA: IN std_logic;
+ RSTB: IN std_logic;
+ ENA: IN std_logic;
+ ENB: IN std_logic;
+ DOA: OUT std_logic_vector(0 downto 0);
+ DOB: OUT std_logic_vector(15 downto 0));
+END component;
+
+-- Counter for wait state/Dallas generator
+signal waitcnt : std_logic_vector(2 downto 0);
+-- Global counter
+signal counter: std_logic_vector(13 downto 0);
+-- Local copy of Global counter
+signal lcounter: std_logic_vector(13 downto 0);
+-- Position in a given buffer
+signal position: std_logic_vector(11 downto 0);
+-- Latched buffer position
+signal lposition: std_logic_vector(11 downto 0);
+-- dbuf represents the buffer that is currently being
+-- operated upon by the T1 part, while not dbuf represents
+-- the buffer that the bus side is operating with
+signal dbuf: std_logic;
+-- Lathed dbuf signal
+signal ldbuf: std_logic;
+-- Which ram of the buffer we are currently operating with
+-- (0 = top, 1 = bottom)
+signal ramno: std_logic;
+-- Latched ramno signal
+signal lramno: std_logic;
+-- Serial output from first upper 16-bit memory
+signal txqt1out: std_logic;
+-- Serial output from second upper 16-bit memory
+signal txqt2out: std_logic;
+-- Serial output from first lower 16-bit memory
+signal txqb1out: std_logic;
+-- Serial output from second lower 16-bit memory
+signal txqb2out: std_logic;
+-- Parallel output from first 32-bits of memory
+signal rxq1out: std_logic_vector(31 downto 0);
+-- Parallel output from second 32-bits of memory
+signal rxq2out: std_logic_vector(31 downto 0);
+-- Ground bus for unnecessary inputs
+signal gndbus: std_logic_vector(15 downto 0);
+-- RWR: Write enable for ram
+signal RWR: std_logic;
+-- RRD: Read enable for ram
+signal RRD: std_logic;
+-- Local version of 1.544 Mhz clock to be output
+signal lclk: std_logic;
+-- 8khz counter
+signal cnt193: std_logic_vector(7 downto 0);
+-- Which of the received clocks to propagate
+signal clkreg: std_logic_vector(2 downto 0);
+-- Control register
+signal ctlreg: std_logic_vector(7 downto 0);
+-- Status register
+signal statreg: std_logic_vector(2 downto 0);
+-- Signal actually driving Rx buffers (after Rxserial loopback mux)
+signal xrser: std_logic;
+-- Signal actually driven by Tx buffers (before Txserial loopback mux)
+signal xtser: std_logic;
+
+-- Register definitions:
+
+-- Write:
+-- 0xC00 -- clkreg (sync source) 0=free run, 1=span 1, 2=span 2, 3=span 3, 4=span 4, 5=external.
+-- 0xC01 -- ctlreg as follows:
+-- bit 0 - Interrupt Enable
+-- bit 1 - Drives "TEST1" signal ("Interrupt" outbit)
+-- bit 2 - Dallas Interrupt Enable (Allows DINT signal to drive INT)
+-- bit 3 - Enable External Synronization Drive (MASTER signal).
+-- bit 5 - Remote serial loopback (When set to 1, TSER is driven from RSER)
+-- bit 6 - Local serial loopback (When set to 1, Rx buffers are driven from Tx buffers)
+-- bit 7 - Interrupt Acknowledge (set to 1 to acknowledge interrupt)
+-- 0xC02 -- LED register as follows:
+-- bit 0 - Span 1 Green
+-- bit 1 - Span 1 Red
+-- bit 2 - Span 2 Green
+-- bit 3 - Span 2 Red
+-- bit 4 - Span 3 Green
+-- bit 5 - Span 3 Red
+-- bit 6 - Span 4 Green
+-- bit 7 - Span 4 Red
+-- NOTE: turning on both red and green yields yellow.
+-- 0xC03 -- TEST2, writing to bit 0 drives TEST2 pin.
+--
+-- Read:
+-- 0xC00 -- statreg as follows:
+-- bit 0 - Interrupt Enabled
+-- bit 1 - Interrupt Active
+-- bit 2 - Dallas Chip Interrupt Active
+-- 0xC01 -- boardid as follows:
+-- bits 0-3 Board ID bits 0-3 (from rotary dip switch)
+
+
+begin
+
+ -- Create statreg for user to be able to read
+ statreg(0) <= ctlreg(0); -- Interrupt enable status
+ statreg(2) <= not DINT; -- Dallas chip interrupt request
+ -- Tie INT signal to bit in statreg
+ INT <= statreg(1) or ((not DINT) and ctlreg(2));
+
+ MASTER <= ctlreg(3); -- Control Bit to enable External Sync Driver
+
+ TEST1 <= ctlreg(1); -- Reflect "Interrupt" Outbit
+ TEST3 <= statreg(1); -- Reflect Interrupt Status
+ TEST4 <= RSER;
+
+ BTERM <= '1'; -- Leave this not enabled for now.
+
+ -- Which ram we read into is from the 5th LSB of the counter
+ ramno <= lcounter(4);
+ -- Which buffer we're using is the most significant
+ dbuf <= lcounter(13);
+ -- Our position is the bottom 4 bits, inverted, and then
+ -- the skip one, and then the next 8 bits.
+ position(3 downto 0) <= not lcounter(3 downto 0);
+ position(11 downto 4) <= lcounter(12 downto 5);
+
+ gndbus <= "0000000000000000";
+
+ txqt1: RAMB4_S1_S16 port map (
+ ADDRA => position, -- Where are we in transmission
+ ADDRB => ADDR(9 downto 2), -- Address into our 16-bit words
+ DIA(0) => '0', -- We never write from the serial side
+ DIB => D(31 downto 16), -- Top 16-bits of data bus
+ WEA => '0', -- Never write from serial side
+ WEB => not WR, -- Write when requested
+ CLKA => CLK8192, -- Clock output at 8.192 Mhz
+ CLKB => RWR, -- Clock input when asked to by PCI bus
+ ENA => '1', -- Always enable output
+ ENB => dbuf, -- Enable when dbuf is set.
+ DOA(0) => txqt1out, -- Serial output to be MUXed
+ RSTA => '0', -- No need for silly reset
+ RSTB => '0'
+ );
+
+ txqt2: RAMB4_S1_S16 port map (
+ ADDRA => position, -- Where are we in transmission
+ ADDRB => ADDR(9 downto 2), -- Address into our 16-bit words
+ DIA(0) => '0', -- We never write from the serial side
+ DIB => D(31 downto 16), -- Top 16-bits of data bus
+ WEA => '0', -- Never write from serial side
+ WEB => not WR, -- Write when requested
+ CLKA => CLK8192, -- Clock output at 8.192 Mhz
+ CLKB => RWR, -- Clock input when asked to by PCI bus
+ ENA => '1', -- Always enable output
+ ENB => not dbuf, -- Take input from user when not in use.
+ DOA(0) => txqt2out, -- Serial output to be MUXed
+ RSTA => '0', -- No need for silly reset
+ RSTB => '0'
+ );
+
+ txqb1: RAMB4_S1_S16 port map (
+ ADDRA => position, -- Where are we in transmission
+ ADDRB => ADDR(9 downto 2), -- Address into our 16-bit words
+ DIA(0) => '0', -- We never write from the serial side
+ DIB => D(15 downto 0), -- Top 16-bits of data bus
+ WEA => '0', -- Never write from serial side
+ WEB => not WR, -- Write when requested
+ CLKA => CLK8192, -- Clock output at 8.192 Mhz
+ CLKB => RWR, -- Clock input when asked to by PCI bus
+ ENA => '1', -- Always enable output
+ ENB => dbuf, -- Enable input when not in use
+ DOA(0) => txqb1out, -- Serial output to be MUXed
+ RSTA => '0', -- No need for silly reset
+ RSTB => '0'
+ );
+
+ txqb2: RAMB4_S1_S16 port map (
+ ADDRA => position, -- Where are we in transmission
+ ADDRB => ADDR(9 downto 2), -- Address into our 16-bit words
+ DIA(0) => '0', -- We never write from the serial side
+ DIB => D(15 downto 0), -- Top 16-bits of data bus
+ WEA => '0', -- Never write from serial side
+ WEB => not WR, -- Write when requested
+ CLKA => CLK8192, -- Clock output at 8.192 Mhz
+ CLKB => RWR, -- Clock input when asked to by PCI bus
+ ENA => '1', -- Always enable output
+ ENB => not dbuf, -- Enable when dbuf is set.
+ DOA(0) => txqb2out, -- Serial output to be MUXed
+ RSTA => '0', -- No need for silly reset
+ RSTB => '0'
+ );
+
+ rxqt1: RAMB4_S1_S16 port map (
+ ADDRA => lposition, -- Where to put the next sample
+ ADDRB => ADDR(9 downto 2), -- Addressable output
+ DIA(0) => XRSER, -- Input from serial from T1
+ DIB => gndbus, -- Never input from bus
+ WEA => not lramno, -- Enable writing when we're in the top
+ WEB => '0',
+ CLKA => not CLK8192, -- Clock input from T1
+ CLKB => RRD, -- Clock output from bus
+ ENA => not ldbuf, -- Enable when we're the selected buffer
+ ENB => '1', -- Always enable output (it gets MUXed)
+ DOB => rxq1out(31 downto 16), -- Data output to MUX
+ RSTA => '0',
+ RSTB => '0'
+ );
+
+ rxqt2: RAMB4_S1_S16 port map (
+ ADDRA => lposition, -- Where to put the next sample
+ ADDRB => ADDR(9 downto 2), -- Addressable output
+ DIA(0) => XRSER, -- Input from serial from T1
+ DIB => gndbus, -- Never input from bus
+ WEA => not lramno, -- Enable writing when we're in the top
+ WEB => '0',
+ CLKA => not CLK8192, -- Clock input from T1
+ CLKB => RRD, -- Clock output from bus
+ ENA => ldbuf, -- Enable when we're the selected buffer
+ ENB => '1', -- Always enable output (it gets MUXed)
+ DOB => rxq2out(31 downto 16), -- Data output to MUX
+ RSTA => '0',
+ RSTB => '0'
+ );
+
+ rxqb1: RAMB4_S1_S16 port map (
+ ADDRA => lposition, -- Where to put the next sample
+ ADDRB => ADDR(9 downto 2), -- Addressable output
+ DIA(0) => XRSER, -- Input from serial from T1
+ DIB => gndbus, -- Never input from bus
+ WEA => lramno, -- Enable writing when we're in the top
+ WEB => '0',
+ CLKA => not CLK8192, -- Clock input from T1
+ CLKB => RRD, -- Clock output from bus
+ ENA => not ldbuf, -- Enable when we're the selected buffer
+ ENB => '1', -- Always enable output (it gets MUXed)
+ DOB => rxq1out(15 downto 0), -- Data output to MUX
+ RSTA => '0',
+ RSTB => '0'
+ );
+
+ rxqb2: RAMB4_S1_S16 port map (
+ ADDRA => lposition, -- Where to put the next sample
+ ADDRB => ADDR(9 downto 2), -- Addressable output
+ DIA(0) => XRSER, -- Input from serial from T1
+ DIB => gndbus, -- Never input from bus
+ WEA => lramno, -- Enable writing when we're in the top
+ WEB => '0',
+ CLKA => not CLK8192, -- Clock input from T1
+ CLKB => RRD, -- Clock output from bus
+ ENA => ldbuf, -- Enable when we're the selected buffer
+ ENB => '1', -- Always enable output (it gets MUXed)
+ DOB => rxq2out(15 downto 0), -- Data output to MUX
+ RSTA => '0',
+ RSTB => '0'
+ );
+
+
+clkdiv193: process(lclk) -- Divider from 1.544 Mhz to 8 Khz to drive MK1574 via KHZ8000 pin
+begin
+ if (lclk'event and lclk = '1') then
+ cnt193 <= cnt193 + 1;
+ -- Go high after 96 samples and
+ -- low after 193 samples
+ if (cnt193 = "01100000") then
+ KHZ8000 <= '1';
+ elsif (cnt193 = "11000000") then -- *YES* C0 hex *IS* the correct value. I even checked it on a freq. counter!
+ KHZ8000 <= '0';
+ cnt193 <= "00000000";
+ end if;
+ end if;
+end process clkdiv193;
+
+
+-- Serial transmit data (TSER) output mux (from RAM outputs)
+txmux: process (txqt1out, txqt2out, txqb1out, txqb2out,dbuf,ramno,rser)
+begin
+ if (dbuf = '0') then
+ if (ramno = '0') then
+ XTSER <= txqt1out;
+ else
+ XTSER <= txqb1out;
+ end if;
+ else
+ if (ramno = '0') then
+ XTSER <= txqt2out;
+ else
+ XTSER <= txqb2out;
+ end if;
+ end if;
+ if (ctlreg(5)='1') then -- If in remote serial loopback
+ TSER <= RSER;
+ else
+ TSER <= XTSER;
+ end if;
+end process txmux;
+
+-- Stuff to do on rising edge of TSYSCLK
+process(CLK8192,lcounter(12 downto 0),ctlreg(7))
+begin
+ -- Make sure we're on the rising edge
+ if (CLK8192'event and CLK8192 = '1') then
+ counter <= counter + 1;
+ -- We latch copies of ramno, dbuf, and position on this clock so that they
+ -- will be stable when the RX buffer stuff needs them on the other edge of the clock
+ lramno <= ramno;
+ ldbuf <= dbuf;
+ lposition <= position;
+ if (lcounter(9 downto 0)="0000000000") then -- Generate TSSYNC signal
+ TSSYNC <= '1';
+ else
+ TSSYNC <= '0';
+ end if;
+ -- If we are on an 8 sample boundary, and interrupts are enabled,
+ if (((lcounter(12 downto 0)="0000000000000") and (ctlreg(0)='1'))) then
+ statreg(1) <= '1';
+ elsif (ctlreg(7)='1' or ctlreg(0)='0') then
+ statreg(1) <= '0'; -- If interrupt ack-ed
+ end if;
+ end if;
+end process;
+
+-- Stuff to do on Falling edge of TSYSCLK
+process(CLK8192,counter(9 downto 0))
+begin
+if (CLK8192'event and CLK8192='0') then
+ lcounter <= counter; -- save local copy of counter
+ if (counter(9 downto 0)="0000000000") then
+ RSYNC <= '1'; -- Generate RSYNC pulse
+ else
+ RSYNC <= '0';
+ end if;
+end if;
+end process;
+
+-- Handle Data input requests
+rxdata: process (ADDR(11 downto 10), rxq1out, rxq2out, RD, dbuf, statreg)
+begin
+ -- If in 32 bit space, Send data from the block we're not using
+ if (RD = '0' and ADDR(11) = '0') then
+ RRD <= '1'; -- Assert clock to output RAM
+ -- Mux DATA bus to proper RAMs
+ if (dbuf = '1') then
+ D <= rxq1out;
+ else
+ D <= rxq2out;
+ end if;
+ -- If in 8 bit space, return statreg
+ elsif ((RD='0') and (ADDR(11 downto 10)="11")) then
+ if (BE(1 downto 0) = "00") then -- if C00, return status
+ D(2 downto 0) <= statreg;
+ D(31 downto 3) <= "ZZZZZZZZZZZZZZZZZZZZZZZZ00000";
+ else -- if C01, return board id
+ D(3 downto 0) <= NOT BOARDID;
+ D(31 downto 4) <= "ZZZZZZZZZZZZZZZZZZZZZZZZ0000";
+ end if;
+ RRD <= '0';
+ else -- If in outer space, Data bus should be tri-state
+ D <= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";
+ RRD <= '0';
+ end if;
+end process rxdata;
+
+-- rx serial loopback mux
+rxmux: process(rser,xtser)
+begin
+ if (ctlreg(6)='1') then
+ XRSER <= XTSER;
+ else
+ XRSER <= RSER;
+ end if;
+end process rxmux;
+
+-- Handle Writing of RAMs when in 32 bit space
+txdecode: process (WR, CLK, BE, dbuf, D, ADDR)
+begin
+ -- Make sure when we write to memory that we only
+ -- enable the clock on the actual RAM units if the
+ -- top bit of address is '0', and is a full 32 bit access.
+ if ((addr(11) = '0') and (BE="0000") and (WR='0') and (CLK='1')) then
+ RWR <= '1';
+ else
+ RWR <= '0';
+ end if;
+end process txdecode;
+
+-- Select the proper output 1.544 Mhz clock
+clkmux: process(clkreg, RCLK)
+begin
+ if (clkreg = "001") then
+ lclk <= RCLK(1);
+ elsif (clkreg = "010") then
+ lclk <= RCLK(2);
+ elsif (clkreg = "011") then
+ lclk <= RCLK(3);
+ elsif (clkreg = "100") then
+ lclk <= RCLK(4);
+ elsif (clkreg = "101") then
+ lclk <= XSYNCIN;
+ else
+ lclk <= RCLK(0);
+ end if;
+ RCLKO <= lclk;
+ XSYNCOUT <= lclk;
+end process clkmux;
+
+-- Stuff to do on positive edge of Local bus clock
+process(CLK,ADDR(11 downto 10),RD,WR)
+begin
+if (CLK'event and CLK='1') then -- On positive transition of clock
+ if ((WR='0' or RD='0') and ADDR(11 downto 10)="10") then -- If in our address range
+ waitcnt <= waitcnt + 1; -- Bump state counter if in Dallas' address range
+ else
+ waitcnt <= "000"; -- Otherwise, leave reset
+ end if;
+ if (WR='0' and ADDR(11 downto 10)="11") then -- If to write to our configuration space
+ if (ADDR(7 downto 2)="000000") then
+ if (BE(1 downto 0)="11") then
+ TEST2 <= D(0); -- Write to TEST2 pin (0xC03)
+ elsif (BE(1 downto 0)="10") then
+ LEDS <= not D(7 downto 0); -- Write to the LED register (0xC02)
+ elsif (BE(1 downto 0)="01") then
+ ctlreg <= D(7 downto 0); -- Write to the ctlreg register (0xC01)
+ else
+ clkreg <= D(2 downto 0); -- Write to the clkreg register (0xC00)
+ end if;
+ end if;
+ end if;
+ if ((statreg(1)='0') and (ctlreg(7)='1')) then -- if interrupt acked and de-asserted, ack the ack
+ ctlreg(7) <= '0';
+ end if;
+ if (ctlreg(0)='0') then -- if interrupts disabled, make sure ack is de-acked
+ ctlreg(7) <= '0';
+ end if;
+end if;
+end process;
+
+-- Generate Dallas Read and Write Signals and Wait states
+process(CLK,ADDR(11 downto 8),RD,WR,waitcnt)
+begin
+if ((WR='0' or RD='0') and ADDR(11 downto 10)="10") then -- If during valid read or write
+ -- Stuff for CS for Dallas Chips
+ if (ADDR(9 downto 8)="00") then
+ CS(4 downto 1) <= "1110"; -- Activate CS1
+ end if;
+ if (ADDR(9 downto 8)="01") then
+ CS(4 downto 1) <= "1101"; -- Activate CS2
+ end if;
+ if (ADDR(9 downto 8)="10") then
+ CS(4 downto 1) <= "1011"; -- Activate CS3
+ end if;
+ if (ADDR(9 downto 8)="11") then
+ CS(4 downto 1) <= "0111"; -- Activate CS4
+ end if;
+ if (waitcnt <= "100") then -- An intermediate cycle (before ready)
+ if (WR='0') then -- If a write cycle, output it
+ DWR <= '0';
+ else
+ DWR <= '1';
+ end if;
+ if (RD='0') then -- If a read cycle, output it
+ DRD <= '0';
+ else
+ DRD <= '1';
+ end if;
+ end if;
+ if ((waitcnt = "011") and (CLK='0')) then -- If were at 4, were ready, and this will be real one
+ READY <= '0';
+ end if;
+ if (waitcnt > "100") then -- Count is greater then 4, time to reset everything
+ READY <= '1';
+ DWR <= '1';
+ DRD <= '1';
+ end if;
+else -- Not in read or write in the appropriate range, reset the stuff
+ READY <= '1';
+ DWR <= '1';
+ DRD <= '1';
+ CS(4 downto 1) <= "1111"; -- No CS outputs
+end if;
+if (waitcnt="100" and CLK='1' and WR='0') then -- De-activate the DWR signal at the final half cycle
+ DWR <= '1';
+ DWR <= '1';
+end if;
+if ((WR='0' or RD='0') and ADDR(11 downto 10)/="10") then -- If during not valid read or write
+ READY <= '0'; -- Dont hang the bus for them
+end if;
+end process;
+
+end behavioral;