diff --git a/lib/SSRAM/src/CY7C1354B.vhd b/lib/SSRAM/src/CY7C1354B.vhd index d652656..7dae7d0 100644 --- a/lib/SSRAM/src/CY7C1354B.vhd +++ b/lib/SSRAM/src/CY7C1354B.vhd @@ -1,388 +1,388 @@ ------------------------------------------------------------------------------------------ --- --- File Name: CY7C1354B.VHD --- Version: 2.0 --- Date: Nov 22nd, 2004 --- Model: BUS Functional --- --- --- Author: RKF --- Company: Cypress Semiconductor --- Model: CY7C1354B (256k x 36) --- Mode: Pipelined --- --- Description: NoBL SRAM VHDL Model --- --- Limitation: None --- --- Note: - BSDL Model available separately --- - Set simulator resolution to "ps" timescale --- --- Disclaimer: THESE DESIGNS ARE PROVIDED "AS IS" WITH NO WARRANTY --- WHATSOEVER AND CYPRESS SPECIFICALLY DISCLAIMS ANY --- IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR --- A PARTICULAR PURPOSE, OR AGAINST INFRINGEMENT. --- --- Copyright (c) 2004 Cypress Semiconductor --- All rights reserved --- --- Trademarks: NoBL and No Bus Latency are trademarks of Cypress Semiconductor --- --- Rev Author Date Changes --- --- -------- ------- ---------- --- 2.0 RKF 11/22/2004 - Second Release --- - Fully Tested with New Test Bench and Test Vectors ------------------------------------------------------------------------------------------ - -LIBRARY ieee,work; - USE ieee.std_logic_1164.all; - USE ieee.std_logic_unsigned.all; - Use IEEE.Std_Logic_Arith.all; --- Use work.all; - USE work.package_utility.all; - -ENTITY cy7c1354 IS - - GENERIC ( - - -- Constant parameters - addr_bits : INTEGER := 18; - data_bits : INTEGER := 32; - par_bits : INTEGER := 4; - - -- Timing parameters for -5 (225 Mhz) --- tCYC : TIME := 4.4 ns; --- tCH : TIME := 1.8 ns; --- tCL : TIME := 1.8 ns; --- tCO : TIME := 2.8 ns; --- tAS : TIME := 1.4 ns; --- tCENS : TIME := 1.4 ns; --- tWES : TIME := 1.4 ns; --- tDS : TIME := 1.4 ns; --- tAH : TIME := 0.4 ns; --- tCENH : TIME := 0.4 ns; --- tWEH : TIME := 0.4 ns; --- tDH : TIME := 0.4 ns - - - - -- Timing parameters for -6 (200 Mhz) - --tCYC : TIME := 5.0 ns; - --tCH : TIME := 2.0 ns; - --tCL : TIME := 2.0 ns; - --tCO : TIME := 3.2 ns; - --tAS : TIME := 1.5 ns; - --tCENS : TIME := 1.5 ns; - --tWES : TIME := 1.5 ns; - --tDS : TIME := 1.5 ns; - --tAH : TIME := 0.5 ns; - --tCENH : TIME := 0.5 ns; - --tWEH : TIME := 0.5 ns; - --tDH : TIME := 0.5 ns - - - -- Timing parameters for -7 (166 Mhz) - tCYC : TIME := 6.0 ns; - tCH : TIME := 2.4 ns; - tCL : TIME := 2.4 ns; - tCO : TIME := 3.5 ns; - tAS : TIME := 1.5 ns; - tCENS : TIME := 1.5 ns; - tWES : TIME := 1.5 ns; - tDS : TIME := 1.5 ns; - tAH : TIME := 0.5 ns; - tCENH : TIME := 0.5 ns; - tWEH : TIME := 0.5 ns; - tDH : TIME := 0.5 ns - - - - ); - - -- Port Declarations - PORT ( - Dq : INOUT STD_LOGIC_VECTOR ((data_bits - 1) DOWNTO 0); -- Data I/O - Dpq : INOUT STD_LOGIC_VECTOR ((par_bits - 1) DOWNTO 0); -- Data parity I/O - Addr : IN STD_LOGIC_VECTOR ((addr_bits - 1) DOWNTO 0); -- Address - Mode : IN STD_LOGIC := '1'; -- Burst Mode - Clk : IN STD_LOGIC; -- Clk - CEN_n : IN STD_LOGIC; -- CEN# - AdvLd_n : IN STD_LOGIC; -- Adv/Ld# - Bwa_n : IN STD_LOGIC; -- Bwa# - Bwb_n : IN STD_LOGIC; -- BWb# - Bwc_n : IN STD_LOGIC; -- Bwc# - Bwd_n : IN STD_LOGIC; -- BWd# - Rw_n : IN STD_LOGIC; -- RW# - Oe_n : IN STD_LOGIC; -- OE# - Ce1_n : IN STD_LOGIC; -- CE1# - Ce2 : IN STD_LOGIC; -- CE2 - Ce3_n : IN STD_LOGIC; -- CE3# - Zz : IN STD_LOGIC -- Snooze Mode - ); -END cy7c1354; - -ARCHITECTURE behave OF cy7c1354 IS - SIGNAL ce : STD_LOGIC := '0'; - SIGNAL doe : STD_LOGIC := '0'; - SIGNAL dout : STD_LOGIC_VECTOR ((data_bits - 1) DOWNTO 0) := (OTHERS => 'Z'); - SIGNAL dout_p : STD_LOGIC_VECTOR ((par_bits - 1) DOWNTO 0) := (OTHERS => 'Z'); - SIGNAL Addr_read_sig : STD_LOGIC_VECTOR ((addr_bits - 1) DOWNTO 0) := (OTHERS => 'Z'); - -BEGIN - - - ce <= NOT(Ce1_n) AND NOT(Ce3_n) AND Ce2; - - doe <= NOT(Oe_n) AND NOT(Zz); - - -- Output Buffers - WITH doe SELECT - Dq <= TRANSPORT dout AFTER (tCO) WHEN '1', - (OTHERS => 'Z') AFTER (tCO) WHEN OTHERS; - - WITH doe SELECT - Dpq <= TRANSPORT dout_p AFTER (tCO) WHEN '1', - (OTHERS => 'Z') AFTER (tCO) WHEN OTHERS; - - - -- Check for Clock Timing Violation - clk_check : PROCESS - VARIABLE clk_high, clk_low : TIME := 0 ns; - BEGIN - WAIT ON Clk; - IF Clk = '1' AND NOW >= tCYC THEN - ASSERT (NOW - clk_low >= tCH) - REPORT "Clk width low - tCH violation" - SEVERITY ERROR; - ASSERT (NOW - clk_high >= tCYC) - REPORT "Clk period high - tCYC violation" - SEVERITY ERROR; - clk_high := NOW; - ELSIF Clk = '0' AND NOW /= 0 ns THEN - ASSERT (NOW - clk_high >= tCL) - REPORT "Clk width high - tCL violation" - SEVERITY ERROR; - ASSERT (NOW - clk_low >= tCYC) - REPORT "Clk period low - tCYC violation" - SEVERITY ERROR; - clk_low := NOW; - END IF; - END PROCESS; - - -- Check for Setup Timing Violation - setup_check : PROCESS - BEGIN - WAIT ON Clk; - IF Clk = '1' and (Ce1_n = '0' and Ce2 = '1' and Ce3_n = '0') THEN - ASSERT (Addr'LAST_EVENT >= tAS) - REPORT "Addr - tAS violation" - SEVERITY ERROR; - ASSERT (CEN_n'LAST_EVENT >= tCENS) - REPORT "CKE# - tCENS violation" - SEVERITY ERROR; - ASSERT (Ce1_n'LAST_EVENT >= tWES) - REPORT "CE1# - tWES violation" - SEVERITY ERROR; - ASSERT (Ce2'LAST_EVENT >= tWES) - REPORT "CE2 - tWES violation" - SEVERITY ERROR; - ASSERT (Ce3_n'LAST_EVENT >= tWES) - REPORT "CE3# - tWES violation" - SEVERITY ERROR; - ASSERT (AdvLd_n'LAST_EVENT >= tWES) - REPORT "ADV/LD# - tWES violation" - SEVERITY ERROR; - ASSERT (Rw_n'LAST_EVENT >= tWES) - REPORT "RW# - tWES violation" - SEVERITY ERROR; - ASSERT (Bwa_n'LAST_EVENT >= tWES) - REPORT "BWa# - tWES violation" - SEVERITY ERROR; - ASSERT (Bwb_n'LAST_EVENT >= tWES) - REPORT "BWb# - tWES violation" - SEVERITY ERROR; - ASSERT (Bwc_n'LAST_EVENT >= tWES) - REPORT "BWc# - tWES violation" - SEVERITY ERROR; - ASSERT (Bwd_n'LAST_EVENT >= tWES) - REPORT "BWd# - tWES violation" - SEVERITY ERROR; - ASSERT (Dq'LAST_EVENT >= tDS) - REPORT "Dq - tDS violation" - SEVERITY ERROR; - END IF; - END PROCESS; - - -- Check for Hold Timing Violation - hold_check : PROCESS - BEGIN - WAIT ON Clk'DELAYED(tAH), Clk'DELAYED(tCENH), Clk'DELAYED(tWEH), Clk'DELAYED(tDH); - IF Clk'DELAYED(tAH) = '1' THEN - ASSERT (Addr'LAST_EVENT > tAH) - REPORT "Addr - tAH violation" - SEVERITY ERROR; - END IF; - IF Clk'DELAYED(tCENH) = '1' THEN - ASSERT (CEN_n'LAST_EVENT > tCENH) - REPORT "CKE# - tCENH violation" - SEVERITY ERROR; - END IF; - IF Clk'DELAYED(tDH) = '1' THEN - ASSERT (Dq'LAST_EVENT > tDH) - REPORT "Dq - tDH violation" - SEVERITY ERROR; - END IF; - IF Clk'DELAYED(tWEH) = '1' THEN - ASSERT (Ce1_n'LAST_EVENT > tWEH) - REPORT "CE1# - tWEH violation" - SEVERITY ERROR; - ASSERT (Ce2'LAST_EVENT > tWEH) - REPORT "CE2 - tWEH violation" - SEVERITY ERROR; - ASSERT (Ce3_n'LAST_EVENT > tWEH) - REPORT "CE3 - tWEH violation" - SEVERITY ERROR; - ASSERT (AdvLd_n'LAST_EVENT > tWEH) - REPORT "ADV/LD# - tWEH violation" - SEVERITY ERROR; - ASSERT (Rw_n'LAST_EVENT > tWEH) - REPORT "RW# - tWEH violation" - SEVERITY ERROR; - ASSERT (Bwa_n'LAST_EVENT > tWEH) - REPORT "BWa# - tWEH violation" - SEVERITY ERROR; - ASSERT (Bwb_n'LAST_EVENT > tWEH) - REPORT "BWb# - tWEH violation" - SEVERITY ERROR; - ASSERT (Bwc_n'LAST_EVENT > tWEH) - REPORT "BWc# - tWEH violation" - SEVERITY ERROR; - ASSERT (Bwd_n'LAST_EVENT > tWEH) - REPORT "BWd# - tWEH violation" - SEVERITY ERROR; - END IF; - - END PROCESS; - - -- Main Program - main : PROCESS - - TYPE memory_array IS ARRAY ((2**addr_bits) - 1 DOWNTO 0) OF STD_LOGIC_VECTOR (((data_bits+par_bits) / 4) - 1 DOWNTO 0); - - VARIABLE Addr_in : STD_LOGIC_VECTOR ((addr_bits - 1) DOWNTO 0) := (OTHERS => '0'); - VARIABLE first_Addr : STD_LOGIC_VECTOR (1 DOWNTO 0) := (OTHERS => '0'); - VARIABLE Addr_read : STD_LOGIC_VECTOR ((addr_bits - 1) DOWNTO 0) := (OTHERS => '0'); - VARIABLE Addr_write : STD_LOGIC_VECTOR ((addr_bits - 1) DOWNTO 0) := (OTHERS => '0'); - VARIABLE bAddr0, bAddr1 : STD_LOGIC := '0'; - VARIABLE bank0 : memory_array; - VARIABLE bank1 : memory_array; - VARIABLE bank2 : memory_array; - VARIABLE bank3 : memory_array; - - VARIABLE ce_in : STD_LOGIC_VECTOR (1 DOWNTO 0) := "00"; - VARIABLE rw_in : STD_LOGIC_VECTOR (2 DOWNTO 0) := "111"; - VARIABLE bwa_in : STD_LOGIC_VECTOR (2 DOWNTO 0) := "000"; - VARIABLE bwb_in : STD_LOGIC_VECTOR (2 DOWNTO 0) := "000"; - VARIABLE bwc_in : STD_LOGIC_VECTOR (2 DOWNTO 0) := "000"; - VARIABLE bwd_in : STD_LOGIC_VECTOR (2 DOWNTO 0) := "000"; - VARIABLE bcnt : STD_LOGIC_VECTOR (1 DOWNTO 0) := "00"; - - BEGIN - WAIT ON Clk; - IF Clk'EVENT AND Clk = '1' THEN - IF CEN_n = '0' AND Zz = '0' THEN - -- Write Address Register - Addr_write := Addr_read; - - -- Read Address Register - Addr_read := Addr_in ((addr_bits - 1) DOWNTO 2) & bAddr1 & bAddr0; - - -- Address Register - IF AdvLd_n = '0' and ce = '1' THEN - Addr_in := Addr; - first_Addr := Addr(1 DOWNTO 0); - bcnt := Addr(1 DOWNTO 0); - END IF; - - - -- Burst Logic - IF Mode = '0' AND AdvLd_n = '1' THEN - bcnt := bcnt + 1; - ELSIF Mode = '1' AND AdvLd_n = '1' THEN - IF (CONV_INTEGER1 (first_Addr) REM 2 = 0) THEN - bcnt := bcnt + 1; - ELSIF (CONV_INTEGER1 (first_Addr) REM 2 = 1) THEN - bcnt := bcnt - 1; - END IF; - END IF; - - - bAddr1 := bcnt (1); - bAddr0 := bcnt (0); - - -- Read Logic - ce_in (0) := ce_in (1); - - IF AdvLd_n = '0' THEN - ce_in (1) := ce; - END IF; - - rw_in (0) := rw_in (1); - rw_in (1) := rw_in (2); - - IF AdvLd_n = '0' THEN - rw_in (2) := NOT(ce AND NOT(Rw_n)); - END IF; - - -- Write Registry and Data Coherency Control Logic - bwa_in (0) := bwa_in (1); - bwb_in (0) := bwb_in (1); - bwc_in (0) := bwc_in (1); - bwd_in (0) := bwd_in (1); - bwa_in (1) := bwa_in (2); - bwb_in (1) := bwb_in (2); - bwc_in (1) := bwc_in (2); - bwd_in (1) := bwd_in (2); - bwa_in (2) := Bwa_n; - bwb_in (2) := Bwb_n; - bwc_in (2) := Bwc_n; - bwd_in (2) := Bwd_n; - - -- Write Data to Memory - IF rw_in (0) = '0' AND bwa_in (0) = '0' THEN - bank0 (CONV_INTEGER1 (Addr_write)) := Dpq(0) & Dq ( (data_bits / 4) - 1 DOWNTO 0); - END IF; - IF rw_in (0) = '0' AND bwb_in (0) = '0' THEN - bank1 (CONV_INTEGER1 (Addr_write)) := Dpq(1) & Dq ((data_bits / 2 - 1) DOWNTO (data_bits / 4)); - END IF; - IF rw_in (0) = '0' AND bwc_in (0) = '0' THEN - bank2 (CONV_INTEGER1 (Addr_write)) := Dpq(2) & Dq ((3 * (data_bits / 4)) - 1 DOWNTO (data_bits / 2)); - END IF; - IF rw_in (0) = '0' AND bwd_in (0) = '0' THEN - bank3 (CONV_INTEGER1 (Addr_write)) := Dpq(3) & Dq (data_bits - 1 DOWNTO (3 * (data_bits / 4))); - END IF; - END IF; - - Addr_read_sig <= Addr_read; - - -- Read Data from Memory Array - IF ce_in (0) = '1' AND rw_in (1) = '1' THEN - dout ((data_bits / 4) - 1 DOWNTO 0) <= bank0 (CONV_INTEGER1 (Addr_read))( (data_bits / 4) - 1 DOWNTO 0); - dout ((data_bits / 2 - 1) DOWNTO (data_bits / 4)) <= bank1 (CONV_INTEGER1 (Addr_read))( (data_bits / 4) - 1 DOWNTO 0); - dout ((3 * (data_bits / 4)) - 1 DOWNTO (data_bits / 2)) <= bank2 (CONV_INTEGER1 (Addr_read))( (data_bits / 4) - 1 DOWNTO 0); - dout (data_bits - 1 DOWNTO (3 * (data_bits / 4))) <= bank3 (CONV_INTEGER1 (Addr_read))( (data_bits / 4) - 1 DOWNTO 0); - dout_p(0) <= bank0 (CONV_INTEGER1 (Addr_read))(data_bits / 4); - dout_p(1) <= bank1 (CONV_INTEGER1 (Addr_read))(data_bits / 4); - dout_p(2) <= bank2 (CONV_INTEGER1 (Addr_read))(data_bits / 4); - dout_p(3) <= bank3 (CONV_INTEGER1 (Addr_read))(data_bits / 4); - ELSE - dout <= (OTHERS => 'Z'); - dout_p <= (OTHERS => 'Z'); - END IF; - END IF; - END PROCESS; - -END behave; - - - +----------------------------------------------------------------------------------------- +-- +-- File Name: CY7C1354B.VHD +-- Version: 2.0 +-- Date: Nov 22nd, 2004 +-- Model: BUS Functional +-- +-- +-- Author: RKF +-- Company: Cypress Semiconductor +-- Model: CY7C1354B (256k x 36) +-- Mode: Pipelined +-- +-- Description: NoBL SRAM VHDL Model +-- +-- Limitation: None +-- +-- Note: - BSDL Model available separately +-- - Set simulator resolution to "ps" timescale +-- +-- Disclaimer: THESE DESIGNS ARE PROVIDED "AS IS" WITH NO WARRANTY +-- WHATSOEVER AND CYPRESS SPECIFICALLY DISCLAIMS ANY +-- IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR +-- A PARTICULAR PURPOSE, OR AGAINST INFRINGEMENT. +-- +-- Copyright (c) 2004 Cypress Semiconductor +-- All rights reserved +-- +-- Trademarks: NoBL and No Bus Latency are trademarks of Cypress Semiconductor +-- +-- Rev Author Date Changes +-- --- -------- ------- ---------- +-- 2.0 RKF 11/22/2004 - Second Release +-- - Fully Tested with New Test Bench and Test Vectors +----------------------------------------------------------------------------------------- + +LIBRARY ieee,work; + USE ieee.std_logic_1164.all; + USE ieee.std_logic_unsigned.all; + Use IEEE.Std_Logic_Arith.all; +-- Use work.all; + USE work.package_utility.all; + +ENTITY cy7c1354 IS + + GENERIC ( + + -- Constant parameters + addr_bits : INTEGER := 18; + data_bits : INTEGER := 32; + par_bits : INTEGER := 4; + + -- Timing parameters for -5 (225 Mhz) +-- tCYC : TIME := 4.4 ns; +-- tCH : TIME := 1.8 ns; +-- tCL : TIME := 1.8 ns; +-- tCO : TIME := 2.8 ns; +-- tAS : TIME := 1.4 ns; +-- tCENS : TIME := 1.4 ns; +-- tWES : TIME := 1.4 ns; +-- tDS : TIME := 1.4 ns; +-- tAH : TIME := 0.4 ns; +-- tCENH : TIME := 0.4 ns; +-- tWEH : TIME := 0.4 ns; +-- tDH : TIME := 0.4 ns + + + + -- Timing parameters for -6 (200 Mhz) + --tCYC : TIME := 5.0 ns; + --tCH : TIME := 2.0 ns; + --tCL : TIME := 2.0 ns; + --tCO : TIME := 3.2 ns; + --tAS : TIME := 1.5 ns; + --tCENS : TIME := 1.5 ns; + --tWES : TIME := 1.5 ns; + --tDS : TIME := 1.5 ns; + --tAH : TIME := 0.5 ns; + --tCENH : TIME := 0.5 ns; + --tWEH : TIME := 0.5 ns; + --tDH : TIME := 0.5 ns + + + -- Timing parameters for -7 (166 Mhz) + tCYC : TIME := 6.0 ns; + tCH : TIME := 2.4 ns; + tCL : TIME := 2.4 ns; + tCO : TIME := 3.5 ns; + tAS : TIME := 1.5 ns; + tCENS : TIME := 1.5 ns; + tWES : TIME := 1.5 ns; + tDS : TIME := 1.5 ns; + tAH : TIME := 0.5 ns; + tCENH : TIME := 0.5 ns; + tWEH : TIME := 0.5 ns; + tDH : TIME := 0.5 ns + + + + ); + + -- Port Declarations + PORT ( + Dq : INOUT STD_LOGIC_VECTOR ((data_bits - 1) DOWNTO 0); -- Data I/O + Dpq : INOUT STD_LOGIC_VECTOR ((par_bits - 1) DOWNTO 0); -- Data parity I/O + Addr : IN STD_LOGIC_VECTOR ((addr_bits - 1) DOWNTO 0); -- Address + Mode : IN STD_LOGIC := '1'; -- Burst Mode + Clk : IN STD_LOGIC; -- Clk + CEN_n : IN STD_LOGIC; -- CEN# + AdvLd_n : IN STD_LOGIC; -- Adv/Ld# + Bwa_n : IN STD_LOGIC; -- Bwa# + Bwb_n : IN STD_LOGIC; -- BWb# + Bwc_n : IN STD_LOGIC; -- Bwc# + Bwd_n : IN STD_LOGIC; -- BWd# + Rw_n : IN STD_LOGIC; -- RW# + Oe_n : IN STD_LOGIC; -- OE# + Ce1_n : IN STD_LOGIC; -- CE1# + Ce2 : IN STD_LOGIC; -- CE2 + Ce3_n : IN STD_LOGIC; -- CE3# + Zz : IN STD_LOGIC -- Snooze Mode + ); +END cy7c1354; + +ARCHITECTURE behave OF cy7c1354 IS + SIGNAL ce : STD_LOGIC := '0'; + SIGNAL doe : STD_LOGIC := '0'; + SIGNAL dout : STD_LOGIC_VECTOR ((data_bits - 1) DOWNTO 0) := (OTHERS => 'Z'); + SIGNAL dout_p : STD_LOGIC_VECTOR ((par_bits - 1) DOWNTO 0) := (OTHERS => 'Z'); + SIGNAL Addr_read_sig : STD_LOGIC_VECTOR ((addr_bits - 1) DOWNTO 0) := (OTHERS => 'Z'); + +BEGIN + + + ce <= NOT(Ce1_n) AND NOT(Ce3_n) AND Ce2; + + doe <= NOT(Oe_n) AND NOT(Zz); + + -- Output Buffers + WITH doe SELECT + Dq <= TRANSPORT dout AFTER (tCO) WHEN '1', + (OTHERS => 'Z') AFTER (tCO) WHEN OTHERS; + + WITH doe SELECT + Dpq <= TRANSPORT dout_p AFTER (tCO) WHEN '1', + (OTHERS => 'Z') AFTER (tCO) WHEN OTHERS; + + + -- Check for Clock Timing Violation + clk_check : PROCESS + VARIABLE clk_high, clk_low : TIME := 0 ns; + BEGIN + WAIT ON Clk; + IF Clk = '1' AND NOW >= tCYC THEN + ASSERT (NOW - clk_low >= tCH) + REPORT "Clk width low - tCH violation" + SEVERITY ERROR; + ASSERT (NOW - clk_high >= tCYC) + REPORT "Clk period high - tCYC violation" + SEVERITY ERROR; + clk_high := NOW; + ELSIF Clk = '0' AND NOW /= 0 ns THEN + ASSERT (NOW - clk_high >= tCL) + REPORT "Clk width high - tCL violation" + SEVERITY ERROR; + ASSERT (NOW - clk_low >= tCYC) + REPORT "Clk period low - tCYC violation" + SEVERITY ERROR; + clk_low := NOW; + END IF; + END PROCESS; + + -- Check for Setup Timing Violation + setup_check : PROCESS + BEGIN + WAIT ON Clk; + IF Clk = '1' and (Ce1_n = '0' and Ce2 = '1' and Ce3_n = '0') THEN + ASSERT (Addr'LAST_EVENT >= tAS) + REPORT "Addr - tAS violation" + SEVERITY ERROR; + ASSERT (CEN_n'LAST_EVENT >= tCENS) + REPORT "CKE# - tCENS violation" + SEVERITY ERROR; + ASSERT (Ce1_n'LAST_EVENT >= tWES) + REPORT "CE1# - tWES violation" + SEVERITY ERROR; + ASSERT (Ce2'LAST_EVENT >= tWES) + REPORT "CE2 - tWES violation" + SEVERITY ERROR; + ASSERT (Ce3_n'LAST_EVENT >= tWES) + REPORT "CE3# - tWES violation" + SEVERITY ERROR; + ASSERT (AdvLd_n'LAST_EVENT >= tWES) + REPORT "ADV/LD# - tWES violation" + SEVERITY ERROR; + ASSERT (Rw_n'LAST_EVENT >= tWES) + REPORT "RW# - tWES violation" + SEVERITY ERROR; + ASSERT (Bwa_n'LAST_EVENT >= tWES) + REPORT "BWa# - tWES violation" + SEVERITY ERROR; + ASSERT (Bwb_n'LAST_EVENT >= tWES) + REPORT "BWb# - tWES violation" + SEVERITY ERROR; + ASSERT (Bwc_n'LAST_EVENT >= tWES) + REPORT "BWc# - tWES violation" + SEVERITY ERROR; + ASSERT (Bwd_n'LAST_EVENT >= tWES) + REPORT "BWd# - tWES violation" + SEVERITY ERROR; + ASSERT (Dq'LAST_EVENT >= tDS) + REPORT "Dq - tDS violation" + SEVERITY ERROR; + END IF; + END PROCESS; + + -- Check for Hold Timing Violation + hold_check : PROCESS + BEGIN + WAIT ON Clk'DELAYED(tAH), Clk'DELAYED(tCENH), Clk'DELAYED(tWEH), Clk'DELAYED(tDH); + IF Clk'DELAYED(tAH) = '1' THEN + ASSERT (Addr'LAST_EVENT > tAH) + REPORT "Addr - tAH violation" + SEVERITY ERROR; + END IF; + IF Clk'DELAYED(tCENH) = '1' THEN + ASSERT (CEN_n'LAST_EVENT > tCENH) + REPORT "CKE# - tCENH violation" + SEVERITY ERROR; + END IF; + IF Clk'DELAYED(tDH) = '1' THEN + ASSERT (Dq'LAST_EVENT > tDH) + REPORT "Dq - tDH violation" + SEVERITY ERROR; + END IF; + IF Clk'DELAYED(tWEH) = '1' THEN + ASSERT (Ce1_n'LAST_EVENT > tWEH) + REPORT "CE1# - tWEH violation" + SEVERITY ERROR; + ASSERT (Ce2'LAST_EVENT > tWEH) + REPORT "CE2 - tWEH violation" + SEVERITY ERROR; + ASSERT (Ce3_n'LAST_EVENT > tWEH) + REPORT "CE3 - tWEH violation" + SEVERITY ERROR; + ASSERT (AdvLd_n'LAST_EVENT > tWEH) + REPORT "ADV/LD# - tWEH violation" + SEVERITY ERROR; + ASSERT (Rw_n'LAST_EVENT > tWEH) + REPORT "RW# - tWEH violation" + SEVERITY ERROR; + ASSERT (Bwa_n'LAST_EVENT > tWEH) + REPORT "BWa# - tWEH violation" + SEVERITY ERROR; + ASSERT (Bwb_n'LAST_EVENT > tWEH) + REPORT "BWb# - tWEH violation" + SEVERITY ERROR; + ASSERT (Bwc_n'LAST_EVENT > tWEH) + REPORT "BWc# - tWEH violation" + SEVERITY ERROR; + ASSERT (Bwd_n'LAST_EVENT > tWEH) + REPORT "BWd# - tWEH violation" + SEVERITY ERROR; + END IF; + + END PROCESS; + + -- Main Program + main : PROCESS + + TYPE memory_array IS ARRAY ((2**addr_bits) - 1 DOWNTO 0) OF STD_LOGIC_VECTOR (((data_bits+par_bits) / 4) - 1 DOWNTO 0); + + VARIABLE Addr_in : STD_LOGIC_VECTOR ((addr_bits - 1) DOWNTO 0) := (OTHERS => '0'); + VARIABLE first_Addr : STD_LOGIC_VECTOR (1 DOWNTO 0) := (OTHERS => '0'); + VARIABLE Addr_read : STD_LOGIC_VECTOR ((addr_bits - 1) DOWNTO 0) := (OTHERS => '0'); + VARIABLE Addr_write : STD_LOGIC_VECTOR ((addr_bits - 1) DOWNTO 0) := (OTHERS => '0'); + VARIABLE bAddr0, bAddr1 : STD_LOGIC := '0'; + VARIABLE bank0 : memory_array; + VARIABLE bank1 : memory_array; + VARIABLE bank2 : memory_array; + VARIABLE bank3 : memory_array; + + VARIABLE ce_in : STD_LOGIC_VECTOR (1 DOWNTO 0) := "00"; + VARIABLE rw_in : STD_LOGIC_VECTOR (2 DOWNTO 0) := "111"; + VARIABLE bwa_in : STD_LOGIC_VECTOR (2 DOWNTO 0) := "000"; + VARIABLE bwb_in : STD_LOGIC_VECTOR (2 DOWNTO 0) := "000"; + VARIABLE bwc_in : STD_LOGIC_VECTOR (2 DOWNTO 0) := "000"; + VARIABLE bwd_in : STD_LOGIC_VECTOR (2 DOWNTO 0) := "000"; + VARIABLE bcnt : STD_LOGIC_VECTOR (1 DOWNTO 0) := "00"; + + BEGIN + WAIT ON Clk; + IF Clk'EVENT AND Clk = '1' THEN + IF CEN_n = '0' AND Zz = '0' THEN + -- Write Address Register + Addr_write := Addr_read; + + -- Read Address Register + Addr_read := Addr_in ((addr_bits - 1) DOWNTO 2) & bAddr1 & bAddr0; + + -- Address Register + IF AdvLd_n = '0' and ce = '1' THEN + Addr_in := Addr; + first_Addr := Addr(1 DOWNTO 0); + bcnt := Addr(1 DOWNTO 0); + END IF; + + + -- Burst Logic + IF Mode = '0' AND AdvLd_n = '1' THEN + bcnt := bcnt + 1; + ELSIF Mode = '1' AND AdvLd_n = '1' THEN + IF (CONV_INTEGER1 (first_Addr) REM 2 = 0) THEN + bcnt := bcnt + 1; + ELSIF (CONV_INTEGER1 (first_Addr) REM 2 = 1) THEN + bcnt := bcnt - 1; + END IF; + END IF; + + + bAddr1 := bcnt (1); + bAddr0 := bcnt (0); + + -- Read Logic + ce_in (0) := ce_in (1); + + IF AdvLd_n = '0' THEN + ce_in (1) := ce; + END IF; + + rw_in (0) := rw_in (1); + rw_in (1) := rw_in (2); + + IF AdvLd_n = '0' THEN + rw_in (2) := NOT(ce AND NOT(Rw_n)); + END IF; + + -- Write Registry and Data Coherency Control Logic + bwa_in (0) := bwa_in (1); + bwb_in (0) := bwb_in (1); + bwc_in (0) := bwc_in (1); + bwd_in (0) := bwd_in (1); + bwa_in (1) := bwa_in (2); + bwb_in (1) := bwb_in (2); + bwc_in (1) := bwc_in (2); + bwd_in (1) := bwd_in (2); + bwa_in (2) := Bwa_n; + bwb_in (2) := Bwb_n; + bwc_in (2) := Bwc_n; + bwd_in (2) := Bwd_n; + + -- Write Data to Memory + IF rw_in (0) = '0' AND bwa_in (0) = '0' THEN + bank0 (CONV_INTEGER1 (Addr_write)) := Dpq(0) & Dq ( (data_bits / 4) - 1 DOWNTO 0); + END IF; + IF rw_in (0) = '0' AND bwb_in (0) = '0' THEN + bank1 (CONV_INTEGER1 (Addr_write)) := Dpq(1) & Dq ((data_bits / 2 - 1) DOWNTO (data_bits / 4)); + END IF; + IF rw_in (0) = '0' AND bwc_in (0) = '0' THEN + bank2 (CONV_INTEGER1 (Addr_write)) := Dpq(2) & Dq ((3 * (data_bits / 4)) - 1 DOWNTO (data_bits / 2)); + END IF; + IF rw_in (0) = '0' AND bwd_in (0) = '0' THEN + bank3 (CONV_INTEGER1 (Addr_write)) := Dpq(3) & Dq (data_bits - 1 DOWNTO (3 * (data_bits / 4))); + END IF; + END IF; + + Addr_read_sig <= Addr_read; + + -- Read Data from Memory Array + IF ce_in (0) = '1' AND rw_in (1) = '1' THEN + dout ((data_bits / 4) - 1 DOWNTO 0) <= bank0 (CONV_INTEGER1 (Addr_read))( (data_bits / 4) - 1 DOWNTO 0); + dout ((data_bits / 2 - 1) DOWNTO (data_bits / 4)) <= bank1 (CONV_INTEGER1 (Addr_read))( (data_bits / 4) - 1 DOWNTO 0); + dout ((3 * (data_bits / 4)) - 1 DOWNTO (data_bits / 2)) <= bank2 (CONV_INTEGER1 (Addr_read))( (data_bits / 4) - 1 DOWNTO 0); + dout (data_bits - 1 DOWNTO (3 * (data_bits / 4))) <= bank3 (CONV_INTEGER1 (Addr_read))( (data_bits / 4) - 1 DOWNTO 0); + dout_p(0) <= bank0 (CONV_INTEGER1 (Addr_read))(data_bits / 4); + dout_p(1) <= bank1 (CONV_INTEGER1 (Addr_read))(data_bits / 4); + dout_p(2) <= bank2 (CONV_INTEGER1 (Addr_read))(data_bits / 4); + dout_p(3) <= bank3 (CONV_INTEGER1 (Addr_read))(data_bits / 4); + ELSE + dout <= (OTHERS => 'Z'); + dout_p <= (OTHERS => 'Z'); + END IF; + END IF; + END PROCESS; + +END behave; + + + diff --git a/lib/SSRAM/src/package_utility.vhd b/lib/SSRAM/src/package_utility.vhd index 9fb543f..fcceb71 100644 --- a/lib/SSRAM/src/package_utility.vhd +++ b/lib/SSRAM/src/package_utility.vhd @@ -1,73 +1,73 @@ ---**************************************************************** ---** MODEL : package_utility ** ---** COMPANY : Cypress Semiconductor ** ---** REVISION: 1.0 Created new package utility model ** ---** ** ---**************************************************************** -Library ieee,work; - Use ieee.std_logic_1164.all; - Use IEEE.Std_Logic_Arith.all; - Use IEEE.std_logic_TextIO.all; - --- Use work.package_timing.all; - -Library Std; - Use STD.TextIO.all; - -Package package_utility is - -FUNCTION convert_string( S: in STRING) RETURN STD_LOGIC_VECTOR; -FUNCTION CONV_INTEGER1(S : STD_LOGIC_VECTOR) RETURN INTEGER; - -End; -- package package_utility - -Package body package_utility is - - ------------------------------------------------------------------------------------------------- ---Converts string into std_logic_vector ------------------------------------------------------------------------------------------------- - -FUNCTION convert_string(S: in STRING) RETURN STD_LOGIC_VECTOR IS - VARIABLE result : STD_LOGIC_VECTOR(S'RANGE); - BEGIN - FOR i IN S'RANGE LOOP - IF S(i) = '0' THEN - result(i) := '0'; - ELSIF S(i) = '1' THEN - result(i) := '1'; - ELSIF S(i) = 'X' THEN - result(i) := 'X'; - ELSE - result(i) := 'Z'; - END IF; - END LOOP; - RETURN result; -END convert_string; - ------------------------------------------------------------------------------------------------- ---Converts std_logic_vector into integer ------------------------------------------------------------------------------------------------- - -FUNCTION CONV_INTEGER1(S : STD_LOGIC_VECTOR) RETURN INTEGER IS - VARIABLE result : INTEGER := 0; - BEGIN - FOR i IN S'RANGE LOOP - IF S(i) = '1' THEN - result := result + (2**i); - ELSIF S(i) = '0' THEN - result := result; - ELSE - result := 0; - END IF; - END LOOP; - RETURN result; - END CONV_INTEGER1; - - - - -end package_utility; - - - - +--**************************************************************** +--** MODEL : package_utility ** +--** COMPANY : Cypress Semiconductor ** +--** REVISION: 1.0 Created new package utility model ** +--** ** +--**************************************************************** +Library ieee,work; + Use ieee.std_logic_1164.all; + Use IEEE.Std_Logic_Arith.all; + Use IEEE.std_logic_TextIO.all; + --- Use work.package_timing.all; + +Library Std; + Use STD.TextIO.all; + +Package package_utility is + +FUNCTION convert_string( S: in STRING) RETURN STD_LOGIC_VECTOR; +FUNCTION CONV_INTEGER1(S : STD_LOGIC_VECTOR) RETURN INTEGER; + +End; -- package package_utility + +Package body package_utility is + + +------------------------------------------------------------------------------------------------ +--Converts string into std_logic_vector +------------------------------------------------------------------------------------------------ + +FUNCTION convert_string(S: in STRING) RETURN STD_LOGIC_VECTOR IS + VARIABLE result : STD_LOGIC_VECTOR(S'RANGE); + BEGIN + FOR i IN S'RANGE LOOP + IF S(i) = '0' THEN + result(i) := '0'; + ELSIF S(i) = '1' THEN + result(i) := '1'; + ELSIF S(i) = 'X' THEN + result(i) := 'X'; + ELSE + result(i) := 'Z'; + END IF; + END LOOP; + RETURN result; +END convert_string; + +------------------------------------------------------------------------------------------------ +--Converts std_logic_vector into integer +------------------------------------------------------------------------------------------------ + +FUNCTION CONV_INTEGER1(S : STD_LOGIC_VECTOR) RETURN INTEGER IS + VARIABLE result : INTEGER := 0; + BEGIN + FOR i IN S'RANGE LOOP + IF S(i) = '1' THEN + result := result + (2**i); + ELSIF S(i) = '0' THEN + result := result; + ELSE + result := 0; + END IF; + END LOOP; + RETURN result; + END CONV_INTEGER1; + + + + +end package_utility; + + + + diff --git a/lib/SSRAM/src/ssram_frontend_wb.vhd b/lib/SSRAM/src/ssram_frontend_wb.vhd index 056b328..b554880 100644 --- a/lib/SSRAM/src/ssram_frontend_wb.vhd +++ b/lib/SSRAM/src/ssram_frontend_wb.vhd @@ -1,181 +1,181 @@ -LIBRARY IEEE; -USE IEEE.STD_LOGIC_1164.ALL; -USE IEEE.NUMERIC_STD.ALL; - -Library UNISIM; -use UNISIM.vcomponents.all; - -ENTITY ssram_frontend_wb IS - Generic - ( - latency : natural := 2; -- clock cycles - addr_width : natural := 20; - data_width : natural := 32; - parity_width : natural := 4 - ); - Port - ( - -- J-Bus domain - CLK_I : in STD_LOGIC; - RST_I : in STD_LOGIC; - CYC_I : in STD_LOGIC; - STB_I : in STD_LOGIC; - SEL_I : in unsigned(3 downto 0); - WE_I : in STD_LOGIC; - ACK_O : out STD_LOGIC; - SRDY_O : out STD_LOGIC; - MRDY_I : in STD_LOGIC; - ADDR_I : in unsigned(31 downto 0); - DAT_I : in unsigned(31 downto 0); - DAT_O : out unsigned(31 downto 0); - - -- Sync SRAM domain - ssram_clk_o : out std_logic; - ssram_clk_fb : in std_logic; - ssram_cke_n : out std_logic; - ssram_ce_n : out std_logic; - ssram_oe_n : out std_logic; - ssram_we_n : out std_logic; - ssram_adv : out std_logic; - ssram_mode : out std_logic; - ssram_zz : out std_logic; - ssram_a : out unsigned(addr_width-1 downto 0); - ssram_d : inout unsigned(data_width-1 downto 0); - ssram_dp : inout unsigned(parity_width-1 downto 0); - ssram_bw_n : out unsigned(3 downto 0) - ); -END ssram_frontend_wb; - -ARCHITECTURE behavior OF ssram_frontend_wb IS - - constant topad : time := 3 ns; - subtype ssram_d_t is unsigned(data_width+parity_width-1 downto 0); - type data_pipe_t is array (latency downto 0) of ssram_d_t; - - signal ssram_clk : std_logic; - signal dcm_locked : std_logic; - signal dcm_clk0 : std_logic; - signal dcm_clk1 : std_logic; - signal data_en : std_logic; - signal drive : std_logic; - signal vld_pipe : unsigned(latency downto 0); - signal drive_pipe : unsigned(latency downto 0); - signal data_pipe : data_pipe_t; - signal ssram_dout : ssram_d_t; - -begin - - SRDY_O <= CYC_I and dcm_locked; - ACK_O <= vld_pipe(vld_pipe'left); - DAT_O(data_width-1 downto 0) <= ssram_d; - - data_en <= CYC_I and STB_I; - ssram_dout <= "0000" & DAT_I(data_width-1 downto 0); - drive <= drive_pipe(drive_pipe'left); - - ssram_clk_o <= ssram_clk after topad; - ssram_cke_n <= not dcm_locked after topad; - ssram_oe_n <= not vld_pipe(vld_pipe'left-1) after topad; - -inst_clock_out : ODDR - generic map - ( - DDR_CLK_EDGE => "OPPOSITE_EDGE", -- "OPPOSITE_EDGE" or "SAME_EDGE" - INIT => '0', -- Initial value for Q port ('1' or '0') - SRTYPE => "SYNC" -- Reset Type ("ASYNC" or "SYNC") - ) - port map ( - Q => ssram_clk, -- 1-bit DDR output - C => dcm_clk1, -- 1-bit clock input - CE => '1', -- 1-bit clock enable input - D1 => '1', -- 1-bit data input (positive edge) - D2 => '0', -- 1-bit data input (negative edge) - R => '0', -- 1-bit reset input - S => '0' -- 1-bit set input - ); - -ssram_bufg: bufg - port map - ( - o => dcm_clk1, - i => dcm_clk0 - ); - -inst_DCM_BASE_0 : DCM_BASE - generic map ( - CLKDV_DIVIDE => 2.0, -- Divide by: 1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5 - -- 7.0,7.5,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0 or 16.0 - CLKFX_DIVIDE => 1, -- Can be any interger from 1 to 32 - CLKFX_MULTIPLY => 4, -- Can be any integer from 2 to 32 - CLKIN_DIVIDE_BY_2 => FALSE, -- TRUE/FALSE to enable CLKIN divide by two feature - CLKIN_PERIOD => 10.0 , -- Specify period of input clock in ns from 1.25 to 1000.00 - CLKOUT_PHASE_SHIFT => "FIXED", -- Specify phase shift mode of NONE or FIXED - CLK_FEEDBACK => "1X", -- Specify clock feedback of NONE or 1X - DCM_AUTOCALIBRATION => TRUE, -- DCM calibrartion circuitry TRUE/FALSE - DCM_PERFORMANCE_MODE => "MAX_SPEED", -- Can be MAX_SPEED or MAX_RANGE - DESKEW_ADJUST => "SOURCE_SYNCHRONOUS", -- SOURCE_SYNCHRONOUS, SYSTEM_SYNCHRONOUS or - -- an integer from 0 to 15 - DFS_FREQUENCY_MODE => "LOW", -- LOW or HIGH frequency mode for frequency synthesis - DLL_FREQUENCY_MODE => "LOW", -- LOW, HIGH, or HIGH_SER frequency mode for DLL - DUTY_CYCLE_CORRECTION => TRUE, -- Duty cycle correction, TRUE or FALSE - FACTORY_JF => X"F0F0", -- FACTORY JF Values Suggested to be set to X"F0F0" - PHASE_SHIFT => 0, -- Amount of fixed phase shift from -255 to 1023 - STARTUP_WAIT => FALSE) -- Delay configuration DONE until DCM LOCK, TRUE/FALSE - port map ( - CLK0 => dcm_clk0, -- 0 degree DCM CLK ouptput - CLK180 => open, -- 180 degree DCM CLK output - CLK270 => open, -- 270 degree DCM CLK output - CLK2X => open, -- 2X DCM CLK output - CLK2X180 => open, -- 2X, 180 degree DCM CLK out - CLK90 => open, -- 90 degree DCM CLK output - CLKDV => open, -- Divided DCM CLK out (CLKDV_DIVIDE) - CLKFX => open, -- DCM CLK synthesis out (M/D) - CLKFX180 => open, -- 180 degree CLK synthesis out - LOCKED => dcm_locked, -- DCM LOCK status output - CLKFB => ssram_clk_fb, -- DCM clock feedback - CLKIN => CLK_I, -- Clock input (from IBUFG, BUFG or DCM) - RST => RST_I -- DCM asynchronous reset input - ); - - -data_valid_pipeline: - process(CLK_I) - begin - if rising_edge(CLK_I) then - if RST_I = '1' then - vld_pipe <= (others => '0'); - else - vld_pipe <= vld_pipe(vld_pipe'left-1 downto 0) & (data_en and MRDY_I and not WE_I); - end if; - end if; - end process; - -data_out_pipeline: - process(CLK_I) - begin - if rising_edge(CLK_I) then - if RST_I = '1' then - ssram_ce_n <= '1' after topad; - ssram_we_n <= '1' after topad; - ssram_adv <= '0' after topad; - ssram_mode <= '0' after topad; - ssram_zz <= '1' after topad; - drive_pipe <= (others => '0'); - elsif dcm_locked = '1' then - ssram_ce_n <= not data_en after topad; - ssram_we_n <= not (WE_I and data_en) after topad; - ssram_adv <= '0' after topad; - ssram_mode <= '0' after topad; - ssram_zz <= '0' after topad; - ssram_a <= ADDR_I(addr_width-1 downto 0) after topad; - ssram_bw_n <= not SEL_I after topad; - drive_pipe <= drive_pipe(drive_pipe'left-1 downto 0) & (data_en and WE_I); - data_pipe <= data_pipe(data_pipe'left-1 downto 0) & ssram_dout; - end if; - end if; - end process; - - ssram_d <= data_pipe(data_pipe'left)(data_width-1 downto 0) after topad when drive = '1' else (others => 'Z') after topad; - ssram_dp <= data_pipe(data_pipe'left)(data_width+parity_width-1 downto data_width) after topad when drive = '1' else (others => 'Z') after topad; - -end behavior; +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.NUMERIC_STD.ALL; + +Library UNISIM; +use UNISIM.vcomponents.all; + +ENTITY ssram_frontend_wb IS + Generic + ( + latency : natural := 2; -- clock cycles + addr_width : natural := 20; + data_width : natural := 32; + parity_width : natural := 4 + ); + Port + ( + -- J-Bus domain + CLK_I : in STD_LOGIC; + RST_I : in STD_LOGIC; + CYC_I : in STD_LOGIC; + STB_I : in STD_LOGIC; + SEL_I : in unsigned(3 downto 0); + WE_I : in STD_LOGIC; + ACK_O : out STD_LOGIC; + SRDY_O : out STD_LOGIC; + MRDY_I : in STD_LOGIC; + ADDR_I : in unsigned(31 downto 0); + DAT_I : in unsigned(31 downto 0); + DAT_O : out unsigned(31 downto 0); + + -- Sync SRAM domain + ssram_clk_o : out std_logic; + ssram_clk_fb : in std_logic; + ssram_cke_n : out std_logic; + ssram_ce_n : out std_logic; + ssram_oe_n : out std_logic; + ssram_we_n : out std_logic; + ssram_adv : out std_logic; + ssram_mode : out std_logic; + ssram_zz : out std_logic; + ssram_a : out unsigned(addr_width-1 downto 0); + ssram_d : inout unsigned(data_width-1 downto 0); + ssram_dp : inout unsigned(parity_width-1 downto 0); + ssram_bw_n : out unsigned(3 downto 0) + ); +END ssram_frontend_wb; + +ARCHITECTURE behavior OF ssram_frontend_wb IS + + constant topad : time := 3 ns; + subtype ssram_d_t is unsigned(data_width+parity_width-1 downto 0); + type data_pipe_t is array (latency downto 0) of ssram_d_t; + + signal ssram_clk : std_logic; + signal dcm_locked : std_logic; + signal dcm_clk0 : std_logic; + signal dcm_clk1 : std_logic; + signal data_en : std_logic; + signal drive : std_logic; + signal vld_pipe : unsigned(latency downto 0); + signal drive_pipe : unsigned(latency downto 0); + signal data_pipe : data_pipe_t; + signal ssram_dout : ssram_d_t; + +begin + + SRDY_O <= CYC_I and dcm_locked; + ACK_O <= vld_pipe(vld_pipe'left); + DAT_O(data_width-1 downto 0) <= ssram_d; + + data_en <= CYC_I and STB_I; + ssram_dout <= "0000" & DAT_I(data_width-1 downto 0); + drive <= drive_pipe(drive_pipe'left); + + ssram_clk_o <= ssram_clk after topad; + ssram_cke_n <= not dcm_locked after topad; + ssram_oe_n <= not vld_pipe(vld_pipe'left-1) after topad; + +inst_clock_out : ODDR + generic map + ( + DDR_CLK_EDGE => "OPPOSITE_EDGE", -- "OPPOSITE_EDGE" or "SAME_EDGE" + INIT => '0', -- Initial value for Q port ('1' or '0') + SRTYPE => "SYNC" -- Reset Type ("ASYNC" or "SYNC") + ) + port map ( + Q => ssram_clk, -- 1-bit DDR output + C => dcm_clk1, -- 1-bit clock input + CE => '1', -- 1-bit clock enable input + D1 => '1', -- 1-bit data input (positive edge) + D2 => '0', -- 1-bit data input (negative edge) + R => '0', -- 1-bit reset input + S => '0' -- 1-bit set input + ); + +ssram_bufg: bufg + port map + ( + o => dcm_clk1, + i => dcm_clk0 + ); + +inst_DCM_BASE_0 : DCM_BASE + generic map ( + CLKDV_DIVIDE => 2.0, -- Divide by: 1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5 + -- 7.0,7.5,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0 or 16.0 + CLKFX_DIVIDE => 1, -- Can be any interger from 1 to 32 + CLKFX_MULTIPLY => 4, -- Can be any integer from 2 to 32 + CLKIN_DIVIDE_BY_2 => FALSE, -- TRUE/FALSE to enable CLKIN divide by two feature + CLKIN_PERIOD => 10.0 , -- Specify period of input clock in ns from 1.25 to 1000.00 + CLKOUT_PHASE_SHIFT => "FIXED", -- Specify phase shift mode of NONE or FIXED + CLK_FEEDBACK => "1X", -- Specify clock feedback of NONE or 1X + DCM_AUTOCALIBRATION => TRUE, -- DCM calibrartion circuitry TRUE/FALSE + DCM_PERFORMANCE_MODE => "MAX_SPEED", -- Can be MAX_SPEED or MAX_RANGE + DESKEW_ADJUST => "SOURCE_SYNCHRONOUS", -- SOURCE_SYNCHRONOUS, SYSTEM_SYNCHRONOUS or + -- an integer from 0 to 15 + DFS_FREQUENCY_MODE => "LOW", -- LOW or HIGH frequency mode for frequency synthesis + DLL_FREQUENCY_MODE => "LOW", -- LOW, HIGH, or HIGH_SER frequency mode for DLL + DUTY_CYCLE_CORRECTION => TRUE, -- Duty cycle correction, TRUE or FALSE + FACTORY_JF => X"F0F0", -- FACTORY JF Values Suggested to be set to X"F0F0" + PHASE_SHIFT => 0, -- Amount of fixed phase shift from -255 to 1023 + STARTUP_WAIT => FALSE) -- Delay configuration DONE until DCM LOCK, TRUE/FALSE + port map ( + CLK0 => dcm_clk0, -- 0 degree DCM CLK ouptput + CLK180 => open, -- 180 degree DCM CLK output + CLK270 => open, -- 270 degree DCM CLK output + CLK2X => open, -- 2X DCM CLK output + CLK2X180 => open, -- 2X, 180 degree DCM CLK out + CLK90 => open, -- 90 degree DCM CLK output + CLKDV => open, -- Divided DCM CLK out (CLKDV_DIVIDE) + CLKFX => open, -- DCM CLK synthesis out (M/D) + CLKFX180 => open, -- 180 degree CLK synthesis out + LOCKED => dcm_locked, -- DCM LOCK status output + CLKFB => ssram_clk_fb, -- DCM clock feedback + CLKIN => CLK_I, -- Clock input (from IBUFG, BUFG or DCM) + RST => RST_I -- DCM asynchronous reset input + ); + + +data_valid_pipeline: + process(CLK_I) + begin + if rising_edge(CLK_I) then + if RST_I = '1' then + vld_pipe <= (others => '0'); + else + vld_pipe <= vld_pipe(vld_pipe'left-1 downto 0) & (data_en and MRDY_I and not WE_I); + end if; + end if; + end process; + +data_out_pipeline: + process(CLK_I) + begin + if rising_edge(CLK_I) then + if RST_I = '1' then + ssram_ce_n <= '1' after topad; + ssram_we_n <= '1' after topad; + ssram_adv <= '0' after topad; + ssram_mode <= '0' after topad; + ssram_zz <= '1' after topad; + drive_pipe <= (others => '0'); + elsif dcm_locked = '1' then + ssram_ce_n <= not data_en after topad; + ssram_we_n <= not (WE_I and data_en) after topad; + ssram_adv <= '0' after topad; + ssram_mode <= '0' after topad; + ssram_zz <= '0' after topad; + ssram_a <= ADDR_I(addr_width-1 downto 0) after topad; + ssram_bw_n <= not SEL_I after topad; + drive_pipe <= drive_pipe(drive_pipe'left-1 downto 0) & (data_en and WE_I); + data_pipe <= data_pipe(data_pipe'left-1 downto 0) & ssram_dout; + end if; + end if; + end process; + + ssram_d <= data_pipe(data_pipe'left)(data_width-1 downto 0) after topad when drive = '1' else (others => 'Z') after topad; + ssram_dp <= data_pipe(data_pipe'left)(data_width+parity_width-1 downto data_width) after topad when drive = '1' else (others => 'Z') after topad; + +end behavior; diff --git a/lib/SSRAM/src/ssram_port_wb.vhd b/lib/SSRAM/src/ssram_port_wb.vhd new file mode 100644 index 0000000..04a522d --- /dev/null +++ b/lib/SSRAM/src/ssram_port_wb.vhd @@ -0,0 +1,192 @@ +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.NUMERIC_STD.ALL; + +Library UNISIM; +use UNISIM.vcomponents.all; + +ENTITY ssram_port_wb IS + Generic + ( + latency : natural := 2; -- clock cycles + addr_width : natural := 20; + data_width : natural := 32; + parity_width : natural := 4 + ); + Port + ( + -- J-Bus domain + CLK_I : in STD_LOGIC; + RST_I : in STD_LOGIC; + CYC_I : in STD_LOGIC; + STB_I : in STD_LOGIC; + SEL_I : in unsigned(3 downto 0); + WE_I : in STD_LOGIC; + ACK_O : out STD_LOGIC; + SRDY_O : out STD_LOGIC; + MRDY_I : in STD_LOGIC; + ADDR_I : in unsigned(31 downto 0); + DAT_I : in unsigned(31 downto 0); + DAT_O : out unsigned(31 downto 0); + + -- Sync SRAM domain + ssram_clk_o : out std_logic; + ssram_clk_fb : in std_logic; + ssram_cke_n : out std_logic; + ssram_ce_n : out std_logic; + port_bsyi : in std_logic; + port_bsyo : out std_logic; + port_a : out unsigned(addr_width-1 downto 0); + port_di : in unsigned(data_width-1 downto 0); + port_do : out unsigned(data_width-1 downto 0); + port_d_drv : out STD_LOGIC; + port_wr : out STD_LOGIC; + port_rd : out STD_LOGIC; + ssram_adv : out std_logic; + ssram_mode : out std_logic; + ssram_zz : out std_logic; + ssram_dp : inout unsigned(parity_width-1 downto 0); + ssram_bw_n : out unsigned(3 downto 0) + ); +END ssram_port_wb; + +ARCHITECTURE behavior OF ssram_port_wb IS + + constant topad : time := 3 ns; + subtype ssram_d_t is unsigned(data_width+parity_width-1 downto 0); + type data_pipe_t is array (latency downto 0) of ssram_d_t; + + signal ssram_clk : std_logic; + signal dcm_locked : std_logic; + signal dcm_clk0 : std_logic; + signal dcm_clk1 : std_logic; + signal data_en : std_logic; + signal drive : std_logic; + signal busy : std_logic; + signal bsy_pipe : unsigned(latency downto 0); + signal vld_pipe : unsigned(latency downto 0); + signal drive_pipe : unsigned(latency downto 0); + signal data_pipe : data_pipe_t; + signal ssram_dout : ssram_d_t; + +begin + + SRDY_O <= CYC_I and dcm_locked and not port_bsyi; + ACK_O <= vld_pipe(vld_pipe'left); + DAT_O(data_width-1 downto 0) <= port_di; + + data_en <= CYC_I and STB_I and not port_bsyi; + ssram_dout <= "0000" & DAT_I(data_width-1 downto 0); + drive <= drive_pipe(drive_pipe'left); + + ssram_clk_o <= ssram_clk after topad; + ssram_cke_n <= not dcm_locked after topad; + + port_a <= ADDR_I(addr_width-1 downto 0); + port_do <= data_pipe(data_pipe'left-1)(data_width-1 downto 0); + port_d_drv <= drive_pipe(drive_pipe'left-1); + port_wr <= not (WE_I and data_en); + port_rd <= not (vld_pipe(vld_pipe'left-2) or vld_pipe(vld_pipe'left-1)); + busy <= '1' when bsy_pipe /= (latency downto 0 => '0') else '0'; + port_bsyo <= busy or data_en; + +inst_clock_out : ODDR + generic map + ( + DDR_CLK_EDGE => "OPPOSITE_EDGE", -- "OPPOSITE_EDGE" or "SAME_EDGE" + INIT => '0', -- Initial value for Q port ('1' or '0') + SRTYPE => "SYNC" -- Reset Type ("ASYNC" or "SYNC") + ) + port map ( + Q => ssram_clk, -- 1-bit DDR output + C => dcm_clk1, -- 1-bit clock input + CE => '1', -- 1-bit clock enable input + D1 => '1', -- 1-bit data input (positive edge) + D2 => '0', -- 1-bit data input (negative edge) + R => '0', -- 1-bit reset input + S => '0' -- 1-bit set input + ); + +ssram_bufg: bufg + port map + ( + o => dcm_clk1, + i => dcm_clk0 + ); + +inst_DCM_BASE_0 : DCM_BASE + generic map ( + CLKDV_DIVIDE => 2.0, -- Divide by: 1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5 + -- 7.0,7.5,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0 or 16.0 + CLKFX_DIVIDE => 1, -- Can be any interger from 1 to 32 + CLKFX_MULTIPLY => 4, -- Can be any integer from 2 to 32 + CLKIN_DIVIDE_BY_2 => FALSE, -- TRUE/FALSE to enable CLKIN divide by two feature + CLKIN_PERIOD => 10.0 , -- Specify period of input clock in ns from 1.25 to 1000.00 + CLKOUT_PHASE_SHIFT => "FIXED", -- Specify phase shift mode of NONE or FIXED + CLK_FEEDBACK => "1X", -- Specify clock feedback of NONE or 1X + DCM_AUTOCALIBRATION => TRUE, -- DCM calibrartion circuitry TRUE/FALSE + DCM_PERFORMANCE_MODE => "MAX_SPEED", -- Can be MAX_SPEED or MAX_RANGE + DESKEW_ADJUST => "SOURCE_SYNCHRONOUS", -- SOURCE_SYNCHRONOUS, SYSTEM_SYNCHRONOUS or + -- an integer from 0 to 15 + DFS_FREQUENCY_MODE => "LOW", -- LOW or HIGH frequency mode for frequency synthesis + DLL_FREQUENCY_MODE => "LOW", -- LOW, HIGH, or HIGH_SER frequency mode for DLL + DUTY_CYCLE_CORRECTION => TRUE, -- Duty cycle correction, TRUE or FALSE + FACTORY_JF => X"F0F0", -- FACTORY JF Values Suggested to be set to X"F0F0" + PHASE_SHIFT => 0, -- Amount of fixed phase shift from -255 to 1023 + STARTUP_WAIT => FALSE) -- Delay configuration DONE until DCM LOCK, TRUE/FALSE + port map ( + CLK0 => dcm_clk0, -- 0 degree DCM CLK ouptput + CLK180 => open, -- 180 degree DCM CLK output + CLK270 => open, -- 270 degree DCM CLK output + CLK2X => open, -- 2X DCM CLK output + CLK2X180 => open, -- 2X, 180 degree DCM CLK out + CLK90 => open, -- 90 degree DCM CLK output + CLKDV => open, -- Divided DCM CLK out (CLKDV_DIVIDE) + CLKFX => open, -- DCM CLK synthesis out (M/D) + CLKFX180 => open, -- 180 degree CLK synthesis out + LOCKED => dcm_locked, -- DCM LOCK status output + CLKFB => ssram_clk_fb, -- DCM clock feedback + CLKIN => CLK_I, -- Clock input (from IBUFG, BUFG or DCM) + RST => RST_I -- DCM asynchronous reset input + ); + + +data_valid_pipeline: + process(CLK_I) + begin + if rising_edge(CLK_I) then + if RST_I = '1' then + vld_pipe <= (others => '0'); + bsy_pipe <= (others => '0'); + else + bsy_pipe <= bsy_pipe(bsy_pipe'left-1 downto 0) & (data_en); + vld_pipe <= vld_pipe(vld_pipe'left-1 downto 0) & (data_en and MRDY_I and not WE_I); + end if; + end if; + end process; + +data_out_pipeline: + process(CLK_I) + begin + if rising_edge(CLK_I) then + if RST_I = '1' then + ssram_ce_n <= '1' after topad; + ssram_adv <= '0' after topad; + ssram_mode <= '0' after topad; + ssram_zz <= '1' after topad; + drive_pipe <= (others => '0'); + else + ssram_ce_n <= not data_en after topad; + ssram_adv <= '0' after topad; + ssram_mode <= '0' after topad; + ssram_zz <= '0' after topad; + ssram_bw_n <= not SEL_I after topad; + drive_pipe <= drive_pipe(drive_pipe'left-1 downto 0) & (data_en and WE_I); + data_pipe <= data_pipe(data_pipe'left-1 downto 0) & ssram_dout; + end if; + end if; + end process; + + ssram_dp <= data_pipe(data_pipe'left)(data_width+parity_width-1 downto data_width) after topad when drive = '1' else (others => 'Z') after topad; + +end behavior; diff --git a/lib/SSRAM/src/tb_ssram_frontend_wb.vhd b/lib/SSRAM/src/tb_ssram_frontend_wb.vhd index 86f1411..d81247c 100644 --- a/lib/SSRAM/src/tb_ssram_frontend_wb.vhd +++ b/lib/SSRAM/src/tb_ssram_frontend_wb.vhd @@ -1,457 +1,457 @@ -------------------------------------------------------------------------- --- Project: JCPU, a portable 8-bit RISC CPU written in VHDL --- This file: testbench for system test using Xilinx ML-402 - --- Copyright (C) 2007 J. Ahrensfeld - --- This library is free software; you can redistribute it and/or --- modify it under the terms of the GNU Lesser General Public --- License as published by the Free Software Foundation; either --- version 2.1 of the License, or (at your option) any later version. - --- This library 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 --- Lesser General Public License for more details. - --- You should have received a copy of the GNU Lesser General Public --- License along with this library; if not, write to the Free Software --- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - --- For questions and ideas, please contact the author at jens@jayfield.org - ------------------------------------------------------------------------ - -LIBRARY ieee; -use IEEE.STD_LOGIC_1164.ALL; -USE ieee.numeric_std.ALL; -USE work.package_utility.all; - -Library UNISIM; -use UNISIM.vcomponents.all; - -ENTITY tb_ssram_frontend_wb IS -END tb_ssram_frontend_wb; - -ARCHITECTURE behavior OF tb_ssram_frontend_wb IS - - constant CLK_PERIOD : time := 10 ns; - signal CLK_O : std_logic := '1'; - signal RST_O : std_logic := '1'; - signal CYC_O : std_logic := '0'; - signal STB_O : std_logic := '0'; - signal WE_O : std_logic := '0'; - signal SEL_O : unsigned(3 downto 0) := (others => '1'); - signal ACK_I : std_logic; - signal MRDY_O : std_logic := '1'; - signal SRDY_I : std_logic; - signal ADDR_O : unsigned(31 downto 0) := (others => '-'); - signal DAT_I : unsigned(31 downto 0); - signal DAT_O : unsigned(31 downto 0) := (others => '-'); - - SIGNAL ssram_d : unsigned (32 - 1 DOWNTO 0) := (OTHERS => 'Z'); - SIGNAL ssram_dp : unsigned (4 - 1 DOWNTO 0) := (OTHERS => 'Z'); - SIGNAL ssram_a : unsigned (20 - 1 DOWNTO 0) := (OTHERS => '0'); - SIGNAL ssram_clk : STD_LOGIC := '0'; - SIGNAL ssram_cke_n : STD_LOGIC; - SIGNAL ssram_adv : STD_LOGIC; - SIGNAL ssram_mode : STD_LOGIC; - SIGNAL ssram_bw_n : unsigned(3 downto 0); - SIGNAL ssram_we_n : STD_LOGIC; - SIGNAL ssram_oe_n : STD_LOGIC; - SIGNAL ssram_ce_n : STD_LOGIC; - SIGNAL ssram_zz : STD_LOGIC; - - SIGNAL ssram_clk_fb : STD_LOGIC; - - signal dout_rst : std_logic := '0'; - signal dout_reg : unsigned(31 downto 0); - signal dout_cnt : natural range 0 to 255; - -BEGIN - - ssram_clk_fb <= ssram_clk after 0.5 ns; - -inst_ssram_frontend_wb : entity work.ssram_frontend_wb - GENERIC MAP - ( - addr_width => 20, - data_width => 32, - parity_width => 4 - ) - PORT MAP - ( - -- J-Bus domain - RST_I => RST_O, - CLK_I => CLK_O, - CYC_I => CYC_O, - STB_I => STB_O, - SEL_I => SEL_O, - WE_I => WE_O, - ACK_O => ACK_I, - SRDY_O => SRDY_I, - MRDY_I => MRDY_O, - ADDR_I => ADDR_O, - DAT_I => DAT_O, - DAT_O => DAT_I, - - -- Sync SRAM domain - ssram_clk_o => ssram_clk, - ssram_clk_fb => ssram_clk_fb, - ssram_cke_n => ssram_cke_n, - ssram_ce_n => ssram_ce_n, - ssram_oe_n => ssram_oe_n, - ssram_we_n => ssram_we_n, - ssram_adv => ssram_adv, - ssram_mode => ssram_mode, - ssram_zz => ssram_zz, - ssram_a => ssram_a, - ssram_d => ssram_d, - ssram_dp => ssram_dp, - ssram_bw_n => ssram_bw_n - ); - -inst_ssram : entity work.cy7c1354 - -- PORT MAP Declarations - PORT MAP - ( - Dq => STD_LOGIC_VECTOR(ssram_d), -- Data I/O - Dpq => STD_LOGIC_VECTOR(ssram_dp), -- Data I/O - Addr => STD_LOGIC_VECTOR(ssram_a(19 downto 2)), -- Address - Mode => ssram_mode, -- Burst Mode - Clk => ssram_clk, -- Clk - CEN_n => ssram_cke_n, -- CEN# - AdvLd_n => ssram_adv, -- Adv/Ld# - Bwa_n => ssram_bw_n(0), -- Bwa# - Bwb_n => ssram_bw_n(1), -- BWb# - Bwc_n => ssram_bw_n(2), -- Bwc# - Bwd_n => ssram_bw_n(3), -- BWd# - Rw_n => ssram_we_n, -- RW# - Oe_n => ssram_oe_n, -- OE# - Ce1_n => ssram_ce_n, -- CE1# - Ce2 => '1', -- CE2 - Ce3_n => '0', -- CE3# - Zz => ssram_zz - ); - -read_register: - process(CLK_O) - begin - if rising_edge(CLK_O) then - if dout_rst = '1' then - dout_cnt <= 0; - elsif ACK_I = '1' and WE_O = '0' then - dout_reg <= DAT_I; - dout_cnt <= dout_cnt + 1; - end if; - end if; - end process; - -CLK_GEN: process - begin - wait for CLK_PERIOD/2; - CLK_O <= not CLK_O; - end process; - -STIMULUS: process - - begin - - wait for 5*CLK_PERIOD; - RST_O <= '0'; - - wait until rising_edge(CLK_O); - -- 8 single cycles - CYC_O <= '1'; - STB_O <= '1'; - WE_O <= '1'; - DAT_O <= X"1234_0000"; - ADDR_O <= X"0000_0000"; - - for i in 0 to 31 loop - wait until rising_edge(CLK_O) and SRDY_I = '1'; - DAT_O <= DAT_O + 1; - ADDR_O <= ADDR_O + 4; - end loop; - - STB_O <= '0'; - wait until rising_edge(CLK_O); - CYC_O <= '0'; - - ------------------------------------------------------------ - wait for 3*CLK_PERIOD; - ------------------------------------------------------------ - - -- 8-word burst cycle - dout_rst <= '1'; - wait until rising_edge(CLK_O); - dout_rst <= '0'; - CYC_O <= '1'; - STB_O <= '1'; - WE_O <= '0'; - ADDR_O <= X"0000_0000"; - - for i in 0 to 31 loop - wait until rising_edge(CLK_O) and SRDY_I = '1'; - ADDR_O <= ADDR_O + 4; - end loop; - - STB_O <= '0'; - wait until rising_edge(CLK_O) and dout_cnt = 31; - CYC_O <= '0'; - - ------------------------------------------------------------ - wait for 3*CLK_PERIOD; - ------------------------------------------------------------ - - wait until rising_edge(CLK_O); - -- 1-word burst cycle - CYC_O <= '1'; - STB_O <= '1'; - WE_O <= '1'; - SEL_O <= "0011"; - ADDR_O <= X"0000_0010"; - DAT_O <= X"DEADBEEF"; - wait until rising_edge(CLK_O) and SRDY_I = '1'; - STB_O <= '0'; - wait until rising_edge(CLK_O); - CYC_O <= '0'; - - ------------------------------------------------------------ - wait for 3*CLK_PERIOD; - ------------------------------------------------------------ - - wait until rising_edge(CLK_O); - -- 1-word burst cycle - CYC_O <= '1'; - STB_O <= '1'; - WE_O <= '0'; - ADDR_O <= X"0000_0010"; - wait until rising_edge(CLK_O) and SRDY_I = '1'; - STB_O <= '0'; - wait until rising_edge(CLK_O) and ACK_I = '1'; - CYC_O <= '0'; - - ------------------------------------------------------------ - wait for 3*CLK_PERIOD; - ------------------------------------------------------------ - - -- 8-word burst cycle - dout_rst <= '1'; - wait until rising_edge(CLK_O); - dout_rst <= '0'; - - CYC_O <= '1'; - STB_O <= '1'; - WE_O <= '0'; - ADDR_O <= X"0000_0000"; - - for i in 0 to 31 loop - wait until rising_edge(CLK_O) and SRDY_I = '1'; - ADDR_O <= ADDR_O + 4; - end loop; - - STB_O <= '0'; - wait until rising_edge(CLK_O) and dout_cnt = 31; - CYC_O <= '0'; - - ------------------------------------------------------------ - wait for 10*CLK_PERIOD; - ------------------------------------------------------------ - - - -- 8-word burst cycle - dout_rst <= '1'; - wait until rising_edge(CLK_O); - dout_rst <= '0'; - - CYC_O <= '1'; - STB_O <= '1'; - WE_O <= '0'; - ADDR_O <= X"0000_0000"; - - for i in 0 to 7 loop - wait until rising_edge(CLK_O) and SRDY_I = '1'; - ADDR_O <= ADDR_O + 4; - end loop; - - STB_O <= '0'; - wait until rising_edge(CLK_O) and dout_cnt = 7; - CYC_O <= '0'; - - - ------------------------------------------------------------ - wait for 10*CLK_PERIOD; - ------------------------------------------------------------ - - -- 8-word burst cycle - dout_rst <= '1'; - wait until rising_edge(CLK_O); - dout_rst <= '0'; - - CYC_O <= '1'; - STB_O <= '1'; - WE_O <= '1'; - SEL_O <= "1111"; - DAT_O <= X"1111_0000"; - ADDR_O <= X"0000_0000"; - - for i in 0 to 7 loop - wait until rising_edge(CLK_O) and SRDY_I = '1'; - DAT_O <= DAT_O + 1; - ADDR_O <= ADDR_O + 4; - end loop; - - WE_O <= '0'; - ADDR_O <= X"0000_0000"; - - for i in 0 to 7 loop - wait until rising_edge(CLK_O) and SRDY_I = '1'; - ADDR_O <= ADDR_O + 4; - end loop; - - STB_O <= '0'; - wait until rising_edge(CLK_O) and dout_cnt = 7; - CYC_O <= '0'; - - -- 8-word burst cycle - dout_rst <= '1'; - wait until rising_edge(CLK_O); - dout_rst <= '0'; - - CYC_O <= '1'; - STB_O <= '1'; - WE_O <= '1'; - SEL_O <= "1111"; - DAT_O <= X"2222_0000"; - ADDR_O <= X"0000_0400"; - - for i in 0 to 7 loop - wait until rising_edge(CLK_O) and SRDY_I = '1'; - DAT_O <= DAT_O + 1; - ADDR_O <= ADDR_O + 4; - end loop; - - WE_O <= '0'; - ADDR_O <= X"0000_0400"; - - for i in 0 to 7 loop - wait until rising_edge(CLK_O) and SRDY_I = '1'; - ADDR_O <= ADDR_O + 4; - end loop; - - STB_O <= '0'; - wait until rising_edge(CLK_O) and dout_cnt = 7; - CYC_O <= '0'; - - -- 8-word burst cycle - dout_rst <= '1'; - wait until rising_edge(CLK_O); - dout_rst <= '0'; - - CYC_O <= '1'; - STB_O <= '1'; - WE_O <= '1'; - SEL_O <= "1111"; - DAT_O <= X"3333_0000"; - ADDR_O <= X"0000_0800"; - - for i in 0 to 7 loop - wait until rising_edge(CLK_O) and SRDY_I = '1'; - DAT_O <= DAT_O + 1; - ADDR_O <= ADDR_O + 4; - end loop; - - WE_O <= '0'; - ADDR_O <= X"0000_0800"; - - for i in 0 to 7 loop - wait until rising_edge(CLK_O) and SRDY_I = '1'; - ADDR_O <= ADDR_O + 4; - end loop; - - STB_O <= '0'; - wait until rising_edge(CLK_O) and dout_cnt = 7; - CYC_O <= '0'; - - -- 8-word burst cycle - dout_rst <= '1'; - wait until rising_edge(CLK_O); - dout_rst <= '0'; - - CYC_O <= '1'; - STB_O <= '1'; - WE_O <= '1'; - SEL_O <= "1111"; - DAT_O <= X"4444_0000"; - ADDR_O <= X"0000_0C00"; - - for i in 0 to 7 loop - wait until rising_edge(CLK_O) and SRDY_I = '1'; - DAT_O <= DAT_O + 1; - ADDR_O <= ADDR_O + 4; - end loop; - - WE_O <= '0'; - ADDR_O <= X"0000_0C00"; - - for i in 0 to 7 loop - wait until rising_edge(CLK_O) and SRDY_I = '1'; - ADDR_O <= ADDR_O + 4; - end loop; - - STB_O <= '0'; - wait until rising_edge(CLK_O) and dout_cnt = 7; - CYC_O <= '0'; - - ------------------------------------------------------------ - wait for 10*CLK_PERIOD; - ------------------------------------------------------------ - - -- 8-word burst cycle - dout_rst <= '1'; - wait until rising_edge(CLK_O); - dout_rst <= '0'; - - CYC_O <= '1'; - STB_O <= '1'; - WE_O <= '0'; - ADDR_O <= X"0000_0000"; - - for i in 0 to 7 loop - wait until rising_edge(CLK_O) and SRDY_I = '1'; - ADDR_O <= ADDR_O + 4; - end loop; - - ADDR_O <= X"0000_0400"; - - for i in 0 to 7 loop - wait until rising_edge(CLK_O) and SRDY_I = '1'; - ADDR_O <= ADDR_O + 4; - end loop; - - - ADDR_O <= X"0000_0800"; - - for i in 0 to 7 loop - wait until rising_edge(CLK_O) and SRDY_I = '1'; - ADDR_O <= ADDR_O + 4; - end loop; - - - ADDR_O <= X"0000_0C00"; - - for i in 0 to 7 loop - wait until rising_edge(CLK_O) and SRDY_I = '1'; - ADDR_O <= ADDR_O + 4; - end loop; - - STB_O <= '0'; - wait until rising_edge(CLK_O) and dout_cnt = 31; - CYC_O <= '0'; - - wait; - - end process; - -END; +------------------------------------------------------------------------- +-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL +-- This file: testbench for system test using Xilinx ML-402 + +-- Copyright (C) 2007 J. Ahrensfeld + +-- This library is free software; you can redistribute it and/or +-- modify it under the terms of the GNU Lesser General Public +-- License as published by the Free Software Foundation; either +-- version 2.1 of the License, or (at your option) any later version. + +-- This library 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 +-- Lesser General Public License for more details. + +-- You should have received a copy of the GNU Lesser General Public +-- License along with this library; if not, write to the Free Software +-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +-- For questions and ideas, please contact the author at jens@jayfield.org + +----------------------------------------------------------------------- + +LIBRARY ieee; +use IEEE.STD_LOGIC_1164.ALL; +USE ieee.numeric_std.ALL; +USE work.package_utility.all; + +Library UNISIM; +use UNISIM.vcomponents.all; + +ENTITY tb_ssram_frontend_wb IS +END tb_ssram_frontend_wb; + +ARCHITECTURE behavior OF tb_ssram_frontend_wb IS + + constant CLK_PERIOD : time := 10 ns; + signal CLK_O : std_logic := '1'; + signal RST_O : std_logic := '1'; + signal CYC_O : std_logic := '0'; + signal STB_O : std_logic := '0'; + signal WE_O : std_logic := '0'; + signal SEL_O : unsigned(3 downto 0) := (others => '1'); + signal ACK_I : std_logic; + signal MRDY_O : std_logic := '1'; + signal SRDY_I : std_logic; + signal ADDR_O : unsigned(31 downto 0) := (others => '-'); + signal DAT_I : unsigned(31 downto 0); + signal DAT_O : unsigned(31 downto 0) := (others => '-'); + + SIGNAL ssram_d : unsigned (32 - 1 DOWNTO 0) := (OTHERS => 'Z'); + SIGNAL ssram_dp : unsigned (4 - 1 DOWNTO 0) := (OTHERS => 'Z'); + SIGNAL ssram_a : unsigned (20 - 1 DOWNTO 0) := (OTHERS => '0'); + SIGNAL ssram_clk : STD_LOGIC := '0'; + SIGNAL ssram_cke_n : STD_LOGIC; + SIGNAL ssram_adv : STD_LOGIC; + SIGNAL ssram_mode : STD_LOGIC; + SIGNAL ssram_bw_n : unsigned(3 downto 0); + SIGNAL ssram_we_n : STD_LOGIC; + SIGNAL ssram_oe_n : STD_LOGIC; + SIGNAL ssram_ce_n : STD_LOGIC; + SIGNAL ssram_zz : STD_LOGIC; + + SIGNAL ssram_clk_fb : STD_LOGIC; + + signal dout_rst : std_logic := '0'; + signal dout_reg : unsigned(31 downto 0); + signal dout_cnt : natural range 0 to 255; + +BEGIN + + ssram_clk_fb <= ssram_clk after 0.5 ns; + +inst_ssram_frontend_wb : entity work.ssram_frontend_wb + GENERIC MAP + ( + addr_width => 20, + data_width => 32, + parity_width => 4 + ) + PORT MAP + ( + -- J-Bus domain + RST_I => RST_O, + CLK_I => CLK_O, + CYC_I => CYC_O, + STB_I => STB_O, + SEL_I => SEL_O, + WE_I => WE_O, + ACK_O => ACK_I, + SRDY_O => SRDY_I, + MRDY_I => MRDY_O, + ADDR_I => ADDR_O, + DAT_I => DAT_O, + DAT_O => DAT_I, + + -- Sync SRAM domain + ssram_clk_o => ssram_clk, + ssram_clk_fb => ssram_clk_fb, + ssram_cke_n => ssram_cke_n, + ssram_ce_n => ssram_ce_n, + ssram_oe_n => ssram_oe_n, + ssram_we_n => ssram_we_n, + ssram_adv => ssram_adv, + ssram_mode => ssram_mode, + ssram_zz => ssram_zz, + ssram_a => ssram_a, + ssram_d => ssram_d, + ssram_dp => ssram_dp, + ssram_bw_n => ssram_bw_n + ); + +inst_ssram : entity work.cy7c1354 + -- PORT MAP Declarations + PORT MAP + ( + Dq => STD_LOGIC_VECTOR(ssram_d), -- Data I/O + Dpq => STD_LOGIC_VECTOR(ssram_dp), -- Data I/O + Addr => STD_LOGIC_VECTOR(ssram_a(19 downto 2)), -- Address + Mode => ssram_mode, -- Burst Mode + Clk => ssram_clk, -- Clk + CEN_n => ssram_cke_n, -- CEN# + AdvLd_n => ssram_adv, -- Adv/Ld# + Bwa_n => ssram_bw_n(0), -- Bwa# + Bwb_n => ssram_bw_n(1), -- BWb# + Bwc_n => ssram_bw_n(2), -- Bwc# + Bwd_n => ssram_bw_n(3), -- BWd# + Rw_n => ssram_we_n, -- RW# + Oe_n => ssram_oe_n, -- OE# + Ce1_n => ssram_ce_n, -- CE1# + Ce2 => '1', -- CE2 + Ce3_n => '0', -- CE3# + Zz => ssram_zz + ); + +read_register: + process(CLK_O) + begin + if rising_edge(CLK_O) then + if dout_rst = '1' then + dout_cnt <= 0; + elsif ACK_I = '1' and WE_O = '0' then + dout_reg <= DAT_I; + dout_cnt <= dout_cnt + 1; + end if; + end if; + end process; + +CLK_GEN: process + begin + wait for CLK_PERIOD/2; + CLK_O <= not CLK_O; + end process; + +STIMULUS: process + + begin + + wait for 5*CLK_PERIOD; + RST_O <= '0'; + + wait until rising_edge(CLK_O); + -- 8 single cycles + CYC_O <= '1'; + STB_O <= '1'; + WE_O <= '1'; + DAT_O <= X"1234_0000"; + ADDR_O <= X"0000_0000"; + + for i in 0 to 31 loop + wait until rising_edge(CLK_O) and SRDY_I = '1'; + DAT_O <= DAT_O + 1; + ADDR_O <= ADDR_O + 4; + end loop; + + STB_O <= '0'; + wait until rising_edge(CLK_O); + CYC_O <= '0'; + + ------------------------------------------------------------ + wait for 3*CLK_PERIOD; + ------------------------------------------------------------ + + -- 8-word burst cycle + dout_rst <= '1'; + wait until rising_edge(CLK_O); + dout_rst <= '0'; + CYC_O <= '1'; + STB_O <= '1'; + WE_O <= '0'; + ADDR_O <= X"0000_0000"; + + for i in 0 to 31 loop + wait until rising_edge(CLK_O) and SRDY_I = '1'; + ADDR_O <= ADDR_O + 4; + end loop; + + STB_O <= '0'; + wait until rising_edge(CLK_O) and dout_cnt = 31; + CYC_O <= '0'; + + ------------------------------------------------------------ + wait for 3*CLK_PERIOD; + ------------------------------------------------------------ + + wait until rising_edge(CLK_O); + -- 1-word burst cycle + CYC_O <= '1'; + STB_O <= '1'; + WE_O <= '1'; + SEL_O <= "0011"; + ADDR_O <= X"0000_0010"; + DAT_O <= X"DEADBEEF"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + wait until rising_edge(CLK_O); + CYC_O <= '0'; + + ------------------------------------------------------------ + wait for 3*CLK_PERIOD; + ------------------------------------------------------------ + + wait until rising_edge(CLK_O); + -- 1-word burst cycle + CYC_O <= '1'; + STB_O <= '1'; + WE_O <= '0'; + ADDR_O <= X"0000_0010"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + wait until rising_edge(CLK_O) and ACK_I = '1'; + CYC_O <= '0'; + + ------------------------------------------------------------ + wait for 3*CLK_PERIOD; + ------------------------------------------------------------ + + -- 8-word burst cycle + dout_rst <= '1'; + wait until rising_edge(CLK_O); + dout_rst <= '0'; + + CYC_O <= '1'; + STB_O <= '1'; + WE_O <= '0'; + ADDR_O <= X"0000_0000"; + + for i in 0 to 31 loop + wait until rising_edge(CLK_O) and SRDY_I = '1'; + ADDR_O <= ADDR_O + 4; + end loop; + + STB_O <= '0'; + wait until rising_edge(CLK_O) and dout_cnt = 31; + CYC_O <= '0'; + + ------------------------------------------------------------ + wait for 10*CLK_PERIOD; + ------------------------------------------------------------ + + + -- 8-word burst cycle + dout_rst <= '1'; + wait until rising_edge(CLK_O); + dout_rst <= '0'; + + CYC_O <= '1'; + STB_O <= '1'; + WE_O <= '0'; + ADDR_O <= X"0000_0000"; + + for i in 0 to 7 loop + wait until rising_edge(CLK_O) and SRDY_I = '1'; + ADDR_O <= ADDR_O + 4; + end loop; + + STB_O <= '0'; + wait until rising_edge(CLK_O) and dout_cnt = 7; + CYC_O <= '0'; + + + ------------------------------------------------------------ + wait for 10*CLK_PERIOD; + ------------------------------------------------------------ + + -- 8-word burst cycle + dout_rst <= '1'; + wait until rising_edge(CLK_O); + dout_rst <= '0'; + + CYC_O <= '1'; + STB_O <= '1'; + WE_O <= '1'; + SEL_O <= "1111"; + DAT_O <= X"1111_0000"; + ADDR_O <= X"0000_0000"; + + for i in 0 to 7 loop + wait until rising_edge(CLK_O) and SRDY_I = '1'; + DAT_O <= DAT_O + 1; + ADDR_O <= ADDR_O + 4; + end loop; + + WE_O <= '0'; + ADDR_O <= X"0000_0000"; + + for i in 0 to 7 loop + wait until rising_edge(CLK_O) and SRDY_I = '1'; + ADDR_O <= ADDR_O + 4; + end loop; + + STB_O <= '0'; + wait until rising_edge(CLK_O) and dout_cnt = 7; + CYC_O <= '0'; + + -- 8-word burst cycle + dout_rst <= '1'; + wait until rising_edge(CLK_O); + dout_rst <= '0'; + + CYC_O <= '1'; + STB_O <= '1'; + WE_O <= '1'; + SEL_O <= "1111"; + DAT_O <= X"2222_0000"; + ADDR_O <= X"0000_0400"; + + for i in 0 to 7 loop + wait until rising_edge(CLK_O) and SRDY_I = '1'; + DAT_O <= DAT_O + 1; + ADDR_O <= ADDR_O + 4; + end loop; + + WE_O <= '0'; + ADDR_O <= X"0000_0400"; + + for i in 0 to 7 loop + wait until rising_edge(CLK_O) and SRDY_I = '1'; + ADDR_O <= ADDR_O + 4; + end loop; + + STB_O <= '0'; + wait until rising_edge(CLK_O) and dout_cnt = 7; + CYC_O <= '0'; + + -- 8-word burst cycle + dout_rst <= '1'; + wait until rising_edge(CLK_O); + dout_rst <= '0'; + + CYC_O <= '1'; + STB_O <= '1'; + WE_O <= '1'; + SEL_O <= "1111"; + DAT_O <= X"3333_0000"; + ADDR_O <= X"0000_0800"; + + for i in 0 to 7 loop + wait until rising_edge(CLK_O) and SRDY_I = '1'; + DAT_O <= DAT_O + 1; + ADDR_O <= ADDR_O + 4; + end loop; + + WE_O <= '0'; + ADDR_O <= X"0000_0800"; + + for i in 0 to 7 loop + wait until rising_edge(CLK_O) and SRDY_I = '1'; + ADDR_O <= ADDR_O + 4; + end loop; + + STB_O <= '0'; + wait until rising_edge(CLK_O) and dout_cnt = 7; + CYC_O <= '0'; + + -- 8-word burst cycle + dout_rst <= '1'; + wait until rising_edge(CLK_O); + dout_rst <= '0'; + + CYC_O <= '1'; + STB_O <= '1'; + WE_O <= '1'; + SEL_O <= "1111"; + DAT_O <= X"4444_0000"; + ADDR_O <= X"0000_0C00"; + + for i in 0 to 7 loop + wait until rising_edge(CLK_O) and SRDY_I = '1'; + DAT_O <= DAT_O + 1; + ADDR_O <= ADDR_O + 4; + end loop; + + WE_O <= '0'; + ADDR_O <= X"0000_0C00"; + + for i in 0 to 7 loop + wait until rising_edge(CLK_O) and SRDY_I = '1'; + ADDR_O <= ADDR_O + 4; + end loop; + + STB_O <= '0'; + wait until rising_edge(CLK_O) and dout_cnt = 7; + CYC_O <= '0'; + + ------------------------------------------------------------ + wait for 10*CLK_PERIOD; + ------------------------------------------------------------ + + -- 8-word burst cycle + dout_rst <= '1'; + wait until rising_edge(CLK_O); + dout_rst <= '0'; + + CYC_O <= '1'; + STB_O <= '1'; + WE_O <= '0'; + ADDR_O <= X"0000_0000"; + + for i in 0 to 7 loop + wait until rising_edge(CLK_O) and SRDY_I = '1'; + ADDR_O <= ADDR_O + 4; + end loop; + + ADDR_O <= X"0000_0400"; + + for i in 0 to 7 loop + wait until rising_edge(CLK_O) and SRDY_I = '1'; + ADDR_O <= ADDR_O + 4; + end loop; + + + ADDR_O <= X"0000_0800"; + + for i in 0 to 7 loop + wait until rising_edge(CLK_O) and SRDY_I = '1'; + ADDR_O <= ADDR_O + 4; + end loop; + + + ADDR_O <= X"0000_0C00"; + + for i in 0 to 7 loop + wait until rising_edge(CLK_O) and SRDY_I = '1'; + ADDR_O <= ADDR_O + 4; + end loop; + + STB_O <= '0'; + wait until rising_edge(CLK_O) and dout_cnt = 31; + CYC_O <= '0'; + + wait; + + end process; + +END;