?? sram512k32bit50mhz-sv05.vhd
字號:
-- -------------------------------------------------------------------
-- sram512k32bit50mhz-sv05.vhd
--
-- 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).
-- locations
-- * 32 bit data (each location holds 32 bits).
--
-- Author: James Brennan
-- Date: January 2001
-- -------------------------------------------------------------------
-- ---------------------------------
-- Clock:
-- 50Mhz or slower required.
-- Must have a 50% duty cycle.
-- ---------------------------------
-- The doWrite signal is currently redundant. It is included for
-- possible future changes to the interface.
-- The two signal canRead and canWrite are are high when reads
-- are writes respectively can be performed. Currently, both
-- signals are identical, but in future this may change.
-- Both a write and a read take one clock cycle each. 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').
-- * 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 cycle after this first edge and will be completed at
-- the second rising clock edge after doWrite is asserted.
-- To perform a read:
-- * When no write is being performed, reads are automatically
-- being performed.
-- * Therefore, first wait until canRead is high (indicating that
-- no write is being performed).
-- * Then place the read address on readAddr at the
-- start of a clock cycle. By the end of the same clock cycle
-- the valid data read from SRAM will be on readData. This data
-- should then be registered.
-- * NOTE: The sraminterface does NOT itself register data read from
-- SRAM. Therefore when performing a read, the "host" or "user
-- entity" should itself register readData before changing
-- readAddr
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; -- Currently unused but may be used in future.
doWrite: in STD_LOGIC; -- Set to perform a write.
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 (31 downto 0); -- Data read (user-side).
writeData: in STD_LOGIC_VECTOR (31 downto 0); -- Data to write (user-side).
canRead: out STD_LOGIC; -- Is '1' when a read can be performed.
canWrite: out STD_LOGIC; -- Is '1' when a write can be performed.
CELeftn: out STD_LOGIC; -- CEn signal to left SRAM bank.
CERightn: out STD_LOGIC; -- CEn signal to right SRAM bank.
OELeftn: out STD_LOGIC; -- OEn signal to left SRAM bank.
OERightn: out STD_LOGIC; -- OEn signal to right SRAM bank.
WELeftn: out STD_LOGIC; -- WEn signal to left SRAM bank.
WERightn: out STD_LOGIC; -- WEn signal to right SRAM bank.
SRAMLeftAddr: out STD_LOGIC_VECTOR (18 downto 0); -- Address bus to left SRAM bank.
SRAMRightAddr: out STD_LOGIC_VECTOR (18 downto 0); -- Address bus to right SRAM bank.
SRAMLeftData: inout STD_LOGIC_VECTOR (15 downto 0); -- Data bus to left SRAM bank.
SRAMRightData: inout STD_LOGIC_VECTOR (15 downto 0) -- Data bus to right SRAM bank.
);
end sraminterface;
architecture sraminterface_arch of sraminterface is
-- ========================================
-- Architechture declarations:
-- ========================================
-- Constants:
-- Constants for addrSelect signal:
constant CONST_USE_READ_ADDR : STD_LOGIC := '0';
constant CONST_USE_WRITE_ADDR : STD_LOGIC := '1';
-- Constants for 3-state buffers:
constant CONST_ENABLED : STD_LOGIC := '1';
constant CONST_DISABLED : STD_LOGIC := '0';
-- Signals for registers:
signal writeAddrReg : STD_LOGIC_VECTOR(18 downto 0);
signal writeDataReg : STD_LOGIC_VECTOR(31 downto 0);
-- Clock-enable controls for the registers:
signal regWriteAddr : STD_LOGIC;
signal regWriteData : STD_LOGIC;
-- Control signals common to both left and right banks of SRAM:
signal CEn : STD_LOGIC;
signal OEn : STD_LOGIC;
signal WEn : STD_LOGIC;
-- Common address bus for both SRAM banks
signal SRAMAddr : STD_LOGIC_VECTOR(18 downto 0);
-- 32-bit data bus:
-- The low 16-bits of data will go to the right SRAM bank.
-- The high 16-bits of data will go to the left SRAM bank.
signal SRAMData : STD_LOGIC_VECTOR(31 downto 0);
-- Other control signals for the data path:
signal addrSelect : STD_LOGIC;
signal readDataSelect : STD_LOGIC;
-- Declarations required for the controller FSM.
type STATE_TYPE is (stIdle, stWrite1);
signal presState, nextState: STATE_TYPE;
begin
-- ========================================
-- Architecture body:
-- ========================================
-- ========================================
-- Combinational signals
-- ========================================
-- Control signals:
CELeftn <= CEn;
CERightn <= CEn;
OELeftn <= OEn;
OERightn <= OEn;
WELeftn <= WEn;
WERightn <= WEn;
-- SRAM address buses:
SRAMLeftAddr <= SRAMAddr;
SRAMRightAddr <= SRAMAddr;
-- SRAM data buses:
-- The low 16-bits of data will go to the right SRAM bank.
-- The high 16-bits of data will go to the left SRAM bank.
SRAMRightData <= SRAMData(15 downto 0);
SRAMLeftData <= SRAMData(31 downto 16);
-- ========================================
-- Implementation of specific structures
-- ========================================
-- Multiplex the address bus:
with addrSelect select
SRAMAddr <= readAddr when CONST_USE_READ_ADDR,
writeAddrReg when others;
-- 3-state buffer placed after the writeDataReg register
-- in the data path:
process(writeDataReg, presState, CLK)
begin
-- We drive the SRAM data I/O bus with data to be written
-- ONLY when:
-- * presState = stWrite1 (i.e. we are in the write
-- cycle)
-- and * CLK = '0' (i.e. we are in the 2nd half of the
-- 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 (presState = stWrite1 and CLK = '0') 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(presState, CLK)
begin
if (presState = stWrite1 and CLK = '0') then
WEn <= '0';
else
WEn <= '1';
end if;
end process;
-- Multiplexor between the SRAM data I/O lines and the
-- readData data bus to the host.
-- When we are NOT writing to SRAM we directly pass the
-- value on the SRAM data I/O lines out to the readData
-- bus. When we are writing to SRAM we set readData to
-- all zeros.
-- Note that we are not registering the data read from SRAM.
-- It is up to the host that we are connecting to to do this.
process(SRAMData, readDataSelect)
begin
if readDataSelect = CONST_ENABLED then
readData <= SRAMData;
else
readData <= (others => '0');
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';
writeAddrReg <= (others => '0');
writeDataReg <= (others => '0');
elsif CLK'EVENT and CLK = '1' then
CEn <= '0';
-- Handle the clock-enabling of each register:
if regWriteAddr = '1' then
writeAddrReg <= writeAddr;
end if;
if regWriteData = '1' then
writeDataReg <= writeData;
end if;
-- 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:
OEn <= '0';
readDataSelect <= CONST_ENABLED;
-- We always pass the read address through to the SRAM
-- unless we are doing a write.
addrSelect <= CONST_USE_READ_ADDR;
regWriteAddr <= '0';
regWriteData <= '0';
canRead <= '1';
canWrite <= '1';
case presState is
when stIdle =>
nextState <= stIdle;
if doWrite = '1' then
nextState <= stWrite1;
regWriteAddr <= '1';
regWriteData <= '1';
end if;
when stWrite1 =>
nextState <= stIdle;
if doWrite = '1' then
nextState <= stWrite1;
regWriteAddr <= '1';
regWriteData <= '1';
end if;
OEn <= '1';
readDataSelect <= CONST_DISABLED;
addrSelect <= CONST_USE_WRITE_ADDR;
canRead <= '0';
canWrite <= '0';
end case;
end process;
end sraminterface_arch;
-- ---------------------------------
-- Major features/changes:
-- ---------------------------------
-- (08/01/2001) The second clock cycle used in
-- performing a write was redundant and has now been
-- removed. Therefore both a read and a write now
-- take only one clock cycle.
-- (08/01/2001) Write data and WEn are only asserted
-- for half a clock cycle (10ns at 50Mhz).
-- (08/01/2001) Write data only asserted while
-- WEn is asserted.
-- (08/01/2001) Timings from 05/01/2001 have now been
-- changed and improved upon.
-- (05/01/2001) THIS SET OF TIMINGS WORKS!
-- To see them clearly, its easiest to simulate.
-- A write currently takes two clock cycles. There
-- is a small chance that we could squeeze it down
-- to one clock cycle. (A read still takes one
-- clock cycle as always).
-- (05/01/2001) While we're writing, as well as
-- lowering WEn we also raise OEn.
-- (05/01/2001) Tried to make read and write cycles
-- as small as possible while still ensuring that
-- there are no read or write errors.
-- We've gone back to automatically doing
-- reads if we're not writing and performing
-- writes in a single clock cycle. (When writing
-- we only drive the SRAM's data lines on the 2nd
-- half of the clock cycle).
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -