OpenCores
URL https://opencores.org/ocsvn/w11/w11/trunk

Subversion Repositories w11

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /w11/tags/w11a_V0.74/rtl/bplib/nxcramlib
    from Rev 37 to Rev 38
    Reverse comparison

Rev 37 → Rev 38

/Makefile
0,0 → 1,37
# $Id: Makefile 761 2016-04-17 08:53:48Z mueller $
#
# Revision History:
# Date Rev Version Comment
# 2016-04-15 761 1.0 Initial version
#
VBOM_all = $(wildcard *.vbom)
DCP_all = $(VBOM_all:.vbom=_syn.dcp)
#
# reference board for test synthesis is Artix-7 based Nexys4
ifndef XTW_BOARD
XTW_BOARD=nexys4
endif
include ${RETROBASE}/rtl/make_viv/viv_default_$(XTW_BOARD).mk
#
.PHONY : catch all
#
catch :
@echo "no default target defined, use"
@echo " make all"
@echo " make <module>_syn.dcp"
@exit 1
#
all : $(DCP_all)
#
clean : viv_clean
#
#-----
#
include ${RETROBASE}/rtl/make_viv/generic_vivado.mk
#
VBOM_all = $(wildcard *.vbom)
#
ifndef DONTINCDEP
include $(VBOM_all:.vbom=.dep_vsyn)
endif
#
/nx_cram_memctl_as.vhd
0,0 → 1,673
-- $Id: nx_cram_memctl_as.vhd 789 2016-07-17 08:26:55Z mueller $
--
-- Copyright 2010-2016 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
-- This program is free software; you may redistribute and/or modify it under
-- the terms of the GNU General Public License as published by the Free
-- Software Foundation, either version 2, or at your option any later version.
--
-- This program is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-- for complete details.
--
------------------------------------------------------------------------------
-- Module Name: nx_cram_memctl_as - syn
-- Description: nexys2/3/4: CRAM driver - async and page mode
--
-- Dependencies: vlib/xlib/iob_reg_o
-- vlib/xlib/iob_reg_o_gen
-- vlib/xlib/iob_reg_io_gen
-- Test bench: tb/tb_nx_cram_memctl_as
-- sys_gen/tst_sram/nexys2/tb/tb_tst_sram_n2
-- sys_gen/tst_sram/nexys3/tb/tb_tst_sram_n3
-- sys_gen/tst_sram/nexys4/tb/tb_tst_sram_n4
-- Target Devices: generic
-- Tool versions: ise 11.4-14.7; viv 2014.4-2016.2; ghdl 0.26-0.33
--
-- Synthesized:
-- Date Rev viv Target flop lutl lutm bram slic
-- 2016-07-03 783 2016.3 xc7a100t-1 91 87 0 0 43
--
-- Synthesized (xst):
-- Date Rev ise Target flop lutl lutm slic t peri
-- Date Rev ise Target flop lutl lutm slic t peri
-- 2016-07-03 767 14.7 131013 xc6slx16-2 100 134 0 60 s 4.2
-- 2010-06-03 299 11.4 L68 xc3s1200e-4 91 100 0 96 s 6.7
-- 2010-05-24 294 11.4 L68 xc3s1200e-4 91 99 0 95 s 6.7
-- 2010-05-23 293 11.4 L68 xc3s1200e-4 91 139 0 99 s 6.7
--
-- Revision History:
-- Date Rev Version Comment
-- 2016-07-16 788 2.1 change *DELAY generics, now absolute delay cycles
-- add s_init1; drop "KEEP" for data (better for dbg)
-- 2016-07-10 786 2.0 add page mode support
-- 2016-05-22 767 1.2.2 don't init N_REGS (vivado fix for fsm inference)
-- 2015-12-26 718 1.2.1 BUGFIX: do_dispatch(): always define imem_oe
-- 2011-11-26 433 1.2 renamed from n2_cram_memctl_as
-- 2011-11-19 432 1.1 remove O_FLA_CE_N port
-- 2011-11-19 427 1.0.5 now numeric_std clean
-- 2010-11-22 339 1.0.4 cntdly now 3 bit; add assert for DELAY generics
-- 2010-06-03 299 1.0.3 add "KEEP" for data iob; MEM_OE='1' on first read
-- cycle;
-- 2010-05-30 297 1.0.2 use READ(0|1)DELAY generic
-- 2010-05-24 294 1.0.1 more compact n.memdi logic; extra wait in s_rdwait1
-- 2010-05-23 293 1.0 Initial version
--
-- Notes:
-- 1. There is no 'bus-turn-around' cycle needed for a write->read change
-- FPGA_OE goes 1->0 and MEM_OE goes 0->1 on the s_wrput1->s_rdinit
-- transition simultaneously. The FPGA will go high-Z quickly, the memory
-- low-Z delay by the IOB and internal memory delays. No clash.
-- 2. There is a hidden 'bus-turn-around' cycle for a read->write change.
-- MEM_OE goes 1->0 on s_rdget1->s_wrinit and the memory will go high-z with
-- some delay. FPGA_OE goes 0->1 in the next cycle at s_wrinit->s_wrwait0.
-- Again no clash due to the 1 cycle delay.
--
-- Nominal timings:
-- READ0 = (T_aa + ext_read_delay) in cycles
-- READ1 = (T_pa + ext_read_delay) in cycles
-- WRITE = (T_aa + ext_write_delay) in cycles
-- with
-- ext_read_delay: output_IOB + 2*PCB_delay + input_IOB + skew
-- ext_write_delay: skew
--
--
-- Timing of some signals:
--
-- single read request:
--
-- state |_idle |_rdinit|_rdwt0 |_rdwt0 |_rdget0|_rdwt1 |_rdget1|
-- 0 20 40 60 80 100 120
-- CLK __|^^^|___|^^^|___|^^^|___|^^^|___|^^^|___|^^^|___|^^^|___|^^^|___|
--
-- REQ _______|^^^^^|_____________________________________________
-- WE ___________________________________________________________
--
-- IOB_CE __________|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|_
-- IOB_OE _________|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|_
--
-- DO oooooooooooooooooooooooooooooooooooooooooo|lllllll|lllllll|h
-- BUSY __________|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|________________
-- ACK_R ___________________________________________________________|^^^^^^^|_
--
-- single write request:
--
-- state |_idle |_wrinit|_wrwt0 |_wrwt0 |_wrwt0 |_wrput0|_idle |
-- 0 20 40 60 80 100 120
-- CLK __|^^^|___|^^^|___|^^^|___|^^^|___|^^^|___|^^^|___|^^^|___|^^^|___|
--
-- REQ _______|^^^^^|______________________________________
-- WE _______|^^^^^|______________________________________
--
-- IOB_CE __________|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|_
-- IOB_BE __________|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|_
-- IOB_OE ____________________________________________________
-- IOB_WE ______________|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|_____
--
-- BUSY __________|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|_________
-- ACK_W __________________________________________|^^^^^^^|_
--
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
use work.slvtypes.all;
use work.xlib.all;
 
entity nx_cram_memctl_as is -- CRAM driver (async+page mode)
generic (
READ0DELAY : positive := 4; -- read word 0 delay in clock cycles
READ1DELAY : positive := 2; -- read word 1 delay in clock cycles
WRITEDELAY : positive := 4); -- write delay in clock cycles
port (
CLK : in slbit; -- clock
RESET : in slbit; -- reset
REQ : in slbit; -- request
WE : in slbit; -- write enable
BUSY : out slbit; -- controller busy
ACK_R : out slbit; -- acknowledge read
ACK_W : out slbit; -- acknowledge write
ACT_R : out slbit; -- signal active read
ACT_W : out slbit; -- signal active write
ADDR : in slv22; -- address (32 bit word address)
BE : in slv4; -- byte enable
DI : in slv32; -- data in (memory view)
DO : out slv32; -- data out (memory view)
O_MEM_CE_N : out slbit; -- cram: chip enable (act.low)
O_MEM_BE_N : out slv2; -- cram: byte enables (act.low)
O_MEM_WE_N : out slbit; -- cram: write enable (act.low)
O_MEM_OE_N : out slbit; -- cram: output enable (act.low)
O_MEM_ADV_N : out slbit; -- cram: address valid (act.low)
O_MEM_CLK : out slbit; -- cram: clock
O_MEM_CRE : out slbit; -- cram: command register enable
I_MEM_WAIT : in slbit; -- cram: mem wait
O_MEM_ADDR : out slv23; -- cram: address lines
IO_MEM_DATA : inout slv16 -- cram: data lines
);
end nx_cram_memctl_as;
 
 
architecture syn of nx_cram_memctl_as is
 
type state_type is (
s_init, -- s_init: startup state
s_init1, -- s_init1: reset released
s_wcinit, -- s_wcinit: write rcr init
s_wcwait, -- s_wcwait: write rcr wait
s_wcput, -- s_wcput: write rcr done
s_rainit, -- s_rainit: read array init
s_rawait, -- s_rawait: wait read array
s_idle, -- s_idle: wait for req
s_rdinit, -- s_rdinit: read init cycle
s_rdwait0, -- s_rdwait0: read wait low word
s_rdget0, -- s_rdget0: read get low word
s_rdwait1, -- s_rdwait1: read wait high word
s_rdget1, -- s_rdget1: read get high word
s_wrinit, -- s_wrinit: write init cycle
s_wrwait0, -- s_rdwait0: write wait 1st word
s_wrput0, -- s_rdput0: write put 1st word
s_wrini1, -- s_wrini1: write init 2nd word
s_wrwait1, -- s_wrwait1: write wait 2nd word
s_wrput1 -- s_wrput1: write put 2nd word
);
type regs_type is record
state : state_type; -- state
ackr : slbit; -- signal ack_r
addr0 : slbit; -- current addr0
be2nd : slv2; -- be's of 2nd write cycle
cntdly : slv3; -- wait delay counter
cntce : slv7; -- ce counter
fidle : slbit; -- force idle flag
memdo0 : slv16; -- mem data out, low word
memdi : slv32; -- mem data in
end record regs_type;
 
constant regs_init : regs_type := (
s_init, -- state
'0', -- ackr
'0', -- addr0
"00", -- be2nd
(others=>'0'), -- cntdly
(others=>'0'), -- cntce
'0', -- fidle
(others=>'0'), -- memdo0
(others=>'0') -- memdi
);
 
constant c_addrh_rcr_setup : slv22 :=
"000" & -- 22:20 reserved MBZ
"00" & -- 19:18 reg sel 00=RCR
"0000000000" & -- 17: 8 reserved MBZ
'1' & -- 7 page mode enable (1=enable)
"00" & -- 6: 5 reserved MBZ
'1' & -- 4 dpd disaable (1=disable)
"000"; -- 3: 1 rest is reserved or PAR, which should be 0
 
signal R_REGS : regs_type := regs_init;
signal N_REGS : regs_type; -- don't init (vivado fix for fsm infer)
signal CLK_180 : slbit := '0';
signal MEM_CE_N : slbit := '1';
signal MEM_BE_N : slv2 := "11";
signal MEM_WE_N : slbit := '1';
signal MEM_OE_N : slbit := '1';
signal MEM_CRE : slbit := '0';
signal BE_CE : slbit := '0';
signal ADDRH_CE : slbit := '0';
signal ADDR0_CE : slbit := '0';
signal ADDRH : slv22 := (others=>'0');
signal ADDR0 : slbit := '0';
signal DATA_CEI : slbit := '0';
signal DATA_CEO : slbit := '0';
signal DATA_OE : slbit := '0';
signal MEM_DO : slv16 := (others=>'0');
signal MEM_DI : slv16 := (others=>'0');
 
begin
 
-- Notes:
-- used READ0DELAY-2 and READ0DELAY-3
-- used READ1DELAY-2
-- used WRITEDELAY-2
assert READ0DELAY-2 < 2**R_REGS.cntdly'length and
READ1DELAY-2 < 2**R_REGS.cntdly'length and
WRITEDELAY-2 < 2**R_REGS.cntdly'length
report "assert( (READ0,READ1,WRITE)DELAY-2 < 2**cntdly'length)"
severity failure;
assert READ0DELAY >= 3 and
READ1DELAY >= 2 and
WRITEDELAY >= 2
report "assert( (READ0,READ1,WRITE)DELAY-2 >= 2 or 3)"
severity failure;
 
CLK_180 <= not CLK;
IOB_MEM_CE : iob_reg_o
generic map (
INIT => '1')
port map (
CLK => CLK,
CE => '1',
DO => MEM_CE_N,
PAD => O_MEM_CE_N
);
IOB_MEM_BE : iob_reg_o_gen
generic map (
DWIDTH => 2,
INIT => '1')
port map (
CLK => CLK,
CE => BE_CE,
DO => MEM_BE_N,
PAD => O_MEM_BE_N
);
IOB_MEM_WE : iob_reg_o
generic map (
INIT => '1')
port map (
CLK => CLK_180,
CE => '1',
DO => MEM_WE_N,
PAD => O_MEM_WE_N
);
IOB_MEM_OE : iob_reg_o
generic map (
INIT => '1')
port map (
CLK => CLK,
CE => '1',
DO => MEM_OE_N,
PAD => O_MEM_OE_N
);
IOB_MEM_CRE : iob_reg_o
generic map (
INIT => '0')
port map (
CLK => CLK,
CE => '1',
DO => MEM_CRE,
PAD => O_MEM_CRE
);
IOB_MEM_ADDRH : iob_reg_o_gen
generic map (
DWIDTH => 22)
port map (
CLK => CLK,
CE => ADDRH_CE,
DO => ADDRH,
PAD => O_MEM_ADDR(22 downto 1)
);
IOB_MEM_ADDR0 : iob_reg_o
port map (
CLK => CLK,
CE => ADDR0_CE,
DO => ADDR0,
PAD => O_MEM_ADDR(0)
);
IOB_MEM_DATA : iob_reg_io_gen
generic map (
DWIDTH => 16,
PULL => "NONE")
port map (
CLK => CLK,
CEI => DATA_CEI,
CEO => DATA_CEO,
OE => DATA_OE,
DI => MEM_DO,
DO => MEM_DI,
PAD => IO_MEM_DATA
);
 
O_MEM_ADV_N <= '0';
O_MEM_CLK <= '0';
 
proc_regs: process (CLK)
begin
 
if rising_edge(CLK) then
if RESET = '1' then
R_REGS <= regs_init;
else
R_REGS <= N_REGS;
end if;
end if;
 
end process proc_regs;
 
proc_next: process (R_REGS, REQ, WE, BE, DI, ADDR, MEM_DO)
 
variable r : regs_type := regs_init;
variable n : regs_type := regs_init;
variable ibusy : slbit := '0';
variable iackw : slbit := '0';
variable iactr : slbit := '0';
variable iactw : slbit := '0';
variable imem_ce : slbit := '0';
variable imem_be : slv2 := "00";
variable imem_we : slbit := '0';
variable imem_oe : slbit := '0';
variable imem_cre : slbit := '0';
variable ibe_ce : slbit := '0';
variable iaddrh_ce : slbit := '0';
variable iaddr0_ce : slbit := '0';
variable iaddrh : slv22 := (others=>'0');
variable iaddr0 : slbit := '0';
variable idata_cei : slbit := '0';
variable idata_ceo : slbit := '0';
variable idata_oe : slbit := '0';
procedure do_dispatch(nstate : out state_type;
iaddrh_ce : out slbit;
iaddr0_ce : out slbit;
iaddr0 : out slbit;
ibe_ce : out slbit;
imem_be : out slv2;
imem_ce : out slbit;
imem_oe : out slbit;
nbe2nd : out slv2) is
begin
iaddrh_ce := '1'; -- latch address (high part)
iaddr0_ce := '1'; -- latch address 0 bit
ibe_ce := '1'; -- latch be's
imem_ce := '1'; -- ce CRAM next cycle
nbe2nd := "00"; -- assume no 2nd write cycle
if WE = '0' then -- if READ requested
iaddr0 := '0'; -- go first for low word
imem_be := "11"; -- on read always on
imem_oe := '1'; -- oe CRAM next cycle
nstate := s_rdinit; -- next: read init part
else -- if WRITE requested
if BE(1 downto 0) /= "00" then -- low word write
iaddr0 := '0'; -- access word 0
imem_be := BE(1 downto 0); -- set be's for 1st cycle
nbe2nd := BE(3 downto 2); -- keep be's for 2nd cycle
else -- high word write
iaddr0 := '1'; -- access word 1
imem_be := BE(3 downto 2); -- set be's for 1st cycle
end if;
imem_oe := '0'; -- oe=0
nstate := s_wrinit; -- next: write init part
end if;
end procedure do_dispatch;
 
begin
 
r := R_REGS;
n := R_REGS;
n.ackr := '0';
 
ibusy := '0';
iackw := '0';
iactr := '0';
iactw := '0';
 
imem_ce := '0';
imem_be := "11";
imem_we := '0';
imem_oe := '0';
imem_cre := '0';
ibe_ce := '0';
iaddrh_ce := '0';
iaddr0_ce := '0';
iaddrh := ADDR;
iaddr0 := '0';
idata_cei := '0';
idata_ceo := '0';
idata_oe := '0';
 
if unsigned(r.cntdly) /= 0 then
n.cntdly := slv(unsigned(r.cntdly) - 1);
end if;
 
case r.state is
when s_init => -- s_init: startup state
ibusy := '1'; -- signal busy, unable to handle req
n.state := s_init1;
 
when s_init1 => -- s_init1: reset released
ibusy := '1'; -- signal busy, unable to handle req
iaddrh := c_addrh_rcr_setup;
iaddr0 := '0';
iaddrh_ce := '1';
iaddr0_ce := '1';
imem_ce := '1'; -- ce CRAM next cycle
imem_cre := '1'; -- cre CRAM next cycle
n.state := s_wcinit;
 
when s_wcinit => -- s_wcinit: write rcr init
ibusy := '1'; -- signal busy, unable to handle req
imem_ce := '1'; -- ce CRAM next cycle
imem_cre := '1'; -- cre CRAM next cycle
imem_we := '1'; -- we CRAM next cycle
n.cntdly := slv(to_unsigned(WRITEDELAY-2, n.cntdly'length));
n.state := s_wcwait;
 
when s_wcwait => -- s_wcinit: write rcr wait
ibusy := '1'; -- signal busy, unable to handle req
imem_ce := '1'; -- ce CRAM next cycle
imem_we := '1'; -- we CRAM next cycle
imem_cre := '1'; -- cre CRAM next cycle
if unsigned(r.cntdly) = 0 then -- wait expired ?
n.state := s_wcput; -- next: write rcr done
end if;
 
when s_wcput => -- s_wcput: write rcr done
ibusy := '1'; -- signal busy, unable to handle req
n.state := s_rainit; -- next: read array init
 
when s_rainit => -- s_rainit: read array init
ibusy := '1'; -- signal busy, unable to handle req
imem_ce := '1'; -- ce CRAM next cycle
n.cntdly:= slv(to_unsigned(READ0DELAY-2, n.cntdly'length));
n.state := s_rawait ; -- next: wait read array
 
when s_rawait => -- s_rawait: wait read array
ibusy := '1'; -- signal busy, unable to handle req
imem_ce := '1'; -- ce CRAM next cycle
if unsigned(r.cntdly) = 0 then -- wait expired ?
n.state := s_idle; -- next: wait for req
end if;
 
when s_idle => -- s_idle: wait for req
if REQ = '1' then -- if IO requested
do_dispatch(n.state, iaddrh_ce, iaddr0_ce, iaddr0,
ibe_ce, imem_be, imem_ce, imem_oe, n.be2nd);
end if;
when s_rdinit => -- s_rdinit: read init cycle
ibusy := '1'; -- signal busy, unable to handle req
iactr := '1'; -- signal mem read
imem_ce := '1'; -- ce CRAM next cycle
imem_oe := '1'; -- oe CRAM next cycle
n.cntdly:= slv(to_unsigned(READ0DELAY-3, n.cntdly'length));
n.state := s_rdwait0; -- next: wait low word
 
when s_rdwait0 => -- s_rdwait0: read wait low word
ibusy := '1'; -- signal busy, unable to handle req
iactr := '1'; -- signal mem read
imem_ce := '1'; -- ce CRAM next cycle
imem_oe := '1'; -- oe CRAM next cycle
if unsigned(r.cntdly) = 0 then -- wait expired ?
n.state := s_rdget0; -- next: get low word
end if;
 
when s_rdget0 => -- s_rdget0: read get low word
ibusy := '1'; -- signal busy, unable to handle req
iactr := '1'; -- signal mem read
imem_ce := '1'; -- ce CRAM next cycle
imem_oe := '1'; -- oe CRAM next cycle
idata_cei := '1'; -- latch input data
iaddr0_ce := '1'; -- latch address 0 bit
iaddr0 := '1'; -- now go for high word
n.cntdly:= slv(to_unsigned(READ1DELAY-2, n.cntdly'length));
n.state := s_rdwait1; -- next: wait high word
 
when s_rdwait1 => -- s_rdwait1: read wait high word
ibusy := '1'; -- signal busy, unable to handle req
iactr := '1'; -- signal mem read
imem_ce := '1'; -- ce CRAM next cycle
imem_oe := '1'; -- oe CRAM next cycle
if unsigned(r.cntdly) = 0 then -- wait expired ?
n.state := s_rdget1; -- next: get high word
end if; --
 
when s_rdget1 => -- s_rdget1: read get high word
iactr := '1'; -- signal mem read
n.memdo0:= MEM_DO; -- save low word data
idata_cei := '1'; -- latch input data
n.ackr := '1'; -- ACK_R next cycle
n.state := s_idle; -- next: wait next request
if r.fidle = '1' then -- forced idle cycle
ibusy := '1'; -- signal busy, unable to handle req
else
if REQ = '1' then -- if IO requested
do_dispatch(n.state, iaddrh_ce, iaddr0_ce, iaddr0,
ibe_ce, imem_be, imem_ce, imem_oe, n.be2nd);
end if;
end if;
 
when s_wrinit => -- s_wrinit: write init cycle
ibusy := '1'; -- signal busy, unable to handle req
iactw := '1'; -- signal mem write
iackw := '1'; -- signal write done (all latched)
idata_ceo:= '1'; -- latch output data
idata_oe := '1'; -- oe FPGA next cycle
imem_ce := '1'; -- ce CRAM next cycle
imem_we := '1'; -- we CRAM in half cycle
n.cntdly:= slv(to_unsigned(WRITEDELAY-2, n.cntdly'length));
n.state := s_wrwait0; -- next: wait
 
when s_wrwait0 => -- s_rdput0: write wait 1st word
ibusy := '1'; -- signal busy, unable to handle req
iactw := '1'; -- signal mem write
idata_oe := '1'; -- oe FPGA next cycle
imem_ce := '1'; -- ce CRAM next cycle
imem_we := '1'; -- we CRAM next cycle
if unsigned(r.cntdly) = 0 then -- wait expired ?
n.state := s_wrput0; -- next: put 1st word
end if;
 
when s_wrput0 => -- s_rdput0: write put 1st word
iactw := '1'; -- signal mem write
imem_we := '0'; -- deassert we CRAM in half cycle
if r.be2nd /= "00" then
ibusy := '1'; -- signal busy, unable to handle req
imem_ce := '1'; -- ce CRAM next cycle
iaddr0_ce := '1'; -- latch address 0 bit
iaddr0 := '1'; -- now go for high word
ibe_ce := '1'; -- latch be's
imem_be := r.be2nd; -- now be's of high word
n.state := s_wrini1; -- next: start 2nd write
else
n.state := s_idle; -- next: wait next request
if r.fidle = '1' then -- forced idle cycle
ibusy := '1'; -- signal busy
else
if REQ = '1' then -- if IO requested
do_dispatch(n.state, iaddrh_ce, iaddr0_ce, iaddr0,
ibe_ce, imem_be, imem_ce, imem_oe, n.be2nd);
end if;
end if;
end if;
 
when s_wrini1 => -- s_wrini1: write init 2nd word
ibusy := '1'; -- signal busy, unable to handle req
iactw := '1'; -- signal mem write
idata_ceo:= '1'; -- latch output data
idata_oe := '1'; -- oe FPGA next cycle
imem_ce := '1'; -- ce CRAM next cycle
imem_we := '1'; -- we CRAM in half cycle
n.cntdly:= slv(to_unsigned(WRITEDELAY-2, n.cntdly'length));
n.state := s_wrwait1; -- next: wait
 
when s_wrwait1 => -- s_wrwait1: write wait 2nd word
ibusy := '1'; -- signal busy, unable to handle req
iactw := '1'; -- signal mem write
idata_oe := '1'; -- oe FPGA next cycle
imem_ce := '1'; -- ce CRAM next cycle
imem_we := '1'; -- we CRAM next cycle
if unsigned(r.cntdly) = 0 then -- wait expired ?
n.state := s_wrput1; -- next: put 2nd word
end if;
 
when s_wrput1 => -- s_wrput1: write put 2nd word
iactw := '1'; -- signal mem write
imem_we := '0'; -- deassert we CRAM in half cycle
n.state := s_idle; -- next: wait next request
if r.fidle = '1' then -- forced idle cycle
ibusy := '1'; -- signal busy, unable to handle req
else
if REQ = '1' then -- if IO requested
do_dispatch(n.state, iaddrh_ce, iaddr0_ce, iaddr0,
ibe_ce, imem_be, imem_ce, imem_oe, n.be2nd);
end if;
end if;
when others => null;
end case;
 
if imem_ce = '0' then -- if cmem not active
n.cntce := (others=>'0'); -- clear counter
n.fidle := '0'; -- clear force idle flag
else -- if cmem active
if unsigned(r.cntce) >= 127 then -- if max ce count expired
n.fidle := '1'; -- set forced idle flag
else -- if max ce count not yet reached
n.cntce := slv(unsigned(r.cntce) + 1); -- increment counter
end if;
end if;
if iaddrh_ce = '1' then -- if addresses are latched
n.memdi := DI; -- latch data too...
end if;
if iaddr0_ce = '1' then -- if address bit 0 changed
n.addr0 := iaddr0; -- mirror it in state regs
end if;
N_REGS <= n;
 
MEM_CE_N <= not imem_ce;
MEM_WE_N <= not imem_we;
MEM_BE_N <= not imem_be;
MEM_OE_N <= not imem_oe;
MEM_CRE <= imem_cre;
 
if r.addr0 = '0' then
MEM_DI <= r.memdi(15 downto 0);
else
MEM_DI <= r.memdi(31 downto 16);
end if;
 
BE_CE <= ibe_ce;
ADDRH_CE <= iaddrh_ce;
ADDR0_CE <= iaddr0_ce;
ADDRH <= iaddrh;
ADDR0 <= iaddr0;
DATA_CEI <= idata_cei;
DATA_CEO <= idata_ceo;
DATA_OE <= idata_oe;
 
BUSY <= ibusy;
ACK_R <= r.ackr;
ACK_W <= iackw;
ACT_R <= iactr;
ACT_W <= iactw;
DO <= MEM_DO & r.memdo0;
end process proc_next;
end syn;
/nxcramlib.vhd
0,0 → 1,131
-- $Id: nxcramlib.vhd 788 2016-07-16 22:23:23Z mueller $
--
-- Copyright 2011-2016 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
-- This program is free software; you may redistribute and/or modify it under
-- the terms of the GNU General Public License as published by the Free
-- Software Foundation, either version 2, or at your option any later version.
--
-- This program is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-- for complete details.
--
------------------------------------------------------------------------------
-- Package Name: nxcramlib
-- Description: Nexys 2/3 CRAM drivers
--
-- Dependencies: -
-- Tool versions: ise 11.4-14.7; viv 2014.4-2016.2; ghdl 0.26-0.33
--
-- Revision History:
-- Date Rev Version Comment
-- 2016-07-16 788 1.1 add cram_(read0|read1|write)delay functions
-- 2011-11-26 433 1.0 Initial version (extracted from nexys2lib)
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
 
use work.slvtypes.all;
 
package nxcramlib is
pure function cram_delay(clk_mhz : positive;
delay_ps : positive) return positive;
pure function cram_read0delay(clk_mhz : positive) return positive;
pure function cram_read1delay(clk_mhz : positive) return positive;
pure function cram_writedelay(clk_mhz : positive) return positive;
 
constant cram_read0delay_ps : positive := 80000; -- initial read delay
constant cram_read1delay_ps : positive := 30000; -- page read delay
constant cram_writedelay_ps : positive := 75000; -- write delay
 
component nx_cram_dummy is -- CRAM protection dummy
port (
O_MEM_CE_N : out slbit; -- cram: chip enable (act.low)
O_MEM_BE_N : out slv2; -- cram: byte enables (act.low)
O_MEM_WE_N : out slbit; -- cram: write enable (act.low)
O_MEM_OE_N : out slbit; -- cram: output enable (act.low)
O_MEM_ADV_N : out slbit; -- cram: address valid (act.low)
O_MEM_CLK : out slbit; -- cram: clock
O_MEM_CRE : out slbit; -- cram: command register enable
I_MEM_WAIT : in slbit; -- cram: mem wait
O_MEM_ADDR : out slv23; -- cram: address lines
IO_MEM_DATA : inout slv16 -- cram: data lines
);
end component;
 
component nx_cram_memctl_as is -- CRAM driver (async+page mode)
generic (
READ0DELAY : positive := 4; -- read word 0 delay in clock cycles
READ1DELAY : positive := 2; -- read word 1 delay in clock cycles
WRITEDELAY : positive := 4); -- write delay in clock cycles
port (
CLK : in slbit; -- clock
RESET : in slbit; -- reset
REQ : in slbit; -- request
WE : in slbit; -- write enable
BUSY : out slbit; -- controller busy
ACK_R : out slbit; -- acknowledge read
ACK_W : out slbit; -- acknowledge write
ACT_R : out slbit; -- signal active read
ACT_W : out slbit; -- signal active write
ADDR : in slv22; -- address (32 bit word address)
BE : in slv4; -- byte enable
DI : in slv32; -- data in (memory view)
DO : out slv32; -- data out (memory view)
O_MEM_CE_N : out slbit; -- cram: chip enable (act.low)
O_MEM_BE_N : out slv2; -- cram: byte enables (act.low)
O_MEM_WE_N : out slbit; -- cram: write enable (act.low)
O_MEM_OE_N : out slbit; -- cram: output enable (act.low)
O_MEM_ADV_N : out slbit; -- cram: address valid (act.low)
O_MEM_CLK : out slbit; -- cram: clock
O_MEM_CRE : out slbit; -- cram: command register enable
I_MEM_WAIT : in slbit; -- cram: mem wait
O_MEM_ADDR : out slv23; -- cram: address lines
IO_MEM_DATA : inout slv16 -- cram: data lines
);
end component;
 
end package nxcramlib;
 
-- ----------------------------------------------------------------------------
package body nxcramlib is
 
-- -------------------------------------
pure function cram_delay( -- calculate delay in clock cycles
clk_mhz : positive; -- clock frequency in MHz
delay_ps : positive) -- delay in ps
return positive is
variable period_ps : natural := 0; -- clk period in ps
begin
period_ps := 1000000 / clk_mhz;
return (delay_ps + period_ps - 10) / period_ps;
end function cram_delay;
 
-- -------------------------------------
pure function cram_read0delay( -- read0 delay in clock cycles
clk_mhz : positive) -- clock frequency in MHz
return positive is
begin
return cram_delay(clk_mhz, cram_read0delay_ps);
end function cram_read0delay;
 
-- -------------------------------------
pure function cram_read1delay( -- read1 delay in clock cycles
clk_mhz : positive) -- clock frequency in MHz
return positive is
begin
return cram_delay(clk_mhz, cram_read1delay_ps);
end function cram_read1delay;
 
-- -------------------------------------
pure function cram_writedelay( -- write delay in clock cycles
clk_mhz : positive) -- clock frequency in MHz
return positive is
begin
return cram_delay(clk_mhz, cram_writedelay_ps);
end function cram_writedelay;
 
end package body nxcramlib;
/tb/.cvsignore
0,0 → 1,3
tb_nx_cram_memctl_as
tb_nx_cram_memctl_stim
list_cram_delay
/tb/Makefile
0,0 → 1,42
# $Id: Makefile 788 2016-07-16 22:23:23Z mueller $
#
# Revision History:
# Date Rev Version Comment
# 2016-04-17 761 1.0 Initial version
#
EXE_all = tb_nx_cram_memctl_as
#
# reference board for test synthesis is Artix-7 based Nexys4
ifndef XTW_BOARD
XTW_BOARD=nexys4
endif
include ${RETROBASE}/rtl/make_viv/viv_default_$(XTW_BOARD).mk
#
.PHONY : all all_ssim all_osim clean
.PHONY : all_XSim all_XSim_ssim all_XSim_osim all_XSim_tsim
#
all : $(EXE_all)
all_ssim : $(EXE_all:=_ssim)
all_osim : $(EXE_all:=_osim)
#
all_XSim : $(EXE_all:=_XSim)
all_XSim_ssim : $(EXE_all:=_XSim_ssim)
all_XSim_osim : $(EXE_all:=_XSim_osim)
all_XSim_tsim : $(EXE_all:=_XSim_tsim)
#
clean : viv_clean ghdl_clean xsim_clean
#
#-----
#
include ${RETROBASE}/rtl/make_viv/generic_ghdl.mk
include ${RETROBASE}/rtl/make_viv/generic_xsim.mk
include ${RETROBASE}/rtl/make_viv/generic_vivado.mk
#
VBOM_all = $(wildcard *.vbom)
#
ifndef DONTINCDEP
include $(VBOM_all:.vbom=.dep_vsyn)
include $(VBOM_all:.vbom=.dep_ghdl)
include $(VBOM_all:.vbom=.dep_vsim)
endif
#
/tb/Makefile.ise
0,0 → 1,39
# $Id: Makefile.ise 788 2016-07-16 22:23:23Z mueller $
#
# Revision History:
# Date Rev Version Comment
# 2015-01-24 637 1.0.2 use nexys3 as default XTW_BOARD
# 2014-07-27 545 1.0.1 make reference board configurable via XTW_BOARD
# 2011-11-26 433 1.0 Initial version (cloned)
#
EXE_all = tb_nx_cram_memctl_as
EXE_all += list_cram_delay
#
ifndef XTW_BOARD
XTW_BOARD=nexys3
endif
include ${RETROBASE}/rtl/make_ise/xflow_default_$(XTW_BOARD).mk
#
.PHONY : all all_ssim all_tsim clean
#
all : $(EXE_all)
all_ssim : $(EXE_all:=_ssim)
all_tsim : $(EXE_all:=_tsim)
#
clean : ise_clean ghdl_clean isim_clean
#
#-----
#
include ${RETROBASE}/rtl/make_ise/generic_ghdl.mk
include ${RETROBASE}/rtl/make_ise/generic_isim.mk
include ${RETROBASE}/rtl/make_ise/generic_xflow.mk
#
VBOM_all = $(wildcard *.vbom)
#
ifndef DONTINCDEP
include $(VBOM_all:.vbom=.dep_xst)
include $(VBOM_all:.vbom=.dep_ghdl)
include $(VBOM_all:.vbom=.dep_isim)
include $(wildcard *.o.dep_ghdl)
endif
#
/tb/tb_nx_cram_memctl.vhd
0,0 → 1,377
-- $Id: tb_nx_cram_memctl.vhd 802 2016-08-27 19:00:23Z mueller $
--
-- Copyright 2010-2011 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
-- This program is free software; you may redistribute and/or modify it under
-- the terms of the GNU General Public License as published by the Free
-- Software Foundation, either version 2, or at your option any later version.
--
-- This program is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-- for complete details.
--
------------------------------------------------------------------------------
-- Module Name: tb_nx_cram_memctl - sim
-- Description: Test bench for nx_cram_memctl
--
-- Dependencies: vlib/simlib/simclk
-- vlib/simlib/simclkcnt
-- bplib/micron/mt45w8mw16b
-- tbd_nx_cram_memctl [UUT, abstact]
--
-- To test: nx_cram_memctl_as (via tbd_nx_cram_memctl_as)
--
-- Target Devices: generic
-- Tool versions: xst 11.4-14.7; ghdl 0.26-0.31
-- Revision History:
-- Date Rev Version Comment
-- 2011-12-23 444 1.4 use new simclk/simclkcnt
-- 2011-11-26 433 1.3 renamed from tb_n2_cram_memctl
-- 2011-11-21 432 1.2 now numeric_std clean; update O_FLA_CE_N usage
-- 2010-05-30 297 1.1 use abstact uut tbd_nx_cram_memctl
-- 2010-05-23 293 1.0 Initial version (derived from tb_s3_sram_memctl)
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_textio.all;
use std.textio.all;
 
use work.slvtypes.all;
use work.simlib.all;
 
entity tb_nx_cram_memctl is
end tb_nx_cram_memctl;
 
architecture sim of tb_nx_cram_memctl is
component tbd_nx_cram_memctl is -- CRAM driver (abstract) [tb design]
port (
CLK : in slbit; -- clock
RESET : in slbit; -- reset
REQ : in slbit; -- request
WE : in slbit; -- write enable
BUSY : out slbit; -- controller busy
ACK_R : out slbit; -- acknowledge read
ACK_W : out slbit; -- acknowledge write
ACT_R : out slbit; -- signal active read
ACT_W : out slbit; -- signal active write
ADDR : in slv22; -- address (32 bit word address)
BE : in slv4; -- byte enable
DI : in slv32; -- data in (memory view)
DO : out slv32; -- data out (memory view)
O_MEM_CE_N : out slbit; -- cram: chip enable (act.low)
O_MEM_BE_N : out slv2; -- cram: byte enables (act.low)
O_MEM_WE_N : out slbit; -- cram: write enable (act.low)
O_MEM_OE_N : out slbit; -- cram: output enable (act.low)
O_MEM_ADV_N : out slbit; -- cram: address valid (act.low)
O_MEM_CLK : out slbit; -- cram: clock
O_MEM_CRE : out slbit; -- cram: command register enable
I_MEM_WAIT : in slbit; -- cram: mem wait
O_MEM_ADDR : out slv23; -- cram: address lines
IO_MEM_DATA : inout slv16 -- cram: data lines
);
end component;
 
signal CLK : slbit := '0';
signal RESET : slbit := '0';
signal REQ : slbit := '0';
signal WE : slbit := '0';
signal BUSY : slbit := '0';
signal ACK_R : slbit := '0';
signal ACK_W : slbit := '0';
signal ACT_R : slbit := '0';
signal ACT_W : slbit := '0';
signal ADDR : slv22 := (others=>'0');
signal BE : slv4 := (others=>'0');
signal DI : slv32 := (others=>'0');
signal DO : slv32 := (others=>'0');
signal O_MEM_CE_N : slbit := '0';
signal O_MEM_BE_N : slv2 := (others=>'0');
signal O_MEM_WE_N : slbit := '0';
signal O_MEM_OE_N : slbit := '0';
signal O_MEM_ADV_N : slbit := '0';
signal O_MEM_CLK : slbit := '0';
signal O_MEM_CRE : slbit := '0';
signal I_MEM_WAIT : slbit := '0';
signal O_MEM_ADDR : slv23 := (others=>'0');
signal IO_MEM_DATA : slv16 := (others=>'0');
 
signal R_MEMON : slbit := '0';
signal N_CHK_DATA : slbit := '0';
signal N_REF_DATA : slv32 := (others=>'0');
signal N_REF_ADDR : slv22 := (others=>'0');
signal R_CHK_DATA_AL : slbit := '0';
signal R_REF_DATA_AL : slv32 := (others=>'0');
signal R_REF_ADDR_AL : slv22 := (others=>'0');
signal R_CHK_DATA_DL : slbit := '0';
signal R_REF_DATA_DL : slv32 := (others=>'0');
signal R_REF_ADDR_DL : slv22 := (others=>'0');
signal CLK_STOP : slbit := '0';
signal CLK_CYCLE : integer := 0;
 
constant clock_period : Delay_length := 20 ns; -- when changed update also
-- READ0DELAY ect delays !!
constant clock_offset : Delay_length := 200 ns;
constant setup_time : Delay_length := 7.5 ns; -- compatible ucf for
constant c2out_time : Delay_length := 12.0 ns; -- tbd_nx_cram_memctl_as
 
begin
 
CLKGEN : simclk
generic map (
PERIOD => clock_period,
OFFSET => clock_offset)
port map (
CLK => CLK,
CLK_STOP => CLK_STOP
);
 
CLKCNT : simclkcnt port map (CLK => CLK, CLK_CYCLE => CLK_CYCLE);
 
MEM : entity work.mt45w8mw16b
port map (
CLK => O_MEM_CLK,
CE_N => O_MEM_CE_N,
OE_N => O_MEM_OE_N,
WE_N => O_MEM_WE_N,
UB_N => O_MEM_BE_N(1),
LB_N => O_MEM_BE_N(0),
ADV_N => O_MEM_ADV_N,
CRE => O_MEM_CRE,
MWAIT => I_MEM_WAIT,
ADDR => O_MEM_ADDR,
DATA => IO_MEM_DATA
);
UUT : tbd_nx_cram_memctl
port map (
CLK => CLK,
RESET => RESET,
REQ => REQ,
WE => WE,
BUSY => BUSY,
ACK_R => ACK_R,
ACK_W => ACK_W,
ACT_R => ACT_R,
ACT_W => ACT_W,
ADDR => ADDR,
BE => BE,
DI => DI,
DO => DO,
O_MEM_CE_N => O_MEM_CE_N,
O_MEM_BE_N => O_MEM_BE_N,
O_MEM_WE_N => O_MEM_WE_N,
O_MEM_OE_N => O_MEM_OE_N,
O_MEM_CLK => O_MEM_CLK,
O_MEM_ADV_N => O_MEM_ADV_N,
O_MEM_CRE => O_MEM_CRE,
I_MEM_WAIT => I_MEM_WAIT,
O_MEM_ADDR => O_MEM_ADDR,
IO_MEM_DATA => IO_MEM_DATA
);
 
proc_stim: process
file fstim : text open read_mode is "tb_nx_cram_memctl_stim";
variable iline : line;
variable oline : line;
variable ok : boolean;
variable dname : string(1 to 6) := (others=>' ');
variable idelta : integer := 0;
variable iaddr : slv22 := (others=>'0');
variable idata : slv32 := (others=>'0');
variable ibe : slv4 := (others=>'0');
variable ival : slbit := '0';
variable nbusy : integer := 0;
 
begin
wait for clock_offset - setup_time;
 
file_loop: while not endfile(fstim) loop
 
readline (fstim, iline);
readcomment(iline, ok);
next file_loop when ok;
 
readword(iline, dname, ok);
if ok then
case dname is
when ".memon" => -- .memon
read_ea(iline, ival);
R_MEMON <= ival;
wait for 2*clock_period;
when ".reset" => -- .reset
write(oline, string'(".reset"));
writeline(output, oline);
RESET <= '1';
wait for clock_period;
RESET <= '0';
wait for 9*clock_period;
 
when ".wait " => -- .wait
read_ea(iline, idelta);
wait for idelta*clock_period;
when "read " => -- read
readgen_ea(iline, iaddr, 16);
readgen_ea(iline, idata, 16);
ADDR <= iaddr;
REQ <= '1';
WE <= '0';
 
writetimestamp(oline, CLK_CYCLE, ": stim read ");
writegen(oline, iaddr, right, 7, 16);
write(oline, string'(" "));
writegen(oline, idata, right, 9, 16);
 
nbusy := 0;
while BUSY='1' loop
nbusy := nbusy + 1;
wait for clock_period;
end loop;
 
write(oline, string'(" nbusy="));
write(oline, nbusy, right, 2);
writeline(output, oline);
 
N_CHK_DATA <= '1', '0' after clock_period;
N_REF_DATA <= idata;
N_REF_ADDR <= iaddr;
 
wait for clock_period;
REQ <= '0';
when "write " => -- write
readgen_ea(iline, iaddr, 16);
read_ea(iline, ibe);
readgen_ea(iline, idata, 16);
ADDR <= iaddr;
BE <= ibe;
DI <= idata;
REQ <= '1';
WE <= '1';
writetimestamp(oline, CLK_CYCLE, ": stim write");
writegen(oline, iaddr, right, 7, 16);
writegen(oline, ibe , right, 5, 2);
writegen(oline, idata, right, 9, 16);
 
nbusy := 0;
while BUSY = '1' loop
nbusy := nbusy + 1;
wait for clock_period;
end loop;
 
write(oline, string'(" nbusy="));
write(oline, nbusy, right, 2);
writeline(output, oline);
 
wait for clock_period;
REQ <= '0';
when others => -- bad directive
write(oline, string'("?? unknown directive: "));
write(oline, dname);
writeline(output, oline);
report "aborting" severity failure;
end case;
else
report "failed to find command" severity failure;
end if;
 
testempty_ea(iline);
 
end loop; -- file fstim
 
wait for 10*clock_period;
 
writetimestamp(oline, CLK_CYCLE, ": DONE ");
writeline(output, oline);
 
CLK_STOP <= '1';
 
wait; -- suspend proc_stim forever
-- clock is stopped, sim will end
 
end process proc_stim;
 
proc_moni: process
variable oline : line;
begin
 
loop
wait until rising_edge(CLK);
 
if ACK_R = '1' then
writetimestamp(oline, CLK_CYCLE, ": moni ");
writegen(oline, DO, right, 9, 16);
if R_CHK_DATA_DL = '1' then
write(oline, string'(" CHECK"));
if R_REF_DATA_DL = DO then
write(oline, string'(" OK"));
else
write(oline, string'(" FAIL, exp="));
writegen(oline, R_REF_DATA_DL, right, 9, 16);
write(oline, string'(" for a="));
writegen(oline, R_REF_ADDR_DL, right, 5, 16);
end if;
R_CHK_DATA_DL <= '0';
end if;
writeline(output, oline);
end if;
 
if R_CHK_DATA_AL = '1' then
R_CHK_DATA_DL <= R_CHK_DATA_AL;
R_REF_DATA_DL <= R_REF_DATA_AL;
R_REF_ADDR_DL <= R_REF_ADDR_AL;
R_CHK_DATA_AL <= '0';
end if;
if N_CHK_DATA = '1' then
R_CHK_DATA_AL <= N_CHK_DATA;
R_REF_DATA_AL <= N_REF_DATA;
R_REF_ADDR_AL <= N_REF_ADDR;
end if;
end loop;
end process proc_moni;
 
 
proc_memon: process
variable oline : line;
begin
 
loop
wait until rising_edge(CLK);
 
if R_MEMON = '1' then
writetimestamp(oline, CLK_CYCLE, ": mem ");
write(oline, string'(" ce="));
write(oline, not O_MEM_CE_N, right, 2);
write(oline, string'(" be="));
write(oline, not O_MEM_BE_N, right, 4);
write(oline, string'(" we="));
write(oline, not O_MEM_WE_N, right);
write(oline, string'(" oe="));
write(oline, not O_MEM_OE_N, right);
write(oline, string'(" a="));
writegen(oline, O_MEM_ADDR, right, 6, 16);
write(oline, string'(" d="));
writegen(oline, IO_MEM_DATA, right, 4, 16);
writeline(output, oline);
end if;
end loop;
end process proc_memon;
 
 
end sim;
/tb/tb_nx_cram_memctl_as.vbom
0,0 → 1,8
# configure tb_nx_cram_memctl with tbd_nx_cram_memctl_as target;
# use vhdl configure file (tb_nx_cram_memctl_as.vhd) to allow
# that all configurations will co-exist in work library
# configure
uut = tbd_nx_cram_memctl_as.vbom
tb_nx_cram_memctl.vbom
# design
tb_nx_cram_memctl_as.vhd
/tb/tb_nx_cram_memctl_as_ssim.vbom
0,0 → 1,6
# configure for _*sim case
# configure
uut = tbd_nx_cram_memctl_as_ssim.vhd
# design
tb_nx_cram_memctl_as.vbom
@top:tb_nx_cram_memctl_as
/tb/tbd_nx_cram_memctl_as.ucf
0,0 → 1,40
## $Id: tbd_nx_cram_memctl_as.ucf 433 2011-11-27 22:04:39Z mueller $
##
## drive strength defs and timing defs for tbd_nx_cram_memctl_as test target
##
## Revision History:
## Date Rev Version Comment
## 2011-11-26 433 1.1 renamed from tbd_n2_cram_memctl_as.ucf
## 2010-05-30 297 1.0 Initial version
##
## Note: default is DRIVE=12 | SLEW=SLOW
##
## The OFFSET rules are compatible with the setup and c2out times
## used in the test bench tb_nx_cram_memctl.
##
NET "CLK" TNM_NET = "CLK";
TIMESPEC "TS_CLK" = PERIOD "CLK" 20 ns HIGH 50 %;
OFFSET = IN 7.5 ns BEFORE "CLK";
OFFSET = OUT 12.0 ns AFTER "CLK";
##
NET "O_MEM_WE_N" OFFSET = OUT 12.0 ns AFTER "CLK" FALLING;
##
## -- define defaults
##
INST "/" IOSTANDARD=LVCMOS33;
##
## CRAM ----------------------------------------------------------------------
NET "O_MEM_CE_N" IOSTANDARD=LVCMOS33 | DRIVE=12 | SLEW=FAST;
NET "O_MEM_WE_N" IOSTANDARD=LVCMOS33 | DRIVE=12 | SLEW=FAST;
NET "O_MEM_OE_N" IOSTANDARD=LVCMOS33 | DRIVE=12 | SLEW=FAST;
##
NET "O_MEM_BE_N<*>" IOSTANDARD=LVCMOS33 | DRIVE=12 | SLEW=FAST;
##
NET "O_MEM_ADV_N" IOSTANDARD=LVCMOS33 | DRIVE=12 | SLEW=FAST;
NET "O_MEM_CLK" IOSTANDARD=LVCMOS33 | DRIVE=12 | SLEW=FAST;
NET "O_MEM_CRE" IOSTANDARD=LVCMOS33 | DRIVE=12 | SLEW=FAST;
NET "I_MEM_WAIT" IOSTANDARD=LVCMOS33 | PULLDOWN;
##
NET "O_MEM_ADDR<*>" IOSTANDARD=LVCMOS33 | DRIVE=6 | SLEW=FAST;
NET "IO_MEM_DATA<*>" IOSTANDARD=LVCMOS33 | DRIVE=6 | SLEW=SLOW | KEEPER;
##
/tb/tbd_nx_cram_memctl_as.vhd
0,0 → 1,122
-- $Id: tbd_nx_cram_memctl_as.vhd 802 2016-08-27 19:00:23Z mueller $
--
-- Copyright 2010-2016 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
-- This program is free software; you may redistribute and/or modify it under
-- the terms of the GNU General Public License as published by the Free
-- Software Foundation, either version 2, or at your option any later version.
--
-- This program is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-- for complete details.
--
------------------------------------------------------------------------------
-- Module Name: tbd_nx_cram_memctl_as - syn
-- Description: Wrapper for nx_cram_memctl_as to avoid records & generics.
-- It has a port interface which will not be modified by xst
-- synthesis (no records, no generic port).
--
-- Dependencies: nx_cram_memctl_as
-- To test: nx_cram_memctl_as
--
-- Target Devices: generic
--
-- Synthesized (xst):
-- Date Rev ise Target flop lutl lutm slic t peri
-- 2010-06-03 299 11.4 L68 xc3s1200e-4 91 122 0 107 t 11.4
-- 2010-05-30 297 11.4 L68 xc3s1200e-4 91 99 0 95 t 13.1
--
-- Tool versions: xst 11.4-14.7; ghdl 0.26-0.31
-- Revision History:
-- Date Rev Version Comment
-- 2016-08-27 802 1.2.1 use cram_read0delay ect
-- 2011-11-26 433 1.2 renamed from tbd_n2_cram_memctl_as
-- 2011-11-23 432 1.1 remove O_FLA_CE_N port from n2_cram_memctl
-- 2010-06-03 298 1.0.1 add hack to force IOB'FFs to O_MEM_ADDR
-- 2010-05-30 297 1.0 Initial version
------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
 
use work.slvtypes.all;
use work.nxcramlib.all;
 
entity tbd_nx_cram_memctl_as is -- CRAM driver (async mode) [tb design]
-- generic: READ0=2;READ1=2;WRITE=3
port (
CLK : in slbit; -- clock
RESET : in slbit; -- reset
REQ : in slbit; -- request
WE : in slbit; -- write enable
BUSY : out slbit; -- controller busy
ACK_R : out slbit; -- acknowledge read
ACK_W : out slbit; -- acknowledge write
ACT_R : out slbit; -- signal active read
ACT_W : out slbit; -- signal active write
ADDR : in slv22; -- address (32 bit word address)
BE : in slv4; -- byte enable
DI : in slv32; -- data in (memory view)
DO : out slv32; -- data out (memory view)
O_MEM_CE_N : out slbit; -- cram: chip enable (act.low)
O_MEM_BE_N : out slv2; -- cram: byte enables (act.low)
O_MEM_WE_N : out slbit; -- cram: write enable (act.low)
O_MEM_OE_N : out slbit; -- cram: output enable (act.low)
O_MEM_ADV_N : out slbit; -- cram: address valid (act.low)
O_MEM_CLK : out slbit; -- cram: clock
O_MEM_CRE : out slbit; -- cram: command register enable
I_MEM_WAIT : in slbit; -- cram: mem wait
O_MEM_ADDR : out slv23; -- cram: address lines
IO_MEM_DATA : inout slv16 -- cram: data lines
);
end tbd_nx_cram_memctl_as;
 
 
architecture syn of tbd_nx_cram_memctl_as is
 
signal ADDR_X : slv22 := (others=>'0');
begin
 
-- Note: This is a hack to ensure that the IOB flops are on the O_MEM_ADDR
-- pins. Without par might choose to use IFF's on ADDR, causing varying
-- routing delays to O_MEM_ADDR. Didn't find a better way, setting
-- iob "false" attributes in ADDR didn't help.
-- This logic doesn't hurt, and prevents that IFFs for ADDR compete with
-- OFF's for O_MEM_ADDR.
ADDR_X <= ADDR when RESET='0' else (others=>'0');
CRAMCTL : nx_cram_memctl_as
generic map (
READ0DELAY => cram_read0delay(50), -- assume 50 MHz system clock. Must be
READ1DELAY => cram_read1delay(50), -- modified when clock_period is
WRITEDELAY => cram_writedelay(50)) -- changed in tb_nx_cram_memctl !!
port map (
CLK => CLK,
RESET => RESET,
REQ => REQ,
WE => WE,
BUSY => BUSY,
ACK_R => ACK_R,
ACK_W => ACK_W,
ACT_R => ACT_R,
ACT_W => ACT_W,
ADDR => ADDR_X,
BE => BE,
DI => DI,
DO => DO,
O_MEM_CE_N => O_MEM_CE_N,
O_MEM_BE_N => O_MEM_BE_N,
O_MEM_WE_N => O_MEM_WE_N,
O_MEM_OE_N => O_MEM_OE_N,
O_MEM_ADV_N => O_MEM_ADV_N,
O_MEM_CLK => O_MEM_CLK,
O_MEM_CRE => O_MEM_CRE,
I_MEM_WAIT => I_MEM_WAIT,
O_MEM_ADDR => O_MEM_ADDR,
IO_MEM_DATA => IO_MEM_DATA
);
end syn;
/tb/tbrun.yml
0,0 → 1,12
# $Id: tbrun.yml 807 2016-09-17 07:49:26Z mueller $
#
# Revision History:
# Date Rev Version Comment
# 2016-08-22 800 1.0 Initial version
#
- default:
mode: ${viv_modes}
#
- tag: [default, viv, bplib, cram_memctl_as]
test: |
tbrun_tbw tb_nx_cram_memctl_as${ms}
/tb/tb_nx_cram_memctl.vbom
0,0 → 1,15
# Not meant for direct top level usage. Used with
# tb_nx_cram_memctl_(....)[_ssim].vbom and config
# lines to generate the different cases.
#
# libs
../../../vlib/slvtypes.vhd
../../../vlib/simlib/simlib.vhd
# components
../../../vlib/simlib/simclk.vbom
../../../vlib/simlib/simclkcnt.vbom
../../micron/mt45w8mw16b.vbom
${uut := tbd_nx_cram_memctl_as.vbom} -UUT
# design
tb_nx_cram_memctl.vhd
@top:tb_nx_cram_memctl
/tb/tb_nx_cram_memctl_as.vhd
0,0 → 1,39
-- $Id: tb_nx_cram_memctl_as.vhd 433 2011-11-27 22:04:39Z mueller $
--
-- Copyright 2010-2011 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
-- This program is free software; you may redistribute and/or modify it under
-- the terms of the GNU General Public License as published by the Free
-- Software Foundation, either version 2, or at your option any later version.
--
-- This program is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-- for complete details.
--
------------------------------------------------------------------------------
-- Module Name: tb_nx_cram_memctl_as
-- Description: Configuration tb_nx_cram_memctl_as for tb_nx_cram_memctl
--
-- Dependencies: tbd_nx_cram_memctl_as
-- To test: nx_cram_memctl_as
--
-- Verified (with tb_nx_cram_memctl_stim.dat):
-- Date Rev Code ghdl ise Target Comment
-- 2010-05-30 297 - 0.26 11.4 L68 xc3s1200e ok
--
-- Revision History:
-- Date Rev Version Comment
-- 2011-11-26 433 1.1 renamed from tb_n2_cram_memctl_as
-- 2010-05-30 297 1.0 Initial version
------------------------------------------------------------------------------
 
configuration tb_nx_cram_memctl_as of tb_nx_cram_memctl is
 
for sim
for all :tbd_nx_cram_memctl
use entity work.tbd_nx_cram_memctl_as;
end for;
end for;
 
end tb_nx_cram_memctl_as;
/tb/tb_nx_cram_memctl_stim.dat
0,0 → 1,212
# $Id: tb_nx_cram_memctl_stim.dat 433 2011-11-27 22:04:39Z mueller $
#
.memon 0
#
C write full word 16 cells
#
write 000000 1111 30201000
write 000001 1111 31211101
write 000002 1111 32221202
write 000003 1111 33231303
write 000004 1111 34241404
write 000005 1111 35251505
write 000006 1111 36261606
write 000007 1111 37271707
write 000008 1111 38281808
write 000009 1111 39291909
write 00000a 1111 3a2a1a0a
write 00000b 1111 3b2b1b0b
write 00000c 1111 3c2c1c0c
write 00000d 1111 3d2d1d0d
write 00000e 1111 3e2e1e0e
write 00000f 1111 3f2f1f0f
#
C read 16 cells
#
read 000000 30201000
read 000001 31211101
read 000002 32221202
read 000003 33231303
read 000004 34241404
read 000005 35251505
read 000006 36261606
read 000007 37271707
read 000008 38281808
read 000009 39291909
read 00000a 3a2a1a0a
read 00000b 3b2b1b0b
read 00000c 3c2c1c0c
read 00000d 3d2d1d0d
read 00000e 3e2e1e0e
read 00000f 3f2f1f0f
#
C write selected bytes in first 16 cells
#
write 000000 0000 70605040
write 000001 0001 71615141
write 000002 0010 72625242
write 000003 0011 73635343
write 000004 0100 74645444
write 000005 0101 75655545
write 000006 0110 76665646
write 000007 0111 77675747
write 000008 1000 78685848
write 000009 1001 79695949
write 00000a 1010 7a6a5a4a
write 00000b 1011 7b6b5b4b
write 00000c 1100 7c6c5c4c
write 00000d 1101 7d6d5d4d
write 00000e 1110 7e6e5e4e
write 00000f 1111 7f6f5f4f
#
C read back
#
read 000000 30201000
read 000001 31211141
read 000002 32225202
read 000003 33235343
read 000004 34641404
read 000005 35651545
read 000006 36665606
read 000007 37675747
read 000008 78281808
read 000009 79291949
read 00000a 7a2a5a0a
read 00000b 7b2b5b4b
read 00000c 7c6c1c0c
read 00000d 7d6d1d4d
read 00000e 7e6e5e0e
read 00000f 7f6f5f4f
#
C read and write with waits
#
.wait 12
write 000010 1111 30201000
.wait 11
write 000011 1111 31211101
.wait 10
write 000012 1111 32221202
.wait 9
write 000013 1111 33231303
.wait 8
write 000014 1111 34241404
.wait 7
write 000015 1111 35251505
.wait 6
write 000016 1111 36261606
.wait 5
write 000017 1111 37271707
.wait 4
write 000018 1111 38281808
.wait 3
write 000019 1111 39291909
.wait 2
write 00001a 1111 3a2a1a0a
.wait 1
write 00001b 1111 3b2b1b0b
write 00001c 1111 3b2b1b0b
#
.wait 12
read 000010 30201000
.wait 11
read 000011 31211101
.wait 10
read 000012 32221202
.wait 9
read 000013 33231303
.wait 8
read 000014 34241404
.wait 7
read 000015 35251505
.wait 6
read 000016 36261606
.wait 5
read 000017 37271707
.wait 4
read 000018 38281808
.wait 3
read 000019 39291909
.wait 2
read 00001a 3a2a1a0a
.wait 1
read 00000e 7e6e5e0e
read 00000f 7f6f5f4f
#
C read and write mixed, with waits
#
.wait 2
write 000014 1111 34241404
.wait 2
read 000012 32221202
.wait 2
write 000015 1111 35251505
.wait 2
read 000013 33231303
#
.wait 1
write 000016 1111 36261606
.wait 1
read 000014 34241404
.wait 1
write 000017 1111 37271707
.wait 1
read 000015 35251505
#
write 000018 1111 38281808
read 000016 36261606
write 000019 1111 39291909
read 000017 37271707
#
.wait 2
write 00001a 1111 3a2a1a0a
write 00001b 1111 3b2b1b0b
.wait 2
read 000018 38281808
read 000019 39291909
.wait 2
write 00001c 1111 3c2c1c0c
write 00001d 1111 3d2d1d0d
.wait 2
read 00001a 3a2a1a0a
read 00001b 3b2b1b0b
#
.wait 1
write 00001e 1111 3e2e1e0e
write 00001f 1111 3f2f1f0f
.wait 1
read 00001c 3c2c1c0c
read 00001d 3d2d1d0d
.wait 1
write 000014 0100 74645444
write 000015 0101 75655545
.wait 1
read 00001e 3e2e1e0e
read 00001f 3f2f1f0f
#
write 000016 0110 76665646
write 000017 0111 77675747
read 000010 30201000
read 000011 31211101
write 000018 1000 78685848
write 000019 1001 79695949
read 000012 32221202
read 000013 33231303
#
write 00001a 1010 7a6a5a4a
write 00001b 1011 7b6b5b4b
write 00001c 1100 7c6c5c4c
read 000014 34641404
read 000015 35651545
read 000016 36665606
write 00001d 1101 7d6d5d4d
write 00001e 1110 7e6e5e4e
write 00001f 1111 7f6f5f4f
read 000017 37675747
read 000018 78281808
read 000019 79291949
read 00001a 7a2a5a0a
read 00001b 7b2b5b4b
read 00001c 7c6c1c0c
read 00001d 7d6d1d4d
read 00001e 7e6e5e0e
read 00001f 7f6f5f4f
/tb/tbw.dat
0,0 → 1,4
# $Id: tbw.dat 433 2011-11-27 22:04:39Z mueller $
#
[tb_nx_cram_memctl_as]
tb_nx_cram_memctl_stim = tb_nx_cram_memctl_stim.dat
/tb/tbd_nx_cram_memctl_as.vbom
0,0 → 1,7
# libs
../../../vlib/slvtypes.vhd
../nxcramlib.vhd
# components
../nx_cram_memctl_as.vbom
# design
tbd_nx_cram_memctl_as.vhd
/tb
tb Property changes : Added: svn:ignore ## -0,0 +1,45 ## +*.gz +*.tar +*.tgz +*.dep_* +work-obj93.cf +*.vcd +*.ghw +*.sav +*.tmp +*.exe +ise +xflow.his +*.ngc +*.ncd +*.pcf +*.bit +*.msk +*.svf +*.log +isim +*_[sfot]sim.vhd +*_tsim.sdf +rlink_cext_fifo_[rt]x +rlink_cext_conf +tmu_ofile +*.dsk +*.tap +*.lst +*.cof +.Xil +project_mflow +xsim.dir +webtalk_* +*_[sfot]sim +*_[IX]Sim +*_[IX]Sim_[sfot]sim +*.dcp +*.jou +*.pb +*.prj +*.rpt +*.wdb +tb_nx_cram_memctl_as +tb_nx_cram_memctl_stim +list_cram_delay Index: Makefile.ise =================================================================== --- Makefile.ise (nonexistent) +++ Makefile.ise (revision 38) @@ -0,0 +1,30 @@ +# $Id: Makefile.ise 761 2016-04-17 08:53:48Z mueller $ +# +# Revision History: +# Date Rev Version Comment +# 2015-01-24 637 1.0.2 use nexys3 as default XTW_BOARD +# 2014-07-27 545 1.0.1 make reference board configurable via XTW_BOARD +# 2011-11-26 433 1.0 Initial version (cloned..) +# +VBOM_all = $(wildcard *.vbom) +NGC_all = $(VBOM_all:.vbom=.ngc) +# +ifndef XTW_BOARD + XTW_BOARD=nexys3 +endif +include ${RETROBASE}/rtl/make_ise/xflow_default_$(XTW_BOARD).mk +# +.PHONY : all clean +# +all : $(NGC_all) +# +clean : ise_clean +# +#---- +# +include ${RETROBASE}/rtl/make_ise/generic_xflow.mk +# +ifndef DONTINCDEP +include $(VBOM_all:.vbom=.dep_xst) +endif +# Index: nx_cram_dummy.vhd =================================================================== --- nx_cram_dummy.vhd (nonexistent) +++ nx_cram_dummy.vhd (revision 38) @@ -0,0 +1,64 @@ +-- $Id: nx_cram_dummy.vhd 641 2015-02-01 22:12:15Z mueller $ +-- +-- Copyright 2010-2011 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, or at your option any later version. +-- +-- This program is distributed in the hope that it will be useful, but +-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY +-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-- for complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: nx_cram_dummy - syn +-- Description: nexys2/3: CRAM protection dummy +-- +-- Dependencies: - +-- Test bench: - +-- Target Devices: generic +-- Tool versions: ise 11.4-14.7; viv 2014.4; ghdl 0.26-0.31 +-- Revision History: +-- Date Rev Version Comment +-- 2011-11-26 433 1.2 renamed from n2_cram_dummy +-- 2011-11-23 432 1.1 remove O_FLA_CE_N port +-- 2010-05-28 295 1.0.1 use _ADV_N +-- 2010-05-21 292 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; + +entity nx_cram_dummy is -- CRAM protection dummy + port ( + O_MEM_CE_N : out slbit; -- cram: chip enable (act.low) + O_MEM_BE_N : out slv2; -- cram: byte enables (act.low) + O_MEM_WE_N : out slbit; -- cram: write enable (act.low) + O_MEM_OE_N : out slbit; -- cram: output enable (act.low) + O_MEM_ADV_N : out slbit; -- cram: address valid (act.low) + O_MEM_CLK : out slbit; -- cram: clock + O_MEM_CRE : out slbit; -- cram: command register enable + I_MEM_WAIT : in slbit; -- cram: mem wait + O_MEM_ADDR : out slv23; -- cram: address lines + IO_MEM_DATA : inout slv16 -- cram: data lines + ); +end nx_cram_dummy; + + +architecture syn of nx_cram_dummy is +begin + + O_MEM_CE_N <= '1'; -- disable cram chip + O_MEM_BE_N <= "11"; + O_MEM_WE_N <= '1'; + O_MEM_OE_N <= '1'; + O_MEM_ADV_N <= '1'; + O_MEM_CLK <= '0'; + O_MEM_CRE <= '0'; + O_MEM_ADDR <= (others=>'0'); + IO_MEM_DATA <= (others=>'0'); + +end syn; Index: nx_cram_dummy.vbom =================================================================== --- nx_cram_dummy.vbom (nonexistent) +++ nx_cram_dummy.vbom (revision 38) @@ -0,0 +1,5 @@ +# libs +../../vlib/slvtypes.vhd +# components +# design +nx_cram_dummy.vhd Index: nx_cram_memctl_as.vbom =================================================================== --- nx_cram_memctl_as.vbom (nonexistent) +++ nx_cram_memctl_as.vbom (revision 38) @@ -0,0 +1,9 @@ +# libs +../../vlib/slvtypes.vhd +../../vlib/xlib/xlib.vhd +# components +../../vlib/xlib/iob_reg_o.vbom +../../vlib/xlib/iob_reg_o_gen.vbom +../../vlib/xlib/iob_reg_io_gen.vbom +# design +nx_cram_memctl_as.vhd Index: . =================================================================== --- . (nonexistent) +++ . (revision 38)
. Property changes : Added: svn:ignore ## -0,0 +1,42 ## +*.gz +*.tar +*.tgz +*.dep_* +work-obj93.cf +*.vcd +*.ghw +*.sav +*.tmp +*.exe +ise +xflow.his +*.ngc +*.ncd +*.pcf +*.bit +*.msk +*.svf +*.log +isim +*_[sfot]sim.vhd +*_tsim.sdf +rlink_cext_fifo_[rt]x +rlink_cext_conf +tmu_ofile +*.dsk +*.tap +*.lst +*.cof +.Xil +project_mflow +xsim.dir +webtalk_* +*_[sfot]sim +*_[IX]Sim +*_[IX]Sim_[sfot]sim +*.dcp +*.jou +*.pb +*.prj +*.rpt +*.wdb

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.