?? sram512kleft16bit50mhzreadreq-sv05c.vhd
字號:
-------------------------------------------------------------------------------
-- sram512kleft16bit50mhzreadreq-sv05c.vhd
--
-- Author(s): James Brennan
-- Created: 19 Feb 2001
-- Last Modified: 19 Feb 2001
--
-- Entity: sraminterface
--
-- * Provides a simple interface to the SRAM on an XSV Board, v1.0
-- * 512k address space (512 * 1024 addressable locations, meaning
-- that addresses are 19 bits wide).
-- * 16 bit data (each location holds 16 bits).
-- * Only uses left-bank of SRAM. (Technically you could connect this entity
-- to either bank of SRAM in your top-level file. The data and address
-- lines have simply been named assuming that the entity will be connected
-- to the left bank of SRAM).
--
-- * Writes are performed in 2 clock cycles. Reads are performed in 1 clock
-- cycle.
--
-- * Read data is NOT registered internally. It must be registered externally.
-------------------------------------------------------------------------------
-- ---------------------------------
-- Clock:
-- 50Mhz or slower required.
-- Must have a 50% duty cycle.
-- ---------------------------------
-- The two signals canRead and canWrite are are high when new requests
-- for reads and writes respectively can be made.
-- Writes and reads can be performed in any order and can be
-- interspersed in any way.
-- To perform a write:
-- * Place the write address on writeAddr and the write data on
-- writeData.
-- * Wait until canWrite is '1'. Then assert doWrite (set to '1').
-- You can assert doWrite on the same clock cycle that canWrite
-- is high. Asserting doWrite is also called making a
-- "write request".
-- * The sraminterface will see doWrite is '1' on the next rising
-- clock edge and on the same edge will register (i.e. place in
-- registers) writeAddr and writeData. The write will take place
-- in the 2 cycles commencing with this first edge and will be
-- completed at the third rising clock edge after doWrite is
-- asserted.
-- To perform a read:
-- * Place the read address on readAddr.
-- * Wait until canRead is '1'. Then assert doRead (set to '1').
-- You can assert doRead on the same clock cycle that canRead
-- is high. Asserting doRead is also called making a
-- "read request".
-- * The sraminterface will see doRead is '1' on the next rising
-- clock edge and on the same edge will register (i.e. place in
-- registers) the value on readAddr. The read will take place
-- over the next single clock cycle. The signal canRead
-- (as well as canWrite) will remain high in the cycle in
-- which the read takes place. This indicates both that the
-- readData will be valid at the end of this cycle and that the
-- sraminterface can at this point handle another read or write
-- request.
-- * At the end of the clock cycle in which the read occurs,
-- the user of the sraminterface must register the value
-- on readData. This value must be registered, as on the next
-- clock cycle it is not guaranteed to be the same and may
-- instead change.
library IEEE;
use IEEE.std_logic_1164.all;
entity sraminterface is
port (
CLK: in STD_LOGIC; -- Clock signal.
Resetn: in STD_LOGIC; -- Asynchronous reset
doRead: in STD_LOGIC; -- Set this to make a read request.
doWrite: in STD_LOGIC; -- Set this to make a write request.
readAddr: in STD_LOGIC_VECTOR (18 downto 0); -- Address to read from (user-side).
writeAddr: in STD_LOGIC_VECTOR (18 downto 0); -- Address to write to (user-side).
readData: out STD_LOGIC_VECTOR (15 downto 0); -- Data read (user-side).
writeData: in STD_LOGIC_VECTOR (15 downto 0); -- Data to write (user-side).
canRead: out STD_LOGIC; -- Is '1' when a read request can be handled.
canWrite: out STD_LOGIC; -- Is '1' when a write request can be handled.
CELeftn: out STD_LOGIC; -- CEn signal to left SRAM bank.
OELeftn: out STD_LOGIC; -- OEn signal to left SRAM bank.
WELeftn: out STD_LOGIC; -- WEn signal to left SRAM bank.
SRAMLeftAddr: out STD_LOGIC_VECTOR (18 downto 0); -- Address bus to left SRAM bank.
SRAMLeftData: inout STD_LOGIC_VECTOR (15 downto 0) -- Data bus to left SRAM bank.
);
end sraminterface;
architecture sraminterface_arch of sraminterface is
-- ========================================
-- Architechture declarations:
-- ========================================
-- Constants:
-- General enabled/disabled constants:
constant CONST_ENABLED : STD_LOGIC := '1';
constant CONST_DISABLED : STD_LOGIC := '0';
-- Signals for registers:
signal addrReg : STD_LOGIC_VECTOR(18 downto 0);
signal writeDataReg : STD_LOGIC_VECTOR(15 downto 0);
-- Clock-enable controls for the registers:
signal regWriteAddr : STD_LOGIC;
signal regReadAddr : STD_LOGIC;
signal regWriteData : STD_LOGIC;
-- Internal values of SRAM control signals:
signal CEn : STD_LOGIC;
signal OEn : STD_LOGIC;
signal WEn : STD_LOGIC;
-- Flip-flop signals for signalling when we are
-- in the "write" states (these are effectively
-- duplicating some of the presState signal to
-- try and improve the timing of the circuit):
signal doingWrite1 : STD_LOGIC;
signal doingWrite2 : STD_LOGIC;
-- Other control signals for the data path:
signal enableWriteData : STD_LOGIC;
-- 16-bit data bus:
-- We are only using the left-hand side SRAM bank.
signal SRAMData : STD_LOGIC_VECTOR(15 downto 0);
-- Signals for latched-mealy outputs:
signal nextOEn: STD_LOGIC;
signal nextWEn: STD_LOGIC;
signal nextDoingWrite1 : STD_LOGIC;
signal nextDoingWrite2 : STD_LOGIC;
-- Declarations required for the controller FSM.
type STATE_TYPE is (stIdle, stWrite1, stWrite2,
stRead1);
signal presState, nextState: STATE_TYPE;
begin
-- ========================================
-- Architecture body:
-- ========================================
-- ========================================
-- Combinational signals
-- ========================================
-- Control signals:
CELeftn <= CEn;
OELeftn <= OEn;
WELeftn <= WEn;
-- SRAM address bus:
SRAMLeftAddr <= addrReg;
-- SRAM data bus:
SRAMLeftData <= SRAMData;
readData <= SRAMData;
-- ========================================
-- Implementation of specific structures
-- ========================================
-- 3-state buffer placed after the writeDataReg register
-- in the data path:
process(writeDataReg, doingWrite1, doingWrite2, CLK)
begin
-- We drive the SRAM data I/O bus with data to be written
-- ONLY at the following times:
-- * For the 2nd half of write cycle 1
-- and * For the entirety of write cycle 2
--
-- To do this we rely on the fact that CLK = '1' for the
-- first half of a clock cycle and CLK = '0' for the
-- second half of a cycle.
-- The reason for the dependancy on CLK is as follows:
-- At the start of the clock cycle in which we are
-- performing a write, we raise OEn. This is to make the
-- SRAM stop driving its bidirectional data lines and
-- instead make its drivers high impedance. We wait half a
-- clock cycle for the SRAM's data line drivers to go high
-- impedance, and THEN we ourselves drive the SRAM's
-- bidirectional data lines with the data that we wish to
-- be written.
if (doingWrite1 = '1' and CLK = '0') or
(doingWrite2 = '1') then
SRAMData <= writeDataReg;
else
SRAMData <= (others => 'Z');
end if;
end process;
-- Process for WEn signal:
-- This process has been placed here simply because it is similar
-- to the 3-state buffer on the write data output above. However
-- we do NOT use a 3-state buffer for WEn.
process(doingWrite1, doingWrite2, CLK)
begin
if (doingWrite1 = '1' and CLK = '0') or
(doingWrite2 = '1' and CLK = '1') then
WEn <= '0';
else
WEn <= '1';
end if;
end process;
-- ========================================
-- Process for reset and clock-edge events
-- ========================================
process(CLK, Resetn)
begin
if Resetn = '0' then
-- Default values of signals that are NOT
-- controlled by the FSM controller:
presState <= stIdle;
CEn <= '1';
OEn <= '0';
doingWrite1 <= '0';
doingWrite2 <= '0';
addrReg <= (others => '0');
writeDataReg <= (others => '0');
elsif CLK'EVENT and CLK = '1' then
CEn <= '0';
-- Handle the clock-enabling of each register:
if regReadAddr = '1' then
addrReg <= readAddr;
elsif regWriteAddr = '1' then
addrReg <= writeAddr;
end if;
if regWriteData = '1' then
writeDataReg <= writeData;
end if;
-- Update latched-mealy outputs:
OEn <= nextOEn;
doingWrite1 <= nextDoingWrite1;
doingWrite2 <= nextDoingWrite2;
-- Update current state for controller FSM:
presState <= nextState;
end if;
end process;
-- ========================================
-- Process for FSM of controller
-- ========================================
process(presState, doRead, doWrite)
begin
-- Set the defaults for all the signals this FSM
-- controls:
nextOEn <= '0';
nextDoingWrite1 <= '0';
nextDoingWrite2 <= '0';
regWriteAddr <= '0';
regWriteData <= '0';
regReadAddr <= '0';
canRead <= '1';
canWrite <= '1';
case presState is
when stIdle =>
nextState <= stIdle;
if doWrite = '1' then
nextState <= stWrite1;
regWriteAddr <= '1';
regWriteData <= '1';
nextOEn <= '1';
nextDoingWrite1 <= '1';
nextDoingWrite2 <= '0';
elsif doRead = '1' then
nextState <= stRead1;
regReadAddr <= '1';
end if;
when stWrite1 =>
nextState <= stWrite2;
nextOEn <= '1';
nextDoingWrite1 <= '0';
nextDoingWrite2 <= '1';
canRead <= '0';
canWrite <= '0';
when stWrite2 =>
nextState <= stIdle;
nextOEn <= '0';
nextDoingWrite1 <= '0';
nextDoingWrite2 <= '0';
canRead <= '1';
canWrite <= '1';
if doWrite = '1' then
nextState <= stWrite1;
regWriteAddr <= '1';
regWriteData <= '1';
nextOEn <= '1';
nextDoingWrite1 <= '1';
nextDoingWrite2 <= '0';
elsif doRead = '1' then
nextState <= stRead1;
regReadAddr <= '1';
end if;
when stRead1 =>
nextState <= stIdle;
canWrite <= '1';
canRead <= '1';
if doWrite = '1' then
nextState <= stWrite1;
regWriteAddr <= '1';
regWriteData <= '1';
nextOEn <= '1';
nextDoingWrite1 <= '1';
nextDoingWrite2 <= '0';
elsif doRead = '1' then
nextState <= stRead1;
regReadAddr <= '1';
end if;
-- readAddrReg already contains the read address and
-- is the default connection for the SRAM address bus.
-- Therefore all the user needs to do is register the SRAM
-- data bus at the end of this clock cycle.
end case;
end process;
end sraminterface_arch;
-- ---------------------------------
-- Major features/changes:
-- ---------------------------------
-- (19/02/2001) sram512kleft16bit50mhzreadreq-sv05c created
-- from sv05. This version is identical to sv05, except that
-- it uses only 1 clock cycle for a read instead of 2. (Writes
-- still take 2 clock cyles). In theory, 2 cycles should be
-- required for a read, but under some circumstances it may
-- be possible to get away with only using one cycle for a read.
-- In such a situation, the sram interface in this file could
-- be used.
-- (15/02/2001) sram512kleft16bit50mhzreadreq-sv05 created
-- from sv04. This version works successfully again.
-- It uses a 2 clock cycle write and a 2 clock cycle read.
-- Note we also have tried to improve the logic that
-- handles generating the value for WEn. We have created
-- two signals (doingWrite1 and doingWrite2) as part of
-- this effort to improve timing. They are basically
-- duplicates of some of the bits of presState. The path
-- from presState to the WEn pad was very long, so this
-- duplication of logic is aimed to shorten that path.
-- The .ucf file we are using is:
-- "Y pport, Y debug, Y timing, Y IOB outputs, N input delay, Y fast slew.ucf"
-- (09/02/2001) sram512kleft16bit50mhzreadreq-sv04 created
-- from sv03. An experimental version with *many* cycles
-- for reads and writes.
-- (06/02/2001) We removed the multiplexor on the readData
-- output port as well.
-- (06/02/1001) Address multiplexer placed before
-- address register, instead of having two address registers
-- and a multiplexor placed between them and the SRAM ports.
-- (05/02/2001) sram512kleft16bit50mhzreadreq-sv02 created
-- from sv02. An experimental version.
-- 3 cycle read introduced. Still using a 2 cycle write.
-- (29/01/2001) sram512kleft16bit50mhzreadreq-sv02 created
-- from sv01b. A read now takes two clock cycles.
-- Also, we have reverted to NOT registering the read data
-- internally. Therefore the read data must be registered
-- externally at the end of the 2nd clock cycle of the read
-- process.
-- (24/01/2001) sram512kleft16bit50mhzreadreq-sv01b created
-- from sram512kleft16bit50mhz-sv01b.
-- To perform a read, a read "request" must now be given using
-- the doRead signal, just as a write request is made using the
-- doWrite signal. In this version of the SRAM interface, the
-- read data is also registered internally. Thus the read data
-- no longer needs to be registered externally.
-- (17/01/2001) File created by copying
-- "sram512kleft16bit50mhz-sv01.vhd" and modifying it.
-- The write process was changed to take 2 clock cycles
-- instead of 1, while the read process still takes
-- only 1 clock cycle.
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -