Commit 3ed4b39c authored by Dimitris Lampridis's avatar Dimitris Lampridis

hdl: delete sim folder

These files, when needed are now available from dependencies in hdl/ip_cores.

(for example, ddr memory model can be found in ddr controller project).

There were also some obsolete testbenches in here.
parent 861bf346
# SPDX-FileCopyrightText: 2022 CERN (home.cern)
#
# SPDX-License-Identifier: CERN-OHL-W-2.0
target = "xilinx"
action = "simulation"
modules = { "local" : ["../../top/ddr_test/",
"testbench",
"sim_models/2048Mb_ddr3"]}
vsim -novopt -t 1ps vme64x_ddr_tb
log -r /*
do wave_wb_buses.do
view wave
view transcript
run 50 us
# SPDX-FileCopyrightText: 2022 CERN (home.cern)
#
# SPDX-License-Identifier: CERN-OHL-W-2.0
files = ["ddr3.v"]
vlog_opt = "+incdir+sim_models/2048Mb_ddr3 +define+sg15E +define+x16"
This source diff could not be displayed because it is too large. You can view the blob instead.
/****************************************************************************************
*
* File Name: ddr3_mcp.v
*
* Dependencies: ddr3.v, ddr3_parameters.vh
*
* Description: Micron SDRAM DDR3 (Double Data Rate 3) multi-chip package model
*
* Disclaimer This software code and all associated documentation, comments or other
* of Warranty: information (collectively "Software") is provided "AS IS" without
* warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
* DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
* OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
* WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
* OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
* FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
* THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
* ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
* OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
* ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
* INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
* WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
* OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
* THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGES. Because some jurisdictions prohibit the exclusion or
* limitation of liability for consequential or incidental damages, the
* above limitation may not apply to you.
*
* Copyright 2003 Micron Technology, Inc. All rights reserved.
*
****************************************************************************************/
`timescale 1ps / 1ps
module ddr3_mcp (
rst_n,
ck,
ck_n,
cke,
cs_n,
ras_n,
cas_n,
we_n,
dm_tdqs,
ba,
addr,
dq,
dqs,
dqs_n,
tdqs_n,
odt
);
`include "ddr3_parameters.vh"
// Declare Ports
input rst_n;
input ck;
input ck_n;
input [CS_BITS-1:0] cke;
input [CS_BITS-1:0] cs_n;
input ras_n;
input cas_n;
input we_n;
inout [DM_BITS-1:0] dm_tdqs;
input [BA_BITS-1:0] ba;
input [ADDR_BITS-1:0] addr;
inout [DQ_BITS-1:0] dq;
inout [DQS_BITS-1:0] dqs;
inout [DQS_BITS-1:0] dqs_n;
output [DQS_BITS-1:0] tdqs_n;
input [CS_BITS-1:0] odt;
wire [RANKS-1:0] cke_mcp = cke;
wire [RANKS-1:0] cs_n_mcp = cs_n;
wire [RANKS-1:0] odt_mcp = odt;
ddr3 rank [RANKS-1:0] (
rst_n,
ck,
ck_n,
cke_mcp,
cs_n_mcp,
ras_n,
cas_n,
we_n,
dm_tdqs,
ba,
addr,
dq,
dqs,
dqs_n,
tdqs_n,
odt_mcp
);
endmodule
/****************************************************************************************
*
* File Name: ddr3_module.v
*
* Description: Micron SDRAM DDR3 (Double Data Rate 3) module model
*
* Limitation: - SPD (Serial Presence-Detect) is not modeled
* - Command/Address parity is not modeled
*
* Disclaimer This software code and all associated documentation, comments or other
* of Warranty: information (collectively "Software") is provided "AS IS" without
* warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
* DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
* OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
* WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
* OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
* FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
* THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
* ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
* OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
* ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
* INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
* WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
* OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
* THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGES. Because some jurisdictions prohibit the exclusion or
* limitation of liability for consequential or incidental damages, the
* above limitation may not apply to you.
*
* Copyright 2003 Micron Technology, Inc. All rights reserved.
*
****************************************************************************************/
`timescale 1ps / 1ps
module ddr3_module (
reset_n,
ck ,
ck_n ,
cke ,
s_n ,
ras_n ,
cas_n ,
we_n ,
ba ,
addr ,
odt ,
dqs ,
dqs_n ,
dq ,
`ifdef SODIMM
`else
cb ,
`endif
scl ,
sa ,
sda
);
`include "ddr3_parameters.vh"
input reset_n;
input [1:0] cke ;
input ras_n ;
input cas_n ;
input we_n ;
input [2:0] ba ;
input [15:0] addr ;
input [1:0] odt ;
inout [17:0] dqs ;
inout [17:0] dqs_n ;
inout [63:0] dq ;
input scl ; // no connect
inout sda ; // no connect
`ifdef QUAD_RANK
initial if (DEBUG) $display("%m: Quad Rank");
`else `ifdef DUAL_RANK
initial if (DEBUG) $display("%m: Dual Rank");
`else
initial if (DEBUG) $display("%m: Single Rank");
`endif `endif
`ifdef ECC
initial if (DEBUG) $display("%m: ECC");
`ifdef SODIMM
initial begin
$display("%m ERROR: ECC is not available on SODIMM configurations");
if (STOP_ON_ERROR) $stop(0);
end
`endif
`else
initial if (DEBUG) $display("%m: non ECC");
`endif
`ifdef RDIMM
initial if (DEBUG) $display("%m: RDIMM");
input ck ;
input ck_n ;
input [3:0] s_n ;
inout [7:0] cb ;
input [2:0] sa ; // no connect
wire [1:0] rck = {2{ck}};
wire [1:0] rck_n = {2{ck_n}};
reg [3:0] rs_n ;
reg rras_n ;
reg rcas_n ;
reg rwe_n ;
reg [2:0] rba ;
reg [15:0] raddr ;
reg [3:0] rcke ;
reg [3:0] rodt ;
always @(negedge reset_n or posedge ck) begin
if (!reset_n) begin
rs_n <= #(500) 0;
rras_n <= #(500) 0;
rcas_n <= #(500) 0;
rwe_n <= #(500) 0;
rba <= #(500) 0;
raddr <= #(500) 0;
rcke <= #(500) 0;
rodt <= #(500) 0;
end else begin
rs_n <= #(500) s_n ;
rras_n <= #(500) ras_n;
rcas_n <= #(500) cas_n;
rwe_n <= #(500) we_n ;
rba <= #(500) ba ;
raddr <= #(500) addr ;
`ifdef QUAD_RANK
rcke <= #(500) {{2{cke[1]}}, {2{cke[0]}}};
rodt <= #(500) {{2{odt[1]}}, {2{odt[0]}}};
`else
rcke <= #(500) {2'b00, cke};
rodt <= #(500) {2'b00, odt};
`endif
end
end
`else
input [1:0] ck ;
input [1:0] ck_n ;
input [1:0] s_n ;
`ifdef SODIMM
initial if (DEBUG) $display("%m: SODIMM");
input [1:0] sa ; // no connect
wire [7:0] cb;
`else
initial if (DEBUG) $display("%m: UDIMM");
inout [7:0] cb ;
input [2:0] sa ; // no connect
`endif
wire [1:0] rck = ck ;
wire [1:0] rck_n = ck_n ;
wire [2:0] rba = ba ;
wire [15:0] raddr = addr ;
wire rras_n = ras_n;
wire rcas_n = cas_n;
wire rwe_n = we_n ;
`ifdef QUAD_RANK
wire [3:0] rs_n = {{2{s_n[1]}}, {2{s_n[0]}}};
wire [3:0] rcke = {{2{cke[1]}}, {2{cke[0]}}};
wire [3:0] rodt = {{2{odt[1]}}, {2{odt[0]}}};
`else
wire [3:0] rs_n = {2'b00, s_n};
wire [3:0] rcke = {2'b00, cke};
wire [3:0] rodt = {2'b00, odt};
`endif
`endif
wire [15:0] rcb = {8'b0, cb};
wire zero = 1'b0;
wire one = 1'b1;
// all DUAL_RANK UDIMMs have mirrored address
`ifdef QUAD_RANK
wire [15:0] maddr = raddr;
wire [2:0] mba = rba;
`else `ifdef DUAL_RANK
`ifdef UDIMM
initial if (DEBUG) $display("%m: ADDRESS MIRROR");
wire [15:0] maddr = {raddr[15:9], raddr[7], raddr[8], raddr[5], raddr[6], raddr[3], raddr[4], raddr[2:0]};
wire [2:0] mba = {rba[2], rba[0], rba[1]};
`else
wire [15:0] maddr = raddr;
wire [2:0] mba = rba;
`endif
`else
wire [15:0] maddr = raddr;
wire [2:0] mba = rba;
`endif `endif
//ddr3 (rst_n , ck , ck_n , cke , cs_n , ras_n , cas_n , we_n , dm_tdqs , ba , addr , dq , dqs , dqs_n , tdqs_n , odt );
`ifdef x4
initial if (DEBUG) $display("%m: Component Width = x4");
ddr3 U1R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [ 3: 0], dqs[ 0] , dqs_n[ 0] , , rodt[0]);
ddr3 U2R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [11: 8], dqs[ 1] , dqs_n[ 1] , , rodt[0]);
ddr3 U3R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [19:16], dqs[ 2] , dqs_n[ 2] , , rodt[0]);
ddr3 U4R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [27:24], dqs[ 3] , dqs_n[ 3] , , rodt[0]);
ddr3 U6R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [35:32], dqs[ 4] , dqs_n[ 4] , , rodt[0]);
ddr3 U7R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [43:40], dqs[ 5] , dqs_n[ 5] , , rodt[0]);
ddr3 U8R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [51:48], dqs[ 6] , dqs_n[ 6] , , rodt[0]);
ddr3 U9R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [59:56], dqs[ 7] , dqs_n[ 7] , , rodt[0]);
`ifdef ECC
ddr3 U5R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], rcb[ 3: 0], dqs[ 8] , dqs_n[ 8] , , rodt[0]);
`endif
ddr3 U18R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [ 7: 4], dqs[ 9] , dqs_n[ 9] , , rodt[0]);
ddr3 U17R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [15:12], dqs[ 10] , dqs_n[ 10] , , rodt[0]);
ddr3 U16R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [23:20], dqs[ 11] , dqs_n[ 11] , , rodt[0]);
ddr3 U15R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [31:28], dqs[ 12] , dqs_n[ 12] , , rodt[0]);
ddr3 U13R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [39:36], dqs[ 13] , dqs_n[ 13] , , rodt[0]);
ddr3 U12R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [47:44], dqs[ 14] , dqs_n[ 14] , , rodt[0]);
ddr3 U11R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [55:52], dqs[ 15] , dqs_n[ 15] , , rodt[0]);
ddr3 U10R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [63:60], dqs[ 16] , dqs_n[ 16] , , rodt[0]);
`ifdef ECC
ddr3 U14R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], rcb[ 7: 4], dqs[ 17] , dqs_n[ 17] , , rodt[0]);
`endif
`ifdef DUAL_RANK
ddr3 U1R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], dq [ 3: 0], dqs[ 0] , dqs_n[ 0] , , rodt[1]);
ddr3 U2R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], dq [11: 8], dqs[ 1] , dqs_n[ 1] , , rodt[1]);
ddr3 U3R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], dq [19:16], dqs[ 2] , dqs_n[ 2] , , rodt[1]);
ddr3 U4R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], dq [27:24], dqs[ 3] , dqs_n[ 3] , , rodt[1]);
ddr3 U6R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], dq [35:32], dqs[ 4] , dqs_n[ 4] , , rodt[1]);
ddr3 U7R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], dq [43:40], dqs[ 5] , dqs_n[ 5] , , rodt[1]);
ddr3 U8R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], dq [51:48], dqs[ 6] , dqs_n[ 6] , , rodt[1]);
ddr3 U9R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], dq [59:56], dqs[ 7] , dqs_n[ 7] , , rodt[1]);
`ifdef ECC
ddr3 U5R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], rcb[ 3: 0], dqs[ 8] , dqs_n[ 8] , , rodt[1]);
`endif
ddr3 U18R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], dq [ 7: 4], dqs[ 9] , dqs_n[ 9] , , rodt[1]);
ddr3 U17R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], dq [15:12], dqs[ 10] , dqs_n[ 10] , , rodt[1]);
ddr3 U16R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], dq [23:20], dqs[ 11] , dqs_n[ 11] , , rodt[1]);
ddr3 U15R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], dq [31:28], dqs[ 12] , dqs_n[ 12] , , rodt[1]);
ddr3 U13R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], dq [39:36], dqs[ 13] , dqs_n[ 13] , , rodt[1]);
ddr3 U12R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], dq [47:44], dqs[ 14] , dqs_n[ 14] , , rodt[1]);
ddr3 U11R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], dq [55:52], dqs[ 15] , dqs_n[ 15] , , rodt[1]);
ddr3 U10R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], dq [63:60], dqs[ 16] , dqs_n[ 16] , , rodt[1]);
`ifdef ECC
ddr3 U14R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, zero , mba, maddr[ADDR_BITS-1:0], rcb[ 7: 4], dqs[ 17] , dqs_n[ 17] , , rodt[1]);
`endif
`endif
`ifdef QUAD_RANK
ddr3 U1R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [ 3: 0], dqs[ 0] , dqs_n[ 0] , , rodt[2]);
ddr3 U2R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [11: 8], dqs[ 1] , dqs_n[ 1] , , rodt[2]);
ddr3 U3R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [19:16], dqs[ 2] , dqs_n[ 2] , , rodt[2]);
ddr3 U4R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [27:24], dqs[ 3] , dqs_n[ 3] , , rodt[2]);
ddr3 U6R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [35:32], dqs[ 4] , dqs_n[ 4] , , rodt[2]);
ddr3 U7R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [43:40], dqs[ 5] , dqs_n[ 5] , , rodt[2]);
ddr3 U8R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [51:48], dqs[ 6] , dqs_n[ 6] , , rodt[2]);
ddr3 U9R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [59:56], dqs[ 7] , dqs_n[ 7] , , rodt[2]);
`ifdef ECC
ddr3 U5R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], rcb[ 3: 0], dqs[ 8] , dqs_n[ 8] , , rodt[2]);
`endif
ddr3 U18R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [ 7: 4], dqs[ 9] , dqs_n[ 9] , , rodt[2]);
ddr3 U17R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [15:12], dqs[ 10] , dqs_n[ 10] , , rodt[2]);
ddr3 U16R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [23:20], dqs[ 11] , dqs_n[ 11] , , rodt[2]);
ddr3 U15R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [31:28], dqs[ 12] , dqs_n[ 12] , , rodt[2]);
ddr3 U13R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [39:36], dqs[ 13] , dqs_n[ 13] , , rodt[2]);
ddr3 U12R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [47:44], dqs[ 14] , dqs_n[ 14] , , rodt[2]);
ddr3 U11R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [55:52], dqs[ 15] , dqs_n[ 15] , , rodt[2]);
ddr3 U10R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [63:60], dqs[ 16] , dqs_n[ 16] , , rodt[2]);
`ifdef ECC
ddr3 U14R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], rcb[ 7: 4], dqs[ 17] , dqs_n[ 17] , , rodt[2]);
`endif
ddr3 U1R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [ 3: 0], dqs[ 0] , dqs_n[ 0] , , rodt[3]);
ddr3 U2R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [11: 8], dqs[ 1] , dqs_n[ 1] , , rodt[3]);
ddr3 U3R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [19:16], dqs[ 2] , dqs_n[ 2] , , rodt[3]);
ddr3 U4R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [27:24], dqs[ 3] , dqs_n[ 3] , , rodt[3]);
ddr3 U6R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [35:32], dqs[ 4] , dqs_n[ 4] , , rodt[3]);
ddr3 U7R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [43:40], dqs[ 5] , dqs_n[ 5] , , rodt[3]);
ddr3 U8R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [51:48], dqs[ 6] , dqs_n[ 6] , , rodt[3]);
ddr3 U9R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [59:56], dqs[ 7] , dqs_n[ 7] , , rodt[3]);
`ifdef ECC
ddr3 U5R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], rcb[ 3: 0], dqs[ 8] , dqs_n[ 8] , , rodt[3]);
`endif
ddr3 U18R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [ 7: 4], dqs[ 9] , dqs_n[ 9] , , rodt[3]);
ddr3 U17R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [15:12], dqs[ 10] , dqs_n[ 10] , , rodt[3]);
ddr3 U16R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [23:20], dqs[ 11] , dqs_n[ 11] , , rodt[3]);
ddr3 U15R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [31:28], dqs[ 12] , dqs_n[ 12] , , rodt[3]);
ddr3 U13R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [39:36], dqs[ 13] , dqs_n[ 13] , , rodt[3]);
ddr3 U12R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [47:44], dqs[ 14] , dqs_n[ 14] , , rodt[3]);
ddr3 U11R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [55:52], dqs[ 15] , dqs_n[ 15] , , rodt[3]);
ddr3 U10R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], dq [63:60], dqs[ 16] , dqs_n[ 16] , , rodt[3]);
`ifdef ECC
ddr3 U14R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, zero , rba, raddr[ADDR_BITS-1:0], rcb[ 7: 4], dqs[ 17] , dqs_n[ 17] , , rodt[3]);
`endif
`endif
`else `ifdef x8
initial if (DEBUG) $display("%m: Component Width = x8");
ddr3 U1R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[ 9] , rba, raddr[ADDR_BITS-1:0], dq [ 7: 0], dqs[ 0] , dqs_n[ 0] , dqs_n[ 9], rodt[0]);
ddr3 U2R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[10] , rba, raddr[ADDR_BITS-1:0], dq [15: 8], dqs[ 1] , dqs_n[ 1] , dqs_n[10], rodt[0]);
ddr3 U3R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[11] , rba, raddr[ADDR_BITS-1:0], dq [23:16], dqs[ 2] , dqs_n[ 2] , dqs_n[11], rodt[0]);
ddr3 U4R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[12] , rba, raddr[ADDR_BITS-1:0], dq [31:24], dqs[ 3] , dqs_n[ 3] , dqs_n[12], rodt[0]);
ddr3 U6R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[13] , rba, raddr[ADDR_BITS-1:0], dq [39:32], dqs[ 4] , dqs_n[ 4] , dqs_n[13], rodt[0]);
ddr3 U7R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[14] , rba, raddr[ADDR_BITS-1:0], dq [47:40], dqs[ 5] , dqs_n[ 5] , dqs_n[14], rodt[0]);
ddr3 U8R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[15] , rba, raddr[ADDR_BITS-1:0], dq [55:48], dqs[ 6] , dqs_n[ 6] , dqs_n[15], rodt[0]);
ddr3 U9R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[16] , rba, raddr[ADDR_BITS-1:0], dq [63:56], dqs[ 7] , dqs_n[ 7] , dqs_n[16], rodt[0]);
`ifdef ECC
ddr3 U5R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[17] , rba, raddr[ADDR_BITS-1:0], rcb[ 7: 0], dqs[ 8] , dqs_n[ 8] , dqs_n[17], rodt[0]);
`endif
`ifdef DUAL_RANK
ddr3 U1R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[ 9] , mba, maddr[ADDR_BITS-1:0], dq [ 7: 0], dqs[ 0] , dqs_n[ 0] , dqs_n[ 9], rodt[1]);
ddr3 U2R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[10] , mba, maddr[ADDR_BITS-1:0], dq [15: 8], dqs[ 1] , dqs_n[ 1] , dqs_n[10], rodt[1]);
ddr3 U3R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[11] , mba, maddr[ADDR_BITS-1:0], dq [23:16], dqs[ 2] , dqs_n[ 2] , dqs_n[11], rodt[1]);
ddr3 U4R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[12] , mba, maddr[ADDR_BITS-1:0], dq [31:24], dqs[ 3] , dqs_n[ 3] , dqs_n[12], rodt[1]);
ddr3 U6R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[13] , mba, maddr[ADDR_BITS-1:0], dq [39:32], dqs[ 4] , dqs_n[ 4] , dqs_n[13], rodt[1]);
ddr3 U7R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[14] , mba, maddr[ADDR_BITS-1:0], dq [47:40], dqs[ 5] , dqs_n[ 5] , dqs_n[14], rodt[1]);
ddr3 U8R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[15] , mba, maddr[ADDR_BITS-1:0], dq [55:48], dqs[ 6] , dqs_n[ 6] , dqs_n[15], rodt[1]);
ddr3 U9R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[16] , mba, maddr[ADDR_BITS-1:0], dq [63:56], dqs[ 7] , dqs_n[ 7] , dqs_n[16], rodt[1]);
`ifdef ECC
ddr3 U5R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[17] , mba, maddr[ADDR_BITS-1:0], rcb[ 7: 0], dqs[ 8] , dqs_n[ 8] , dqs_n[17], rodt[1]);
`endif
`endif
`ifdef QUAD_RANK
ddr3 U1R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[ 9] , rba, raddr[ADDR_BITS-1:0], dq [ 7: 0], dqs[ 0] , dqs_n[ 0] , dqs_n[ 9], rodt[2]);
ddr3 U2R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[10] , rba, raddr[ADDR_BITS-1:0], dq [15: 8], dqs[ 1] , dqs_n[ 1] , dqs_n[10], rodt[2]);
ddr3 U3R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[11] , rba, raddr[ADDR_BITS-1:0], dq [23:16], dqs[ 2] , dqs_n[ 2] , dqs_n[11], rodt[2]);
ddr3 U4R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[12] , rba, raddr[ADDR_BITS-1:0], dq [31:24], dqs[ 3] , dqs_n[ 3] , dqs_n[12], rodt[2]);
ddr3 U6R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[13] , rba, raddr[ADDR_BITS-1:0], dq [39:32], dqs[ 4] , dqs_n[ 4] , dqs_n[13], rodt[2]);
ddr3 U7R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[14] , rba, raddr[ADDR_BITS-1:0], dq [47:40], dqs[ 5] , dqs_n[ 5] , dqs_n[14], rodt[2]);
ddr3 U8R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[15] , rba, raddr[ADDR_BITS-1:0], dq [55:48], dqs[ 6] , dqs_n[ 6] , dqs_n[15], rodt[2]);
ddr3 U9R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[16] , rba, raddr[ADDR_BITS-1:0], dq [63:56], dqs[ 7] , dqs_n[ 7] , dqs_n[16], rodt[2]);
`ifdef ECC
ddr3 U5R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[17] , rba, raddr[ADDR_BITS-1:0], rcb[ 7: 0], dqs[ 8] , dqs_n[ 8] , dqs_n[17], rodt[2]);
`endif
ddr3 U1R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[ 9] , rba, raddr[ADDR_BITS-1:0], dq [ 7: 0], dqs[ 0] , dqs_n[ 0] , dqs_n[ 9], rodt[3]);
ddr3 U2R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[10] , rba, raddr[ADDR_BITS-1:0], dq [15: 8], dqs[ 1] , dqs_n[ 1] , dqs_n[10], rodt[3]);
ddr3 U3R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[11] , rba, raddr[ADDR_BITS-1:0], dq [23:16], dqs[ 2] , dqs_n[ 2] , dqs_n[11], rodt[3]);
ddr3 U4R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[12] , rba, raddr[ADDR_BITS-1:0], dq [31:24], dqs[ 3] , dqs_n[ 3] , dqs_n[12], rodt[3]);
ddr3 U6R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[13] , rba, raddr[ADDR_BITS-1:0], dq [39:32], dqs[ 4] , dqs_n[ 4] , dqs_n[13], rodt[3]);
ddr3 U7R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[14] , rba, raddr[ADDR_BITS-1:0], dq [47:40], dqs[ 5] , dqs_n[ 5] , dqs_n[14], rodt[3]);
ddr3 U8R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[15] , rba, raddr[ADDR_BITS-1:0], dq [55:48], dqs[ 6] , dqs_n[ 6] , dqs_n[15], rodt[3]);
ddr3 U9R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[16] , rba, raddr[ADDR_BITS-1:0], dq [63:56], dqs[ 7] , dqs_n[ 7] , dqs_n[16], rodt[3]);
`ifdef ECC
ddr3 U5R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[17] , rba, raddr[ADDR_BITS-1:0], rcb[ 7: 0], dqs[ 8] , dqs_n[ 8] , dqs_n[17], rodt[3]);
`endif
`endif
`else `ifdef x16
initial if (DEBUG) $display("%m: Component Width = x16");
ddr3 U1R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[10: 9] , rba, raddr[ADDR_BITS-1:0], dq [15: 0], dqs[1:0] , dqs_n[1:0] , , rodt[0]);
ddr3 U2R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[12:11] , rba, raddr[ADDR_BITS-1:0], dq [31:16], dqs[3:2] , dqs_n[3:2] , , rodt[0]);
ddr3 U4R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[14:13] , rba, raddr[ADDR_BITS-1:0], dq [47:32], dqs[5:4] , dqs_n[5:4] , , rodt[0]);
ddr3 U5R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, dqs[16:15] , rba, raddr[ADDR_BITS-1:0], dq [63:48], dqs[7:6] , dqs_n[7:6] , , rodt[0]);
`ifdef ECC
ddr3 U3R0 (reset_n, rck[0], rck_n[0], rcke[0], rs_n[0], rras_n, rcas_n, rwe_n, {one, dqs[17]}, rba, raddr[ADDR_BITS-1:0], rcb[15: 0], {zero, dqs[8]}, {one, dqs_n[8]}, , rodt[0]);
`endif
`ifdef DUAL_RANK
ddr3 U1R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[10: 9] , mba, maddr[ADDR_BITS-1:0], dq [15: 0], dqs[1:0] , dqs_n[1:0] , , rodt[1]);
ddr3 U2R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[12:11] , mba, maddr[ADDR_BITS-1:0], dq [31:16], dqs[3:2] , dqs_n[3:2] , , rodt[1]);
ddr3 U4R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[14:13] , mba, maddr[ADDR_BITS-1:0], dq [47:32], dqs[5:4] , dqs_n[5:4] , , rodt[1]);
ddr3 U5R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, dqs[16:15] , mba, maddr[ADDR_BITS-1:0], dq [63:48], dqs[7:6] , dqs_n[7:6] , , rodt[1]);
`ifdef ECC
ddr3 U3R1 (reset_n, rck[1], rck_n[1], rcke[1], rs_n[1], rras_n, rcas_n, rwe_n, {one, dqs[17]}, mba, maddr[ADDR_BITS-1:0], rcb[15: 0], {zero, dqs[8]}, {one, dqs_n[8]}, , rodt[1]);
`endif
`endif
`ifdef QUAD_RANK
ddr3 U1R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[10: 9] , rba, raddr[ADDR_BITS-1:0], dq [15: 0], dqs[1:0] , dqs_n[1:0] , , rodt[2]);
ddr3 U2R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[12:11] , rba, raddr[ADDR_BITS-1:0], dq [31:16], dqs[3:2] , dqs_n[3:2] , , rodt[2]);
ddr3 U4R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[14:13] , rba, raddr[ADDR_BITS-1:0], dq [47:32], dqs[5:4] , dqs_n[5:4] , , rodt[2]);
ddr3 U5R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, dqs[16:15] , rba, raddr[ADDR_BITS-1:0], dq [63:48], dqs[7:6] , dqs_n[7:6] , , rodt[2]);
`ifdef ECC
ddr3 U3R2 (reset_n, rck[0], rck_n[0], rcke[2], rs_n[2], rras_n, rcas_n, rwe_n, {one, dqs[17]}, rba, raddr[ADDR_BITS-1:0], rcb[15: 0], {zero, dqs[8]}, {one, dqs_n[8]}, , rodt[2]);
`endif
ddr3 U1R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[10: 9] , rba, raddr[ADDR_BITS-1:0], dq [15: 0], dqs[1:0] , dqs_n[1:0] , , rodt[3]);
ddr3 U2R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[12:11] , rba, raddr[ADDR_BITS-1:0], dq [31:16], dqs[3:2] , dqs_n[3:2] , , rodt[3]);
ddr3 U4R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[14:13] , rba, raddr[ADDR_BITS-1:0], dq [47:32], dqs[5:4] , dqs_n[5:4] , , rodt[3]);
ddr3 U5R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, dqs[16:15] , rba, raddr[ADDR_BITS-1:0], dq [63:48], dqs[7:6] , dqs_n[7:6] , , rodt[3]);
`ifdef ECC
ddr3 U3R3 (reset_n, rck[1], rck_n[1], rcke[3], rs_n[3], rras_n, rcas_n, rwe_n, {one, dqs[17]}, rba, raddr[ADDR_BITS-1:0], rcb[15: 0], {zero, dqs[8]}, {one, dqs_n[8]}, , rodt[3]);
`endif
`endif
`endif `endif `endif
endmodule
/****************************************************************************************
*
* Disclaimer This software code and all associated documentation, comments or other
* of Warranty: information (collectively "Software") is provided "AS IS" without
* warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
* DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
* OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
* WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
* OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
* FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
* THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
* ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
* OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
* ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
* INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
* WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
* OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
* THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGES. Because some jurisdictions prohibit the exclusion or
* limitation of liability for consequential or incidental damages, the
* above limitation may not apply to you.
*
* Copyright 2003 Micron Technology, Inc. All rights reserved.
*
****************************************************************************************/
// Parameters based on DDR3e PreJEDEC Micron specs 09022009.fm RevC 9/2/09 EN
// DDR3-2133 093/E/F
// DDR3-1866 107/E/F
// Parameters based on DDR3 Micron specs 2Gb_DDR3_SDRAM.pdf - Rev. I 7/09 EN
// DDR3-1600 125/E
// DDR3-1333 15/E
// DDR3-1066 187/E
// DDR3-800 25/E
// Timing parameters based on Speed Grade
// SYMBOL UNITS DESCRIPTION
// ------ ----- -----------
`ifdef sg093 // sg093 is equivalent to the JEDEC DDR3-2133 (14-14-14) speed bin
parameter TCK_MIN = 935; // tCK ps Minimum Clock Cycle Time
parameter TJIT_PER = 50; // tJIT(per) ps Period JItter
parameter TJIT_CC = 100; // tJIT(cc) ps Cycle to Cycle jitter
parameter TERR_2PER = 74; // tERR(2per) ps Accumulated Error (2-cycle)
parameter TERR_3PER = 87; // tERR(3per) ps Accumulated Error (3-cycle)
parameter TERR_4PER = 97; // tERR(4per) ps Accumulated Error (4-cycle)
parameter TERR_5PER = 105; // tERR(5per) ps Accumulated Error (5-cycle)
parameter TERR_6PER = 111; // tERR(6per) ps Accumulated Error (6-cycle)
parameter TERR_7PER = 116; // tERR(7per) ps Accumulated Error (7-cycle)
parameter TERR_8PER = 121; // tERR(8per) ps Accumulated Error (8-cycle)
parameter TERR_9PER = 125; // tERR(9per) ps Accumulated Error (9-cycle)
parameter TERR_10PER = 128; // tERR(10per)ps Accumulated Error (10-cycle)
parameter TERR_11PER = 132; // tERR(11per)ps Accumulated Error (11-cycle)
parameter TERR_12PER = 134; // tERR(12per)ps Accumulated Error (12-cycle)
parameter TDS = 5; // tDS ps DQ and DM input setup time relative to DQS
parameter TDH = 20; // tDH ps DQ and DM input hold time relative to DQS
parameter TDQSQ = 70; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
parameter TDQSS = 0.27; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
parameter TDSS = 0.18; // tDSS tCK DQS falling edge to CLK rising (setup time)
parameter TDSH = 0.18; // tDSH tCK DQS falling edge from CLK rising (hold time)
parameter TDQSCK = 180; // tDQSCK ps DQS output access time from CK/CK#
parameter TQSH = 0.40; // tQSH tCK DQS Output High Pulse Width
parameter TQSL = 0.40; // tQSL tCK DQS Output Low Pulse Width
parameter TDIPW = 280; // tDIPW ps DQ and DM input Pulse Width
parameter TIPW = 470; // tIPW ps Control and Address input Pulse Width
parameter TIS = 35; // tIS ps Input Setup Time
parameter TIH = 75; // tIH ps Input Hold Time
parameter TRAS_MIN = 33000; // tRAS ps Minimum Active to Precharge command time
parameter TRC = 48090; // tRC ps Active to Active/Auto Refresh command time
parameter TRCD = 13090; // tRCD ps Active to Read/Write command time
parameter TRP = 13090; // tRP ps Precharge command period
parameter TXP = 6000; // tXP ps Exit power down to a valid command
parameter TCKE = 5000; // tCKE ps CKE minimum high or low pulse width
parameter TAON = 180; // tAON ps RTT turn-on from ODTLon reference
parameter TWLS = 122; // tWLS ps Setup time for tDQS flop
parameter TWLH = 122; // tWLH ps Hold time of tDQS flop
parameter TWLO = 7500; // tWLO ps Write levelization output delay
parameter TAA_MIN = 13090; // TAA ps Internal READ command to first data
parameter CL_TIME = 13090; // CL ps Minimum CAS Latency
`elsif sg093E // sg093E is equivalent to the JEDEC DDR3-2133 (13-13-13) speed bin
parameter TCK_MIN = 935; // tCK ps Minimum Clock Cycle Time
parameter TJIT_PER = 50; // tJIT(per) ps Period JItter
parameter TJIT_CC = 100; // tJIT(cc) ps Cycle to Cycle jitter
parameter TERR_2PER = 74; // tERR(2per) ps Accumulated Error (2-cycle)
parameter TERR_3PER = 87; // tERR(3per) ps Accumulated Error (3-cycle)
parameter TERR_4PER = 97; // tERR(4per) ps Accumulated Error (4-cycle)
parameter TERR_5PER = 105; // tERR(5per) ps Accumulated Error (5-cycle)
parameter TERR_6PER = 111; // tERR(6per) ps Accumulated Error (6-cycle)
parameter TERR_7PER = 116; // tERR(7per) ps Accumulated Error (7-cycle)
parameter TERR_8PER = 121; // tERR(8per) ps Accumulated Error (8-cycle)
parameter TERR_9PER = 125; // tERR(9per) ps Accumulated Error (9-cycle)
parameter TERR_10PER = 128; // tERR(10per)ps Accumulated Error (10-cycle)
parameter TERR_11PER = 132; // tERR(11per)ps Accumulated Error (11-cycle)
parameter TERR_12PER = 134; // tERR(12per)ps Accumulated Error (12-cycle)
parameter TDS = 5; // tDS ps DQ and DM input setup time relative to DQS
parameter TDH = 20; // tDH ps DQ and DM input hold time relative to DQS
parameter TDQSQ = 70; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
parameter TDQSS = 0.27; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
parameter TDSS = 0.18; // tDSS tCK DQS falling edge to CLK rising (setup time)
parameter TDSH = 0.18; // tDSH tCK DQS falling edge from CLK rising (hold time)
parameter TDQSCK = 175; // tDQSCK ps DQS output access time from CK/CK#
parameter TQSH = 0.40; // tQSH tCK DQS Output High Pulse Width
parameter TQSL = 0.40; // tQSL tCK DQS Output Low Pulse Width
parameter TDIPW = 280; // tDIPW ps DQ and DM input Pulse Width
parameter TIPW = 470; // tIPW ps Control and Address input Pulse Width
parameter TIS = 35; // tIS ps Input Setup Time
parameter TIH = 75; // tIH ps Input Hold Time
parameter TRAS_MIN = 33000; // tRAS ps Minimum Active to Precharge command time
parameter TRC = 47155; // tRC ps Active to Active/Auto Refresh command time
parameter TRCD = 12155; // tRCD ps Active to Read/Write command time
parameter TRP = 12155; // tRP ps Precharge command period
parameter TXP = 6000; // tXP ps Exit power down to a valid command
parameter TCKE = 5000; // tCKE ps CKE minimum high or low pulse width
parameter TAON = 180; // tAON ps RTT turn-on from ODTLon reference
parameter TWLS = 122; // tWLS ps Setup time for tDQS flop
parameter TWLH = 122; // tWLH ps Hold time of tDQS flop
parameter TWLO = 7500; // tWLO ps Write levelization output delay
parameter TAA_MIN = 12155; // TAA ps Internal READ command to first data
parameter CL_TIME = 12155; // CL ps Minimum CAS Latency
`elsif sg093F // sg093F is equivalent to the JEDEC DDR3-2133 (12-12-12) speed bin
parameter TCK_MIN = 935; // tCK ps Minimum Clock Cycle Time
parameter TJIT_PER = 50; // tJIT(per) ps Period JItter
parameter TJIT_CC = 100; // tJIT(cc) ps Cycle to Cycle jitter
parameter TERR_2PER = 74; // tERR(2per) ps Accumulated Error (2-cycle)
parameter TERR_3PER = 87; // tERR(3per) ps Accumulated Error (3-cycle)
parameter TERR_4PER = 97; // tERR(4per) ps Accumulated Error (4-cycle)
parameter TERR_5PER = 105; // tERR(5per) ps Accumulated Error (5-cycle)
parameter TERR_6PER = 111; // tERR(6per) ps Accumulated Error (6-cycle)
parameter TERR_7PER = 116; // tERR(7per) ps Accumulated Error (7-cycle)
parameter TERR_8PER = 121; // tERR(8per) ps Accumulated Error (8-cycle)
parameter TERR_9PER = 125; // tERR(9per) ps Accumulated Error (9-cycle)
parameter TERR_10PER = 128; // tERR(10per)ps Accumulated Error (10-cycle)
parameter TERR_11PER = 132; // tERR(11per)ps Accumulated Error (11-cycle)
parameter TERR_12PER = 134; // tERR(12per)ps Accumulated Error (12-cycle)
parameter TDS = 5; // tDS ps DQ and DM input setup time relative to DQS
parameter TDH = 20; // tDH ps DQ and DM input hold time relative to DQS
parameter TDQSQ = 70; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
parameter TDQSS = 0.27; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
parameter TDSS = 0.18; // tDSS tCK DQS falling edge to CLK rising (setup time)
parameter TDSH = 0.18; // tDSH tCK DQS falling edge from CLK rising (hold time)
parameter TDQSCK = 175; // tDQSCK ps DQS output access time from CK/CK#
parameter TQSH = 0.40; // tQSH tCK DQS Output High Pulse Width
parameter TQSL = 0.40; // tQSL tCK DQS Output Low Pulse Width
parameter TDIPW = 280; // tDIPW ps DQ and DM input Pulse Width
parameter TIPW = 470; // tIPW ps Control and Address input Pulse Width
parameter TIS = 35; // tIS ps Input Setup Time
parameter TIH = 75; // tIH ps Input Hold Time
parameter TRAS_MIN = 33000; // tRAS ps Minimum Active to Precharge command time
parameter TRC = 46220; // tRC ps Active to Active/Auto Refresh command time
parameter TRCD = 11220; // tRCD ps Active to Read/Write command time
parameter TRP = 11220; // tRP ps Precharge command period
parameter TXP = 6000; // tXP ps Exit power down to a valid command
parameter TCKE = 5000; // tCKE ps CKE minimum high or low pulse width
parameter TAON = 180; // tAON ps RTT turn-on from ODTLon reference
parameter TWLS = 122; // tWLS ps Setup time for tDQS flop
parameter TWLH = 122; // tWLH ps Hold time of tDQS flop
parameter TWLO = 7500; // tWLO ps Write levelization output delay
parameter TAA_MIN = 11220; // TAA ps Internal READ command to first data
parameter CL_TIME = 11220; // CL ps Minimum CAS Latency
`elsif sg107 // sg107 is equivalent to the JEDEC DDR3-1866 (13-13-13) speed bin
parameter TCK_MIN = 1070; // tCK ps Minimum Clock Cycle Time
parameter TJIT_PER = 60; // tJIT(per) ps Period JItter
parameter TJIT_CC = 120; // tJIT(cc) ps Cycle to Cycle jitter
parameter TERR_2PER = 88; // tERR(2per) ps Accumulated Error (2-cycle)
parameter TERR_3PER = 105; // tERR(3per) ps Accumulated Error (3-cycle)
parameter TERR_4PER = 117; // tERR(4per) ps Accumulated Error (4-cycle)
parameter TERR_5PER = 126; // tERR(5per) ps Accumulated Error (5-cycle)
parameter TERR_6PER = 133; // tERR(6per) ps Accumulated Error (6-cycle)
parameter TERR_7PER = 139; // tERR(7per) ps Accumulated Error (7-cycle)
parameter TERR_8PER = 145; // tERR(8per) ps Accumulated Error (8-cycle)
parameter TERR_9PER = 150; // tERR(9per) ps Accumulated Error (9-cycle)
parameter TERR_10PER = 154; // tERR(10per)ps Accumulated Error (10-cycle)
parameter TERR_11PER = 158; // tERR(11per)ps Accumulated Error (11-cycle)
parameter TERR_12PER = 161; // tERR(12per)ps Accumulated Error (12-cycle)
parameter TDS = 10; // tDS ps DQ and DM input setup time relative to DQS
parameter TDH = 20; // tDH ps DQ and DM input hold time relative to DQS
parameter TDQSQ = 80; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
parameter TDQSS = 0.27; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
parameter TDSS = 0.18; // tDSS tCK DQS falling edge to CLK rising (setup time)
parameter TDSH = 0.18; // tDSH tCK DQS falling edge from CLK rising (hold time)
parameter TDQSCK = 200; // tDQSCK ps DQS output access time from CK/CK#
parameter TQSH = 0.40; // tQSH tCK DQS Output High Pulse Width
parameter TQSL = 0.40; // tQSL tCK DQS Output Low Pulse Width
parameter TDIPW = 320; // tDIPW ps DQ and DM input Pulse Width
parameter TIPW = 535; // tIPW ps Control and Address input Pulse Width
parameter TIS = 50; // tIS ps Input Setup Time
parameter TIH = 100; // tIH ps Input Hold Time
parameter TRAS_MIN = 34000; // tRAS ps Minimum Active to Precharge command time
parameter TRC = 48910; // tRC ps Active to Active/Auto Refresh command time
parameter TRCD = 13910; // tRCD ps Active to Read/Write command time
parameter TRP = 13910; // tRP ps Precharge command period
parameter TXP = 6000; // tXP ps Exit power down to a valid command
parameter TCKE = 5000; // tCKE ps CKE minimum high or low pulse width
parameter TAON = 200; // tAON ps RTT turn-on from ODTLon reference
parameter TWLS = 140; // tWLS ps Setup time for tDQS flop
parameter TWLH = 140; // tWLH ps Hold time of tDQS flop
parameter TWLO = 7500; // tWLO ps Write levelization output delay
parameter TAA_MIN = 13910; // TAA ps Internal READ command to first data
parameter CL_TIME = 13910; // CL ps Minimum CAS Latency
`elsif sg107E // sg107E is equivalent to the JEDEC DDR3-1866 (12-12-12) speed bin
parameter TCK_MIN = 1070; // tCK ps Minimum Clock Cycle Time
parameter TJIT_PER = 60; // tJIT(per) ps Period JItter
parameter TJIT_CC = 120; // tJIT(cc) ps Cycle to Cycle jitter
parameter TERR_2PER = 88; // tERR(2per) ps Accumulated Error (2-cycle)
parameter TERR_3PER = 105; // tERR(3per) ps Accumulated Error (3-cycle)
parameter TERR_4PER = 117; // tERR(4per) ps Accumulated Error (4-cycle)
parameter TERR_5PER = 126; // tERR(5per) ps Accumulated Error (5-cycle)
parameter TERR_6PER = 133; // tERR(6per) ps Accumulated Error (6-cycle)
parameter TERR_7PER = 139; // tERR(7per) ps Accumulated Error (7-cycle)
parameter TERR_8PER = 145; // tERR(8per) ps Accumulated Error (8-cycle)
parameter TERR_9PER = 150; // tERR(9per) ps Accumulated Error (9-cycle)
parameter TERR_10PER = 154; // tERR(10per)ps Accumulated Error (10-cycle)
parameter TERR_11PER = 158; // tERR(11per)ps Accumulated Error (11-cycle)
parameter TERR_12PER = 161; // tERR(12per)ps Accumulated Error (12-cycle)
parameter TDS = 10; // tDS ps DQ and DM input setup time relative to DQS
parameter TDH = 20; // tDH ps DQ and DM input hold time relative to DQS
parameter TDQSQ = 80; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
parameter TDQSS = 0.27; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
parameter TDSS = 0.18; // tDSS tCK DQS falling edge to CLK rising (setup time)
parameter TDSH = 0.18; // tDSH tCK DQS falling edge from CLK rising (hold time)
parameter TDQSCK = 200; // tDQSCK ps DQS output access time from CK/CK#
parameter TQSH = 0.40; // tQSH tCK DQS Output High Pulse Width
parameter TQSL = 0.40; // tQSL tCK DQS Output Low Pulse Width
parameter TDIPW = 320; // tDIPW ps DQ and DM input Pulse Width
parameter TIPW = 535; // tIPW ps Control and Address input Pulse Width
parameter TIS = 50; // tIS ps Input Setup Time
parameter TIH = 100; // tIH ps Input Hold Time
parameter TRAS_MIN = 34000; // tRAS ps Minimum Active to Precharge command time
parameter TRC = 47840; // tRC ps Active to Active/Auto Refresh command time
parameter TRCD = 12840; // tRCD ps Active to Read/Write command time
parameter TRP = 12840; // tRP ps Precharge command period
parameter TXP = 6000; // tXP ps Exit power down to a valid command
parameter TCKE = 5000; // tCKE ps CKE minimum high or low pulse width
parameter TAON = 200; // tAON ps RTT turn-on from ODTLon reference
parameter TWLS = 140; // tWLS ps Setup time for tDQS flop
parameter TWLH = 140; // tWLH ps Hold time of tDQS flop
parameter TWLO = 7500; // tWLO ps Write levelization output delay
parameter TAA_MIN = 12840; // TAA ps Internal READ command to first data
parameter CL_TIME = 12840; // CL ps Minimum CAS Latency
`elsif sg107F // sg107F is equivalent to the JEDEC DDR3-1866 (11-11-11) speed bin
parameter TCK_MIN = 1070; // tCK ps Minimum Clock Cycle Time
parameter TJIT_PER = 60; // tJIT(per) ps Period JItter
parameter TJIT_CC = 120; // tJIT(cc) ps Cycle to Cycle jitter
parameter TERR_2PER = 88; // tERR(2per) ps Accumulated Error (2-cycle)
parameter TERR_3PER = 105; // tERR(3per) ps Accumulated Error (3-cycle)
parameter TERR_4PER = 117; // tERR(4per) ps Accumulated Error (4-cycle)
parameter TERR_5PER = 126; // tERR(5per) ps Accumulated Error (5-cycle)
parameter TERR_6PER = 133; // tERR(6per) ps Accumulated Error (6-cycle)
parameter TERR_7PER = 139; // tERR(7per) ps Accumulated Error (7-cycle)
parameter TERR_8PER = 145; // tERR(8per) ps Accumulated Error (8-cycle)
parameter TERR_9PER = 150; // tERR(9per) ps Accumulated Error (9-cycle)
parameter TERR_10PER = 154; // tERR(10per)ps Accumulated Error (10-cycle)
parameter TERR_11PER = 158; // tERR(11per)ps Accumulated Error (11-cycle)
parameter TERR_12PER = 161; // tERR(12per)ps Accumulated Error (12-cycle)
parameter TDS = 10; // tDS ps DQ and DM input setup time relative to DQS
parameter TDH = 20; // tDH ps DQ and DM input hold time relative to DQS
parameter TDQSQ = 80; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
parameter TDQSS = 0.27; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
parameter TDSS = 0.18; // tDSS tCK DQS falling edge to CLK rising (setup time)
parameter TDSH = 0.18; // tDSH tCK DQS falling edge from CLK rising (hold time)
parameter TDQSCK = 200; // tDQSCK ps DQS output access time from CK/CK#
parameter TQSH = 0.40; // tQSH tCK DQS Output High Pulse Width
parameter TQSL = 0.40; // tQSL tCK DQS Output Low Pulse Width
parameter TDIPW = 320; // tDIPW ps DQ and DM input Pulse Width
parameter TIPW = 535; // tIPW ps Control and Address input Pulse Width
parameter TIS = 50; // tIS ps Input Setup Time
parameter TIH = 100; // tIH ps Input Hold Time
parameter TRAS_MIN = 34000; // tRAS ps Minimum Active to Precharge command time
parameter TRC = 46770; // tRC ps Active to Active/Auto Refresh command time
parameter TRCD = 11770; // tRCD ps Active to Read/Write command time
parameter TRP = 11770; // tRP ps Precharge command period
parameter TXP = 6000; // tXP ps Exit power down to a valid command
parameter TCKE = 5000; // tCKE ps CKE minimum high or low pulse width
parameter TAON = 200; // tAON ps RTT turn-on from ODTLon reference
parameter TWLS = 140; // tWLS ps Setup time for tDQS flop
parameter TWLH = 140; // tWLH ps Hold time of tDQS flop
parameter TWLO = 7500; // tWLO ps Write levelization output delay
parameter TAA_MIN = 11770; // TAA ps Internal READ command to first data
parameter CL_TIME = 11770; // CL ps Minimum CAS Latency
`elsif sg125E // sg125E is equivalent to the JEDEC DDR3-1600 (10-10-10) speed bin
parameter TCK_MIN = 1250; // tCK ps Minimum Clock Cycle Time
parameter TJIT_PER = 70; // tJIT(per) ps Period JItter
parameter TJIT_CC = 140; // tJIT(cc) ps Cycle to Cycle jitter
parameter TERR_2PER = 103; // tERR(2per) ps Accumulated Error (2-cycle)
parameter TERR_3PER = 122; // tERR(3per) ps Accumulated Error (3-cycle)
parameter TERR_4PER = 136; // tERR(4per) ps Accumulated Error (4-cycle)
parameter TERR_5PER = 147; // tERR(5per) ps Accumulated Error (5-cycle)
parameter TERR_6PER = 155; // tERR(6per) ps Accumulated Error (6-cycle)
parameter TERR_7PER = 163; // tERR(7per) ps Accumulated Error (7-cycle)
parameter TERR_8PER = 169; // tERR(8per) ps Accumulated Error (8-cycle)
parameter TERR_9PER = 175; // tERR(9per) ps Accumulated Error (9-cycle)
parameter TERR_10PER = 180; // tERR(10per)ps Accumulated Error (10-cycle)
parameter TERR_11PER = 184; // tERR(11per)ps Accumulated Error (11-cycle)
parameter TERR_12PER = 188; // tERR(12per)ps Accumulated Error (12-cycle)
parameter TDS = 10; // tDS ps DQ and DM input setup time relative to DQS
parameter TDH = 45; // tDH ps DQ and DM input hold time relative to DQS
parameter TDQSQ = 100; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
parameter TDQSS = 0.27; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
parameter TDSS = 0.18; // tDSS tCK DQS falling edge to CLK rising (setup time)
parameter TDSH = 0.18; // tDSH tCK DQS falling edge from CLK rising (hold time)
parameter TDQSCK = 225; // tDQSCK ps DQS output access time from CK/CK#
parameter TQSH = 0.40; // tQSH tCK DQS Output High Pulse Width
parameter TQSL = 0.40; // tQSL tCK DQS Output Low Pulse Width
parameter TDIPW = 360; // tDIPW ps DQ and DM input Pulse Width
parameter TIPW = 560; // tIPW ps Control and Address input Pulse Width
parameter TIS = 170; // tIS ps Input Setup Time
parameter TIH = 120; // tIH ps Input Hold Time
parameter TRAS_MIN = 35000; // tRAS ps Minimum Active to Precharge command time
parameter TRC = 47500; // tRC ps Active to Active/Auto Refresh command time
parameter TRCD = 12500; // tRCD ps Active to Read/Write command time
parameter TRP = 12500; // tRP ps Precharge command period
parameter TXP = 6000; // tXP ps Exit power down to a valid command
parameter TCKE = 5000; // tCKE ps CKE minimum high or low pulse width
parameter TAON = 250; // tAON ps RTT turn-on from ODTLon reference
parameter TWLS = 165; // tWLS ps Setup time for tDQS flop
parameter TWLH = 165; // tWLH ps Hold time of tDQS flop
parameter TWLO = 7500; // tWLO ps Write levelization output delay
parameter TAA_MIN = 12500; // TAA ps Internal READ command to first data
parameter CL_TIME = 12500; // CL ps Minimum CAS Latency
`elsif sg125 // sg125 is equivalent to the JEDEC DDR3-1600 (11-11-11) speed bin
parameter TCK_MIN = 1250; // tCK ps Minimum Clock Cycle Time
parameter TJIT_PER = 70; // tJIT(per) ps Period JItter
parameter TJIT_CC = 140; // tJIT(cc) ps Cycle to Cycle jitter
parameter TERR_2PER = 103; // tERR(2per) ps Accumulated Error (2-cycle)
parameter TERR_3PER = 122; // tERR(3per) ps Accumulated Error (3-cycle)
parameter TERR_4PER = 136; // tERR(4per) ps Accumulated Error (4-cycle)
parameter TERR_5PER = 147; // tERR(5per) ps Accumulated Error (5-cycle)
parameter TERR_6PER = 155; // tERR(6per) ps Accumulated Error (6-cycle)
parameter TERR_7PER = 163; // tERR(7per) ps Accumulated Error (7-cycle)
parameter TERR_8PER = 169; // tERR(8per) ps Accumulated Error (8-cycle)
parameter TERR_9PER = 175; // tERR(9per) ps Accumulated Error (9-cycle)
parameter TERR_10PER = 180; // tERR(10per)ps Accumulated Error (10-cycle)
parameter TERR_11PER = 184; // tERR(11per)ps Accumulated Error (11-cycle)
parameter TERR_12PER = 188; // tERR(12per)ps Accumulated Error (12-cycle)
parameter TDS = 10; // tDS ps DQ and DM input setup time relative to DQS
parameter TDH = 45; // tDH ps DQ and DM input hold time relative to DQS
parameter TDQSQ = 100; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
parameter TDQSS = 0.27; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
parameter TDSS = 0.18; // tDSS tCK DQS falling edge to CLK rising (setup time)
parameter TDSH = 0.18; // tDSH tCK DQS falling edge from CLK rising (hold time)
parameter TDQSCK = 225; // tDQSCK ps DQS output access time from CK/CK#
parameter TQSH = 0.40; // tQSH tCK DQS Output High Pulse Width
parameter TQSL = 0.40; // tQSL tCK DQS Output Low Pulse Width
parameter TDIPW = 360; // tDIPW ps DQ and DM input Pulse Width
parameter TIPW = 560; // tIPW ps Control and Address input Pulse Width
parameter TIS = 170; // tIS ps Input Setup Time
parameter TIH = 120; // tIH ps Input Hold Time
parameter TRAS_MIN = 35000; // tRAS ps Minimum Active to Precharge command time
parameter TRC = 48750; // tRC ps Active to Active/Auto Refresh command time
parameter TRCD = 13750; // tRCD ps Active to Read/Write command time
parameter TRP = 13750; // tRP ps Precharge command period
parameter TXP = 6000; // tXP ps Exit power down to a valid command
parameter TCKE = 5000; // tCKE ps CKE minimum high or low pulse width
parameter TAON = 250; // tAON ps RTT turn-on from ODTLon reference
parameter TWLS = 165; // tWLS ps Setup time for tDQS flop
parameter TWLH = 165; // tWLH ps Hold time of tDQS flop
parameter TWLO = 7500; // tWLO ps Write levelization output delay
parameter TAA_MIN = 13750; // TAA ps Internal READ command to first data
parameter CL_TIME = 13750; // CL ps Minimum CAS Latency
`elsif sg15E // sg15E is equivalent to the JEDEC DDR3-1333H (9-9-9) speed bin
parameter TCK_MIN = 1500; // tCK ps Minimum Clock Cycle Time
parameter TJIT_PER = 80; // tJIT(per) ps Period JItter
parameter TJIT_CC = 160; // tJIT(cc) ps Cycle to Cycle jitter
parameter TERR_2PER = 118; // tERR(2per) ps Accumulated Error (2-cycle)
parameter TERR_3PER = 140; // tERR(3per) ps Accumulated Error (3-cycle)
parameter TERR_4PER = 155; // tERR(4per) ps Accumulated Error (4-cycle)
parameter TERR_5PER = 168; // tERR(5per) ps Accumulated Error (5-cycle)
parameter TERR_6PER = 177; // tERR(6per) ps Accumulated Error (6-cycle)
parameter TERR_7PER = 186; // tERR(7per) ps Accumulated Error (7-cycle)
parameter TERR_8PER = 193; // tERR(8per) ps Accumulated Error (8-cycle)
parameter TERR_9PER = 200; // tERR(9per) ps Accumulated Error (9-cycle)
parameter TERR_10PER = 205; // tERR(10per)ps Accumulated Error (10-cycle)
parameter TERR_11PER = 210; // tERR(11per)ps Accumulated Error (11-cycle)
parameter TERR_12PER = 215; // tERR(12per)ps Accumulated Error (12-cycle)
parameter TDS = 30; // tDS ps DQ and DM input setup time relative to DQS
parameter TDH = 65; // tDH ps DQ and DM input hold time relative to DQS
parameter TDQSQ = 125; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
parameter TDQSS = 0.25; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
parameter TDSS = 0.20; // tDSS tCK DQS falling edge to CLK rising (setup time)
parameter TDSH = 0.20; // tDSH tCK DQS falling edge from CLK rising (hold time)
parameter TDQSCK = 255; // tDQSCK ps DQS output access time from CK/CK#
parameter TQSH = 0.40; // tQSH tCK DQS Output High Pulse Width
parameter TQSL = 0.40; // tQSL tCK DQS Output Low Pulse Width
parameter TDIPW = 400; // tDIPW ps DQ and DM input Pulse Width
parameter TIPW = 620; // tIPW ps Control and Address input Pulse Width
parameter TIS = 190; // tIS ps Input Setup Time
parameter TIH = 140; // tIH ps Input Hold Time
parameter TRAS_MIN = 36000; // tRAS ps Minimum Active to Precharge command time
parameter TRC = 49500; // tRC ps Active to Active/Auto Refresh command time
parameter TRCD = 13500; // tRCD ps Active to Read/Write command time
parameter TRP = 13500; // tRP ps Precharge command period
parameter TXP = 6000; // tXP ps Exit power down to a valid command
parameter TCKE = 5625; // tCKE ps CKE minimum high or low pulse width
parameter TAON = 250; // tAON ps RTT turn-on from ODTLon reference
parameter TWLS = 195; // tWLS ps Setup time for tDQS flop
parameter TWLH = 195; // tWLH ps Hold time of tDQS flop
parameter TWLO = 9000; // tWLO ps Write levelization output delay
parameter TAA_MIN = 13500; // TAA ps Internal READ command to first data
parameter CL_TIME = 13500; // CL ps Minimum CAS Latency
`elsif sg15 // sg15 is equivalent to the JEDEC DDR3-1333J (10-10-10) speed bin
parameter TCK_MIN = 1500; // tCK ps Minimum Clock Cycle Time
parameter TJIT_PER = 80; // tJIT(per) ps Period JItter
parameter TJIT_CC = 160; // tJIT(cc) ps Cycle to Cycle jitter
parameter TERR_2PER = 118; // tERR(2per) ps Accumulated Error (2-cycle)
parameter TERR_3PER = 140; // tERR(3per) ps Accumulated Error (3-cycle)
parameter TERR_4PER = 155; // tERR(4per) ps Accumulated Error (4-cycle)
parameter TERR_5PER = 168; // tERR(5per) ps Accumulated Error (5-cycle)
parameter TERR_6PER = 177; // tERR(6per) ps Accumulated Error (6-cycle)
parameter TERR_7PER = 186; // tERR(7per) ps Accumulated Error (7-cycle)
parameter TERR_8PER = 193; // tERR(8per) ps Accumulated Error (8-cycle)
parameter TERR_9PER = 200; // tERR(9per) ps Accumulated Error (9-cycle)
parameter TERR_10PER = 205; // tERR(10per)ps Accumulated Error (10-cycle)
parameter TERR_11PER = 210; // tERR(11per)ps Accumulated Error (11-cycle)
parameter TERR_12PER = 215; // tERR(12per)ps Accumulated Error (12-cycle)
parameter TDS = 30; // tDS ps DQ and DM input setup time relative to DQS
parameter TDH = 65; // tDH ps DQ and DM input hold time relative to DQS
parameter TDQSQ = 125; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
parameter TDQSS = 0.25; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
parameter TDSS = 0.20; // tDSS tCK DQS falling edge to CLK rising (setup time)
parameter TDSH = 0.20; // tDSH tCK DQS falling edge from CLK rising (hold time)
parameter TDQSCK = 255; // tDQSCK ps DQS output access time from CK/CK#
parameter TQSH = 0.40; // tQSH tCK DQS Output High Pulse Width
parameter TQSL = 0.40; // tQSL tCK DQS Output Low Pulse Width
parameter TDIPW = 400; // tDIPW ps DQ and DM input Pulse Width
parameter TIPW = 620; // tIPW ps Control and Address input Pulse Width
parameter TIS = 190; // tIS ps Input Setup Time
parameter TIH = 140; // tIH ps Input Hold Time
parameter TRAS_MIN = 36000; // tRAS ps Minimum Active to Precharge command time
parameter TRC = 51000; // tRC ps Active to Active/Auto Refresh command time
parameter TRCD = 15000; // tRCD ps Active to Read/Write command time
parameter TRP = 15000; // tRP ps Precharge command period
parameter TXP = 6000; // tXP ps Exit power down to a valid command
parameter TCKE = 5625; // tCKE ps CKE minimum high or low pulse width
parameter TAON = 250; // tAON ps RTT turn-on from ODTLon reference
parameter TWLS = 195; // tWLS ps Setup time for tDQS flop
parameter TWLH = 195; // tWLH ps Hold time of tDQS flop
parameter TWLO = 9000; // tWLO ps Write levelization output delay
parameter TAA_MIN = 15000; // TAA ps Internal READ command to first data
parameter CL_TIME = 15000; // CL ps Minimum CAS Latency
`elsif sg187E // sg187E is equivalent to the JEDEC DDR3-1066F (7-7-7) speed bin
parameter TCK_MIN = 1875; // tCK ps Minimum Clock Cycle Time
parameter TJIT_PER = 90; // tJIT(per) ps Period JItter
parameter TJIT_CC = 180; // tJIT(cc) ps Cycle to Cycle jitter
parameter TERR_2PER = 132; // tERR(2per) ps Accumulated Error (2-cycle)
parameter TERR_3PER = 157; // tERR(3per) ps Accumulated Error (3-cycle)
parameter TERR_4PER = 175; // tERR(4per) ps Accumulated Error (4-cycle)
parameter TERR_5PER = 188; // tERR(5per) ps Accumulated Error (5-cycle)
parameter TERR_6PER = 200; // tERR(6per) ps Accumulated Error (6-cycle)
parameter TERR_7PER = 209; // tERR(7per) ps Accumulated Error (7-cycle)
parameter TERR_8PER = 217; // tERR(8per) ps Accumulated Error (8-cycle)
parameter TERR_9PER = 224; // tERR(9per) ps Accumulated Error (9-cycle)
parameter TERR_10PER = 231; // tERR(10per)ps Accumulated Error (10-cycle)
parameter TERR_11PER = 237; // tERR(11per)ps Accumulated Error (11-cycle)
parameter TERR_12PER = 242; // tERR(12per)ps Accumulated Error (12-cycle)
parameter TDS = 75; // tDS ps DQ and DM input setup time relative to DQS
parameter TDH = 100; // tDH ps DQ and DM input hold time relative to DQS
parameter TDQSQ = 150; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
parameter TDQSS = 0.25; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
parameter TDSS = 0.20; // tDSS tCK DQS falling edge to CLK rising (setup time)
parameter TDSH = 0.20; // tDSH tCK DQS falling edge from CLK rising (hold time)
parameter TDQSCK = 300; // tDQSCK ps DQS output access time from CK/CK#
parameter TQSH = 0.38; // tQSH tCK DQS Output High Pulse Width
parameter TQSL = 0.38; // tQSL tCK DQS Output Low Pulse Width
parameter TDIPW = 490; // tDIPW ps DQ and DM input Pulse Width
parameter TIPW = 780; // tIPW ps Control and Address input Pulse Width
parameter TIS = 275; // tIS ps Input Setup Time
parameter TIH = 200; // tIH ps Input Hold Time
parameter TRAS_MIN = 37500; // tRAS ps Minimum Active to Precharge command time
parameter TRC = 50625; // tRC ps Active to Active/Auto Refresh command time
parameter TRCD = 13125; // tRCD ps Active to Read/Write command time
parameter TRP = 13125; // tRP ps Precharge command period
parameter TXP = 7500; // tXP ps Exit power down to a valid command
parameter TCKE = 5625; // tCKE ps CKE minimum high or low pulse width
parameter TAON = 300; // tAON ps RTT turn-on from ODTLon reference
parameter TWLS = 245; // tWLS ps Setup time for tDQS flop
parameter TWLH = 245; // tWLH ps Hold time of tDQS flop
parameter TWLO = 9000; // tWLO ps Write levelization output delay
parameter TAA_MIN = 13125; // TAA ps Internal READ command to first data
parameter CL_TIME = 13125; // CL ps Minimum CAS Latency
`elsif sg187 // sg187 is equivalent to the JEDEC DDR3-1066G (8-8-8) speed bin
parameter TCK_MIN = 1875; // tCK ps Minimum Clock Cycle Time
parameter TJIT_PER = 90; // tJIT(per) ps Period JItter
parameter TJIT_CC = 180; // tJIT(cc) ps Cycle to Cycle jitter
parameter TERR_2PER = 132; // tERR(2per) ps Accumulated Error (2-cycle)
parameter TERR_3PER = 157; // tERR(3per) ps Accumulated Error (3-cycle)
parameter TERR_4PER = 175; // tERR(4per) ps Accumulated Error (4-cycle)
parameter TERR_5PER = 188; // tERR(5per) ps Accumulated Error (5-cycle)
parameter TERR_6PER = 200; // tERR(6per) ps Accumulated Error (6-cycle)
parameter TERR_7PER = 209; // tERR(7per) ps Accumulated Error (7-cycle)
parameter TERR_8PER = 217; // tERR(8per) ps Accumulated Error (8-cycle)
parameter TERR_9PER = 224; // tERR(9per) ps Accumulated Error (9-cycle)
parameter TERR_10PER = 231; // tERR(10per)ps Accumulated Error (10-cycle)
parameter TERR_11PER = 237; // tERR(11per)ps Accumulated Error (11-cycle)
parameter TERR_12PER = 242; // tERR(12per)ps Accumulated Error (12-cycle)
parameter TDS = 75; // tDS ps DQ and DM input setup time relative to DQS
parameter TDH = 100; // tDH ps DQ and DM input hold time relative to DQS
parameter TDQSQ = 150; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
parameter TDQSS = 0.25; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
parameter TDSS = 0.20; // tDSS tCK DQS falling edge to CLK rising (setup time)
parameter TDSH = 0.20; // tDSH tCK DQS falling edge from CLK rising (hold time)
parameter TDQSCK = 300; // tDQSCK ps DQS output access time from CK/CK#
parameter TQSH = 0.38; // tQSH tCK DQS Output High Pulse Width
parameter TQSL = 0.38; // tQSL tCK DQS Output Low Pulse Width
parameter TDIPW = 490; // tDIPW ps DQ and DM input Pulse Width
parameter TIPW = 780; // tIPW ps Control and Address input Pulse Width
parameter TIS = 275; // tIS ps Input Setup Time
parameter TIH = 200; // tIH ps Input Hold Time
parameter TRAS_MIN = 37500; // tRAS ps Minimum Active to Precharge command time
parameter TRC = 52500; // tRC ps Active to Active/Auto Refresh command time
parameter TRCD = 15000; // tRCD ps Active to Read/Write command time
parameter TRP = 15000; // tRP ps Precharge command period
parameter TXP = 7500; // tXP ps Exit power down to a valid command
parameter TCKE = 5625; // tCKE ps CKE minimum high or low pulse width
parameter TAON = 300; // tAON ps RTT turn-on from ODTLon reference
parameter TWLS = 245; // tWLS ps Setup time for tDQS flop
parameter TWLH = 245; // tWLH ps Hold time of tDQS flop
parameter TWLO = 9000; // tWLO ps Write levelization output delay
parameter TAA_MIN = 15000; // TAA ps Internal READ command to first data
parameter CL_TIME = 15000; // CL ps Minimum CAS Latency
`elsif sg25E // sg25E is equivalent to the JEDEC DDR3-800D (5-5-5) speed bin
parameter TCK_MIN = 2500; // tCK ps Minimum Clock Cycle Time
parameter TJIT_PER = 100; // tJIT(per) ps Period JItter
parameter TJIT_CC = 200; // tJIT(cc) ps Cycle to Cycle jitter
parameter TERR_2PER = 147; // tERR(2per) ps Accumulated Error (2-cycle)
parameter TERR_3PER = 175; // tERR(3per) ps Accumulated Error (3-cycle)
parameter TERR_4PER = 194; // tERR(4per) ps Accumulated Error (4-cycle)
parameter TERR_5PER = 209; // tERR(5per) ps Accumulated Error (5-cycle)
parameter TERR_6PER = 222; // tERR(6per) ps Accumulated Error (6-cycle)
parameter TERR_7PER = 232; // tERR(7per) ps Accumulated Error (7-cycle)
parameter TERR_8PER = 241; // tERR(8per) ps Accumulated Error (8-cycle)
parameter TERR_9PER = 249; // tERR(9per) ps Accumulated Error (9-cycle)
parameter TERR_10PER = 257; // tERR(10per)ps Accumulated Error (10-cycle)
parameter TERR_11PER = 263; // tERR(11per)ps Accumulated Error (11-cycle)
parameter TERR_12PER = 269; // tERR(12per)ps Accumulated Error (12-cycle)
parameter TDS = 125; // tDS ps DQ and DM input setup time relative to DQS
parameter TDH = 150; // tDH ps DQ and DM input hold time relative to DQS
parameter TDQSQ = 200; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
parameter TDQSS = 0.25; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
parameter TDSS = 0.20; // tDSS tCK DQS falling edge to CLK rising (setup time)
parameter TDSH = 0.20; // tDSH tCK DQS falling edge from CLK rising (hold time)
parameter TDQSCK = 400; // tDQSCK ps DQS output access time from CK/CK#
parameter TQSH = 0.38; // tQSH tCK DQS Output High Pulse Width
parameter TQSL = 0.38; // tQSL tCK DQS Output Low Pulse Width
parameter TDIPW = 600; // tDIPW ps DQ and DM input Pulse Width
parameter TIPW = 900; // tIPW ps Control and Address input Pulse Width
parameter TIS = 350; // tIS ps Input Setup Time
parameter TIH = 275; // tIH ps Input Hold Time
parameter TRAS_MIN = 37500; // tRAS ps Minimum Active to Precharge command time
parameter TRC = 50000; // tRC ps Active to Active/Auto Refresh command time
parameter TRCD = 12500; // tRCD ps Active to Read/Write command time
parameter TRP = 12500; // tRP ps Precharge command period
parameter TXP = 7500; // tXP ps Exit power down to a valid command
parameter TCKE = 7500; // tCKE ps CKE minimum high or low pulse width
parameter TAON = 400; // tAON ps RTT turn-on from ODTLon reference
parameter TWLS = 325; // tWLS ps Setup time for tDQS flop
parameter TWLH = 325; // tWLH ps Hold time of tDQS flop
parameter TWLO = 9000; // tWLO ps Write levelization output delay
parameter TAA_MIN = 12500; // TAA ps Internal READ command to first data
parameter CL_TIME = 12500; // CL ps Minimum CAS Latency
`else `define sg25 // sg25 is equivalent to the JEDEC DDR3-800E (6-6-6) speed bin
parameter TCK_MIN = 2500; // tCK ps Minimum Clock Cycle Time
parameter TJIT_PER = 100; // tJIT(per) ps Period JItter
parameter TJIT_CC = 200; // tJIT(cc) ps Cycle to Cycle jitter
parameter TERR_2PER = 147; // tERR(2per) ps Accumulated Error (2-cycle)
parameter TERR_3PER = 175; // tERR(3per) ps Accumulated Error (3-cycle)
parameter TERR_4PER = 194; // tERR(4per) ps Accumulated Error (4-cycle)
parameter TERR_5PER = 209; // tERR(5per) ps Accumulated Error (5-cycle)
parameter TERR_6PER = 222; // tERR(6per) ps Accumulated Error (6-cycle)
parameter TERR_7PER = 232; // tERR(7per) ps Accumulated Error (7-cycle)
parameter TERR_8PER = 241; // tERR(8per) ps Accumulated Error (8-cycle)
parameter TERR_9PER = 249; // tERR(9per) ps Accumulated Error (9-cycle)
parameter TERR_10PER = 257; // tERR(10per)ps Accumulated Error (10-cycle)
parameter TERR_11PER = 263; // tERR(11per)ps Accumulated Error (11-cycle)
parameter TERR_12PER = 269; // tERR(12per)ps Accumulated Error (12-cycle)
parameter TDS = 125; // tDS ps DQ and DM input setup time relative to DQS
parameter TDH = 150; // tDH ps DQ and DM input hold time relative to DQS
parameter TDQSQ = 200; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
parameter TDQSS = 0.25; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
parameter TDSS = 0.20; // tDSS tCK DQS falling edge to CLK rising (setup time)
parameter TDSH = 0.20; // tDSH tCK DQS falling edge from CLK rising (hold time)
parameter TDQSCK = 400; // tDQSCK ps DQS output access time from CK/CK#
parameter TQSH = 0.38; // tQSH tCK DQS Output High Pulse Width
parameter TQSL = 0.38; // tQSL tCK DQS Output Low Pulse Width
parameter TDIPW = 600; // tDIPW ps DQ and DM input Pulse Width
parameter TIPW = 900; // tIPW ps Control and Address input Pulse Width
parameter TIS = 350; // tIS ps Input Setup Time
parameter TIH = 275; // tIH ps Input Hold Time
parameter TRAS_MIN = 37500; // tRAS ps Minimum Active to Precharge command time
parameter TRC = 52500; // tRC ps Active to Active/Auto Refresh command time
parameter TRCD = 15000; // tRCD ps Active to Read/Write command time
parameter TRP = 15000; // tRP ps Precharge command period
parameter TXP = 7500; // tXP ps Exit power down to a valid command
parameter TCKE = 7500; // tCKE ps CKE minimum high or low pulse width
parameter TAON = 400; // tAON ps RTT turn-on from ODTLon reference
parameter TWLS = 325; // tWLS ps Setup time for tDQS flop
parameter TWLH = 325; // tWLH ps Hold time of tDQS flop
parameter TWLO = 9000; // tWLO ps Write levelization output delay
parameter TAA_MIN = 15000; // TAA ps Internal READ command to first data
parameter CL_TIME = 15000; // CL ps Minimum CAS Latency
`endif
`ifdef x16
`ifdef sg093
parameter TRRD = 6000; // tRRD ps (2KB page size) Active bank a to Active bank b command time
parameter TFAW = 35000; // tFAW ps (2KB page size) Four Bank Activate window
`elsif sg093E
parameter TRRD = 6000; // tRRD ps (2KB page size) Active bank a to Active bank b command time
parameter TFAW = 35000; // tFAW ps (2KB page size) Four Bank Activate window
`elsif sg093F
parameter TRRD = 6000; // tRRD ps (2KB page size) Active bank a to Active bank b command time
parameter TFAW = 35000; // tFAW ps (2KB page size) Four Bank Activate window
`elsif sg107
parameter TRRD = 6000; // tRRD ps (2KB page size) Active bank a to Active bank b command time
parameter TFAW = 35000; // tFAW ps (2KB page size) Four Bank Activate window
`elsif sg107E
parameter TRRD = 6000; // tRRD ps (2KB page size) Active bank a to Active bank b command time
parameter TFAW = 35000; // tFAW ps (2KB page size) Four Bank Activate window
`elsif sg107F
parameter TRRD = 6000; // tRRD ps (2KB page size) Active bank a to Active bank b command time
parameter TFAW = 35000; // tFAW ps (2KB page size) Four Bank Activate window
`elsif sg125E
parameter TRRD = 7500; // tRRD ps (2KB page size) Active bank a to Active bank b command time
parameter TFAW = 40000; // tFAW ps (2KB page size) Four Bank Activate window
`elsif sg125
parameter TRRD = 7500; // tRRD ps (2KB page size) Active bank a to Active bank b command time
parameter TFAW = 40000; // tFAW ps (2KB page size) Four Bank Activate window
`elsif sg15E
parameter TRRD = 7500; // tRRD ps (2KB page size) Active bank a to Active bank b command time
parameter TFAW = 45000; // tFAW ps (2KB page size) Four Bank Activate window
`elsif sg15
parameter TRRD = 7500; // tRRD ps (2KB page size) Active bank a to Active bank b command time
parameter TFAW = 45000; // tFAW ps (2KB page size) Four Bank Activate window
`else // sg187E, sg187, sg25, sg25E
parameter TRRD = 10000; // tRRD ps (2KB page size) Active bank a to Active bank b command time
parameter TFAW = 50000; // tFAW ps (2KB page size) Four Bank Activate window
`endif
`else // x4, x8
`ifdef sg093
parameter TRRD = 5000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
parameter TFAW = 25000; // tFAW ps (1KB page size) Four Bank Activate window
`elsif sg093E
parameter TRRD = 5000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
parameter TFAW = 25000; // tFAW ps (1KB page size) Four Bank Activate window
`elsif sg093F
parameter TRRD = 5000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
parameter TFAW = 25000; // tFAW ps (1KB page size) Four Bank Activate window
`elsif sg107
parameter TRRD = 5000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
parameter TFAW = 25000; // tFAW ps (1KB page size) Four Bank Activate window
`elsif sg107E
parameter TRRD = 5000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
parameter TFAW = 25000; // tFAW ps (1KB page size) Four Bank Activate window
`elsif sg107F
parameter TRRD = 5000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
parameter TFAW = 25000; // tFAW ps (1KB page size) Four Bank Activate window
`elsif sg125E
parameter TRRD = 6000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
parameter TFAW = 30000; // tFAW ps (1KB page size) Four Bank Activate window
`elsif sg125
parameter TRRD = 6000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
parameter TFAW = 30000; // tFAW ps (1KB page size) Four Bank Activate window
`elsif sg15E
parameter TRRD = 6000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
parameter TFAW = 30000; // tFAW ps (1KB page size) Four Bank Activate window
`elsif sg15
parameter TRRD = 6000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
parameter TFAW = 30000; // tFAW ps (1KB page size) Four Bank Activate window
`elsif sg187E
parameter TRRD = 7500; // tRRD ps (1KB page size) Active bank a to Active bank b command time
parameter TFAW = 37500; // tFAW ps (1KB page size) Four Bank Activate window
`elsif sg187
parameter TRRD = 7500; // tRRD ps (1KB page size) Active bank a to Active bank b command time
parameter TFAW = 37500; // tFAW ps (1KB page size) Four Bank Activate window
`else // sg25, sg25E
parameter TRRD = 10000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
parameter TFAW = 40000; // tFAW ps (1KB page size) Four Bank Activate window
`endif
`endif
// Timing Parameters
// Mode Register
parameter CL_MIN = 5; // CL tCK Minimum CAS Latency
parameter CL_MAX = 14; // CL tCK Maximum CAS Latency
parameter AL_MIN = 0; // AL tCK Minimum Additive Latency
parameter AL_MAX = 2; // AL tCK Maximum Additive Latency
parameter WR_MIN = 5; // WR tCK Minimum Write Recovery
parameter WR_MAX = 16; // WR tCK Maximum Write Recovery
parameter BL_MIN = 4; // BL tCK Minimum Burst Length
parameter BL_MAX = 8; // BL tCK Minimum Burst Length
parameter CWL_MIN = 5; // CWL tCK Minimum CAS Write Latency
parameter CWL_MAX = 10; // CWL tCK Maximum CAS Write Latency
// Clock
parameter TCK_MAX = 3300; // tCK ps Maximum Clock Cycle Time
parameter TCH_AVG_MIN = 0.47; // tCH tCK Minimum Clock High-Level Pulse Width
parameter TCL_AVG_MIN = 0.47; // tCL tCK Minimum Clock Low-Level Pulse Width
parameter TCH_AVG_MAX = 0.53; // tCH tCK Maximum Clock High-Level Pulse Width
parameter TCL_AVG_MAX = 0.53; // tCL tCK Maximum Clock Low-Level Pulse Width
parameter TCH_ABS_MIN = 0.43; // tCH tCK Minimum Clock High-Level Pulse Width
parameter TCL_ABS_MIN = 0.43; // tCL tCK Maximum Clock Low-Level Pulse Width
parameter TCKE_TCK = 3; // tCKE tCK CKE minimum high or low pulse width
parameter TAA_MAX = 20000; // TAA ps Internal READ command to first data
// Data OUT
parameter TQH = 0.38; // tQH ps DQ output hold time from DQS, DQS#
// Data Strobe OUT
parameter TRPRE = 0.90; // tRPRE tCK DQS Read Preamble
parameter TRPST = 0.30; // tRPST tCK DQS Read Postamble
// Data Strobe IN
parameter TDQSH = 0.45; // tDQSH tCK DQS input High Pulse Width
parameter TDQSL = 0.45; // tDQSL tCK DQS input Low Pulse Width
parameter TWPRE = 0.90; // tWPRE tCK DQS Write Preamble
parameter TWPST = 0.30; // tWPST tCK DQS Write Postamble
// Command and Address
parameter TZQCS = 64; // tZQCS tCK ZQ Cal (Short) time
parameter TZQINIT = 512; // tZQinit tCK ZQ Cal (Long) time
parameter TZQOPER = 256; // tZQoper tCK ZQ Cal (Long) time
parameter TCCD = 4; // tCCD tCK Cas to Cas command delay
parameter TCCD_DG = 2; // tCCD_DG tCK Cas to Cas command delay to different group
parameter TRAS_MAX = 60e9; // tRAS ps Maximum Active to Precharge command time
parameter TWR = 15000; // tWR ps Write recovery time
parameter TMRD = 4; // tMRD tCK Load Mode Register command cycle time
parameter TMOD = 15000; // tMOD ps LOAD MODE to non-LOAD MODE command cycle time
parameter TMOD_TCK = 12; // tMOD tCK LOAD MODE to non-LOAD MODE command cycle time
parameter TRRD_TCK = 4; // tRRD tCK Active bank a to Active bank b command time
parameter TRRD_DG = 3000; // tRRD_DG ps Active bank a to Active bank b command time to different group
parameter TRRD_DG_TCK = 2; // tRRD_DG tCK Active bank a to Active bank b command time to different group
parameter TRTP = 7500; // tRTP ps Read to Precharge command delay
parameter TRTP_TCK = 4; // tRTP tCK Read to Precharge command delay
parameter TWTR = 7500; // tWTR ps Write to Read command delay
parameter TWTR_DG = 3750; // tWTR_DG ps Write to Read command delay to different group
parameter TWTR_TCK = 4; // tWTR tCK Write to Read command delay
parameter TWTR_DG_TCK = 2; // tWTR_DG tCK Write to Read command delay to different group
parameter TDLLK = 512; // tDLLK tCK DLL locking time
// Refresh - 2Gb
parameter TRFC_MIN = 160000; // tRFC ps Refresh to Refresh Command interval minimum value
parameter TRFC_MAX =70312500; // tRFC ps Refresh to Refresh Command Interval maximum value
// Power Down
parameter TXP_TCK = 3; // tXP tCK Exit power down to a valid command
parameter TXPDLL = 24000; // tXPDLL ps Exit precharge power down to READ or WRITE command (DLL-off mode)
parameter TXPDLL_TCK = 10; // tXPDLL tCK Exit precharge power down to READ or WRITE command (DLL-off mode)
parameter TACTPDEN = 1; // tACTPDEN tCK Timing of last ACT command to power down entry
parameter TPRPDEN = 1; // tPREPDEN tCK Timing of last PRE command to power down entry
parameter TREFPDEN = 1; // tARPDEN tCK Timing of last REFRESH command to power down entry
parameter TCPDED = 1; // tCPDED tCK Command pass disable/enable delay
parameter TPD_MAX =TRFC_MAX; // tPD ps Power-down entry-to-exit timing
parameter TXPR = 170000; // tXPR ps Exit Reset from CKE assertion to a valid command
parameter TXPR_TCK = 5; // tXPR tCK Exit Reset from CKE assertion to a valid command
// Self Refresh
parameter TXS = 170000; // tXS ps Exit self refesh to a non-read or write command
parameter TXS_TCK = 5; // tXS tCK Exit self refesh to a non-read or write command
parameter TXSDLL = TDLLK; // tXSRD tCK Exit self refresh to a read or write command
parameter TISXR = TIS; // tISXR ps CKE setup time during self refresh exit.
parameter TCKSRE = 10000; // tCKSRE ps Valid Clock requirement after self refresh entry (SRE)
parameter TCKSRE_TCK = 5; // tCKSRE tCK Valid Clock requirement after self refresh entry (SRE)
parameter TCKSRX = 10000; // tCKSRX ps Valid Clock requirement prior to self refresh exit (SRX)
parameter TCKSRX_TCK = 5; // tCKSRX tCK Valid Clock requirement prior to self refresh exit (SRX)
parameter TCKESR_TCK = 4; // tCKESR tCK Minimum CKE low width for Self Refresh entry to exit timing
// ODT
parameter TAOF = 0.7; // tAOF tCK RTT turn-off from ODTLoff reference
parameter TAONPD = 8500; // tAONPD ps Asynchronous RTT turn-on delay (Power-Down with DLL frozen)
parameter TAOFPD = 8500; // tAONPD ps Asynchronous RTT turn-off delay (Power-Down with DLL frozen)
parameter ODTH4 = 4; // ODTH4 tCK ODT minimum HIGH time after ODT assertion or write (BL4)
parameter ODTH8 = 6; // ODTH8 tCK ODT minimum HIGH time after write (BL8)
parameter TADC = 0.7; // tADC tCK RTT dynamic change skew
// Write Levelization
parameter TWLMRD = 40; // tWLMRD tCK First DQS pulse rising edge after tDQSS margining mode is programmed
parameter TWLDQSEN = 25; // tWLDQSEN tCK DQS/DQS delay after tDQSS margining mode is programmed
parameter TWLOE = 2000; // tWLOE ps Write levelization output error
// Size Parameters based on Part Width
`ifdef x4
parameter DM_BITS = 1; // Set this parameter to control how many Data Mask bits are used
parameter ADDR_BITS = 15; // MAX Address Bits
parameter ROW_BITS = 15; // Set this parameter to control how many Address bits are used
parameter COL_BITS = 11; // Set this parameter to control how many Column bits are used
parameter DQ_BITS = 4; // Set this parameter to control how many Data bits are used **Same as part bit width**
parameter DQS_BITS = 1; // Set this parameter to control how many Dqs bits are used
`elsif x8
parameter DM_BITS = 1; // Set this parameter to control how many Data Mask bits are used
parameter ADDR_BITS = 15; // MAX Address Bits
parameter ROW_BITS = 15; // Set this parameter to control how many Address bits are used
parameter COL_BITS = 10; // Set this parameter to control how many Column bits are used
parameter DQ_BITS = 8; // Set this parameter to control how many Data bits are used **Same as part bit width**
parameter DQS_BITS = 1; // Set this parameter to control how many Dqs bits are used
`else `define x16
parameter DM_BITS = 2; // Set this parameter to control how many Data Mask bits are used
parameter ADDR_BITS = 14; // MAX Address Bits
parameter ROW_BITS = 14; // Set this parameter to control how many Address bits are used
parameter COL_BITS = 10; // Set this parameter to control how many Column bits are used
parameter DQ_BITS = 16; // Set this parameter to control how many Data bits are used **Same as part bit width**
parameter DQS_BITS = 2; // Set this parameter to control how many Dqs bits are used
`endif
// Size Parameters
parameter BA_BITS = 3; // Set this parmaeter to control how many Bank Address bits are used
parameter MEM_BITS = 16; // Set this parameter to control how many write data bursts can be stored in memory. The default is 2^10=1024.
parameter AP = 10; // the address bit that controls auto-precharge and precharge-all
parameter BC = 12; // the address bit that controls burst chop
parameter BL_BITS = 3; // the number of bits required to count to BL_MAX
parameter BO_BITS = 2; // the number of Burst Order Bits
`ifdef QUAD_RANK
`define DUAL_RANK // also define DUAL_RANK
parameter CS_BITS = 4; // Number of Chip Select Bits
parameter RANKS = 4; // Number of Chip Selects
`elsif DUAL_RANK
parameter CS_BITS = 2; // Number of Chip Select Bits
parameter RANKS = 2; // Number of Chip Selects
`else
parameter CS_BITS = 2; // Number of Chip Select Bits
parameter RANKS = 1; // Number of Chip Selects
`endif
// Simulation parameters
parameter RZQ = 240; // termination resistance
parameter PRE_DEF_PAT = 8'hAA; // value returned during mpr pre-defined pattern readout
parameter STOP_ON_ERROR = 1; // If set to 1, the model will halt on command sequence/major errors
parameter DEBUG = 1; // Turn on Debug messages
parameter BUS_DELAY = 0; // delay in nanoseconds
parameter RANDOM_OUT_DELAY = 0; // If set to 1, the model will put a random amount of delay on DQ/DQS during reads
parameter RANDOM_SEED = 711689044; //seed value for random generator.
parameter RDQSEN_PRE = 2; // DQS driving time prior to first read strobe
parameter RDQSEN_PST = 1; // DQS driving time after last read strobe
parameter RDQS_PRE = 2; // DQS low time prior to first read strobe
parameter RDQS_PST = 1; // DQS low time after last read strobe
parameter RDQEN_PRE = 0; // DQ/DM driving time prior to first read data
parameter RDQEN_PST = 0; // DQ/DM driving time after last read data
parameter WDQS_PRE = 2; // DQS half clock periods prior to first write strobe
parameter WDQS_PST = 1; // DQS half clock periods after last write strobe
// check for legal cas latency based on the cas write latency
function valid_cl;
input [3:0] cl;
input [3:0] cwl;
case ({cwl, cl})
`ifdef sg093
{4'd5, 4'd6 },
{4'd6, 4'd7 },
{4'd6, 4'd8 },
{4'd7, 4'd9 },
{4'd7, 4'd10},
{4'd8, 4'd11},
{4'd9, 4'd13},
{4'd10, 4'd14}: valid_cl = 1;
`elsif sg093E
{4'd5, 4'd5 },
{4'd5, 4'd6 },
{4'd6, 4'd7 },
{4'd6, 4'd8 },
{4'd7, 4'd9 },
{4'd7, 4'd10},
{4'd8, 4'd10},
{4'd8, 4'd11},
{4'd9, 4'd12},
{4'd9, 4'd13},
{4'd10, 4'd13},
{4'd10, 4'd14}: valid_cl = 1;
`elsif sg093F
{4'd5, 4'd5 },
{4'd5, 4'd6 },
{4'd6, 4'd6 },
{4'd6, 4'd7 },
{4'd6, 4'd8 },
{4'd7, 4'd8 },
{4'd7, 4'd9 },
{4'd7, 4'd10},
{4'd8, 4'd9 },
{4'd8, 4'd10},
{4'd8, 4'd11},
{4'd9, 4'd11},
{4'd9, 4'd12},
{4'd9, 4'd13},
{4'd10, 4'd12},
{4'd10, 4'd13},
{4'd10, 4'd14}: valid_cl = 1;
`elsif sg107
{4'd5, 4'd6 },
{4'd6, 4'd8 },
{4'd7, 4'd10},
{4'd9, 4'd13}: valid_cl = 1;
`elsif sg107E
{4'd5, 4'd6 },
{4'd6, 4'd7 },
{4'd6, 4'd8 },
{4'd7, 4'd9 },
{4'd7, 4'd10},
{4'd8, 4'd11},
{4'd9, 4'd12},
{4'd9, 4'd13}: valid_cl = 1;
`elsif sg107F
{4'd5, 4'd5 },
{4'd5, 4'd6 },
{4'd6, 4'd7 },
{4'd6, 4'd8 },
{4'd7, 4'd8 },
{4'd7, 4'd9 },
{4'd7, 4'd10},
{4'd8, 4'd10},
{4'd8, 4'd11},
{4'd9, 4'd11},
{4'd9, 4'd12},
{4'd9, 4'd13}: valid_cl = 1;
`elsif sg125E
{4'd5, 4'd5 },
{4'd5, 4'd6 },
{4'd6, 4'd7 },
{4'd6, 4'd8 },
{4'd7, 4'd9 },
{4'd7, 4'd10},
{4'd8, 4'd10},
{4'd8, 4'd11}: valid_cl = 1;
`elsif sg125
{4'd5, 4'd5 },
{4'd5, 4'd6 },
{4'd6, 4'd7 },
{4'd6, 4'd8 },
{4'd7, 4'd9 },
{4'd7, 4'd10},
{4'd8, 4'd11}: valid_cl = 1;
`elsif sg15E
{4'd5, 4'd5 },
{4'd5, 4'd6 },
{4'd6, 4'd7 },
{4'd6, 4'd8 },
{4'd7, 4'd9 },
{4'd7, 4'd10}: valid_cl = 1;
`elsif sg15
{4'd5, 4'd5 },
{4'd5, 4'd6 },
{4'd6, 4'd8 },
{4'd7, 4'd10}: valid_cl = 1;
`elsif sg187E
{4'd5, 4'd5 },
{4'd5, 4'd6 },
{4'd6, 4'd7 },
{4'd6, 4'd8 }: valid_cl = 1;
`elsif sg187
{4'd5, 4'd5 },
{4'd5, 4'd6 },
{4'd6, 4'd8 }: valid_cl = 1;
`elsif sg25E
{4'd5, 4'd5 },
{4'd5, 4'd6 }: valid_cl = 1;
`elsif sg25
{4'd5, 4'd5 },
{4'd5, 4'd6 }: valid_cl = 1;
`endif
default : valid_cl = 0;
endcase
endfunction
// find the minimum valid cas write latency
function [3:0] min_cwl;
input period;
real period;
min_cwl = (period >= 2500.0) ? 5:
(period >= 1875.0) ? 6:
(period >= 1500.0) ? 7:
(period >= 1250.0) ? 8:
(period >= 1070.0) ? 9:
10; // (period >= 935)
endfunction
// find the minimum valid cas latency
function [3:0] min_cl;
input period;
real period;
reg [3:0] cwl;
reg [3:0] cl;
begin
cwl = min_cwl(period);
for (cl=CL_MAX; cl>=CL_MIN; cl=cl-1) begin
if (valid_cl(cl, cwl)) begin
min_cl = cl;
end
end
end
endfunction
Disclaimer of Warranty:
-----------------------
This software code and all associated documentation, comments or other
information (collectively "Software") is provided "AS IS" without
warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES. Because some jurisdictions prohibit the exclusion or
limitation of liability for consequential or incidental damages, the
above limitation may not apply to you.
Copyright 2003 Micron Technology, Inc. All rights reserved.
Getting Started:
----------------
Unzip the included files to a folder.
Compile ddr3.v and tb.v in a verilog simulator.
Simulate the top level test bench tb.
Or, if you are using the ModelSim simulator, type "do tb.do" at the prompt.
File Descriptions:
------------------
ddr3.v -ddr3 model
ddr3_mcp.v -structural wrapper for ddr3 - multi-chip package model
ddr3_module.v -structural wrapper for ddr3 - module model
ddr3_parameters.vh -file that contains all parameters used by the model
readme.txt -this file
tb.v -ddr3 model test bench
subtest.vh -example test included by the test bench.
tb.do -compiles and runs the ddr3 model and test bench
Defining the Speed Grade:
-------------------------
The verilog compiler directive "`define" may be used to choose between
multiple speed grades supported by the ddr3 model. Allowable speed
grades are listed in the ddr3_parameters.vh file and begin with the
letters "sg". The speed grade is used to select a set of timing
parameters for the ddr3 model. The following are examples of defining
the speed grade.
simulator command line
--------- ------------
ModelSim vlog +define+sg25 ddr3.v
VCS vcs +define+sg25 ddr3.v
NC-Verilog ncverilog +define+sg25 ddr3.v
Defining the Organization:
--------------------------
The verilog compiler directive "`define" may be used to choose between
multiple organizations supported by the ddr3 model. Valid
organizations include "x4", "x8", and x16, and are listed in the
ddr3_parameters.vh file. The organization is used to select the amount
of memory and the port sizes of the ddr3 model. The following are
examples of defining the organization.
simulator command line
--------- ------------
ModelSim vlog +define+x8 ddr3.v
NC-Verilog ncverilog +define+x8 ddr3.v
VCS vcs +define+x8 ddr3.v
All combinations of speed grade and organization are considered valid
by the ddr3 model even though a Micron part may not exist for every
combination.
Allocating Memory:
------------------
An associative array has been implemented to reduce the amount of
static memory allocated by the ddr3 model. Each entry in the
associative array is a burst length of eight in size. The number of
entries in the associative array is controlled by the MEM_BITS
parameter, and is equal to 2^MEM_BITS. For example, if the MEM_BITS
parameter is equal to 10, the associative array will be large enough
to store 1024 writes of burst length 8 to unique addresses. The
following are examples of setting the MEM_BITS parameter to 8.
simulator command line
--------- ------------
ModelSim vsim -GMEM_BITS=8 ddr3
NC-Verilog ncverilog +defparam+ddr3.MEM_BITS=8 ddr3.v
VCS vcs -pvalue+MEM_BITS=8 ddr3.v
It is possible to allocate memory for every address supported by the
ddr3 model by using the verilog compiler directive "`define MAX_MEM".
This procedure will improve simulation performance at the expense of
system memory. The following are examples of allocating memory for
every address.
Simulator command line
--------- ------------
ModelSim vlog +define+MAX_MEM ddr3.v
NC-Verilog ncverilog +define+MAX_MEM ddr3.v
VCS vcs +define+MAX_MEM ddr3.v
**********************************************************************
The following information is provided to assist the modeling engineer
in creating multi-chip package (mcp) models. ddr3_mcp.v is a
structural wrapper that instantiates ddr3 models. This wrapper can be
used to create single, dual, or quad rank mcp models. From the
perspective of the model, the only item that needs to be defined is the
number of ranks.
**********************************************************************
Defining the Number of Ranks in a multi-chip package:
----------------------------------------------------
The verilog compiler directive "`define" may be used to choose between
single, dual, and quad rank mcp configurations. The default is single
rank if nothing is defined. Dual rank configuration can be selected by
defining "DUAL_RANK" when the ddr3_mcp is compiled. Quad rank
configuration can be selected by defining "QUAD_RANK" when the ddr3_mcp
is compiled. The following are examples of defining a dual rank mcp
configuration.
simulator command line
--------- ------------
ModelSim vlog +define+DUAL_RANK ddr3.v ddr3_mcp.v
NC-Verilog ncverilog +define+DUAL_RANK ddr3.v ddr3_mcp.v
VCS vcs +define+DUAL_RANK ddr3.v ddr3_mcp.v
**********************************************************************
The following information is provided to assist the modeling engineer
in creating DIMM models. ddr3_module.v is a structural wrapper that
instantiates ddr3 models. This wrapper can be used to create UDIMM,
RDIMM or SODIMM models. Other form factors are not supported
(MiniDIMM, VLP DIMM, etc.). From the perspective of the model, the
items that need to be defined are the number of ranks, the module
type, and the presence of ECC. All combinations of ranks, module
type, and ECC are considered valid by the ddr3_module model even
though a Micron part may not exist for every combination.
**********************************************************************
Defining the Number of Ranks on a module:
----------------------------------------
The verilog compiler directive "`define" may be used to choose between
single, dual, and quad rank module configurations. The default is single
rank if nothing is defined. Dual rank configuration can be selected by
defining "DUAL_RANK" when the ddr3_module is compiled. Quad rank
configuration can be selected by defining "QUAD_RANK" when the ddr3_module
is compiled. The following are examples of defining a dual rank module
configuration.
simulator command line
--------- ------------
ModelSim vlog +define+DUAL_RANK ddr3.v ddr3_module.v
NC-Verilog ncverilog +define+DUAL_RANK ddr3.v ddr3_module.v
VCS vcs +define+DUAL_RANK ddr3.v ddr3_module.v
Defining the Module Type:
-----------------------------------
The verilog compiler directive "`define" may be used to choose between
UDIMM, RDIMM, and SODIMM module configurations. The default is
unregistered (UDIMM) if nothing is defined. SODIMM configuration can be
selected by defining "SODIMM" when the ddr3_module is compiled. Registered
configuration can be selected by defining "RDIMM" when the ddr3_module is
compiled. The following are examples of defining a registered module
configuration.
simulator command line
--------- ------------
ModelSim vlog +define+RDIMM ddr3.v ddr3_module.v
NC-Verilog ncverilog +define+RDIMM ddr3.v ddr3_module.v
VCS vcs +define+RDIMM ddr3.v ddr3_module.v
Defining the ECC for a module:
-----------------------------
The verilog compiler directive "`define" may be used to choose between
ECC and nonECC module configurations. The default is nonECC if nothing
is defined. ECC configuration can be selected by defining "ECC" when
the ddr3_module is compiled. The following are examples of defining an
ECC module configuration.
simulator command line
--------- ------------
ModelSim vlog +define+ECC ddr3.v ddr3_module.v
NC-Verilog ncverilog +define+ECC ddr3.v ddr3_module.v
VCS vcs +define+ECC ddr3.v ddr3_module.v
/****************************************************************************************
*
* File Name: subtest.vh
*
* Description: Micron SDRAM DDR3 (Double Data Rate 3)
* This file is included by tb.v
*
* Disclaimer This software code and all associated documentation, comments or other
* of Warranty: information (collectively "Software") is provided "AS IS" without
* warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
* DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
* OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
* WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
* OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
* FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
* THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
* ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
* OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
* ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
* INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
* WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
* OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
* THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGES. Because some jurisdictions prohibit the exclusion or
* limitation of liability for consequential or incidental damages, the
* above limitation may not apply to you.
*
* Copyright 2003 Micron Technology, Inc. All rights reserved.
*
****************************************************************************************/
initial begin : test
parameter [31:0] REP = DQ_BITS/8.0;
real original_tck;
reg [8*DQ_BITS-1:0] d0, d1, d2, d3;
d0 = {
{REP{8'h07}}, {REP{8'h06}}, {REP{8'h05}}, {REP{8'h04}},
{REP{8'h03}}, {REP{8'h02}}, {REP{8'h01}}, {REP{8'h00}}
};
d1 = {
{REP{8'h17}}, {REP{8'h16}}, {REP{8'h15}}, {REP{8'h14}},
{REP{8'h13}}, {REP{8'h12}}, {REP{8'h11}}, {REP{8'h10}}
};
d2 = {
{REP{8'h27}}, {REP{8'h26}}, {REP{8'h25}}, {REP{8'h24}},
{REP{8'h23}}, {REP{8'h22}}, {REP{8'h21}}, {REP{8'h20}}
};
d3 = {
{REP{8'h37}}, {REP{8'h36}}, {REP{8'h35}}, {REP{8'h34}},
{REP{8'h33}}, {REP{8'h32}}, {REP{8'h31}}, {REP{8'h30}}
};
rst_n <= 1'b0;
cke <= 1'b0;
cs_n <= 1'b1;
ras_n <= 1'b1;
cas_n <= 1'b1;
we_n <= 1'b1;
ba <= {BA_BITS{1'bz}};
a <= {ADDR_BITS{1'bz}};
odt_out <= 1'b0;
dq_en <= 1'b0;
dqs_en <= 1'b0;
// POWERUP SECTION
power_up;
// INITIALIZE SECTION
zq_calibration (1); // perform Long ZQ Calibration
load_mode (3, 14'b00000000000000); // Extended Mode Register (3)
nop (tmrd-1);
load_mode (2, {14'b00001000_000_000} | mr_cwl<<3); // Extended Mode Register 2 with DCC Disable
nop (tmrd-1);
load_mode (1, 14'b0000010110); // Extended Mode Register with DLL Enable, AL=CL-1
nop (tmrd-1);
load_mode (0, {14'b0_0_000_1_0_000_1_0_01} | mr_wr<<9 | mr_cl<<2); // Mode Register with DLL Reset
nop (tdllk);
odt_out <= 1; // turn on odt
activate (0, 0); // Activate Bank 0, Row 0
nop (trcd);
$display ("READ (BL4) to WRITE (BL4)");
read (0, 0, 0, 0);
nop (rl + tccd/2 + 1 - wl);
write (0, 0, 0, 0, 0, 10);
$display ("Consecutive WRITE (BL8) to WRITE (BL8)");
nop (tccd - 1);
write (0, 0, 0, 1, 0, 20);
nop (tccd - 1);
write (0, 0, 0, 1, 0, 30);
$display ("Consecutive WRITE (BL4) to WRITE (BL4)");
nop (tccd - 1);
write (0, 0, 0, 0, 0, 40);
nop (tccd - 1);
write (0, 0, 0, 0, 0, 50);
$display ("WRITE (BL4 on the fly) to READ (BL4 on the fly)");
nop (cwl + 3 + twtr);
read_verify (0, 0, 0, 0, 0, 50);
nop (rl + tccd/2 + 1 - wl);
$display ("READ (BL4) to WRITE (BL8)");
write (0, 0, 0, 1, 0, 10);
nop (cwl + 3 + twtr);
$display ("WRITE (BL8) to READ (BL4)");
read_verify (0, 0, 1, 0, 0, 10);
nop (al + trtp + trp);
$display ("tRRD Timing");
activate (0, 0);
nop (trrd - 1);
activate (1, 0);
nop (trrd - 1);
activate (2, 0);
nop (trrd - 1);
activate (3, 0);
nop (trcd - 1);
$display ("Consecutive Writes");
write (0, 0, 0, 1, 0, d0);
nop (tccd - 1);
write (1, 0, 0, 1, 0, d1);
nop (tccd - 1);
write (2, 0, 0, 1, 0, d2);
nop (tccd - 1);
write (3, 0, 0, 1, 0, d3);
nop (wl + bl/2 + twtr);
$display ("Consecutive Reads");
read_verify (0, 0, 0, 1, 0, d0);
nop (tccd - 1);
read_verify (1, 0, 0, 1, 0, d1);
nop (tccd - 1);
read_verify (2, 0, 0, 1, 0, d2);
nop (tccd - 1);
read_verify (3, 0, 0, 1, 0, d3);
nop (rl + bl/2);
$display ("Non Consecutive Writes");
write (0, 0, 0, 1, 0, d0);
nop (tccd);
write (1, 0, 0, 1, 0, d1);
nop (tccd);
write (2, 0, 0, 1, 0, d2);
nop (tccd);
write (3, 0, 0, 1, 0, d3);
nop (wl + bl/2 + twtr);
$display ("Non Consecutive Reads");
read_verify (0, 0, 1, 1, 0, d0);
nop (tccd);
read_verify (1, 0, 1, 1, 0, d1);
nop (tccd);
read_verify (2, 0, 1, 1, 0, d2);
nop (tccd);
read_verify (3, 0, 1, 1, 0, d3);
nop (max(rl + bl/2, al + trtp + trp - 1));
// POWER DOWN SECTION
odt_out <= 1'b0;
odt_out <= #(50*tck) 1'b1;
odt_out <= #((50 + BL_MAX)*tck) 1'b0;
refresh;
power_down (trfc);
nop (txp);
self_refresh (trfc);
nop (txsdll);
$display ("Power-Down Entry after WRITE /w AP (WRA)");
load_mode (0, {14'b0_0_000_0_0_000_1_0_10} | mr_wr<<9 | mr_cl<<2); // Mode Register with Burst Chop
nop (tmod-1);
activate (0, 0); // Activate Bank 0, Row 0
nop (trcd-1);
write (0, 0, 1, 0, 0, 10);
nop (wl + bl/2 + twr-1);
power_down (tcke-1);
nop (txpdll);
$display ("refresh to power down re-entry");
refresh;
power_down (tcke-1);
nop (trfc-tcke);
power_down (tcke-1);
nop (txp);
$display ("Power-Down Exit to Refresh to Power-Down Entry");
refresh;
nop (txpdll-txp-1);
power_down (tcke-1);
nop (trfc-txp);
$display ("Change Frequency during Precharge Power-down");
original_tck <= tck;
pd_change_period (TCK_MAX);
nop (tcke + 1);
$display ("Change Frequency during Self Refresh");
sr_change_period (original_tck);
nop (txsdll);
// multipurpose register section
// pre-defined pattern
load_mode (3, 14'b00000000000100);
nop (tmod);
read (0, 0, 0, 1);
nop (rl + bl/2 + trtp);
load_mode (3, 14'b00000000000000);
nop (tmod);
// self refresh with ck off
cke <= 1'b0;
self_refresh (tcksre);
assign ck = 0;
# (trfc*tck);
deassign ck;
ck <= 1'b1;
# ((tcksrx + 0.5)*tck);
nop (txsdll + 1);
// write levelization section
load_mode (2, {14'b00000000_000_000} | mr_cwl<<3); // Extended Mode Register 2 with DCC Disable
nop (tmrd - 1);
load_mode (1, 14'b00000010010110);
nop (tmod);
odt_out <= 1'b1;
nop (TWLDQSEN - tmod);
dqs_en <= 1'b1;
dqs_out <= {DQS_BITS{1'b0}};
nop (TWLMRD - TWLDQSEN);
dqs_out <= #(TWLH + 1) {DQS_BITS{1'b1}};
dqs_out <= #(TWLH + tck/2 + 1) {DQS_BITS{1'b0}};
nop (16);
dqs_out <= #(TWLH + tck/2 + 1) {DQS_BITS{1'b1}};
dqs_out <= #(TWLH + tck + 1) {DQS_BITS{1'b0}};
odt_out <= 1'b0;
nop (wl - 1); // ODTLoff + tAOF
load_mode (1, 14'b00000000010110);
dqs_en <= 1'b0;
nop (tmod);
power_up;
nop (txp);
// INITIALIZE SECTION
zq_calibration (1); // perform Long ZQ Calibration
load_mode (3, 14'b00000000000000); // Extended Mode Register (3)
nop (tmrd - 1);
load_mode (2, {14'b00001000_000_000} | mr_cwl<<3); // Extended Mode Register 2 with DCC Disable
nop (tmrd - 1);
load_mode (1, 14'b0000010110); // Extended Mode Register with DLL Enable, AL=CL-1
nop (tmrd - 1);
load_mode (0, {14'b0_0_000_1_0_000_1_0_01} | mr_wr<<9 | mr_cl<<2); // Mode Register with DLL Reset
nop (tdllk);
odt_out <= 1'b1;
activate (0, 0); // Activate Bank 0, Row 0
nop (trcd);
read (0, 1, 1, 1);
nop (rl + bl/2 + trtp + trp);
`ifdef TRUEBL4
// true BL4 section
odt_out <= 1'b0;
nop (wl - 1); // ODTLoff + tAOF
load_mode (1, 14'b00000000000110); // Extended Mode Register with DLL Enable, AL=0
nop (tmrd - 1);
load_mode (0, {14'b0_0_000_0_0_000_0_0_11} | mr_wr<<9 | mr_cl<<2); // Mode Register with true BL4
nop (tmod - 1);
odt_out <= 1'b1;
$display ("tRRD Timing in True BL4 Mode");
activate (0, 0);
nop (trrd_dg - 1);
activate (2, 0);
nop (max(trcd - trrd_dg - 1, trcd - tccd_dg - 1));
$display ("Consecutive True BL4 Writes");
write (0, 0, 0, 0, 0, d0);
nop (tccd_dg - 1);
write (2, 0, 0, 0, 0, d1);
nop (tccd_dg - 1);
write (0, 0, 0, 0, 0, d2);
nop (tccd_dg - 1);
write (2, 0, 0, 0, 0, d3);
nop (wl + bl/2 + twtr_dg);
$display ("Consecutive True BL4 Reads");
read_verify (0, 0, 0, 0, 0, d2);
nop (tccd_dg - 1);
read_verify (2, 0, 0, 0, 0, d3);
nop (rl + bl/2);
$display ("Non Consecutive True BL4 Writes");
write (0, 0, 0, 0, 0, d0);
nop (tccd_dg);
write (2, 0, 0, 0, 0, d1);
nop (tccd_dg);
write (0, 0, 0, 0, 0, d2);
nop (tccd_dg);
write (2, 0, 0, 0, 0, d3);
nop (wl + bl/2 + twtr_dg);
$display ("Non Consecutive True BL4 Reads");
read_verify (0, 0, 0, 0, 0, d2);
nop (tccd_dg);
read_verify (2, 0, 0, 0, 0, d3);
nop (rl + tccd_dg/2 + 2 - wl - 1);
$display ("True BL4 Write to Read (Same Group)");
write (0, 0, 0, 0, 0, d0);
nop (wl + bl/2 + twtr - 1);
read_verify (0, 0, 0, 0, 0, d0);
nop (rl + tccd_dg/2 + 2 - wl - 1);
$display ("True BL4 Write to Read (Different Group)");
write (2, 0, 0, 0, 0, d1);
nop (wl + bl/2 + twtr_dg - 1);
read_verify (0, 0, 0, 0, 0, d0);
nop (rl + bl/2);
`endif
test_done;
end
#########################################################################################
#
# Disclaimer This software code and all associated documentation, comments or other
# of Warranty: information (collectively "Software") is provided "AS IS" without
# warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
# DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
# TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
# OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
# WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
# OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
# FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
# THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
# ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
# OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
# ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
# INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
# WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
# OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
# THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGES. Because some jurisdictions prohibit the exclusion or
# limitation of liability for consequential or incidental damages, the
# above limitation may not apply to you.
#
# Copyright 2003 Micron Technology, Inc. All rights reserved.
#
#########################################################################################
vlog -novopt ddr3.v tb.v
vsim -novopt tb
add wave -p sdramddr3/*
run -all
/****************************************************************************************
*
* File Name: tb.v
*
* Dependencies: ddr3.v, ddr3_parameters.vh
*
* Description: Micron SDRAM DDR3 (Double Data Rate 3) test bench
*
* Note: -Set simulator resolution to "ps" accuracy
* -Set Debug = 0 to disable $display messages
*
* Disclaimer This software code and all associated documentation, comments or other
* of Warranty: information (collectively "Software") is provided "AS IS" without
* warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
* DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
* OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
* WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
* OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
* FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
* THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
* ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
* OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
* ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
* INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
* WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
* OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
* THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGES. Because some jurisdictions prohibit the exclusion or
* limitation of liability for consequential or incidental damages, the
* above limitation may not apply to you.
*
* Copyright 2003 Micron Technology, Inc. All rights reserved.
*
****************************************************************************************/
`timescale 1ps / 1ps
module tb;
`include "ddr3_parameters.vh"
// ports
reg rst_n;
reg ck;
wire ck_n = ~ck;
reg cke;
reg cs_n;
reg ras_n;
reg cas_n;
reg we_n;
reg [BA_BITS-1:0] ba;
reg [ADDR_BITS-1:0] a;
wire [DM_BITS-1:0] dm;
wire [DQ_BITS-1:0] dq;
wire [DQS_BITS-1:0] dqs;
wire [DQS_BITS-1:0] dqs_n;
wire [DQS_BITS-1:0] tdqs_n;
wire odt;
// mode registers
reg [ADDR_BITS-1:0] mode_reg0; //Mode Register
reg [ADDR_BITS-1:0] mode_reg1; //Extended Mode Register
reg [ADDR_BITS-1:0] mode_reg2; //Extended Mode Register 2
wire [3:0] cl = {mode_reg0[2], mode_reg0[6:4]} + 4; //CAS Latency
wire bo = mode_reg0[3]; //Burst Order
reg [3:0] bl; //Burst Length
wire [3:0] cwl = mode_reg2[5:3] + 5; //CAS Write Latency
wire [3:0] al = (mode_reg1[4:3] === 2'b00) ? 4'h0 : cl - mode_reg1[4:3]; //Additive Latency
wire [4:0] rl = cl + al; //Read Latency
wire [4:0] wl = cwl + al; //Write Latency
// dq transmit
reg dq_en;
reg [DM_BITS-1:0] dm_out;
reg [DQ_BITS-1:0] dq_out;
reg dqs_en;
reg [DQS_BITS-1:0] dqs_out;
assign dm = dq_en ? dm_out : {DM_BITS{1'bz}};
assign dq = dq_en ? dq_out : {DQ_BITS{1'bz}};
assign dqs = dqs_en ? dqs_out : {DQS_BITS{1'bz}};
assign dqs_n = dqs_en ? ~dqs_out : {DQS_BITS{1'bz}};
// dq receive
reg [DM_BITS-1:0] dm_fifo [4*CL_MAX+BL_MAX+2:0];
reg [DQ_BITS-1:0] dq_fifo [4*CL_MAX+BL_MAX+2:0];
wire [DQ_BITS-1:0] q0, q1, q2, q3;
reg ptr_rst_n;
reg [1:0] burst_cntr;
// odt
reg odt_out;
reg [(AL_MAX+CL_MAX):0] odt_fifo;
assign odt = odt_out & !odt_fifo[0];
// timing definition in tCK units
real tck;
wire [11:0] tccd = TCCD;
wire [11:0] tcke = max(ceil(TCKE/tck), TCKE_TCK);
wire [11:0] tckesr = TCKESR_TCK;
wire [11:0] tcksre = max(ceil(TCKSRE/tck), TCKSRE_TCK);
wire [11:0] tcksrx = max(ceil(TCKSRX/tck), TCKSRX_TCK);
wire [11:0] tcl_min = min_cl(tck);
wire [6:2] mr_cl = (tcl_min - 4)<<2 | (tcl_min/12);
wire [11:0] tcpded = TCPDED;
wire [11:0] tcwl_min = min_cwl(tck);
wire [5:3] mr_cwl = tcwl_min - 5;
wire [11:0] tdllk = TDLLK;
wire [11:0] tfaw = ceil(TFAW/tck);
wire [11:0] tmod = max(ceil(TMOD/tck), TMOD_TCK);
wire [11:0] tmrd = TMRD;
wire [11:0] tras = ceil(TRAS_MIN/tck);
wire [11:0] trc = ceil(TRC/tck);
wire [11:0] trcd = ceil(TRCD/tck);
wire [11:0] trfc = ceil(TRFC_MIN/tck);
wire [11:0] trp = ceil(TRP/tck);
wire [11:0] trrd = max(ceil(TRRD/tck), TRRD_TCK);
wire [11:0] trtp = max(ceil(TRTP/tck), TRTP_TCK);
wire [11:0] twr = ceil(TWR/tck);
wire [11:0] twtr = max(ceil(TWTR/tck), TWTR_TCK);
wire [11:0] txp = max(ceil(TXP/tck), TXP_TCK);
wire [11:0] txpdll = max(ceil(TXPDLL/tck), TXPDLL_TCK);
wire [11:0] txpr = max(ceil(TXPR/tck), TXPR_TCK);
wire [11:0] txs = max(ceil(TXS/tck), TXS_TCK);
wire [11:0] txsdll = TXSDLL;
wire [11:0] tzqcs = TZQCS;
wire [11:0] tzqoper = TZQOPER;
wire [11:0] wr = (twr < 8) ? twr : twr + twr%2;
wire [11:9] mr_wr = (twr < 8) ? (twr - 4) : twr>>1;
`ifdef TRUEBL4
wire [11:0] tccd_dg = TCCD_DG;
wire [11:0] trrd_dg = max(ceil(TRRD_DG/tck), TRRD_DG_TCK);
wire [11:0] twtr_dg = max(ceil(TWTR_DG/tck), TWTR_DG_TCK);
`endif
initial begin
$timeformat (-9, 1, " ns", 1);
`ifdef period
tck <= `period;
`else
tck <= ceil(TCK_MIN);
`endif
ck <= 1'b1;
odt_fifo <= 0;
end
// component instantiation
ddr3 sdramddr3 (
rst_n,
ck,
ck_n,
cke,
cs_n,
ras_n,
cas_n,
we_n,
dm,
ba,
a,
dq,
dqs,
dqs_n,
tdqs_n,
odt
);
// clock generator
always @(posedge ck) begin
ck <= #(tck/2) 1'b0;
ck <= #(tck) 1'b1;
end
function integer ceil;
input number;
real number;
if (number > $rtoi(number))
ceil = $rtoi(number) + 1;
else
ceil = number;
endfunction
function integer max;
input arg1;
input arg2;
integer arg1;
integer arg2;
if (arg1 > arg2)
max = arg1;
else
max = arg2;
endfunction
task power_up;
begin
rst_n <= 1'b0;
cke <= 1'b0;
cs_n <= 1'b1;
odt_out <= 1'b0;
# (10000); // CKE must be LOW 10ns prior to RST# transitioning HIGH.
@ (negedge ck) rst_n = 1'b1;
# (10000) // After RST# transitions HIGH, wait 500us (minus one clock) with CKE LOW. (wait 10 ns instead of 500 us)
@ (negedge ck) nop(TXPR/tck + 1); // After CKE is registered HIGH and after tXPR has been satisfied, MRS commands may be issued.
end
endtask
task load_mode;
input [BA_BITS-1:0] bank;
input [ADDR_BITS-1:0] addr;
begin
case (bank)
0: mode_reg0 = addr;
1: mode_reg1 = addr;
2: mode_reg2 = addr;
endcase
cke <= 1'b1;
cs_n <= 1'b0;
ras_n <= 1'b0;
cas_n <= 1'b0;
we_n <= 1'b0;
ba <= bank;
a <= addr;
@(negedge ck);
end
endtask
task refresh;
begin
cke <= 1'b1;
cs_n <= 1'b0;
ras_n <= 1'b0;
cas_n <= 1'b0;
we_n <= 1'b1;
@(negedge ck);
end
endtask
task precharge;
input [BA_BITS-1:0] bank;
input ap; //precharge all
begin
cke <= 1'b1;
cs_n <= 1'b0;
ras_n <= 1'b0;
cas_n <= 1'b1;
we_n <= 1'b0;
ba <= bank;
a <= (ap<<10);
@(negedge ck);
end
endtask
task activate;
input [BA_BITS-1:0] bank;
input [ROW_BITS-1:0] row;
begin
cke <= 1'b1;
cs_n <= 1'b0;
ras_n <= 1'b0;
cas_n <= 1'b1;
we_n <= 1'b1;
ba <= bank;
a <= row;
@(negedge ck);
end
endtask
//write task supports burst lengths <= 8
task write;
input [BA_BITS-1:0] bank;
input [COL_BITS-1:0] col;
input ap; //Auto Precharge
input bc; //Burst Chop
input [8*DM_BITS-1:0] dm;
input [8*DQ_BITS-1:0] dq;
reg [ADDR_BITS-1:0] atemp [2:0];
integer i;
begin
cke <= 1'b1;
cs_n <= 1'b0;
ras_n <= 1'b1;
cas_n <= 1'b0;
we_n <= 1'b0;
ba <= bank;
atemp[0] = col & 10'h3ff; //a[ 9: 0] = COL[ 9: 0]
atemp[1] = ((col>>10) & 1'h1)<<11;//a[ 11] = COL[ 10]
atemp[2] = (col>>11)<<13; //a[ N:13] = COL[ N:11]
a <= atemp[0] | atemp[1] | atemp[2] | (ap<<10) | (bc<<12);
casex ({bc, mode_reg0[1:0]})
3'bx00, 3'b101:bl=8;
3'bx1x, 3'b001:bl=4;
endcase
dqs_en <= #(wl*tck-tck/2) 1'b1;
dqs_out <= #(wl*tck-tck/2) {DQS_BITS{1'b1}};
for (i=0; i<=bl; i=i+1) begin
dqs_en <= #(wl*tck + i*tck/2) 1'b1;
if (i%2 == 0) begin
dqs_out <= #(wl*tck + i*tck/2) {DQS_BITS{1'b0}};
end else begin
dqs_out <= #(wl*tck + i*tck/2) {DQS_BITS{1'b1}};
end
dq_en <= #(wl*tck + i*tck/2 + tck/4) 1'b1;
dm_out <= #(wl*tck + i*tck/2 + tck/4) dm>>i*DM_BITS;
dq_out <= #(wl*tck + i*tck/2 + tck/4) dq>>i*DQ_BITS;
end
dqs_en <= #(wl*tck + bl*tck/2 + tck/2) 1'b0;
dq_en <= #(wl*tck + bl*tck/2 + tck/4) 1'b0;
@(negedge ck);
end
endtask
// read without data verification
task read;
input [BA_BITS-1:0] bank;
input [COL_BITS-1:0] col;
input ap; //Auto Precharge
input bc; //Burst Chop
reg [ADDR_BITS-1:0] atemp [2:0];
integer i;
begin
cke <= 1'b1;
cs_n <= 1'b0;
ras_n <= 1'b1;
cas_n <= 1'b0;
we_n <= 1'b1;
ba <= bank;
atemp[0] = col & 10'h3ff; //a[ 9: 0] = COL[ 9: 0]
atemp[1] = ((col>>10) & 1'h1)<<11;//a[ 11] = COL[ 10]
atemp[2] = (col>>11)<<13; //a[ N:13] = COL[ N:11]
a <= atemp[0] | atemp[1] | atemp[2] | (ap<<10) | (bc<<12);
casex ({bc, mode_reg0[1:0]})
3'bx00, 3'b101:bl=8;
3'bx1x, 3'b001:bl=4;
endcase
for (i=0; i<(bl/2 + 2); i=i+1) begin
odt_fifo[rl-wl + i] = 1'b1;
end
@(negedge ck);
end
endtask
task zq_calibration;
input long;
begin
cke <= 1'b1;
cs_n <= 1'b0;
ras_n <= 1'b1;
cas_n <= 1'b1;
we_n <= 1'b0;
ba <= 0;
a <= long<<10;
@(negedge ck);
end
endtask
task nop;
input [31:0] count;
begin
cke <= 1'b1;
cs_n <= 1'b0;
ras_n <= 1'b1;
cas_n <= 1'b1;
we_n <= 1'b1;
repeat(count) @(negedge ck);
end
endtask
task deselect;
input [31:0] count;
begin
cke <= 1'b1;
cs_n <= 1'b1;
ras_n <= 1'b1;
cas_n <= 1'b1;
we_n <= 1'b1;
repeat(count) @(negedge ck);
end
endtask
task power_down;
input [31:0] count;
begin
cke <= 1'b0;
cs_n <= 1'b1;
ras_n <= 1'b1;
cas_n <= 1'b1;
we_n <= 1'b1;
repeat(count) @(negedge ck);
end
endtask
task self_refresh;
input [31:0] count;
begin
cke <= 1'b0;
cs_n <= 1'b0;
ras_n <= 1'b0;
cas_n <= 1'b0;
we_n <= 1'b1;
cs_n <= #(tck) 1'b1;
ras_n <= #(tck) 1'b1;
cas_n <= #(tck) 1'b1;
we_n <= #(tck) 1'b1;
repeat(count) @(negedge ck);
end
endtask
task pd_change_period;
input [31:0] new_period;
begin
$display ("%m at time %t: INFO: Changing Clock Period to %08.3f ps", $time, new_period);
power_down (tcksre+1);
tck <= new_period;
@(posedge ck);
@(negedge ck);
repeat(tcksrx) @(negedge ck);
end
endtask
task sr_change_period;
input [31:0] new_period;
begin
$display ("%m at time %t: INFO: Changing Clock Period to %08.3f ps", $time, new_period);
self_refresh (tcksre+1);
tck <= new_period;
@(posedge ck);
@(negedge ck);
repeat(tcksrx) @(negedge ck);
end
endtask
// read with data verification
task read_verify;
input [BA_BITS-1:0] bank;
input [COL_BITS-1:0] col;
input ap; //Auto Precharge
input bc; //Burst Chop
input [8*DM_BITS-1:0] dm; //Expected Data Mask
input [8*DQ_BITS-1:0] dq; //Expected Data
integer i, j;
begin
read (bank, col, ap, bc);
for (i=0; i<bl; i=i+1) begin
j = (col ^ i)%bl;
if (!bo) begin
j = (j & -4) + ((col + i) & 3);
end
dm_fifo[2*rl + i] = dm>>(i*DM_BITS);
dq_fifo[2*rl + i] = dq>>(i*DQ_BITS);
end
end
endtask
// receiver(s) for data_verify process
dqrx dqrx[DQS_BITS-1:0] (ptr_rst_n, dqs, dq, q0, q1, q2, q3);
// perform data verification as a result of read_verify task call
always @(ck) begin:data_verify
integer i;
integer j;
reg [DQ_BITS-1:0] bit_mask;
reg [DM_BITS-1:0] dm_temp;
reg [DQ_BITS-1:0] dq_temp;
for (i = !ck; (i < 2/(2.0 - !ck)); i=i+1) begin
if (dm_fifo[i] === {DM_BITS{1'bx}}) begin
burst_cntr = 0;
end else begin
dm_temp = dm_fifo[i];
for (j=0; j<DQ_BITS; j=j+1) begin
bit_mask[j] = !dm_temp[j/(DQ_BITS/DM_BITS)];
end
case (burst_cntr)
0: dq_temp = q0;
1: dq_temp = q1;
2: dq_temp = q2;
3: dq_temp = q3;
endcase
//if (((dq_temp & bit_mask) === (dq_fifo[i] & bit_mask)))
// $display ("%m at time %t: INFO: Successful read data compare. Expected = %h, Actual = %h, Mask = %h, i = %d", $time, dq_fifo[i], dq_temp, bit_mask, burst_cntr);
if ((dq_temp & bit_mask) !== (dq_fifo[i] & bit_mask))
$display ("%m at time %t: ERROR: Read data miscompare. Expected = %h, Actual = %h, Mask = %h, i = %d", $time, dq_fifo[i], dq_temp, bit_mask, burst_cntr);
burst_cntr = burst_cntr + 1;
end
end
if (!ck) begin
ptr_rst_n <= (dm_fifo[4] !== {DM_BITS{1'bx}});
for (i=0; i<=(4*CL_MAX+BL_MAX); i=i+1) begin
dm_fifo[i] = dm_fifo[i+2];
dq_fifo[i] = dq_fifo[i+2];
end
odt_fifo = odt_fifo>>1;
end
end
// End-of-test triggered in 'subtest.vh'
task test_done;
begin
$display ("%m at time %t: INFO: Simulation is Complete", $time);
$finish(0);
end
endtask
// Test included from external file
`include "subtest.vh"
endmodule
module dqrx (
ptr_rst_n, dqs, dq, q0, q1, q2, q3
);
`include "ddr3_parameters.vh"
input ptr_rst_n;
input dqs;
input [DQ_BITS/DQS_BITS-1:0] dq;
output [DQ_BITS/DQS_BITS-1:0] q0;
output [DQ_BITS/DQS_BITS-1:0] q1;
output [DQ_BITS/DQS_BITS-1:0] q2;
output [DQ_BITS/DQS_BITS-1:0] q3;
reg [1:0] ptr;
reg [DQ_BITS/DQS_BITS-1:0] q [3:0];
reg ptr_rst_dly_n;
always @(ptr_rst_n) ptr_rst_dly_n <= #(TDQSCK + TDQSQ + 2) ptr_rst_n;
reg dqs_dly;
always @(dqs) dqs_dly <= #(TDQSQ + 1) dqs;
always @(negedge ptr_rst_dly_n or posedge dqs_dly or negedge dqs_dly) begin
if (!ptr_rst_dly_n) begin
ptr <= 0;
end else if (dqs_dly || ptr) begin
q[ptr] <= dq;
ptr <= ptr + 1;
end
end
assign q0 = q[0];
assign q1 = q[1];
assign q2 = q[2];
assign q3 = q[3];
endmodule
# SPDX-FileCopyrightText: 2022 CERN (home.cern)
#
# SPDX-License-Identifier: CERN-OHL-W-2.0
files = [ "VME64x_Package.vhd",
"VME64x_SIM_Package.vhd",
"vme64x_ddr_tb.vhd" ]
-- SPDX-FileCopyrightText: 2022 CERN (home.cern)
--
-- SPDX-License-Identifier: CERN-OHL-W-2.0+
--------------------------------------------------------------------------------------
---------------------------VME64x_Package-----------------------------------------
--------------------------------------------------------------------------------------
-- Date : Fri Mar 03 2012
--
-- Author : Davide Pedretti
--
-- Company : CERN
--
-- Description : VME64x constants, records, type...
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
use work.all;
use work.vme64x_pack.all;
package VME64x is
subtype Vme64xAddressType is std_logic_vector(31 downto 1); -- (31 downto 0)
subtype Vme64xDataType is std_logic_vector(31 downto 0);
subtype Vme64xAddressModType is std_logic_vector(5 downto 0);
type VME64xBusOut_Record is -- This is an output for the VME64x master
record
Vme64xAsN : std_logic;
Vme64xDs1N : std_logic;
Vme64xDs0N : std_logic;
Vme64xLWORDN : std_logic;
Vme64xIACK : std_logic;
Vme64xIACKIN : std_logic;
Vme64xWRITEN : std_logic;
Vme64xAM : Vme64xAddressModType;
Vme64xADDR : Vme64xAddressType;
Vme64xDATA : Vme64xDataType;
end record;
type VME64xBusIn_Record is -- This is an input for the VME64x master
record
Vme64xDtackN : std_logic;
Vme64xBerrN : std_logic;
Vme64xRetryN : std_logic;
Vme64xADDR : Vme64xAddressType;
Vme64xDATA : Vme64xDataType;
Vme64xLWORDN : std_logic;
Vme64xIACKOUT : std_logic;
Vme64xIRQ : std_logic_vector(6 downto 0);
end record;
-- Types
type t_Buffer_BLT is array (0 to 66) of std_logic_vector(31 downto 0); -- for BLT transfer
--The buffer has 65 positions, not 64; the last position is for test the error if i transfer more of 256 bytes.
type t_Buffer_MBLT is array (0 to 258) of std_logic_vector(63 downto 0); -- for MBLT transfer
--The buffer has 258 positions, not 256; the last position is for test the error if i transfer more of 256 bytes.
type t_dataTransferType is (D08Byte0, D08Byte1, D08Byte2, D08Byte3, D16Byte01, D16Byte23, D32); -- for D64 use dataTransferType D32!
type t_Addressing_Type is (A24, A24_BLT, A24_MBLT, A24_LCK, CR_CSR, A16, A16_LCK, A32, A32_BLT, A32_MBLT, A32_LCK,
A64, A64_BLT, A64_MBLT, A64_LCK, A32_2eVME, A64_2eVME, A32_2eSST, A64_2eSST, error);
-- Declare constants
-- constant <constant_name> : time := <time_unit> ns;
constant BA : std_logic_vector(7 downto 0) := "11110000";
constant VME_GA : std_logic_vector(5 downto 0) := "110111"; -- GA parity match '1' & slot number
constant ID_Master : std_logic_vector(7 downto 0) := "00001111"; -- max 31
constant ADER0_A16_S : std_logic_vector(31 downto 0) := "0000000000000000" & BA(7 downto 3) & "000" & c_A16 &"00";
constant ADER0_A24_S : std_logic_vector(31 downto 0) := "00000000" & BA(7 downto 3) & "00000000000" & c_A24_S &"00";
constant ADER0_A24_BLT : std_logic_vector(31 downto 0) := "00000000" & BA(7 downto 3) & "00000000000" & c_A24_BLT &"00";
constant ADER0_A24_MBLT : std_logic_vector(31 downto 0) := "00000000" & BA(7 downto 3) & "00000000000" & c_A24_MBLT &"00";
constant ADER0_A32 : std_logic_vector(31 downto 0) := BA(7 downto 3) & "0000000000000000000" & c_A32 &"00";
constant ADER0_A32_BLT : std_logic_vector(31 downto 0) := BA(7 downto 3) & "0000000000000000000" & c_A32_BLT &"00";
constant ADER0_A32_MBLT : std_logic_vector(31 downto 0) := BA(7 downto 3) & "0000000000000000000" & c_A32_MBLT &"00";
constant ADER1_A64 : std_logic_vector(31 downto 0) := "000000000000000000000000" & c_A64 &"00";
constant ADER1_A64_BLT : std_logic_vector(31 downto 0) := "000000000000000000000000" & c_A64_BLT &"00";
constant ADER1_A64_MBLT : std_logic_vector(31 downto 0) := "000000000000000000000000" & c_A64_MBLT &"00";
constant ADER1_A64_b : std_logic_vector(31 downto 0) := BA(7 downto 3) & "000000000000000000000000000";
constant ADER2_A32_2eVME : std_logic_vector(31 downto 0) := BA(7 downto 3) & "00000000000000000" & x"01" &"01";
constant ADER2_A64_2eVME : std_logic_vector(31 downto 0) := "0000000000000000000000" & x"02" &"01";
constant ADER2_A32_2eSST : std_logic_vector(31 downto 0) := "0000000000000000000000" & x"11" &"01";
constant ADER2_A64_2eSST : std_logic_vector(31 downto 0) := "0000000000000000000000" & x"12" &"01";
constant ADER2_2e_b : std_logic_vector(31 downto 0) := BA(7 downto 3) & "000000000000000000000000000";
-- CSR constants
constant c_BAR : std_logic_vector := x"7FFFF";
constant c_BIT_SET_REG : std_logic_vector := x"7FFFB";
constant c_BIT_CLR_REG : std_logic_vector := x"7FFF7";
constant c_CRAM_OWNER : std_logic_vector := x"7FFF3";
constant c_USR_BIT_SET_REG : std_logic_vector := x"7FFEF";
constant c_USR_BIT_CLR_REG : std_logic_vector := x"7FFEB";
constant c_FUNC7_ADER_0 : std_logic_vector := x"7FFDF";
constant c_FUNC7_ADER_1 : std_logic_vector := x"7FFDB";
constant c_FUNC7_ADER_2 : std_logic_vector := x"7FFD7";
constant c_FUNC7_ADER_3 : std_logic_vector := x"7FFD3";
constant c_FUNC6_ADER_0 : std_logic_vector := x"7FFCF";
constant c_FUNC6_ADER_1 : std_logic_vector := x"7FFCB";
constant c_FUNC6_ADER_2 : std_logic_vector := x"7FFC7";
constant c_FUNC6_ADER_3 : std_logic_vector := x"7FFC3";
constant c_FUNC5_ADER_0 : std_logic_vector := x"7FFBF";
constant c_FUNC5_ADER_1 : std_logic_vector := x"7FFBB";
constant c_FUNC5_ADER_2 : std_logic_vector := x"7FFB7";
constant c_FUNC5_ADER_3 : std_logic_vector := x"7FFB3";
constant c_FUNC4_ADER_0 : std_logic_vector := x"7FFAF";
constant c_FUNC4_ADER_1 : std_logic_vector := x"7FFAB";
constant c_FUNC4_ADER_2 : std_logic_vector := x"7FFA7";
constant c_FUNC4_ADER_3 : std_logic_vector := x"7FFA3";
constant c_FUNC3_ADER_0 : std_logic_vector := x"7FF9F";
constant c_FUNC3_ADER_1 : std_logic_vector := x"7FF9B";
constant c_FUNC3_ADER_2 : std_logic_vector := x"7FF97";
constant c_FUNC3_ADER_3 : std_logic_vector := x"7FF93";
constant c_FUNC2_ADER_0 : std_logic_vector := x"7FF8F";
constant c_FUNC2_ADER_1 : std_logic_vector := x"7FF8B";
constant c_FUNC2_ADER_2 : std_logic_vector := x"7FF87";
constant c_FUNC2_ADER_3 : std_logic_vector := x"7FF83";
constant c_FUNC1_ADER_0 : std_logic_vector := x"7FF7F";
constant c_FUNC1_ADER_1 : std_logic_vector := x"7FF7B";
constant c_FUNC1_ADER_2 : std_logic_vector := x"7FF77";
constant c_FUNC1_ADER_3 : std_logic_vector := x"7FF73";
constant c_FUNC0_ADER_0 : std_logic_vector := x"7FF6F";
constant c_FUNC0_ADER_1 : std_logic_vector := x"7FF6B";
constant c_FUNC0_ADER_2 : std_logic_vector := x"7FF67";
constant c_FUNC0_ADER_3 : std_logic_vector := x"7FF63";
constant c_BYTES0 : std_logic_vector := x"7FF3b";
constant c_MBLT_Endian : std_logic_vector := x"7Ff53";
constant c_IRQ_Vector : std_logic_vector := x"7FF5F";
constant c_IRQ_level : std_logic_vector := x"7FF5B";
constant c_WB32or64 : std_logic_vector := x"7FF33";
-- CR constant
constant c_StartDefinedCR : std_logic_vector := x"00000";
constant c_EndDefinedCR : std_logic_vector := x"00FFF";
end VME64x;
package body VME64x is
end VME64x;
-- SPDX-FileCopyrightText: 2022 CERN (home.cern)
--
-- SPDX-License-Identifier: CERN-OHL-W-2.0+
--------------------------------------------------------------------------------------
---------------------------VME64x_SIM_Package-----------------------------------------
--------------------------------------------------------------------------------------
-- Date : Fri Mar 03 2012
--
-- Author : Davide Pedretti
--
-- Company : CERN
--
-- Description : VME64x procedures for test the VME64x Slave
library IEEE;
library std;
use IEEE.STD_LOGIC_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
use IEEE.numeric_std.all;
use IEEE.numeric_std.unsigned;
use work.vme64x_pack.all;
use work.VME64x.all;
use work.VME_CR_pack.all;
use std.textio.all;
package VME64xSim is
-- All the constants and records are in the VME64x_Package
-- Procedures:
-- function <function_name> (signal <signal_name> : in <type_declaration>) return <type_declaration>;
procedure WriteCSR (c_address : in std_logic_vector(19 downto 0); signal s_dataToSend : in std_logic_vector(31 downto 0);
signal s_dataTransferType : in t_dataTransferType; signal s_AddressingType : in t_Addressing_Type;
signal VME64xBus_In : in VME64xBusIn_Record; signal VME64xBus_Out : out VME64xBusOut_Record);
procedure S_Write (v_address : in std_logic_vector(63 downto 0); signal s_dataToSend : in std_logic_vector(31 downto 0); -- this procedure is for A16, A24, A32 address type
signal s_dataTransferType : in t_dataTransferType; signal s_AddressingType : in t_Addressing_Type;
signal VME64xBus_In : in VME64xBusIn_Record; signal VME64xBus_Out : out VME64xBusOut_Record);
procedure A64S_Write (v_address : in std_logic_vector(63 downto 0); signal s_dataToSend : in std_logic_vector(31 downto 0); -- this procedure is for A16, A24, A32 address type
signal s_dataTransferType : in t_dataTransferType; signal s_AddressingType : in t_Addressing_Type;
signal VME64xBus_In : in VME64xBusIn_Record; signal VME64xBus_Out : out VME64xBusOut_Record);
procedure A64S_Read (v_address : in std_logic_vector(63 downto 0); signal s_dataToReceive : in std_logic_vector(31 downto 0); -- this procedure is for A16, A24, A32 address type
signal s_dataTransferType : in t_dataTransferType; signal s_AddressingType : in t_Addressing_Type;
signal VME64xBus_In : in VME64xBusIn_Record; signal VME64xBus_Out : out VME64xBusOut_Record);
procedure S_Read (v_address : in std_logic_vector(63 downto 0); signal s_dataToReceive : in std_logic_vector(31 downto 0); -- this procedure is for A16, A24, A32 address type
signal s_dataTransferType : in t_dataTransferType; signal s_AddressingType : in t_Addressing_Type;
signal VME64xBus_In : in VME64xBusIn_Record; signal VME64xBus_Out : out VME64xBusOut_Record);
procedure Blt_Read(v_address : in std_logic_vector(63 downto 0); signal s_Buffer_BLT : in t_Buffer_BLT; -- this procedure is for A16, A24, A32 address type
signal s_dataTransferType : in t_dataTransferType; signal s_AddressingType : in t_Addressing_Type; num : in std_logic_vector(8 downto 0);
signal VME64xBus_In : in VME64xBusIn_Record; signal VME64xBus_Out : out VME64xBusOut_Record);
procedure Blt_write(v_address : in std_logic_vector(63 downto 0); signal s_Buffer_BLT : in t_Buffer_BLT; -- this procedure is for A16, A24, A32 address type
signal s_dataTransferType : in t_dataTransferType; signal s_AddressingType : in t_Addressing_Type; num : in std_logic_vector(8 downto 0);
signal VME64xBus_In : in VME64xBusIn_Record; signal VME64xBus_Out : out VME64xBusOut_Record);
procedure A64Blt_write(v_address : in std_logic_vector(63 downto 0); signal s_Buffer_BLT : in t_Buffer_BLT; -- this procedure is for A16, A24, A32 address type
signal s_dataTransferType : in t_dataTransferType; signal s_AddressingType : in t_Addressing_Type; num : in std_logic_vector(8 downto 0);
signal VME64xBus_In : in VME64xBusIn_Record; signal VME64xBus_Out : out VME64xBusOut_Record);
procedure A64Blt_Read(v_address : in std_logic_vector(63 downto 0); signal s_Buffer_BLT : in t_Buffer_BLT; -- this procedure is for A16, A24, A32 address type
signal s_dataTransferType : in t_dataTransferType; signal s_AddressingType : in t_Addressing_Type; num : in std_logic_vector(8 downto 0);
signal VME64xBus_In : in VME64xBusIn_Record; signal VME64xBus_Out : out VME64xBusOut_Record);
procedure Mblt_write(v_address : in std_logic_vector(63 downto 0); signal s_Buffer_MBLT : in t_Buffer_MBLT; -- this procedure is for A16, A24, A32 address type
signal s_dataTransferType : in t_dataTransferType; signal s_AddressingType : in t_Addressing_Type; num : in std_logic_vector(8 downto 0);
signal VME64xBus_In : in VME64xBusIn_Record; signal VME64xBus_Out : out VME64xBusOut_Record);
procedure A64Mblt_write(v_address : in std_logic_vector(63 downto 0); signal s_Buffer_MBLT : in t_Buffer_MBLT; -- this procedure is for A16, A24, A32 address type
signal s_dataTransferType : in t_dataTransferType; signal s_AddressingType : in t_Addressing_Type; num : in std_logic_vector(8 downto 0);
signal VME64xBus_In : in VME64xBusIn_Record; signal VME64xBus_Out : out VME64xBusOut_Record);
procedure Mblt_Read(v_address : in std_logic_vector(63 downto 0); signal s_Buffer_MBLT : in t_Buffer_MBLT; -- this procedure is for A16, A24, A32 address type
signal s_dataTransferType : in t_dataTransferType; signal s_AddressingType : in t_Addressing_Type; num : in std_logic_vector(8 downto 0);
signal VME64xBus_In : in VME64xBusIn_Record; signal VME64xBus_Out : out VME64xBusOut_Record);
procedure A64Mblt_Read(v_address : in std_logic_vector(63 downto 0); signal s_Buffer_MBLT : in t_Buffer_MBLT; -- this procedure is for A16, A24, A32 address type
signal s_dataTransferType : in t_dataTransferType; signal s_AddressingType : in t_Addressing_Type; num : in std_logic_vector(8 downto 0);
signal VME64xBus_In : in VME64xBusIn_Record; signal VME64xBus_Out : out VME64xBusOut_Record);
procedure Interrupt_Handler(signal VME64xBus_In : in VME64xBusIn_Record; signal VME64xBus_Out : out VME64xBusOut_Record; signal s_dataToReceive : in std_logic_vector(31 downto 0);
signal s_dataTransferType : in t_dataTransferType; signal s_AddressingType : in t_Addressing_Type);
procedure ReadCR_CSR(c_address : in std_logic_vector(19 downto 0); signal s_dataToReceive : in std_logic_vector(31 downto 0);
signal s_dataTransferType : in t_dataTransferType; signal s_AddressingType : in t_Addressing_Type;
signal VME64xBus_In : in VME64xBusIn_Record; signal VME64xBus_Out : out VME64xBusOut_Record);
procedure SetAmAddress (signal s_dataTransferType : in t_dataTransferType;
signal s_AddressingType : in t_Addressing_Type; Vme64xAM : out std_logic_vector(5 downto 0);
DataType : out std_logic_vector(3 downto 0));
procedure SetXAmAddress(signal s_AddressingType : in t_Addressing_Type; v_XAm : out std_logic_vector(7 downto 0));
procedure A64SetAddress (c_address : in std_logic_vector(63 downto 0); signal s_AddressingType : in t_Addressing_Type; v_address : out std_logic_vector(63 downto 0));
procedure ShiftData (write_n : in std_logic; signal s_dataTransferType : in t_dataTransferType; signal s_dataToShift : in std_logic_vector(31 downto 0); v_dataToShiftOut : out std_logic_vector(31 downto 0));
procedure SetCrCsrAddress (c_address : in std_logic_vector(19 downto 0); v_address : out std_logic_vector(31 downto 0));
procedure SetAddress (c_address : in std_logic_vector(63 downto 0); signal s_AddressingType : in t_Addressing_Type; v_address : out std_logic_vector(31 downto 0));
procedure ControlCR (signal s_dataTransferType : in t_dataTransferType; signal s_AddressingType : in t_Addressing_Type; signal VME64xBus_In : in VME64xBusIn_Record;
signal s_dataToReceive : inout std_logic_vector(31 downto 0); signal VME64xBus_Out : out VME64xBusOut_Record);
procedure TWOeVME_write(v_address : in std_logic_vector(63 downto 0); signal s_Buffer_MBLT : in t_Buffer_MBLT; -- this procedure is for A16, A24, A32 address type
signal s_AddressingType : in t_Addressing_Type; v_beat_count : in std_logic_vector(7 downto 0);
signal VME64xBus_In : in VME64xBusIn_Record; signal VME64xBus_Out : out VME64xBusOut_Record);
procedure TWOeVME_read(v_address : in std_logic_vector(63 downto 0); signal s_Buffer_MBLT : in t_Buffer_MBLT; -- this procedure is for A16, A24, A32 address type
signal s_AddressingType : in t_Addressing_Type; v_beat_count : in std_logic_vector(7 downto 0);
signal VME64xBus_In : in VME64xBusIn_Record; signal VME64xBus_Out : out VME64xBusOut_Record);
end VME64xSim;
package body VME64xSim is
procedure WriteCSR (c_address : in std_logic_vector(19 downto 0); signal s_dataToSend : in std_logic_vector(31 downto 0);
signal s_dataTransferType : in t_dataTransferType; signal s_AddressingType : in t_Addressing_Type;
signal VME64xBus_In : in VME64xBusIn_Record; signal VME64xBus_Out : out VME64xBusOut_Record) is
variable Vme64xAM : std_logic_vector(5 downto 0);
variable DataType : std_logic_vector(3 downto 0) := (others => '1');
variable v_address : std_logic_vector(31 downto 0) := (others => '0');
variable v_dataToSendOut : std_logic_vector(31 downto 0) := (others => '0');
variable ti : time;
begin
ti := now;
if VME64xBus_In.Vme64xDtackN /= '1' or VME64xBus_In.Vme64xBerrN /= '0' then
wait until VME64xBus_In.Vme64xDtackN = '1' and VME64xBus_In.Vme64xBerrN = '0';
end if;
VME64xBus_Out.Vme64xAsN <= '1'; --initialisation
VME64xBus_Out.Vme64xWRITEN <= '1';
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
VME64xBus_Out.Vme64xLWORDN <= '1';
VME64xBus_Out.Vme64xADDR <= (others => '1');
wait for 10 ns;
report "Start Address Phase";
-- Address phase
SetAmAddress(s_dataTransferType => s_dataTransferType, s_AddressingType => s_AddressingType,
Vme64xAM => Vme64xAM, DataType => DataType);
-- controllo
if s_AddressingType = CR_CSR then
assert ((DataType = "0101") or (DataType = "1001") or (DataType = "0111") or (DataType = "1011"))report "Error, DataType must be D08!!!" severity failure;
end if;
SetCrCsrAddress(c_address => c_address, v_address => v_address);
VME64xBus_Out.Vme64xADDR(31 downto 2) <= v_address(31 downto 2);
VME64xBus_Out.Vme64xAM <= Vme64xAM;
VME64xBus_Out.Vme64xLWORDN <= DataType(0);
VME64xBus_Out.Vme64xADDR(1) <= DataType(1);
VME64xBus_Out.Vme64xWRITEN <= '0';
report "End Address Phase";
wait for 35 ns;
VME64xBus_Out.Vme64xAsN <= '0';
VME64xBus_Out.Vme64xDs1N <= DataType(3);
VME64xBus_Out.Vme64xDs0N <= DataType(2);
ShiftData(write_n => '0', s_dataTransferType => s_dataTransferType, s_dataToShift => s_dataToSend, v_dataToShiftOut => v_dataToSendOut); --procedura che prende il dato dai lsb e lo mette nei byte giusti
VME64xBus_Out.Vme64xDATA <= v_dataToSendOut;
report "Wait for DTACK";
wait until (VME64xBus_In.Vme64xDtackN = '0' or (now > (ti + 4 us)) or VME64xBus_In.Vme64xBerrN = '1');
assert (VME64xBus_In.Vme64xBerrN /= '1') report "THE SLAVE ASSERTED THE Berr LINE" severity error;
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
VME64xBus_Out.Vme64xLWORDN <= '1';
wait for 10 ns; -- not necessary
VME64xBus_Out.Vme64xADDR <= (others => '1');
VME64xBus_Out.Vme64xAM <= (others => '1');
VME64xBus_Out.Vme64xDATA <= (others => 'Z');
VME64xBus_Out.Vme64xAsN <= '1';
VME64xBus_Out.Vme64xWRITEN <= '1';
end;
procedure ReadCR_CSR (c_address : in std_logic_vector(19 downto 0); signal s_dataToReceive : in std_logic_vector(31 downto 0);
signal s_dataTransferType : in t_dataTransferType; signal s_AddressingType : in t_Addressing_Type;
signal VME64xBus_In : in VME64xBusIn_Record; signal VME64xBus_Out : out VME64xBusOut_Record) is
variable Vme64xAM : std_logic_vector(5 downto 0);
variable DataType : std_logic_vector(3 downto 0) := (others => '1');
variable v_address : std_logic_vector(31 downto 0) := (others => '0');
variable v_dataToReceiveOut : std_logic_vector(31 downto 0) := (others => '0');
variable ti : time;
begin
ti := now;
if VME64xBus_In.Vme64xDtackN /= '1' or VME64xBus_In.Vme64xBerrN /= '0' then
wait until VME64xBus_In.Vme64xDtackN = '1' and VME64xBus_In.Vme64xBerrN = '0';
end if;
--initialisation
VME64xBus_Out.Vme64xAsN <= '1';
VME64xBus_Out.Vme64xWRITEN <= '1';
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
VME64xBus_Out.Vme64xLWORDN <= '1';
VME64xBus_Out.Vme64xADDR <= (others => '1');
wait for 10 ns;
report "Start Address Phase";
-- Address phase
SetAmAddress(s_dataTransferType => s_dataTransferType, s_AddressingType => s_AddressingType,
Vme64xAM => Vme64xAM, DataType => DataType);
-- controllo
--if s_AddressingType = CR_CSR then
-- assert ((DataType = "0101") or (DataType = "1001") or (DataType = "0111") or (DataType = "1011"))report "Error, DataType must be D08!!!" severity failure;
-- end if;
SetCrCsrAddress(c_address => c_address, v_address => v_address);
VME64xBus_Out.Vme64xADDR(31 downto 2) <= v_address(31 downto 2);
VME64xBus_Out.Vme64xAM <= Vme64xAM;
VME64xBus_Out.Vme64xLWORDN <= DataType(0);
VME64xBus_Out.Vme64xADDR(1) <= DataType(1);
VME64xBus_Out.Vme64xWRITEN <= '1';
report "End Address Phase";
wait for 35 ns; -- check the min time here...for master is 35 ns and for slave 10 ns.
report "Master drive the AS low";
VME64xBus_Out.Vme64xAsN <= '0';
VME64xBus_Out.Vme64xDs1N <= DataType(3);
VME64xBus_Out.Vme64xDs0N <= DataType(2);
report "Wait for DTACK";
wait until (VME64xBus_In.Vme64xDtackN = '0' or (now > (ti + 4 us)) or VME64xBus_In.Vme64xBerrN = '1');
wait for 10 ns;
if(VME64xBus_In.Vme64xBerrN = '1') then
assert(VME64xBus_In.Vme64xBerrN /= '1') report "THE SLAVE ASSERTED THE Berr LINE" severity error;
else
ShiftData(write_n => '1', s_dataTransferType => s_dataTransferType, s_dataToShift => VME64xBus_In.Vme64xDATA, v_dataToShiftOut => v_dataToReceiveOut);
assert (v_dataToReceiveOut /= s_dataToReceive)report "CORRECT DATA!!!" severity error;
assert (v_dataToReceiveOut = s_dataToReceive)report "RECEIVED WRONG DATA!!!" severity failure;
--assert (VME64xBus_In.Vme64xDATA = s_dataToReceive)report "Error Received Wrong Data" severity failure;
--wait for 10 ns;
end if;
VME64xBus_Out.Vme64xLWORDN <= '1';
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
VME64xBus_Out.Vme64xADDR <= (others => '1');
VME64xBus_Out.Vme64xAM <= (others => '1');
-- wait for 0 ns; -- not necessary
VME64xBus_Out.Vme64xDATA <= (others => 'Z');
VME64xBus_Out.Vme64xAsN <= '1';
VME64xBus_Out.Vme64xWRITEN <= '1';
report "As hight";
end ReadCR_CSR;
procedure SetAmAddress (signal s_dataTransferType : in t_dataTransferType;
signal s_AddressingType : in t_Addressing_Type; Vme64xAM : out std_logic_vector (5 downto 0);
DataType : out std_logic_vector (3 downto 0)) is
begin
case s_AddressingType is
when CR_CSR => Vme64xAM := c_CR_CSR;
when A16 => Vme64xAM := c_A16;
when A16_LCK => Vme64xAM := c_A16_LCK;
when A24 => Vme64xAM := c_A24_S;
when A24_BLT => Vme64xAM := c_A24_BLT;
when A24_MBLT => Vme64xAM := c_A24_MBLT;
when A24_LCK => Vme64xAM := c_A24_LCK;
when A32 => Vme64xAM := c_A32;
when A32_BLT => Vme64xAM := c_A32_BLT;
when A32_MBLT => Vme64xAM := c_A32_MBLT;
when A32_LCK => Vme64xAM := c_A32_LCK;
when A64 => Vme64xAM := c_A64;
when A64_BLT => Vme64xAM := c_A64_BLT;
when A64_MBLT => Vme64xAM := c_A64_MBLT;
when A64_LCK => Vme64xAM := c_A64_LCK;
when A32_2eVME => Vme64xAM := c_TWOedge;
when A64_2eVME => Vme64xAM := c_TWOedge;
when A32_2eSST => Vme64xAM := c_TWOedge;
when A64_2eSST => Vme64xAM := c_TWOedge;
when others => null;
end case;
case s_dataTransferType is
when D08Byte0 => DataType := "0101";
when D08Byte1 => DataType := "1001";
when D08Byte2 => DataType := "0111";
when D08Byte3 => DataType := "1011";
when D16Byte01 => DataType := "0001";
when D16Byte23 => DataType := "0011";
when D32 => DataType := "0000";
when others => null;
end case;
end SetAmAddress;
procedure ShiftData (write_n : in std_logic; signal s_dataTransferType : in t_dataTransferType; signal s_dataToShift : in std_logic_vector(31 downto 0); v_dataToShiftOut : out std_logic_vector(31 downto 0)) is
variable v_int : natural := 0;
variable v_int1 : natural := 0;
variable dataToShiftOut : std_logic_vector(31 downto 0) := (others => '0');
begin
case s_dataTransferType is
when D08Byte0 => v_int := 1;
when D08Byte1 => v_int := 0;
when D08Byte2 => v_int := 1;
when D08Byte3 => v_int := 0;
when D16Byte01 => v_int := 0;
when D16Byte23 => v_int := 0;
when D32 => v_int := 0;
when others => null;
end case;
v_int1 := v_int * 8;
dataToShiftOut := s_dataToShift;
while (v_int1 > 0) loop
if write_n = '0' then
dataToShiftOut := dataToShiftOut(30 downto 0) & '0';
else dataToShiftOut := '0' & dataToShiftOut(31 downto 1);
end if;
v_int1 := v_int1 -1;
end loop;
v_dataToShiftOut := dataToShiftOut;
end ShiftData;
procedure SetCrCsrAddress (c_address : in std_logic_vector(19 downto 0); v_address : out std_logic_vector(31 downto 0)) is
begin
v_address := x"00" & not VME_GA(4 downto 0) & c_address(18 downto 0);
end SetCrCsrAddress;
procedure ControlCR (signal s_dataTransferType : in t_dataTransferType; signal s_AddressingType : in t_Addressing_Type; signal VME64xBus_In : in VME64xBusIn_Record;
signal s_dataToReceive : inout std_logic_vector(31 downto 0); signal VME64xBus_Out : out VME64xBusOut_Record) is
file result : text;
variable sample : line;
variable address : integer;
begin
address := 0;
file_open(result, "CR.dat", write_mode);
while address <= 424 loop
--if (address = 20) then s_dataToReceive(7 downto 0) <= x"05";
--else s_dataToReceive(7 downto 0) <= c_cr_array(address);
--end if;
s_dataToReceive(7 downto 0) <= c_cr_array(address);
ReadCR_CSR(c_address => std_logic_vector(to_unsigned((address*4) +3, 20)), s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
write(sample, address, right, 5);
--write(sample, "OK", right, 10);
writeline(result, sample);
address := address + 1;
end loop;
file_close(result);
end;
procedure S_Write (v_address : in std_logic_vector(63 downto 0); signal s_dataToSend : in std_logic_vector(31 downto 0); -- this procedure is for A16, A24, A32 address type
signal s_dataTransferType : in t_dataTransferType; signal s_AddressingType : in t_Addressing_Type;
signal VME64xBus_In : in VME64xBusIn_Record; signal VME64xBus_Out : out VME64xBusOut_Record) is
variable Vme64xAM : std_logic_vector(5 downto 0);
variable DataType : std_logic_vector(3 downto 0) := (others => '1');
variable v_addressout : std_logic_vector(31 downto 0) := (others => '0');
variable v_dataToSendOut : std_logic_vector(31 downto 0) := (others => '0');
variable ti : time;
begin
ti := now;
if VME64xBus_In.Vme64xDtackN /= '1' or VME64xBus_In.Vme64xBerrN /= '0' then
wait until VME64xBus_In.Vme64xDtackN = '1' and VME64xBus_In.Vme64xBerrN = '0';
end if;
VME64xBus_Out.Vme64xAsN <= '1'; --initialisation
VME64xBus_Out.Vme64xWRITEN <= '1';
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
VME64xBus_Out.Vme64xLWORDN <= '1';
VME64xBus_Out.Vme64xADDR <= (others => '1');
wait for 10 ns;
report "Start Address Phase";
-- Address phase
SetAmAddress(s_dataTransferType => s_dataTransferType, s_AddressingType => s_AddressingType,
Vme64xAM => Vme64xAM, DataType => DataType);
SetAddress(c_address => v_address, s_AddressingType => s_AddressingType, v_address => v_addressout);
VME64xBus_Out.Vme64xADDR(31 downto 2) <= v_addressout(31 downto 2);
VME64xBus_Out.Vme64xAM <= Vme64xAM;
VME64xBus_Out.Vme64xLWORDN <= DataType(0);
VME64xBus_Out.Vme64xADDR(1) <= DataType(1);
VME64xBus_Out.Vme64xWRITEN <= '0';
report "End Address Phase";
wait for 35 ns;
VME64xBus_Out.Vme64xAsN <= '0';
VME64xBus_Out.Vme64xDs1N <= DataType(3);
VME64xBus_Out.Vme64xDs0N <= DataType(2);
ShiftData(write_n => '0', s_dataTransferType => s_dataTransferType, s_dataToShift => s_dataToSend, v_dataToShiftOut => v_dataToSendOut); --procedura che prende il dato dai lsb e lo mette nei byte giusti
VME64xBus_Out.Vme64xDATA <= v_dataToSendOut;
report "Wait for DTACK";
wait until (VME64xBus_In.Vme64xDtackN = '0' or (now > (ti + 4 us)) or VME64xBus_In.Vme64xBerrN = '1');
assert (VME64xBus_In.Vme64xBerrN /= '1') report "THE SLAVE ASSERTED THE Berr LINE" severity error;
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
VME64xBus_Out.Vme64xLWORDN <= '1';
wait for 0 ns; -- not necessary
VME64xBus_Out.Vme64xADDR <= (others => '1');
VME64xBus_Out.Vme64xAM <= (others => '1');
VME64xBus_Out.Vme64xDATA <= (others => 'Z');
VME64xBus_Out.Vme64xAsN <= '1';
VME64xBus_Out.Vme64xWRITEN <= '1';
end;
procedure S_Read (v_address : in std_logic_vector(63 downto 0); signal s_dataToReceive : in std_logic_vector(31 downto 0); -- this procedure is for A16, A24, A32 address type
signal s_dataTransferType : in t_dataTransferType; signal s_AddressingType : in t_Addressing_Type;
signal VME64xBus_In : in VME64xBusIn_Record; signal VME64xBus_Out : out VME64xBusOut_Record) is
variable Vme64xAM : std_logic_vector(5 downto 0);
variable DataType : std_logic_vector(3 downto 0) := (others => '1');
variable v_addressout : std_logic_vector(31 downto 0) := (others => '0');
variable v_dataToReceiveOut : std_logic_vector(31 downto 0) := (others => '0');
variable ti : time;
begin
ti := now;
if VME64xBus_In.Vme64xDtackN /= '1' or VME64xBus_In.Vme64xBerrN /= '0' then
wait until VME64xBus_In.Vme64xDtackN = '1' and VME64xBus_In.Vme64xBerrN = '0';
end if;
--initialisation
VME64xBus_Out.Vme64xAsN <= '1';
VME64xBus_Out.Vme64xWRITEN <= '1';
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
VME64xBus_Out.Vme64xLWORDN <= '1';
VME64xBus_Out.Vme64xADDR <= (others => '1');
wait for 10 ns;
report "Start Address Phase";
-- Address phase
SetAmAddress(s_dataTransferType => s_dataTransferType, s_AddressingType => s_AddressingType,
Vme64xAM => Vme64xAM, DataType => DataType);
SetAddress(c_address => v_address, s_AddressingType => s_AddressingType, v_address => v_addressout);
VME64xBus_Out.Vme64xADDR(31 downto 2) <= v_addressout(31 downto 2);
VME64xBus_Out.Vme64xAM <= Vme64xAM;
VME64xBus_Out.Vme64xLWORDN <= DataType(0);
VME64xBus_Out.Vme64xADDR(1) <= DataType(1);
VME64xBus_Out.Vme64xWRITEN <= '1';
report "End Address Phase";
wait for 35 ns; -- check the min time here...for master is 35 ns and for slave 10 ns.
report "Master drive the AS low";
VME64xBus_Out.Vme64xAsN <= '0';
VME64xBus_Out.Vme64xDs1N <= DataType(3);
VME64xBus_Out.Vme64xDs0N <= DataType(2);
report "Wait for DTACK";
wait until (VME64xBus_In.Vme64xDtackN = '0' or (now > (ti + 4 us)) or VME64xBus_In.Vme64xBerrN = '1');
-- wait for 10 ns;
if(VME64xBus_In.Vme64xBerrN = '1') then
assert(VME64xBus_In.Vme64xBerrN /= '1') report "THE SLAVE ASSERTED THE Berr LINE" severity error;
else
ShiftData(write_n => '1', s_dataTransferType => s_dataTransferType, s_dataToShift => VME64xBus_In.Vme64xDATA, v_dataToShiftOut => v_dataToReceiveOut);
assert (v_dataToReceiveOut /= s_dataToReceive)report "CORRECT DATA!!!" severity error;
assert (v_dataToReceiveOut = s_dataToReceive)report "RECEIVED WRONG DATA!!!" severity failure;
end if;
VME64xBus_Out.Vme64xLWORDN <= '1';
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
VME64xBus_Out.Vme64xADDR <= (others => '1');
VME64xBus_Out.Vme64xAM <= (others => '1');
-- wait for 0 ns; -- not necessary
VME64xBus_Out.Vme64xDATA <= (others => 'Z');
VME64xBus_Out.Vme64xAsN <= '1';
VME64xBus_Out.Vme64xWRITEN <= '1';
report "As hight";
end;
--------------------------------------------------------------------------
procedure Blt_Read(v_address : in std_logic_vector(63 downto 0); signal s_Buffer_BLT : in t_Buffer_BLT; -- this procedure is for A16, A24, A32 address type
signal s_dataTransferType : in t_dataTransferType; signal s_AddressingType : in t_Addressing_Type; num : in std_logic_vector(8 downto 0);
signal VME64xBus_In : in VME64xBusIn_Record; signal VME64xBus_Out : out VME64xBusOut_Record) is
variable n : integer;
variable Vme64xAM : std_logic_vector(5 downto 0);
variable DataType : std_logic_vector(3 downto 0) := (others => '1');
variable v_addressout : std_logic_vector(31 downto 0) := (others => '0');
variable v_dataToReceiveOut : std_logic_vector(31 downto 0) := (others => '0');
variable ti : time;
begin
n := 0;
ti := now;
if VME64xBus_In.Vme64xDtackN /= '1' or VME64xBus_In.Vme64xBerrN /= '0' then
wait until VME64xBus_In.Vme64xDtackN = '1' and VME64xBus_In.Vme64xBerrN = '0';
end if;
--initialisation
VME64xBus_Out.Vme64xAsN <= '1';
VME64xBus_Out.Vme64xWRITEN <= '1';
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
VME64xBus_Out.Vme64xLWORDN <= '1';
VME64xBus_Out.Vme64xADDR <= (others => '1');
wait for 10 ns;
SetAmAddress(s_dataTransferType => s_dataTransferType, s_AddressingType => s_AddressingType,
Vme64xAM => Vme64xAM, DataType => DataType);
SetAddress(c_address => v_address, s_AddressingType => s_AddressingType, v_address => v_addressout);
VME64xBus_Out.Vme64xADDR(31 downto 2) <= v_addressout(31 downto 2);
VME64xBus_Out.Vme64xAM <= Vme64xAM;
VME64xBus_Out.Vme64xLWORDN <= DataType(0);
VME64xBus_Out.Vme64xADDR(1) <= DataType(1);
VME64xBus_Out.Vme64xWRITEN <= '1';
wait for 35 ns;
VME64xBus_Out.Vme64xAsN <= '0';
wait for 10 ns;
while n < (num) loop
VME64xBus_Out.Vme64xDs1N <= DataType(3);
VME64xBus_Out.Vme64xDs0N <= DataType(2);
wait until (VME64xBus_In.Vme64xDtackN = '0' or (now > (ti + 4 us)) or VME64xBus_In.Vme64xBerrN = '1');
if(VME64xBus_In.Vme64xBerrN = '1') then
assert(VME64xBus_In.Vme64xBerrN /= '1') report "THE SLAVE ASSERTED THE Berr LINE" severity error;
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
exit;
else
v_dataToReceiveOut := VME64xBus_In.Vme64xDATA;
assert (v_dataToReceiveOut /= s_Buffer_BLT(n))report "CORRECT DATA!!!" severity error;
assert (v_dataToReceiveOut = s_Buffer_BLT(n))report "RECEIVED WRONG DATA!!!" severity failure;
end if;
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
wait for 40 ns;
n := n + 1;
end loop;
VME64xBus_Out.Vme64xADDR <= (others => '1');
VME64xBus_Out.Vme64xAM <= (others => '1');
VME64xBus_Out.Vme64xDATA <= (others => 'Z');
VME64xBus_Out.Vme64xAsN <= '1';
VME64xBus_Out.Vme64xWRITEN <= '1';
end;
procedure Blt_write(v_address : in std_logic_vector(63 downto 0); signal s_Buffer_BLT : in t_Buffer_BLT; -- this procedure is for A16, A24, A32 address type
signal s_dataTransferType : in t_dataTransferType; signal s_AddressingType : in t_Addressing_Type; num : in std_logic_vector(8 downto 0);
signal VME64xBus_In : in VME64xBusIn_Record; signal VME64xBus_Out : out VME64xBusOut_Record) is
variable n : integer;
variable Vme64xAM : std_logic_vector(5 downto 0);
variable DataType : std_logic_vector(3 downto 0) := (others => '1');
variable v_addressout : std_logic_vector(31 downto 0) := (others => '0');
--variable v_dataToSendOut : std_logic_vector(31 downto 0) := (others => '0');
variable ti : time;
begin
n := 0;
ti := now;
if VME64xBus_In.Vme64xDtackN /= '1' or VME64xBus_In.Vme64xBerrN /= '0' then
wait until VME64xBus_In.Vme64xDtackN = '1' and VME64xBus_In.Vme64xBerrN = '0';
end if;
--initialisation
VME64xBus_Out.Vme64xAsN <= '1';
VME64xBus_Out.Vme64xWRITEN <= '1';
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
VME64xBus_Out.Vme64xLWORDN <= '1';
VME64xBus_Out.Vme64xADDR <= (others => '1');
wait for 10 ns;
SetAmAddress(s_dataTransferType => s_dataTransferType, s_AddressingType => s_AddressingType,
Vme64xAM => Vme64xAM, DataType => DataType);
SetAddress(c_address => v_address, s_AddressingType => s_AddressingType, v_address => v_addressout);
VME64xBus_Out.Vme64xADDR(31 downto 2) <= v_addressout(31 downto 2);
VME64xBus_Out.Vme64xAM <= Vme64xAM;
VME64xBus_Out.Vme64xLWORDN <= DataType(0);
VME64xBus_Out.Vme64xADDR(1) <= DataType(1);
VME64xBus_Out.Vme64xWRITEN <= '0';
wait for 35 ns;
VME64xBus_Out.Vme64xAsN <= '0';
while n < (num) loop
VME64xBus_Out.Vme64xDATA <= s_Buffer_BLT(n);
wait for 35 ns;
VME64xBus_Out.Vme64xDs1N <= DataType(3);
VME64xBus_Out.Vme64xDs0N <= DataType(2);
wait until (VME64xBus_In.Vme64xDtackN = '0' or (now > (ti + 15 us)) or VME64xBus_In.Vme64xBerrN = '1');
if(VME64xBus_In.Vme64xBerrN = '1') then
assert(VME64xBus_In.Vme64xBerrN /= '1') report "THE SLAVE ASSERTED THE Berr LINE" severity error;
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
exit;
end if;
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
wait for 10 ns;
n := n + 1;
end loop;
VME64xBus_Out.Vme64xADDR <= (others => '1');
VME64xBus_Out.Vme64xAM <= (others => '1');
VME64xBus_Out.Vme64xDATA <= (others => 'Z');
VME64xBus_Out.Vme64xAsN <= '1';
VME64xBus_Out.Vme64xWRITEN <= '1';
end;
procedure Mblt_write(v_address : in std_logic_vector(63 downto 0); signal s_Buffer_MBLT : in t_Buffer_MBLT; -- this procedure is for A16, A24, A32 address type
signal s_dataTransferType : in t_dataTransferType; signal s_AddressingType : in t_Addressing_Type; num : in std_logic_vector(8 downto 0);
signal VME64xBus_In : in VME64xBusIn_Record; signal VME64xBus_Out : out VME64xBusOut_Record) is
variable n : integer;
variable Vme64xAM : std_logic_vector(5 downto 0);
variable DataType : std_logic_vector(3 downto 0) := (others => '1');
variable v_addressout : std_logic_vector(31 downto 0) := (others => '0');
variable ti : time;
begin
n := 0;
ti := now;
if VME64xBus_In.Vme64xDtackN /= '1' or VME64xBus_In.Vme64xBerrN /= '0' then
wait until VME64xBus_In.Vme64xDtackN = '1' and VME64xBus_In.Vme64xBerrN = '0';
end if;
--initialisation
VME64xBus_Out.Vme64xAsN <= '1';
VME64xBus_Out.Vme64xWRITEN <= '1';
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
VME64xBus_Out.Vme64xLWORDN <= '1';
VME64xBus_Out.Vme64xADDR <= (others => '1');
wait for 10 ns;
SetAmAddress(s_dataTransferType => s_dataTransferType, s_AddressingType => s_AddressingType,
Vme64xAM => Vme64xAM, DataType => DataType);
SetAddress(c_address => v_address, s_AddressingType => s_AddressingType, v_address => v_addressout);
VME64xBus_Out.Vme64xADDR(31 downto 2) <= v_addressout(31 downto 2);
VME64xBus_Out.Vme64xAM <= Vme64xAM;
VME64xBus_Out.Vme64xLWORDN <= DataType(0);
VME64xBus_Out.Vme64xADDR(1) <= DataType(1);
VME64xBus_Out.Vme64xWRITEN <= '0';
wait for 35 ns;
VME64xBus_Out.Vme64xAsN <= '0';
wait for 10 ns;
VME64xBus_Out.Vme64xDs1N <= DataType(3);
VME64xBus_Out.Vme64xDs0N <= DataType(2);
wait until (VME64xBus_In.Vme64xDtackN = '0' or (now > (ti + 5 us)) or VME64xBus_In.Vme64xBerrN = '1');
if(VME64xBus_In.Vme64xBerrN = '1' or (now > (ti + 5 us))) then
assert(VME64xBus_In.Vme64xBerrN /= '1') report "THE SLAVE ASSERTED THE Berr LINE" severity error;
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
else
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
wait for 35 ns;
while n < (num) loop
VME64xBus_Out.Vme64xDATA <= s_Buffer_MBLT(n)(31 downto 0);
VME64xBus_Out.Vme64xADDR(31 downto 1) <= s_Buffer_MBLT(n)(63 downto 33);
VME64xBus_Out.Vme64xLWORDN <= s_Buffer_MBLT(n)(32);
VME64xBus_Out.Vme64xDs1N <= DataType(3);
VME64xBus_Out.Vme64xDs0N <= DataType(2);
wait until (VME64xBus_In.Vme64xDtackN = '0' or (now > (ti + 100 us)) or VME64xBus_In.Vme64xBerrN = '1');
if(VME64xBus_In.Vme64xBerrN = '1' or (now > (ti + 100 us))) then
assert(VME64xBus_In.Vme64xBerrN /= '1') report "THE SLAVE ASSERTED THE Berr LINE" severity error;
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
exit;
else
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
n := n + 1;
wait for 35 ns;
end if;
end loop;
end if;
VME64xBus_Out.Vme64xADDR <= (others => '1');
VME64xBus_Out.Vme64xAM <= (others => '1');
VME64xBus_Out.Vme64xDATA <= (others => 'Z');
VME64xBus_Out.Vme64xAsN <= '1';
VME64xBus_Out.Vme64xWRITEN <= '1';
end;
procedure Mblt_Read(v_address : in std_logic_vector(63 downto 0); signal s_Buffer_MBLT : in t_Buffer_MBLT; -- this procedure is for A16, A24, A32 address type
signal s_dataTransferType : in t_dataTransferType; signal s_AddressingType : in t_Addressing_Type; num : in std_logic_vector(8 downto 0);
signal VME64xBus_In : in VME64xBusIn_Record; signal VME64xBus_Out : out VME64xBusOut_Record) is
variable n : integer;
variable Vme64xAM : std_logic_vector(5 downto 0);
variable DataType : std_logic_vector(3 downto 0) := (others => '1');
variable v_addressout : std_logic_vector(31 downto 0) := (others => '0');
variable v_dataToReceiveOut : std_logic_vector(63 downto 0) := (others => '0');
variable ti : time;
begin
n := 0;
ti := now;
if VME64xBus_In.Vme64xDtackN /= '1' or VME64xBus_In.Vme64xBerrN /= '0' then
wait until VME64xBus_In.Vme64xDtackN = '1' and VME64xBus_In.Vme64xBerrN = '0';
end if;
--initialisation
VME64xBus_Out.Vme64xAsN <= '1';
VME64xBus_Out.Vme64xWRITEN <= '1';
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
VME64xBus_Out.Vme64xLWORDN <= '1';
VME64xBus_Out.Vme64xADDR <= (others => '1');
wait for 10 ns;
SetAmAddress(s_dataTransferType => s_dataTransferType, s_AddressingType => s_AddressingType,
Vme64xAM => Vme64xAM, DataType => DataType);
SetAddress(c_address => v_address, s_AddressingType => s_AddressingType, v_address => v_addressout);
VME64xBus_Out.Vme64xADDR(31 downto 2) <= v_addressout(31 downto 2);
VME64xBus_Out.Vme64xAM <= Vme64xAM;
VME64xBus_Out.Vme64xLWORDN <= DataType(0);
VME64xBus_Out.Vme64xADDR(1) <= DataType(1);
VME64xBus_Out.Vme64xWRITEN <= '1';
wait for 35 ns;
VME64xBus_Out.Vme64xAsN <= '0';
wait for 10 ns;
VME64xBus_Out.Vme64xDs1N <= DataType(3);
VME64xBus_Out.Vme64xDs0N <= DataType(2);
wait until (VME64xBus_In.Vme64xDtackN = '0' or (now > (ti + 5 us)) or VME64xBus_In.Vme64xBerrN = '1');
if(VME64xBus_In.Vme64xBerrN = '1' or (now > (ti + 5 us))) then -- if the slave answer, will answer in 5/10 Tclk
assert(VME64xBus_In.Vme64xBerrN /= '1') report "THE SLAVE ASSERTED THE Berr LINE" severity error;
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
else
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
wait for 35 ns;
while n < (num) loop
VME64xBus_Out.Vme64xDs1N <= DataType(3);
VME64xBus_Out.Vme64xDs0N <= DataType(2);
wait until (VME64xBus_In.Vme64xDtackN = '0' or (now > (ti + 100 us)) or VME64xBus_In.Vme64xBerrN = '1');
if(VME64xBus_In.Vme64xBerrN = '1' or (now > (ti + 100 us))) then
assert(VME64xBus_In.Vme64xBerrN /= '1') report "THE SLAVE ASSERTED THE Berr LINE" severity error;
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
exit;
else
v_dataToReceiveOut(63 downto 33) := VME64xBus_In.Vme64xADDR;
v_dataToReceiveOut(31 downto 0) := VME64xBus_In.Vme64xDATA;
v_dataToReceiveOut(32) := VME64xBus_In.Vme64xLWORDN;
--assert (v_dataToReceiveOut /= s_Buffer_MBLT(n))report "CORRECT DATA!!!" severity error;
--assert (v_dataToReceiveOut = s_Buffer_MBLT(n))report "RECEIVED WRONG DATA!!!" severity failure;
--NB start to read from the first location written otherwise use n + x
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
n := n + 1;
wait for 35 ns;
end if;
end loop;
end if;
VME64xBus_Out.Vme64xADDR <= (others => '1');
VME64xBus_Out.Vme64xAM <= (others => '1');
VME64xBus_Out.Vme64xDATA <= (others => 'Z');
VME64xBus_Out.Vme64xAsN <= '1';
VME64xBus_Out.Vme64xWRITEN <= '1';
end;
procedure SetAddress (c_address : in std_logic_vector(63 downto 0); signal s_AddressingType : in t_Addressing_Type; v_address : out std_logic_vector(31 downto 0)) is
begin
case s_AddressingType is
when A16 => v_address := x"0000" & BA(7 downto 3) & c_address(10 downto 2) & "00";
when A24 => v_address := x"00" & BA(7 downto 3) & c_address(18 downto 2) & "00";
when A32 => v_address := BA(7 downto 3) & c_address(26 downto 2) & "00";
when A32_BLT => v_address := BA(7 downto 3) & c_address(26 downto 2) & "00";
when A24_BLT => v_address := x"00" & BA(7 downto 3) & c_address(18 downto 2) & "00";
when A32_MBLT => v_address := BA(7 downto 3) & c_address(26 downto 2) & "00";
when A24_MBLT => v_address := x"00" & BA(7 downto 3) & c_address(18 downto 2) & "00";
when others => null;
end case;
end;
procedure A64SetAddress (c_address : in std_logic_vector(63 downto 0); signal s_AddressingType : in t_Addressing_Type; v_address : out std_logic_vector(63 downto 0)) is
begin
case s_AddressingType is
when A64 => v_address := BA(7 downto 3) & c_address(58 downto 2) & "00";
when A64_BLT => v_address := BA(7 downto 3) & c_address(58 downto 2) & "00";
when A64_MBLT => v_address := BA(7 downto 3) & c_address(58 downto 2) & "00";
when A32_2eVME => v_address := x"00000000" & BA(7 downto 3) & c_address(26 downto 0);
when A32_2eSST => v_address := x"00000000" & BA(7 downto 3) & c_address(26 downto 0);
when A64_2eVME => v_address := BA(7 downto 3) & c_address(58 downto 0);
when A64_2eSST => v_address := BA(7 downto 3) & c_address(58 downto 0);
when others => null;
end case;
end;
procedure Interrupt_Handler(signal VME64xBus_In : in VME64xBusIn_Record; signal VME64xBus_Out : out VME64xBusOut_Record; signal s_dataToReceive : in std_logic_vector(31 downto 0);
signal s_dataTransferType : in t_dataTransferType; signal s_AddressingType : in t_Addressing_Type) is
--variable v_dataTransferType : t_dataTransferType;
--variable v_AddressingType : t_Addressing_Type;
variable v_address : std_logic_vector(63 downto 0);
--variable v_dataToReceive : std_logic_vector(31 downto 0);
variable ti : time;
begin
ti := now;
wait until VME64xBus_In.Vme64xIRQ /= x"0000000";
if VME64xBus_In.Vme64xDtackN /= '1' or VME64xBus_In.Vme64xBerrN /= '0' then
wait until VME64xBus_In.Vme64xDtackN = '1' and VME64xBus_In.Vme64xBerrN = '0';
end if;
--initialisation
VME64xBus_Out.Vme64xAsN <= '1';
VME64xBus_Out.Vme64xWRITEN <= '1';
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
VME64xBus_Out.Vme64xLWORDN <= '1';
VME64xBus_Out.Vme64xADDR <= (others => '1');
wait for 10 ns;
--The interrupt handler take the bus and start the int. ack cycle
VME64xBus_Out.Vme64xIACK <= '0';
VME64xBus_Out.Vme64xIACKIN <= '0';
VME64xBus_Out.Vme64xADDR <= x"0000000"& b"010";
VME64xBus_Out.Vme64xLWORDN <= '0';
wait for 10 ns;
VME64xBus_Out.Vme64xAsN <= '0';
VME64xBus_Out.Vme64xDs0N <= '0';
VME64xBus_Out.Vme64xDs1N <= '0';
wait until (VME64xBus_In.Vme64xDtackN = '0' or VME64xBus_In.Vme64xBerrN = '1' or (now > (ti + 2 us)));
wait for 10 ns;
if (VME64xBus_In.Vme64xDtackN = '0') then
VME64xBus_Out.Vme64xAsN <= '1';
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
VME64xBus_Out.Vme64xIACK <= '1';
VME64xBus_Out.Vme64xLWORDN <= '1';
VME64xBus_Out.Vme64xIACKIN <= '1';
wait for 30 ns;
--v_dataTransferType := D32;
--v_AddressingType := A32;
v_address := x"0000000000000000";
--v_dataToReceive := x"00000001";
S_Read(v_address => v_address, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In, VME64xBus_Out => VME64xBus_Out);
else
VME64xBus_Out.Vme64xAsN <= '1';
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
VME64xBus_Out.Vme64xIACK <= '1';
VME64xBus_Out.Vme64xLWORDN <= '1';
VME64xBus_Out.Vme64xIACKIN <= '1';
wait for 30 ns;
end if;
end;
procedure A64S_Write (v_address : in std_logic_vector(63 downto 0); signal s_dataToSend : in std_logic_vector(31 downto 0); -- this procedure is for A16, A24, A32 address type
signal s_dataTransferType : in t_dataTransferType; signal s_AddressingType : in t_Addressing_Type;
signal VME64xBus_In : in VME64xBusIn_Record; signal VME64xBus_Out : out VME64xBusOut_Record) is
variable Vme64xAM : std_logic_vector(5 downto 0);
variable DataType : std_logic_vector(3 downto 0) := (others => '1');
variable v_addressout : std_logic_vector(63 downto 0) := (others => '0');
variable v_dataToSendOut : std_logic_vector(31 downto 0) := (others => '0');
variable ti : time;
begin
ti := now;
if VME64xBus_In.Vme64xDtackN /= '1' or VME64xBus_In.Vme64xBerrN /= '0' then
wait until VME64xBus_In.Vme64xDtackN = '1' and VME64xBus_In.Vme64xBerrN = '0';
end if;
VME64xBus_Out.Vme64xAsN <= '1'; --initialisation
VME64xBus_Out.Vme64xWRITEN <= '1';
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
VME64xBus_Out.Vme64xLWORDN <= '1';
VME64xBus_Out.Vme64xADDR <= (others => '1');
wait for 10 ns;
report "Start Address Phase";
-- Address phase
SetAmAddress(s_dataTransferType => s_dataTransferType, s_AddressingType => s_AddressingType,
Vme64xAM => Vme64xAM, DataType => DataType);
A64SetAddress(c_address => v_address, s_AddressingType => s_AddressingType, v_address => v_addressout);
VME64xBus_Out.Vme64xADDR(31 downto 2) <= v_addressout(31 downto 2);
VME64xBus_Out.Vme64xAM <= Vme64xAM;
VME64xBus_Out.Vme64xLWORDN <= DataType(0);
VME64xBus_Out.Vme64xADDR(1) <= DataType(1);
VME64xBus_Out.Vme64xWRITEN <= '0';
VME64xBus_Out.Vme64xDATA <= v_addressout(63 downto 32);
wait for 35 ns;
VME64xBus_Out.Vme64xAsN <= '0';
VME64xBus_Out.Vme64xDs1N <= DataType(3);
VME64xBus_Out.Vme64xDs0N <= DataType(2);
report "End Address Phase";
report "Wait for DTACK";
wait until (VME64xBus_In.Vme64xDtackN = '0' or (now > (ti + 4 us)) or VME64xBus_In.Vme64xBerrN = '1');
assert (VME64xBus_In.Vme64xBerrN /= '1') report "THE SLAVE ASSERTED THE Berr LINE" severity error;
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
wait for 35 ns;
ShiftData(write_n => '0', s_dataTransferType => s_dataTransferType, s_dataToShift => s_dataToSend, v_dataToShiftOut => v_dataToSendOut); --procedura che prende il dato dai lsb e lo mette nei byte giusti
VME64xBus_Out.Vme64xDATA <= v_dataToSendOut;
VME64xBus_Out.Vme64xDs1N <= DataType(3);
VME64xBus_Out.Vme64xDs0N <= DataType(2);
wait until (VME64xBus_In.Vme64xDtackN = '0' or (now > (ti + 4 us)) or VME64xBus_In.Vme64xBerrN = '1');
assert (VME64xBus_In.Vme64xBerrN /= '1') report "THE SLAVE ASSERTED THE Berr LINE" severity error;
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
VME64xBus_Out.Vme64xLWORDN <= '1';
VME64xBus_Out.Vme64xADDR <= (others => '1');
VME64xBus_Out.Vme64xAM <= (others => '1');
VME64xBus_Out.Vme64xDATA <= (others => 'Z');
VME64xBus_Out.Vme64xAsN <= '1';
VME64xBus_Out.Vme64xWRITEN <= '1';
end;
procedure A64S_Read (v_address : in std_logic_vector(63 downto 0); signal s_dataToReceive : in std_logic_vector(31 downto 0); -- this procedure is for A16, A24, A32 address type
signal s_dataTransferType : in t_dataTransferType; signal s_AddressingType : in t_Addressing_Type;
signal VME64xBus_In : in VME64xBusIn_Record; signal VME64xBus_Out : out VME64xBusOut_Record) is
variable Vme64xAM : std_logic_vector(5 downto 0);
variable DataType : std_logic_vector(3 downto 0) := (others => '1');
variable v_addressout : std_logic_vector(63 downto 0) := (others => '0');
variable v_dataToReceiveOut : std_logic_vector(31 downto 0) := (others => '0');
variable ti : time;
begin
ti := now;
if VME64xBus_In.Vme64xDtackN /= '1' or VME64xBus_In.Vme64xBerrN /= '0' then
wait until VME64xBus_In.Vme64xDtackN = '1' and VME64xBus_In.Vme64xBerrN = '0';
end if;
--initialisation
VME64xBus_Out.Vme64xAsN <= '1';
VME64xBus_Out.Vme64xWRITEN <= '1';
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
VME64xBus_Out.Vme64xLWORDN <= '1';
VME64xBus_Out.Vme64xADDR <= (others => '1');
wait for 10 ns;
report "Start Address Phase";
-- Address phase
SetAmAddress(s_dataTransferType => s_dataTransferType, s_AddressingType => s_AddressingType,
Vme64xAM => Vme64xAM, DataType => DataType);
A64SetAddress(c_address => v_address, s_AddressingType => s_AddressingType, v_address => v_addressout);
VME64xBus_Out.Vme64xADDR(31 downto 2) <= v_addressout(31 downto 2);
VME64xBus_Out.Vme64xAM <= Vme64xAM;
VME64xBus_Out.Vme64xLWORDN <= DataType(0);
VME64xBus_Out.Vme64xADDR(1) <= DataType(1);
VME64xBus_Out.Vme64xWRITEN <= '1';
VME64xBus_Out.Vme64xDATA(31 downto 0) <= v_addressout(63 downto 32);
wait for 35 ns; -- check the min time here...for master is 35 ns and for slave 10 ns.
report "Master drive the AS low";
VME64xBus_Out.Vme64xAsN <= '0';
VME64xBus_Out.Vme64xDs1N <= DataType(3);
VME64xBus_Out.Vme64xDs0N <= DataType(2);
report "Wait for DTACK";
wait until (VME64xBus_In.Vme64xDtackN = '0' or (now > (ti + 4 us)) or VME64xBus_In.Vme64xBerrN = '1');
assert (VME64xBus_In.Vme64xBerrN /= '1') report "THE SLAVE ASSERTED THE Berr LINE" severity error;
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
report "End Address Phase";
wait for 35 ns;
VME64xBus_Out.Vme64xDs1N <= DataType(3);
VME64xBus_Out.Vme64xDs0N <= DataType(2);
report "Wait for DTACK";
wait until (VME64xBus_In.Vme64xDtackN = '0' or (now > (ti + 4 us)) or VME64xBus_In.Vme64xBerrN = '1');
if(VME64xBus_In.Vme64xBerrN = '1') then
assert(VME64xBus_In.Vme64xBerrN /= '1') report "THE SLAVE ASSERTED THE Berr LINE" severity error;
else
ShiftData(write_n => '1', s_dataTransferType => s_dataTransferType, s_dataToShift => VME64xBus_In.Vme64xDATA, v_dataToShiftOut => v_dataToReceiveOut);
assert (v_dataToReceiveOut /= s_dataToReceive)report "CORRECT DATA!!!" severity error;
assert (v_dataToReceiveOut = s_dataToReceive)report "RECEIVED WRONG DATA!!!" severity failure;
end if;
VME64xBus_Out.Vme64xLWORDN <= '1';
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
VME64xBus_Out.Vme64xADDR <= (others => '1');
VME64xBus_Out.Vme64xAM <= (others => '1');
-- wait for 0 ns; -- not necessary
VME64xBus_Out.Vme64xDATA <= (others => 'Z');
VME64xBus_Out.Vme64xAsN <= '1';
VME64xBus_Out.Vme64xWRITEN <= '1';
end;
procedure A64Blt_write(v_address : in std_logic_vector(63 downto 0); signal s_Buffer_BLT : in t_Buffer_BLT; -- this procedure is for A16, A24, A32 address type
signal s_dataTransferType : in t_dataTransferType; signal s_AddressingType : in t_Addressing_Type; num : in std_logic_vector(8 downto 0);
signal VME64xBus_In : in VME64xBusIn_Record; signal VME64xBus_Out : out VME64xBusOut_Record)is
variable n : integer;
variable Vme64xAM : std_logic_vector(5 downto 0);
variable DataType : std_logic_vector(3 downto 0) := (others => '1');
variable v_addressout : std_logic_vector(63 downto 0) := (others => '0');
variable ti : time;
begin
n := 0;
ti := now;
if VME64xBus_In.Vme64xDtackN /= '1' or VME64xBus_In.Vme64xBerrN /= '0' then
wait until VME64xBus_In.Vme64xDtackN = '1' and VME64xBus_In.Vme64xBerrN = '0';
end if;
--initialisation
VME64xBus_Out.Vme64xAsN <= '1';
VME64xBus_Out.Vme64xWRITEN <= '1';
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
VME64xBus_Out.Vme64xLWORDN <= '1';
VME64xBus_Out.Vme64xADDR <= (others => '1');
wait for 10 ns;
SetAmAddress(s_dataTransferType => s_dataTransferType, s_AddressingType => s_AddressingType,
Vme64xAM => Vme64xAM, DataType => DataType);
A64SetAddress(c_address => v_address, s_AddressingType => s_AddressingType, v_address => v_addressout);
VME64xBus_Out.Vme64xADDR(31 downto 2) <= v_addressout(31 downto 2);
VME64xBus_Out.Vme64xDATA(31 downto 0) <= v_addressout(63 downto 32);
VME64xBus_Out.Vme64xAM <= Vme64xAM;
VME64xBus_Out.Vme64xLWORDN <= DataType(0);
VME64xBus_Out.Vme64xADDR(1) <= DataType(1);
VME64xBus_Out.Vme64xWRITEN <= '0';
wait for 35 ns;
VME64xBus_Out.Vme64xAsN <= '0';
VME64xBus_Out.Vme64xDs1N <= DataType(3);
VME64xBus_Out.Vme64xDs0N <= DataType(2);
wait until (VME64xBus_In.Vme64xDtackN = '0' or (now > (ti + 15 us)) or VME64xBus_In.Vme64xBerrN = '1');
assert (VME64xBus_In.Vme64xBerrN /= '1') report "THE SLAVE ASSERTED THE Berr LINE" severity error;
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
report "End Address Phase";
wait for 35 ns;
while n < (num) loop
VME64xBus_Out.Vme64xDATA <= s_Buffer_BLT(n);
wait for 35 ns;
VME64xBus_Out.Vme64xDs1N <= DataType(3);
VME64xBus_Out.Vme64xDs0N <= DataType(2);
wait until (VME64xBus_In.Vme64xDtackN = '0' or (now > (ti + 15 us)) or VME64xBus_In.Vme64xBerrN = '1');
if(VME64xBus_In.Vme64xBerrN = '1') then
assert(VME64xBus_In.Vme64xBerrN /= '1') report "THE SLAVE ASSERTED THE Berr LINE" severity error;
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
exit;
end if;
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
wait for 10 ns;
n := n + 1;
end loop;
VME64xBus_Out.Vme64xADDR <= (others => '1');
VME64xBus_Out.Vme64xAM <= (others => '1');
VME64xBus_Out.Vme64xDATA <= (others => 'Z');
VME64xBus_Out.Vme64xAsN <= '1';
VME64xBus_Out.Vme64xWRITEN <= '1';
VME64xBus_Out.Vme64xLWORDN <= '1';
end;
procedure A64Blt_Read(v_address : in std_logic_vector(63 downto 0); signal s_Buffer_BLT : in t_Buffer_BLT; -- this procedure is for A16, A24, A32 address type
signal s_dataTransferType : in t_dataTransferType; signal s_AddressingType : in t_Addressing_Type; num : in std_logic_vector(8 downto 0);
signal VME64xBus_In : in VME64xBusIn_Record; signal VME64xBus_Out : out VME64xBusOut_Record) is
variable n : integer;
variable Vme64xAM : std_logic_vector(5 downto 0);
variable DataType : std_logic_vector(3 downto 0) := (others => '1');
variable v_addressout : std_logic_vector(63 downto 0) := (others => '0');
variable v_dataToReceiveOut : std_logic_vector(31 downto 0) := (others => '0');
variable ti : time;
begin
n := 0;
ti := now;
if VME64xBus_In.Vme64xDtackN /= '1' or VME64xBus_In.Vme64xBerrN /= '0' then
wait until VME64xBus_In.Vme64xDtackN = '1' and VME64xBus_In.Vme64xBerrN = '0';
end if;
--initialisation
VME64xBus_Out.Vme64xAsN <= '1';
VME64xBus_Out.Vme64xWRITEN <= '1';
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
VME64xBus_Out.Vme64xLWORDN <= '1';
VME64xBus_Out.Vme64xADDR <= (others => '1');
wait for 10 ns;
SetAmAddress(s_dataTransferType => s_dataTransferType, s_AddressingType => s_AddressingType,
Vme64xAM => Vme64xAM, DataType => DataType);
A64SetAddress(c_address => v_address, s_AddressingType => s_AddressingType, v_address => v_addressout);
VME64xBus_Out.Vme64xADDR(31 downto 2) <= v_addressout(31 downto 2);
VME64xBus_Out.Vme64xDATA(31 downto 0) <= v_addressout(63 downto 32);
VME64xBus_Out.Vme64xAM <= Vme64xAM;
VME64xBus_Out.Vme64xLWORDN <= DataType(0);
VME64xBus_Out.Vme64xADDR(1) <= DataType(1);
VME64xBus_Out.Vme64xWRITEN <= '1';
wait for 35 ns;
VME64xBus_Out.Vme64xAsN <= '0';
VME64xBus_Out.Vme64xDs1N <= DataType(3);
VME64xBus_Out.Vme64xDs0N <= DataType(2);
wait until (VME64xBus_In.Vme64xDtackN = '0' or (now > (ti + 15 us)) or VME64xBus_In.Vme64xBerrN = '1');
assert (VME64xBus_In.Vme64xBerrN /= '1') report "THE SLAVE ASSERTED THE Berr LINE" severity error;
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
report "End Address Phase";
wait for 35 ns;
while n < (num) loop
VME64xBus_Out.Vme64xDs1N <= DataType(3);
VME64xBus_Out.Vme64xDs0N <= DataType(2);
wait until (VME64xBus_In.Vme64xDtackN = '0' or (now > (ti + 4 us)) or VME64xBus_In.Vme64xBerrN = '1');
if(VME64xBus_In.Vme64xBerrN = '1') then
assert(VME64xBus_In.Vme64xBerrN /= '1') report "THE SLAVE ASSERTED THE Berr LINE" severity error;
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
exit;
else
v_dataToReceiveOut := VME64xBus_In.Vme64xDATA;
assert (v_dataToReceiveOut /= s_Buffer_BLT(n))report "CORRECT DATA!!!" severity error;
assert (v_dataToReceiveOut = s_Buffer_BLT(n))report "RECEIVED WRONG DATA!!!" severity failure;
end if;
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
wait for 40 ns;
n := n + 1;
end loop;
VME64xBus_Out.Vme64xADDR <= (others => '1');
VME64xBus_Out.Vme64xAM <= (others => '1');
VME64xBus_Out.Vme64xDATA <= (others => 'Z');
VME64xBus_Out.Vme64xAsN <= '1';
VME64xBus_Out.Vme64xWRITEN <= '1';
VME64xBus_Out.Vme64xLWORDN <= '1';
end;
procedure A64Mblt_write(v_address : in std_logic_vector(63 downto 0); signal s_Buffer_MBLT : in t_Buffer_MBLT; -- this procedure is for A16, A24, A32 address type
signal s_dataTransferType : in t_dataTransferType; signal s_AddressingType : in t_Addressing_Type; num : in std_logic_vector(8 downto 0);
signal VME64xBus_In : in VME64xBusIn_Record; signal VME64xBus_Out : out VME64xBusOut_Record)is
variable n : integer;
variable Vme64xAM : std_logic_vector(5 downto 0);
variable DataType : std_logic_vector(3 downto 0) := (others => '1');
variable v_addressout : std_logic_vector(63 downto 0) := (others => '0');
variable ti : time;
begin
n := 0;
ti := now;
if VME64xBus_In.Vme64xDtackN /= '1' or VME64xBus_In.Vme64xBerrN /= '0' then
wait until VME64xBus_In.Vme64xDtackN = '1' and VME64xBus_In.Vme64xBerrN = '0';
end if;
--initialisation
VME64xBus_Out.Vme64xAsN <= '1';
VME64xBus_Out.Vme64xWRITEN <= '1';
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
VME64xBus_Out.Vme64xLWORDN <= '1';
VME64xBus_Out.Vme64xADDR <= (others => '1');
wait for 10 ns;
SetAmAddress(s_dataTransferType => s_dataTransferType, s_AddressingType => s_AddressingType,
Vme64xAM => Vme64xAM, DataType => DataType);
A64SetAddress(c_address => v_address, s_AddressingType => s_AddressingType, v_address => v_addressout);
VME64xBus_Out.Vme64xADDR(31 downto 2) <= v_addressout(31 downto 2);
VME64xBus_Out.Vme64xDATA(31 downto 0) <= v_addressout(63 downto 32);
VME64xBus_Out.Vme64xAM <= Vme64xAM;
VME64xBus_Out.Vme64xLWORDN <= DataType(0);
VME64xBus_Out.Vme64xADDR(1) <= DataType(1);
VME64xBus_Out.Vme64xWRITEN <= '0';
wait for 35 ns;
VME64xBus_Out.Vme64xAsN <= '0';
wait for 10 ns;
VME64xBus_Out.Vme64xDs1N <= DataType(3);
VME64xBus_Out.Vme64xDs0N <= DataType(2);
wait until (VME64xBus_In.Vme64xDtackN = '0' or (now > (ti + 5 us)) or VME64xBus_In.Vme64xBerrN = '1');
if(VME64xBus_In.Vme64xBerrN = '1' or (now > (ti + 5 us))) then
assert(VME64xBus_In.Vme64xBerrN /= '1') report "THE SLAVE ASSERTED THE Berr LINE" severity error;
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
else
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
wait for 35 ns;
while n < (num) loop
VME64xBus_Out.Vme64xDATA <= s_Buffer_MBLT(n)(31 downto 0);
VME64xBus_Out.Vme64xADDR(31 downto 1) <= s_Buffer_MBLT(n)(63 downto 33);
VME64xBus_Out.Vme64xLWORDN <= s_Buffer_MBLT(n)(32);
VME64xBus_Out.Vme64xDs1N <= DataType(3);
VME64xBus_Out.Vme64xDs0N <= DataType(2);
wait until (VME64xBus_In.Vme64xDtackN = '0' or (now > (ti + 100 us)) or VME64xBus_In.Vme64xBerrN = '1');
if(VME64xBus_In.Vme64xBerrN = '1' or (now > (ti + 100 us))) then
assert(VME64xBus_In.Vme64xBerrN /= '1') report "THE SLAVE ASSERTED THE Berr LINE" severity error;
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
exit;
else
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
n := n + 1;
wait for 35 ns;
end if;
end loop;
end if;
VME64xBus_Out.Vme64xADDR <= (others => '1');
VME64xBus_Out.Vme64xAM <= (others => '1');
VME64xBus_Out.Vme64xDATA <= (others => 'Z');
VME64xBus_Out.Vme64xAsN <= '1';
VME64xBus_Out.Vme64xWRITEN <= '1';
end;
procedure A64Mblt_Read(v_address : in std_logic_vector(63 downto 0); signal s_Buffer_MBLT : in t_Buffer_MBLT; -- this procedure is for A16, A24, A32 address type
signal s_dataTransferType : in t_dataTransferType; signal s_AddressingType : in t_Addressing_Type; num : in std_logic_vector(8 downto 0);
signal VME64xBus_In : in VME64xBusIn_Record; signal VME64xBus_Out : out VME64xBusOut_Record) is
variable n : integer;
variable Vme64xAM : std_logic_vector(5 downto 0);
variable DataType : std_logic_vector(3 downto 0) := (others => '1');
variable v_addressout : std_logic_vector(63 downto 0) := (others => '0');
variable v_dataToReceiveOut : std_logic_vector(63 downto 0) := (others => '0');
variable ti : time;
begin
n := 0;
ti := now;
if VME64xBus_In.Vme64xDtackN /= '1' or VME64xBus_In.Vme64xBerrN /= '0' then
wait until VME64xBus_In.Vme64xDtackN = '1' and VME64xBus_In.Vme64xBerrN = '0';
end if;
--initialisation
VME64xBus_Out.Vme64xAsN <= '1';
VME64xBus_Out.Vme64xWRITEN <= '1';
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
VME64xBus_Out.Vme64xLWORDN <= '1';
VME64xBus_Out.Vme64xADDR <= (others => '1');
wait for 10 ns;
SetAmAddress(s_dataTransferType => s_dataTransferType, s_AddressingType => s_AddressingType,
Vme64xAM => Vme64xAM, DataType => DataType);
A64SetAddress(c_address => v_address, s_AddressingType => s_AddressingType, v_address => v_addressout);
VME64xBus_Out.Vme64xADDR(31 downto 2) <= v_addressout(31 downto 2);
VME64xBus_Out.Vme64xDATA(31 downto 0) <= v_addressout(63 downto 32);
VME64xBus_Out.Vme64xAM <= Vme64xAM;
VME64xBus_Out.Vme64xLWORDN <= DataType(0);
VME64xBus_Out.Vme64xADDR(1) <= DataType(1);
VME64xBus_Out.Vme64xWRITEN <= '1';
wait for 35 ns;
VME64xBus_Out.Vme64xAsN <= '0';
wait for 10 ns;
VME64xBus_Out.Vme64xDs1N <= DataType(3);
VME64xBus_Out.Vme64xDs0N <= DataType(2);
wait until (VME64xBus_In.Vme64xDtackN = '0' or (now > (ti + 5 us)) or VME64xBus_In.Vme64xBerrN = '1');
if(VME64xBus_In.Vme64xBerrN = '1' or (now > (ti + 5 us))) then -- if the slave answer, will answer in 5/10 Tclk
assert(VME64xBus_In.Vme64xBerrN /= '1') report "THE SLAVE ASSERTED THE Berr LINE" severity error;
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
else
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
wait for 35 ns;
while n < (num) loop
VME64xBus_Out.Vme64xDs1N <= DataType(3);
VME64xBus_Out.Vme64xDs0N <= DataType(2);
wait until (VME64xBus_In.Vme64xDtackN = '0' or (now > (ti + 100 us)) or VME64xBus_In.Vme64xBerrN = '1');
if(VME64xBus_In.Vme64xBerrN = '1' or (now > (ti + 100 us))) then
assert(VME64xBus_In.Vme64xBerrN /= '1') report "THE SLAVE ASSERTED THE Berr LINE" severity error;
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
exit;
else
v_dataToReceiveOut(63 downto 33) := VME64xBus_In.Vme64xADDR;
v_dataToReceiveOut(31 downto 0) := VME64xBus_In.Vme64xDATA;
v_dataToReceiveOut(32) := VME64xBus_In.Vme64xLWORDN;
assert (v_dataToReceiveOut /= s_Buffer_MBLT(n))report "CORRECT DATA!!!" severity error;
assert (v_dataToReceiveOut = s_Buffer_MBLT(n))report "RECEIVED WRONG DATA!!!" severity failure;
--NB start to read from the first location written otherwise use n + x
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
n := n + 1;
wait for 35 ns;
end if;
end loop;
end if;
VME64xBus_Out.Vme64xADDR <= (others => '1');
VME64xBus_Out.Vme64xAM <= (others => '1');
VME64xBus_Out.Vme64xDATA <= (others => 'Z');
VME64xBus_Out.Vme64xAsN <= '1';
VME64xBus_Out.Vme64xWRITEN <= '1';
end;
procedure SetXAmAddress(signal s_AddressingType : in t_Addressing_Type; v_XAm : out std_logic_vector(7 downto 0))is
begin
case s_AddressingType is
when A32_2eVME => v_XAm := c_A32_2eVME;
when A64_2eVME => v_XAm := c_A64_2eVME;
when A32_2eSST => v_XAm := c_A32_2eSST;
when A64_2eSST => v_XAm := c_A64_2eSST;
when others => null;
end case;
end;
procedure TWOeVME_write(v_address : in std_logic_vector(63 downto 0); signal s_Buffer_MBLT : in t_Buffer_MBLT; -- this procedure is for A16, A24, A32 address type
signal s_AddressingType : in t_Addressing_Type; v_beat_count : in std_logic_vector(7 downto 0);
signal VME64xBus_In : in VME64xBusIn_Record; signal VME64xBus_Out : out VME64xBusOut_Record) is
variable n : integer;
variable Vme64xAM : std_logic_vector(5 downto 0);
variable v_addressout : std_logic_vector(63 downto 0) := (others => '0');
variable v_XAM : std_logic_vector(7 downto 0);
variable ti : time;
variable v_DS0 : std_logic;
variable v_DS1 : std_logic;
begin
n := 0;
ti := now;
if VME64xBus_In.Vme64xDtackN /= '1' or VME64xBus_In.Vme64xBerrN /= '0' then
wait until VME64xBus_In.Vme64xDtackN = '1' and VME64xBus_In.Vme64xBerrN = '0';
end if;
--initialisation
VME64xBus_Out.Vme64xAsN <= '1';
VME64xBus_Out.Vme64xWRITEN <= '1';
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
VME64xBus_Out.Vme64xLWORDN <= '1';
VME64xBus_Out.Vme64xADDR <= (others => '1');
v_DS0 := '1';
v_DS1 := '1';
wait for 10 ns;
SetXAmAddress(s_AddressingType => s_AddressingType, v_XAm => v_XAM);
A64SetAddress(c_address => v_address, s_AddressingType => s_AddressingType, v_address => v_addressout);
-- Address phase 1
VME64xBus_Out.Vme64xWRITEN <= '0';
VME64xBus_Out.Vme64xDATA <= v_addressout(63 downto 32);
VME64xBus_Out.Vme64xADDR <= v_addressout(31 downto 8) & v_XAM(7 downto 1);
VME64xBus_Out.Vme64xLWORDN <= v_XAM(0);
VME64xBus_Out.Vme64xAM <= c_TWOedge;
wait for 35 ns;
VME64xBus_Out.Vme64xAsN <= '0';
v_DS0 := '0';
VME64xBus_Out.Vme64xDs0N <= v_DS0;
wait until (VME64xBus_In.Vme64xDtackN = '0' or (now > (ti + 5 us)));
wait for 5 ns; --H1 time
--Address phase 2
VME64xBus_Out.Vme64xDATA <= (others => '0');
VME64xBus_Out.Vme64xADDR <= x"0000" & v_beat_count & v_addressout(7 downto 1);
VME64xBus_Out.Vme64xLWORDN <= v_addressout(0);
v_DS0 := not v_DS0;
VME64xBus_Out.Vme64xDs0N <= v_DS0;
wait until (VME64xBus_In.Vme64xDtackN = '1' or (now > (ti + 5 us)));
wait for 5 ns; --H1 time
--Address phase 3
VME64xBus_Out.Vme64xDATA <= (others => '0');
VME64xBus_Out.Vme64xADDR <= (others => '0');
VME64xBus_Out.Vme64xLWORDN <= '0';
v_DS0 := not v_DS0;
VME64xBus_Out.Vme64xDs0N <= v_DS0;
wait until (VME64xBus_In.Vme64xDtackN = '0' or (now > (ti + 5 us)));
wait for 5 ns; --H1 time
--Data Phase
while n < (v_beat_count) loop
VME64xBus_Out.Vme64xDATA <= s_Buffer_MBLT(n)(31 downto 0);
VME64xBus_Out.Vme64xADDR(31 downto 1) <= s_Buffer_MBLT(n)(63 downto 33);
VME64xBus_Out.Vme64xLWORDN <= s_Buffer_MBLT(n)(32);
v_DS1 := not v_DS1;
VME64xBus_Out.Vme64xDs1N <= v_DS1;
wait until (VME64xBus_In.Vme64xDtackN = not (VME64xBus_In.Vme64xDtackN) or (now > (ti + 100 us)) or VME64xBus_In.Vme64xBerrN = '1');
if(VME64xBus_In.Vme64xBerrN = '1' or (now > (ti + 100 us))) then
assert(VME64xBus_In.Vme64xBerrN /= '1') report "THE SLAVE ASSERTED THE Berr LINE" severity error;
wait for 10 ns;
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
exit;
else
wait for 10 ns;
n := n + 1;
end if;
end loop;
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
wait for 10 ns;
VME64xBus_Out.Vme64xWRITEN <= '1';
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
VME64xBus_Out.Vme64xLWORDN <= '1';
VME64xBus_Out.Vme64xADDR <= (others => '1');
VME64xBus_Out.Vme64xAM <= (others => '1');
VME64xBus_Out.Vme64xAsN <= '1';
end;
procedure TWOeVME_read(v_address : in std_logic_vector(63 downto 0); signal s_Buffer_MBLT : in t_Buffer_MBLT; -- this procedure is for A16, A24, A32 address type
signal s_AddressingType : in t_Addressing_Type; v_beat_count : in std_logic_vector(7 downto 0);
signal VME64xBus_In : in VME64xBusIn_Record; signal VME64xBus_Out : out VME64xBusOut_Record) is
variable n : integer;
variable Vme64xAM : std_logic_vector(5 downto 0);
variable v_addressout : std_logic_vector(63 downto 0) := (others => '0');
variable v_XAM : std_logic_vector(7 downto 0);
variable ti : time;
variable v_DS0 : std_logic;
variable v_DS1 : std_logic;
variable v_dataToReceiveOut : std_logic_vector(63 downto 0);
begin
n := 0;
ti := now;
if VME64xBus_In.Vme64xDtackN /= '1' or VME64xBus_In.Vme64xBerrN /= '0' then
wait until VME64xBus_In.Vme64xDtackN = '1' and VME64xBus_In.Vme64xBerrN = '0';
end if;
--initialisation
VME64xBus_Out.Vme64xAsN <= '1';
VME64xBus_Out.Vme64xWRITEN <= '1';
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
VME64xBus_Out.Vme64xLWORDN <= '1';
VME64xBus_Out.Vme64xADDR <= (others => '1');
v_DS0 := '1';
v_DS1 := '1';
wait for 10 ns;
SetXAmAddress(s_AddressingType => s_AddressingType, v_XAm => v_XAM);
A64SetAddress(c_address => v_address, s_AddressingType => s_AddressingType, v_address => v_addressout);
-- Address phase 1
VME64xBus_Out.Vme64xWRITEN <= '1';
VME64xBus_Out.Vme64xDATA <= v_addressout(63 downto 32);
VME64xBus_Out.Vme64xADDR <= v_addressout(31 downto 8) & v_XAM(7 downto 1);
VME64xBus_Out.Vme64xLWORDN <= v_XAM(0);
VME64xBus_Out.Vme64xAM <= c_TWOedge;
wait for 35 ns;
VME64xBus_Out.Vme64xAsN <= '0';
v_DS0 := '0';
VME64xBus_Out.Vme64xDs0N <= v_DS0;
wait until (VME64xBus_In.Vme64xDtackN = '0' or (now > (ti + 5 us)));
wait for 5 ns; --H1 time
--Address phase 2
VME64xBus_Out.Vme64xDATA <= (others => '0');
VME64xBus_Out.Vme64xADDR <= x"0000" & v_beat_count & v_addressout(7 downto 1);
VME64xBus_Out.Vme64xLWORDN <= v_addressout(0);
v_DS0 := not v_DS0;
VME64xBus_Out.Vme64xDs0N <= v_DS0;
wait until (VME64xBus_In.Vme64xDtackN = '1' or (now > (ti + 5 us)));
wait for 5 ns; --H1 time
--Address phase 3
VME64xBus_Out.Vme64xDATA <= (others => '0');
VME64xBus_Out.Vme64xADDR <= (others => '0');
VME64xBus_Out.Vme64xLWORDN <= '0';
v_DS0 := not v_DS0;
VME64xBus_Out.Vme64xDs0N <= v_DS0;
wait until (VME64xBus_In.Vme64xDtackN = '0' or (now > (ti + 5 us)));
wait for 5 ns; --H1 time
--Data Phase
while n < (v_beat_count) loop
v_DS1 := not(v_DS1);
VME64xBus_Out.Vme64xDs1N <= v_DS1;
wait until (VME64xBus_In.Vme64xDtackN = not(VME64xBus_In.Vme64xDtackN) or (now > (ti + 100 us)) or VME64xBus_In.Vme64xBerrN = '1');
if(VME64xBus_In.Vme64xBerrN = '1' or (now > (ti + 100 us))) then
assert(VME64xBus_In.Vme64xBerrN /= '1') report "THE SLAVE ASSERTED THE Berr LINE" severity error;
wait for 10 ns;
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
exit;
else
v_dataToReceiveOut(63 downto 33) := VME64xBus_In.Vme64xADDR;
v_dataToReceiveOut(31 downto 0) := VME64xBus_In.Vme64xDATA;
v_dataToReceiveOut(32) := VME64xBus_In.Vme64xLWORDN;
assert (v_dataToReceiveOut /= s_Buffer_MBLT(n))report "CORRECT DATA!!!" severity error;
assert (v_dataToReceiveOut = s_Buffer_MBLT(n))report "RECEIVED WRONG DATA!!!" severity failure;
--NB start to read from the first location written otherwise use n + x
n := n + 1;
wait for 10 ns;
end if;
end loop;
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
wait for 10 ns;
VME64xBus_Out.Vme64xWRITEN <= '1';
VME64xBus_Out.Vme64xDs0N <= '1';
VME64xBus_Out.Vme64xDs1N <= '1';
VME64xBus_Out.Vme64xLWORDN <= '1';
VME64xBus_Out.Vme64xADDR <= (others => '1');
VME64xBus_Out.Vme64xAM <= (others => '1');
VME64xBus_Out.Vme64xAsN <= '1';
end;
end VME64xSim;
-- SPDX-FileCopyrightText: 2022 CERN (home.cern)
--
-- SPDX-License-Identifier: CERN-OHL-W-2.0+
--------------------------------------------------------------------------------
LIBRARY ieee;
library std;
library work;
USE ieee.std_logic_1164.ALL;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
use IEEE.numeric_std.all;
use IEEE.numeric_std.unsigned;
use work.VME_CR_pack.all;
use work.VME_CSR_pack.all;
use work.VME64xSim.all;
use work.VME64x.all;
use work.wishbone_pkg.all;
use std.textio.all;
use work.vme64x_pack.all;
ENTITY VME64x_TB IS
END VME64x_TB;
ARCHITECTURE behavior OF VME64x_TB IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT TOP_LEVEL
PORT(
clk_i : IN std_logic;
VME_AS_n_i : IN std_logic;
VME_RST_n_i : IN std_logic;
VME_WRITE_n_i : IN std_logic;
VME_AM_i : IN std_logic_vector(5 downto 0);
VME_DS_n_i : IN std_logic_vector(1 downto 0);
VME_GA_i : IN std_logic_vector(5 downto 0);
VME_BERR_o : OUT std_logic;
VME_DTACK_n_o : OUT std_logic;
VME_RETRY_n_o : OUT std_logic;
VME_RETRY_OE_o : OUT std_logic;
VME_LWORD_n_b : INOUT std_logic;
VME_ADDR_b : INOUT std_logic_vector(31 downto 1);
VME_DATA_b : INOUT std_logic_vector(31 downto 0);
VME_IRQ_n_o : OUT std_logic_vector(6 downto 0);
VME_IACK_n_i : IN std_logic;
VME_IACKIN_n_i : IN std_logic;
VME_IACKOUT_n_o : OUT std_logic;
VME_DTACK_OE_o : OUT std_logic;
VME_DATA_DIR_o : OUT std_logic;
VME_DATA_OE_N_o : OUT std_logic;
VME_ADDR_DIR_o : OUT std_logic;
VME_ADDR_OE_N_o : OUT std_logic;
Reset : IN std_logic
);
END COMPONENT;
--Inputs
signal clk_i : std_logic := '0';
signal VME_AS_n_i : std_logic := '0';
signal VME_RST_n_i : std_logic := '0';
signal VME_WRITE_n_i : std_logic := '0';
signal VME_AM_i : std_logic_vector(5 downto 0) := (others => '0');
signal VME_DS_n_i : std_logic_vector(1 downto 0) := (others => '0');
signal VME_GA_i : std_logic_vector(5 downto 0) := (others => '0');
signal VME_BBSY_n_i : std_logic := '0';
signal VME_IACKIN_n_i : std_logic := '1';
signal VME_IACK_n_i : std_logic := '1';
signal Reset : std_logic := '1';
--BiDirs
signal VME_LWORD_n_b : std_logic;
signal VME_ADDR_b : std_logic_vector(31 downto 1);
signal VME_DATA_b : std_logic_vector(31 downto 0);
--Outputs
signal VME_BERR_o : std_logic;
signal VME_DTACK_n_o : std_logic;
signal VME_RETRY_n_o : std_logic;
signal VME_RETRY_OE_o : std_logic;
signal VME_IRQ_n_o : std_logic_vector(6 downto 0);
signal VME_IACKOUT_n_o : std_logic;
signal VME_DTACK_OE_o : std_logic;
signal VME_DATA_DIR_o : std_logic;
signal VME_DATA_OE_N_o : std_logic;
signal VME_ADDR_DIR_o : std_logic;
signal VME_ADDR_OE_N_o : std_logic;
-- Flags
signal ReadInProgress : std_logic := '0';
signal WriteInProgress : std_logic := '0';
signal s_Buffer_BLT : t_Buffer_BLT;
signal s_Buffer_MBLT : t_Buffer_MBLT;
signal s_dataTransferType : t_dataTransferType;
signal s_AddressingType : t_Addressing_Type;
-- Control signals
signal s_dataToSendOut : std_logic_vector(31 downto 0);
signal s_dataToSend : std_logic_vector(31 downto 0);
signal s_dataToReceive : std_logic_vector(31 downto 0);
signal s_address : std_logic_vector(63 downto 0);
signal localAddress : std_logic_vector(19 downto 0);
signal s_num : std_logic_vector(8 downto 0);
signal s_temp : std_logic_vector(31 downto 0);
signal s_beat_count : std_logic_vector(7 downto 0);
-- Records
signal VME64xBus_out : VME64xBusOut_Record;
signal VME64xBus_in : VME64xBusIn_Record;
-- Clock period definitions
constant clk_i_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: TOP_LEVEL PORT MAP (
clk_i => clk_i,
VME_AS_n_i => VME_AS_n_i,
VME_RST_n_i => VME_RST_n_i,
VME_WRITE_n_i => VME_WRITE_n_i,
VME_AM_i => VME_AM_i,
VME_DS_n_i => VME_DS_n_i,
VME_GA_i => VME_GA_i,
VME_BERR_o => VME_BERR_o,
VME_DTACK_n_o => VME_DTACK_n_o,
VME_RETRY_n_o => VME_RETRY_n_o,
VME_RETRY_OE_o => VME_RETRY_OE_o,
VME_LWORD_n_b => VME_LWORD_n_b,
VME_ADDR_b => VME_ADDR_b,
VME_DATA_b => VME_DATA_b,
VME_IRQ_n_o => VME_IRQ_n_o,
VME_IACK_n_i => VME_IACK_n_i,
VME_IACKIN_n_i => VME_IACKIN_n_i,
VME_IACKOUT_n_o => VME_IACKOUT_n_o,
VME_DTACK_OE_o => VME_DTACK_OE_o,
VME_DATA_DIR_o => VME_DATA_DIR_o,
VME_DATA_OE_N_o => VME_DATA_OE_N_o,
VME_ADDR_DIR_o => VME_ADDR_DIR_o,
VME_ADDR_OE_N_o => VME_ADDR_OE_N_o,
Reset => Reset
);
VME_IACKIN_n_i <= VME64xBus_out.Vme64xIACKIN;
VME_IACK_n_i <= VME64xBus_out.Vme64xIACK;
VME_AS_n_i <= VME64xBus_out.Vme64xAsN;
VME_WRITE_n_i <= VME64xBus_out.Vme64xWRITEN;
VME_AM_i <= VME64xBus_out.Vme64xAM;
VME_DS_n_i(1) <= VME64xBus_out.Vme64xDs1N;
VME_DS_n_i(0) <= VME64xBus_out.Vme64xDs0N;
VME_LWORD_n_b <= VME64xBus_out.Vme64xLWORDN when VME_ADDR_DIR_o = '0' else 'Z';
VME64xBus_in.Vme64xLWORDN <= VME_LWORD_n_b;
VME_ADDR_b <= VME64xBus_out.Vme64xADDR when VME_ADDR_DIR_o = '0' else (others => 'Z');
VME64xBus_in.Vme64xADDR <= VME_ADDR_b;
VME_DATA_b <= VME64xBus_out.Vme64xDATA when VME_DATA_DIR_o = '0' else (others => 'Z');
VME64xBus_in.Vme64xDATA <= VME_DATA_b;
VME64xBus_in.Vme64xDtackN <= VME_DTACK_n_o;
VME64xBus_in.Vme64xBerrN <= VME_BERR_o;
VME64xBus_in.Vme64xRetryN <= VME_RETRY_n_o;
VME64xBus_in.Vme64xIRQ <= VME_IRQ_n_o;
VME64xBus_in.Vme64xIACKOUT <= VME_IACKOUT_n_o;
-- Clock process definitions
clk_i_process :process
begin
clk_i <= '0';
wait for clk_i_period/2;
clk_i <= '1';
wait for clk_i_period/2;
end process;
test_VME64x : process
begin
wait for 8800 ns; -- wait until the initialization finish (wait more than 8705 ns)
-- Write in CSR:
VME64xBus_Out.Vme64xIACK <= '1';
VME64xBus_Out.Vme64xIACKIN <= '1';
report "START READ CSR";
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
-- Put the data to receive in the 8 lsb also if you are using D08Byte1 or D08Byte2 ecc..
s_dataToReceive <= x"00000040";
ReadCR_CSR(c_address => c_BAR, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
VME64xBus_Out => VME64xBus_Out);
-- wait for 30 ns;
-- s_dataTransferType <= D32;
-- s_AddressingType <= CR_CSR;
-- Put the data to receive in the 8 lsb also if you are using D08Byte1 or D08Byte2 ecc..
-- s_dataToReceive <= x"00000002";
-- ReadCR_CSR(c_address => c_MBLT_Endian, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
-- VME64xBus_Out => VME64xBus_Out);
-- wait for 30 ns;
-- s_dataTransferType <= D32;
-- s_AddressingType <= CR_CSR;
-- Put the data to receive in the 8 lsb also if you are using D08Byte1 or D08Byte2 ecc..
-- s_dataToReceive <= x"00000052";
-- ReadCR_CSR(c_address => std_logic_vector(to_unsigned((8*4) , 20)), s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
-- VME64xBus_Out => VME64xBus_Out);
--
-- wait for 30 ns;
--
-- s_dataTransferType <= D08Byte3;
-- s_AddressingType <= CR_CSR;
--
-- -- Put the data to receive in the 8 lsb also if you are using D08Byte1 or D08Byte2 ecc..
-- s_dataToReceive <= x"00000024";
-- ReadCR_CSR(c_address => c_FUNC0_ADER_0, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
-- VME64xBus_Out => VME64xBus_Out);
--
-- wait for 30 ns;
--
-- --read ADER0:
--
-- s_dataTransferType <= D08Byte3;
-- s_AddressingType <= CR_CSR;
--
-- -- Put the data to receive in the 8 lsb also if you are using D08Byte1 or D08Byte2 ecc..
-- s_dataToReceive <= x"000000c0";
-- ReadCR_CSR(c_address => c_FUNC0_ADER_3, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
-- VME64xBus_Out => VME64xBus_Out);
--
-- wait for 30 ns;
--
-- s_dataTransferType <= D08Byte3;
-- s_AddressingType <= CR_CSR;
--
-- -- Put the data to receive in the 8 lsb also if you are using D08Byte1 or D08Byte2 ecc..
-- s_dataToReceive <= x"00000000";
-- ReadCR_CSR(c_address => c_FUNC0_ADER_2, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
-- VME64xBus_Out => VME64xBus_Out);
--
-- wait for 30 ns;
--
-- s_dataTransferType <= D08Byte3;
-- s_AddressingType <= CR_CSR;
--
-- -- Put the data to receive in the 8 lsb also if you are using D08Byte1 or D08Byte2 ecc..
-- s_dataToReceive <= x"00000000";
-- ReadCR_CSR(c_address => c_FUNC0_ADER_1, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
-- VME64xBus_Out => VME64xBus_Out);
--
-- wait for 30 ns;
--
report "START WRITE CSR";
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"00000000"; -- Put the data to send in the 8 lsb.
WriteCSR(c_address => c_BIT_CLR_REG , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
VME64xBus_Out => VME64xBus_Out);
report "END WRITE CSR";
wait for 0 ns;
report "START READ CSR";
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
-- Put the data to receive in the 8 lsb also if you are using D08Byte1 or D08Byte2 ecc..
s_dataToReceive <= x"00000000";
ReadCR_CSR(c_address => c_USR_BIT_SET_REG, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
VME64xBus_Out => VME64xBus_Out);
report "END READ CSR";
wait for 10 ns;
s_dataToReceive <= (others => '0');
wait for 10 ns;
-- report "PROVA READ CR============================================================================================================================================";
-- s_dataTransferType <= D08Byte3;
-- s_AddressingType <= CR_CSR;
-- s_dataToReceive(7 downto 0) <= c_cr_array(7);
-- wait for 10 ns;
-- assert (s_dataToReceive = x"00000043")report "FERMA" severity failure;
-- ReadCR_CSR(c_address => std_logic_vector(to_unsigned((7*4) +3, 20)), s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
-- VME64xBus_Out => VME64xBus_Out);
-- report "END PROVA READ CR";
-- report "PROVA ERROR ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????";
--
-- s_dataTransferType <= D08Byte3;
-- s_AddressingType <= CR_CSR;
--
-- -- Put the data to receive in the 8 lsb also if you are using D08Byte1 or D08Byte2 ecc..
-- s_dataToReceive <= x"00000000";
-- ReadCR_CSR(c_address => c_BIT_SET_REG, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
-- VME64xBus_Out => VME64xBus_Out);
--
-- wait for 30 ns;
--
-- s_dataTransferType <= D08Byte3;
-- s_AddressingType <= CR_CSR;
--
-- -- Put the data to receive in the 8 lsb also if you are using D08Byte1 or D08Byte2 ecc..
-- s_dataToReceive <= x"00000010";
-- ReadCR_CSR(c_address => c_BIT_SET_REG, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
-- VME64xBus_Out => VME64xBus_Out);
--
--
-- report "FINE PROVA ERROR????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????";
--
wait for 50 ns;
-- report "START READ CR";
-- s_dataTransferType <= D08Byte3;
-- s_AddressingType <= CR_CSR;
-- s_dataToReceive <= (others => '0');
-- ControlCR (s_dataTransferType => s_dataTransferType, s_AddressingType => s_AddressingType,VME64xBus_In => VME64xBus_In,s_dataToReceive => s_dataToReceive, VME64xBus_Out => VME64xBus_Out);
-- report "END READ CR";
-- The read in the CR work correctly!
-- wait for 50ns;
-- Test CRAM
report "START TEST CRAM **************************************************************************************************************";
-- The master read the CRAM_ACCESS_WIDTH
wait for 30 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToReceive <= x"00000084";
ReadCR_CSR(c_address => std_logic_vector(to_unsigned((63*4) +3, 20)), s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
VME64xBus_Out => VME64xBus_Out);
wait for 30 ns;
--The Master writes CRAM_OWNER
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"000000" & ID_Master; -- Put the data to send in the 8 lsb.
WriteCSR(c_address => c_CRAM_OWNER , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
VME64xBus_Out => VME64xBus_Out);
report "Master has written the CRAM_OWNER *************************************************************************************************";
--The Master read the CRAM_OWNER for check his ownership
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToReceive <= x"000000" & ID_Master;
ReadCR_CSR(c_address => c_CRAM_OWNER, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
VME64xBus_Out => VME64xBus_Out);
report "Master has the ownership of the CRAM memory ******************************************************************************************";
--if I'm here the Master has the ownership of the CRAM memory
-- Check if the BIT_SET_REG's bit 2 is set
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToReceive <= x"000000" & b"00000100";
ReadCR_CSR(c_address => c_BIT_SET_REG, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
VME64xBus_Out => VME64xBus_Out);
report "BIT_SET_REG's bit 2 is set ***************************************************************************************************************";
-- The Master writes one register in the CRAM space
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"000000AA";
localAddress <= x"01007";
WriteCSR(c_address => localAddress , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
VME64xBus_Out => VME64xBus_Out);
report "End write in CRAM ************************************************************************************************************************";
wait for 50 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToReceive <= x"000000AA";
-- Check the CRAM's lower limit:
--localAddress <= x"00FFF"; -- CR addressed !!!
--ReadCR_CSR(c_address => localAddress, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
-- VME64xBus_Out => VME64xBus_Out);
-- Failure; received wrong data!!
-- wait for 50 ns;
-- Check the CRAM's upper limit:
--localAddress <= x"7FFEB"; -- CSR addressed!!
--ReadCR_CSR(c_address => localAddress, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
-- VME64xBus_Out => VME64xBus_Out);
-- Failure; received wrong data!!
-- La CRAM non è indirizzata ma comunque la Main FSM percorre tutti gli stadi della lettura
-- e il dato che leggo è un dato della CR o CSR quindi leggo il dato errato.
-- wait for 50 ns;
-- read x"000000AA":
localAddress <= x"01007";
ReadCR_CSR(c_address => localAddress, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
VME64xBus_Out => VME64xBus_Out);
report "READ CRAM CORRECT **********************************************************************************************************************************************";
wait for 50 ns;
-- If i'm here without severity failure the CRAM work correctly.
-- report "CRAM access fixed correctly";
-- The Master can release the CRAM writing '0' in the BIT_SET_REG's bit 2 (or writing '1'in the BIT_CLR_REG's bit 2):
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"000000" & b"00000100";
WriteCSR(c_address => c_BIT_CLR_REG , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
VME64xBus_Out => VME64xBus_Out);
report "Master released the CRAM **********************************************************************************************************************************************";
-- Check if the CRAM_OWNER is x"00":
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToReceive <= x"00000000";
ReadCR_CSR(c_address => c_CRAM_OWNER, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
VME64xBus_Out => VME64xBus_Out);
report "END TEST CRAM *************************************************************************************************************************************************************";
-- wait for 50 ns;
-- report "START TEST Berr";
-- s_dataTransferType <= D08Byte3;
-- s_AddressingType <= error;
-- s_dataToSend <= x"000000" & b"00000100";
-- WriteCSR(c_address => c_BIT_CLR_REG , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
-- VME64xBus_Out => VME64xBus_Out);
-- I have inserted here a read procedure for test if the slave go out of the Berr status correctly
-- and check if the master can read a new data immediately, without wait.
-- s_dataTransferType <= D08Byte3;
-- s_AddressingType <= CR_CSR;
-- s_dataToReceive <= x"00000000";
-- ReadCR_CSR(c_address => c_CRAM_OWNER, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
-- VME64xBus_Out => VME64xBus_Out);
-- report "END TEST Berr";
wait for 50 ns;
report "START TEST TRANSFER DATA FROM VME TO WB";
-- Before the Master has to write the ADERs.
-- start write ADER0
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"000000" & ADER0_A16_S(31 downto 24);
WriteCSR(c_address => c_FUNC2_ADER_3 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"000000" & ADER0_A16_S(23 downto 16);
WriteCSR(c_address => c_FUNC2_ADER_2 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"000000" & ADER0_A16_S(15 downto 8);
WriteCSR(c_address => c_FUNC2_ADER_1 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"000000" & ADER0_A16_S(7 downto 0);
WriteCSR(c_address => c_FUNC2_ADER_0 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
-- start write ADER1
-- s_dataTransferType <= D08Byte3;
-- s_AddressingType <= CR_CSR;
-- s_dataToSend <= x"000000" & ADER1_A64(31 downto 24);
-- WriteCSR(c_address => c_FUNC1_ADER_3 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
-- VME64xBus_Out => VME64xBus_Out);
--
-- wait for 20 ns;
--
-- s_dataTransferType <= D08Byte3;
--
-- s_AddressingType <= CR_CSR;
--
-- s_dataToSend <= x"000000" & ADER1_A64(23 downto 16);
-- WriteCSR(c_address => c_FUNC1_ADER_2 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
-- VME64xBus_Out => VME64xBus_Out);
--
-- wait for 20 ns;
--
-- s_dataTransferType <= D08Byte3;
--
-- s_AddressingType <= CR_CSR;
--
-- s_dataToSend <= x"000000" & ADER1_A64(15 downto 8);
-- WriteCSR(c_address => c_FUNC1_ADER_1 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
-- VME64xBus_Out => VME64xBus_Out);
--
-- wait for 20 ns;
--
-- s_dataTransferType <= D08Byte3;
--
-- s_AddressingType <= CR_CSR;
--
-- s_dataToSend <= x"000000" & ADER1_A64(7 downto 0);
-- WriteCSR(c_address => c_FUNC1_ADER_0 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
-- VME64xBus_Out => VME64xBus_Out);
--
-- -- start write ADER2 (ADER1_b)
--
-- s_dataTransferType <= D08Byte3;
--
-- s_AddressingType <= CR_CSR;
--
-- s_dataToSend <= x"000000" & ADER1_A64_b(31 downto 24);
-- WriteCSR(c_address => c_FUNC2_ADER_3 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
-- VME64xBus_Out => VME64xBus_Out);
--
-- wait for 20 ns;
--
-- s_dataTransferType <= D08Byte3;
--
-- s_AddressingType <= CR_CSR;
--
-- s_dataToSend <= x"000000" & ADER1_A64_b(23 downto 16);
-- WriteCSR(c_address => c_FUNC2_ADER_2 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
-- VME64xBus_Out => VME64xBus_Out);
--
-- wait for 20 ns;
--
-- s_dataTransferType <= D08Byte3;
--
-- s_AddressingType <= CR_CSR;
--
-- s_dataToSend <= x"000000" & ADER1_A64_b(15 downto 8);
-- WriteCSR(c_address => c_FUNC2_ADER_1 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
-- VME64xBus_Out => VME64xBus_Out);
--
-- wait for 20 ns;
--
-- s_dataTransferType <= D08Byte3;
--
-- s_AddressingType <= CR_CSR;
--
-- s_dataToSend <= x"000000" & ADER1_A64_b(7 downto 0);
-- WriteCSR(c_address => c_FUNC2_ADER_0 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
-- VME64xBus_Out => VME64xBus_Out);
-- -- start write ADER3
--
-- s_dataTransferType <= D08Byte3;
--
-- s_AddressingType <= CR_CSR;
--
-- s_dataToSend <= x"000000" & ADER2_A32_2eVME(31 downto 24);
-- WriteCSR(c_address => c_FUNC3_ADER_3 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
-- VME64xBus_Out => VME64xBus_Out);
--
-- wait for 20 ns;
--
-- s_dataTransferType <= D08Byte3;
--
-- s_AddressingType <= CR_CSR;
--
-- s_dataToSend <= x"000000" & ADER2_A32_2eVME(23 downto 16);
-- WriteCSR(c_address => c_FUNC3_ADER_2 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
-- VME64xBus_Out => VME64xBus_Out);
--
-- wait for 20 ns;
--
-- s_dataTransferType <= D08Byte3;
--
-- s_AddressingType <= CR_CSR;
--
-- s_dataToSend <= x"000000" & ADER2_A32_2eVME(15 downto 8);
-- WriteCSR(c_address => c_FUNC3_ADER_1 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
-- VME64xBus_Out => VME64xBus_Out);
--
-- wait for 20 ns;
--
-- s_dataTransferType <= D08Byte3;
--
-- s_AddressingType <= CR_CSR;
--
-- s_dataToSend <= x"000000" & ADER2_A32_2eVME(7 downto 0);
-- WriteCSR(c_address => c_FUNC3_ADER_0 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
-- VME64xBus_Out => VME64xBus_Out);
-- -- start write ADER4 (ADER2_b)
--
-- s_dataTransferType <= D08Byte3;
--
-- s_AddressingType <= CR_CSR;
--
-- s_dataToSend <= x"000000" & ADER2_2e_b(31 downto 24);
-- WriteCSR(c_address => c_FUNC4_ADER_3 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
-- VME64xBus_Out => VME64xBus_Out);
--
-- wait for 20 ns;
--
-- s_dataTransferType <= D08Byte3;
--
-- s_AddressingType <= CR_CSR;
--
-- s_dataToSend <= x"000000" & ADER2_2e_b(23 downto 16);
-- WriteCSR(c_address => c_FUNC4_ADER_2 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
-- VME64xBus_Out => VME64xBus_Out);
--
-- wait for 20 ns;
--
-- s_dataTransferType <= D08Byte3;
--
-- s_AddressingType <= CR_CSR;
--
-- s_dataToSend <= x"000000" & ADER2_2e_b(15 downto 8);
-- WriteCSR(c_address => c_FUNC4_ADER_1 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
-- VME64xBus_Out => VME64xBus_Out);
--
-- wait for 20 ns;
--
-- s_dataTransferType <= D08Byte3;
--
-- s_AddressingType <= CR_CSR;
--
-- s_dataToSend <= x"000000" & ADER2_2e_b(7 downto 0);
-- WriteCSR(c_address => c_FUNC4_ADER_0 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
-- VME64xBus_Out => VME64xBus_Out);
-- check some ADER byte :
wait for 20 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToReceive <= x"000000" & c_A16 &"00";
ReadCR_CSR(c_address => c_FUNC2_ADER_0, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
report "FUNC0_ADER_0 Correct!!!!";
wait for 20 ns;
-- s_dataTransferType <= D08Byte3;
-- s_AddressingType <= CR_CSR;
--
-- s_dataToReceive <= x"000000" & c_A64 &"00";
-- ReadCR_CSR(c_address => c_FUNC1_ADER_0, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
-- VME64xBus_Out => VME64xBus_Out);
-- report "FUNC1_ADER_0 Correct!!!!";
report "THE MASTER HAS WRITTEN CORRECTLY ALL THE ADERs $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$";
-- start write BAR
--s_dataTransferType <= D08Byte3;
--s_AddressingType <= CR_CSR;
--s_dataToSend <= x"000000" & BA_MyMemory;
--WriteCSR(c_address => c_BAR , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
--s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
--VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
-- Now also for read and write the CR/
-- START WRITE IN THE WB MEMORY
report "START WRITE AND READ WB MEMORY YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY";
-- The Master check if the WB data bus as 64 bit
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToReceive <= x"00000001";
ReadCR_CSR(c_address => c_WB32or64, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
-- Module Enabled:
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"00000010";
WriteCSR(c_address => c_BIT_SET_REG , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
s_dataTransferType <= D08Byte0;
s_AddressingType <= A16;
s_dataToSend <= x"000000AB";
s_address <= x"0000000000000008";
S_Write(v_address => s_address , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 10 ns;
s_dataTransferType <= D08Byte1;
s_AddressingType <= A16;
s_dataToSend <= x"00000011";
s_address <= x"0000000000000009";
S_Write(v_address => s_address , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 10 ns;
s_dataTransferType <= D08Byte2;
s_AddressingType <= A16;
s_dataToSend <= x"00000000";
s_address <= x"000000000000000a";
S_Write(v_address => s_address , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 10 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= A16;
s_dataToSend <= x"00000022";
s_address <= x"000000000000000b";
S_Write(v_address => s_address , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 10 ns;
s_dataTransferType <= D08Byte0;
s_AddressingType <= A16;
s_dataToSend <= x"00000002";
s_address <= x"000000000000000c";
S_Write(v_address => s_address , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 10 ns;
s_dataTransferType <= D08Byte1;
s_AddressingType <= A16;
s_dataToSend <= x"00000018";
s_address <= x"000000000000000d";
S_Write(v_address => s_address , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 10 ns;
s_dataTransferType <= D08Byte2;
s_AddressingType <= A16;
s_dataToSend <= x"00000032";
s_address <= x"000000000000000e";
S_Write(v_address => s_address , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 10 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= A16;
s_dataToSend <= x"00000082";
s_address <= x"000000000000000f";
S_Write(v_address => s_address , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
report "THE MASTER HAS WRITTEN 8 byte £££££££££££££££££££££££££££££££££££££££££££££££££££££££££££££££££££££££££££££££££££££";
s_dataTransferType <= D32;
s_AddressingType <= A16;
s_address <= x"0000000000000008";
s_dataToReceive <= x"AB110022";
S_Read(v_address => s_address, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
--wait for 10 ns;
-- s_dataTransferType <= D32;
-- s_AddressingType <= A16;
-- s_address <= x"0000000000000002";
--s_dataToReceive <= x"AB";
--S_Read(v_address => s_address, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
--VME64xBus_Out => VME64xBus_Out);
wait for 10 ns;
s_dataTransferType <= D32;
s_AddressingType <= A16;
s_address <= x"000000000000000c";
s_dataToReceive <= x"02183282";
S_Read(v_address => s_address, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 10 ns;
s_dataTransferType <= D16Byte01;
s_AddressingType <= A16;
s_address <= x"0000000000000008";
s_dataToReceive <= x"0000AB11";
S_Read(v_address => s_address, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 10 ns;
s_dataTransferType <= D16Byte23;
s_AddressingType <= A16;
s_address <= x"000000000000000a";
s_dataToReceive <= x"00000022";
S_Read(v_address => s_address, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 10 ns;
s_dataTransferType <= D16Byte01;
s_AddressingType <= A16;
s_address <= x"000000000000000c";
s_dataToReceive <= x"00000218";
S_Read(v_address => s_address, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 10 ns;
s_dataTransferType <= D16Byte23;
s_AddressingType <= A16;
s_address <= x"000000000000000e";
s_dataToReceive <= x"00003282";
S_Read(v_address => s_address, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
-- wait for 10 ns;
-- s_dataTransferType <= D08Byte2;
-- s_AddressingType <= A16;
-- s_address <= x"0000000000000004";
-- s_dataToReceive <= x"00000032";
-- S_Read(v_address => s_address, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
-- VME64xBus_Out => VME64xBus_Out);
wait for 10 ns;
s_dataTransferType <= D08Byte0;
s_AddressingType <= A16;
s_address <= x"000000000000000c";
s_dataToReceive <= x"00000002";
S_Read(v_address => s_address, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 10 ns;
s_dataTransferType <= D08Byte1;
s_AddressingType <= A16;
s_address <= x"0000000000000008";
s_dataToReceive <= x"00000011";
S_Read(v_address => s_address, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 10 ns;
s_dataTransferType <= D08Byte1;
s_AddressingType <= A16;
s_address <= x"0000000000000009";
s_dataToReceive <= x"00000011";
S_Read(v_address => s_address, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
report "THE MASTER HAS RED CORRECTLY ALL THE BYTES PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP";
-- wait for 10 ns;
-- s_dataTransferType <= D08Byte3;
-- s_AddressingType <= A16;
-- s_address <= x"0000000000000002";
-- s_dataToReceive <= x"00000022";
-- S_Read(v_address => s_address, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
-- VME64xBus_Out => VME64xBus_Out);
-- The Byte x"22" is put in the DTB's bits 7-0
wait for 10 ns;
-- wait for 10 ns;
s_dataTransferType <= D16Byte01;
s_AddressingType <= A16;
s_dataToSend <= x"00001308";
s_address <= x"0000000000000008";
S_Write(v_address => s_address , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 10 ns;
s_dataTransferType <= D16Byte23;
s_AddressingType <= A16;
s_dataToSend <= x"00001987";
s_address <= x"000000000000000A";
S_Write(v_address => s_address , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 10 ns;
s_dataTransferType <= D32;
s_AddressingType <= A16;
s_dataToSend <= x"56781234";
s_address <= x"0000000000000014";
S_Write(v_address => s_address , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 10 ns;
s_dataTransferType <= D16Byte01;
s_AddressingType <= A16;
s_address <= x"0000000000000008";
s_dataToReceive <= x"00001308";
S_Read(v_address => s_address, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 10 ns;
s_dataTransferType <= D32;
s_AddressingType <= A16;
s_address <= x"0000000000000014";
s_dataToReceive <= x"56781234";
S_Read(v_address => s_address, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- The Master write again the ADER 1 for access with A24 mode!
wait for 20 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"000000" & ADER0_A24_S(31 downto 24);
WriteCSR(c_address => c_FUNC1_ADER_3 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"000000" & ADER0_A24_S(23 downto 16);
WriteCSR(c_address => c_FUNC1_ADER_2 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"000000" & ADER0_A24_S(15 downto 8);
WriteCSR(c_address => c_FUNC1_ADER_1 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"000000" & ADER0_A24_S(7 downto 0);
WriteCSR(c_address => c_FUNC1_ADER_0 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 10 ns;
-- write a new value for test A24 mode
s_dataTransferType <= D32;
s_AddressingType <= A24;
s_dataToSend <= x"33221100";
s_address <= x"0000000000000018";
S_Write(v_address => s_address , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 10 ns;
s_dataTransferType <= D32;
s_AddressingType <= A24;
s_dataToSend <= x"08080808";
s_address <= x"000000000000001c";
S_Write(v_address => s_address , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 10 ns;
s_dataTransferType <= D32;
s_AddressingType <= A24;
s_address <= x"0000000000000018";
s_dataToReceive <= x"33221100";
S_Read(v_address => s_address, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 10 ns;
s_dataTransferType <= D16Byte01;
s_AddressingType <= A24;
s_address <= x"000000000000001c";
s_dataToReceive <= x"00000808";
S_Read(v_address => s_address, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 10 ns;
s_dataTransferType <= D08Byte0;
s_AddressingType <= A24;
s_address <= x"000000000000001c";
s_dataToReceive <= x"00000008";
S_Read(v_address => s_address, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 10 ns;
s_dataTransferType <= D08Byte2;
s_AddressingType <= A24;
s_address <= x"000000000000001a";
s_dataToReceive <= x"00000011";
S_Read(v_address => s_address, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
-- A32 mode tested on board
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- START TEST BLT TRANSFER
for i in 64 downto 1 loop
s_Buffer_BLT(i) <= (others => '0');
end loop;
s_Buffer_BLT(0) <= x"12345678";
s_Buffer_BLT(1) <= x"23456781";
s_Buffer_BLT(2) <= x"34567812";
s_Buffer_BLT(3) <= x"45678123";
s_Buffer_BLT(4) <= x"56781234";
s_Buffer_BLT(5) <= x"67812345";
s_Buffer_BLT(6) <= x"78123456";
s_Buffer_BLT(7) <= x"81234567";
s_Buffer_BLT(8) <= x"12345678";
s_Buffer_BLT(9) <= x"23456781";
s_Buffer_BLT(10) <= x"34567812";
s_Buffer_BLT(11) <= x"45678123";
s_Buffer_BLT(12) <= x"56781234";
s_Buffer_BLT(13) <= x"67812345";
s_Buffer_BLT(14) <= x"78123456";
s_Buffer_BLT(15) <= x"81234567";
s_Buffer_BLT(16) <= x"12345678";
s_Buffer_BLT(17) <= x"23456781";
s_Buffer_BLT(18) <= x"34567812";
s_Buffer_BLT(19) <= x"45678123";
s_Buffer_BLT(20) <= x"56781234";
s_Buffer_BLT(21) <= x"67812345";
s_Buffer_BLT(22) <= x"78123456";
s_Buffer_BLT(23) <= x"81234567";
s_Buffer_BLT(24) <= x"12345678";
s_Buffer_BLT(25) <= x"23456781";
s_Buffer_BLT(26) <= x"34567812";
s_Buffer_BLT(27) <= x"45678123";
s_Buffer_BLT(28) <= x"56781234";
s_Buffer_BLT(29) <= x"67812345";
s_Buffer_BLT(30) <= x"78123456";
s_Buffer_BLT(31) <= x"81234567";
s_Buffer_BLT(32) <= x"12345678";
s_Buffer_BLT(33) <= x"23456781";
s_Buffer_BLT(34) <= x"34567812";
s_Buffer_BLT(35) <= x"45678123";
s_Buffer_BLT(36) <= x"56781234";
s_Buffer_BLT(37) <= x"67812345";
s_Buffer_BLT(38) <= x"78123456";
s_Buffer_BLT(39) <= x"81234567";
s_Buffer_BLT(40) <= x"12345678";
s_Buffer_BLT(41) <= x"23456781";
s_Buffer_BLT(42) <= x"34567812";
s_Buffer_BLT(43) <= x"45678123";
s_Buffer_BLT(44) <= x"56781234";
s_Buffer_BLT(45) <= x"67812345";
s_Buffer_BLT(46) <= x"78123456";
s_Buffer_BLT(47) <= x"81234567";
s_Buffer_BLT(48) <= x"23456781";
s_Buffer_BLT(49) <= x"34567812";
s_Buffer_BLT(50) <= x"45678123";
s_Buffer_BLT(51) <= x"56781234";
s_Buffer_BLT(52) <= x"67812345";
s_Buffer_BLT(53) <= x"78123456";
s_Buffer_BLT(54) <= x"81234567";
s_Buffer_BLT(55) <= x"12345678";
s_Buffer_BLT(56) <= x"23456781";
s_Buffer_BLT(57) <= x"34567812";
s_Buffer_BLT(58) <= x"45678123";
s_Buffer_BLT(59) <= x"56781234";
s_Buffer_BLT(60) <= x"67812345";
s_Buffer_BLT(61) <= x"78123456";
s_Buffer_BLT(62) <= x"81234567";
s_Buffer_BLT(63) <= x"56781234";
s_Buffer_BLT(64) <= x"67812345";
s_Buffer_BLT(65) <= x"78123456";
---the master write the ADER 0:
wait for 20 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"000000" & ADER0_A32_BLT(31 downto 24);
WriteCSR(c_address => c_FUNC0_ADER_3 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"000000" & ADER0_A32_BLT(23 downto 16);
WriteCSR(c_address => c_FUNC0_ADER_2 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"000000" & ADER0_A32_BLT(15 downto 8);
WriteCSR(c_address => c_FUNC0_ADER_1 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"000000" & ADER0_A32_BLT(7 downto 0);
WriteCSR(c_address => c_FUNC0_ADER_0 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
s_dataTransferType <= D32; --only D32 is possible with BLT transfer
s_AddressingType <= A32_BLT;
s_address <= x"0000000000000010";
s_num <= "100000001"; --Number of access; (max 64)
Blt_write(v_address => s_address, s_Buffer_BLT => s_Buffer_BLT,
s_dataTransferType => s_dataTransferType, s_AddressingType => s_AddressingType,
num => s_num, VME64xBus_In => VME64xBus_In, VME64xBus_Out => VME64xBus_Out);
wait for 10 ns;
s_address <= x"0000000000000010"; -- use n+1 inside the function if I start to read from the second D32 word written
s_num <= "000000100";
Blt_Read(v_address => s_address, s_Buffer_BLT => s_Buffer_BLT,
s_dataTransferType => s_dataTransferType, s_AddressingType => s_AddressingType,
num => s_num, VME64xBus_In => VME64xBus_In, VME64xBus_Out => VME64xBus_Out);
-- Check error condition:
wait for 10 ns;
s_dataTransferType <= D08Byte3; --only D32 is possible with BLT transfer
s_AddressingType <= A32_BLT;
s_address <= x"0000000000000010";
s_num <= "000000100";
Blt_Read(v_address => s_address, s_Buffer_BLT => s_Buffer_BLT,
s_dataTransferType => s_dataTransferType, s_AddressingType => s_AddressingType,
num => s_num, VME64xBus_In => VME64xBus_In, VME64xBus_Out => VME64xBus_Out);
-- START TEST MBLT:
---the master write the ADER 0:
wait for 20 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"000000" & ADER0_A32_MBLT(31 downto 24);
WriteCSR(c_address => c_FUNC0_ADER_3 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"000000" & ADER0_A32_MBLT(23 downto 16);
WriteCSR(c_address => c_FUNC0_ADER_2 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"000000" & ADER0_A32_MBLT(15 downto 8);
WriteCSR(c_address => c_FUNC0_ADER_1 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"000000" & ADER0_A32_MBLT(7 downto 0);
WriteCSR(c_address => c_FUNC0_ADER_0 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
-- ADER0 written
wait for 20 ns;
for i in 256 downto 0 loop
s_Buffer_MBLT(i) <= (others => '0');
end loop;
s_Buffer_MBLT(0) <= x"0123456789ABCDEF";
s_Buffer_MBLT(1) <= x"123456789ABCDEF0";
s_Buffer_MBLT(2) <= x"23456789ABCDEF01";
s_Buffer_MBLT(3) <= x"3456789ABCDEF012";
s_Buffer_MBLT(4) <= x"456789ABCDEF0123";
s_Buffer_MBLT(5) <= x"56789ABCDEF01234";
s_Buffer_MBLT(6) <= x"6789ABCDEF012345";
s_Buffer_MBLT(7) <= x"789ABCDEF0123456";
s_dataTransferType <= D32; -- Data transfer type is D32 also if the data width is 64!!
s_AddressingType <= A32_MBLT;
s_address <= x"0000000000000010"; --Put here a multiple of 8!!!
s_num <= "000001000"; -- max 256;
Mblt_write(v_address => s_address, s_Buffer_MBLT => s_Buffer_MBLT, -- this procedure is for A16, A24, A32 address type
s_dataTransferType => s_dataTransferType, s_AddressingType => s_AddressingType, num => s_num,
VME64xBus_In => VME64xBus_in, VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToReceive <= x"00000040";
ReadCR_CSR(c_address => c_BYTES0, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
VME64xBus_Out => VME64xBus_Out);
s_dataTransferType <= D32; -- Data transfer type is D32 also if the data width is 64!!
s_AddressingType <= A32_MBLT;
s_address <= x"0000000000000010"; --Put here a multiple of 8!!!
s_num <= "000000011"; -- max 256;
Mblt_Read(v_address => s_address, s_Buffer_MBLT => s_Buffer_MBLT, -- this procedure is for A16, A24, A32 address type
s_dataTransferType => s_dataTransferType, s_AddressingType => s_AddressingType, num => s_num,
VME64xBus_In => VME64xBus_in, VME64xBus_Out => VME64xBus_Out);
for i in 1 downto 0 loop
Mblt_Read(v_address => s_address, s_Buffer_MBLT => s_Buffer_MBLT, -- this procedure is for A16, A24, A32 address type
s_dataTransferType => s_dataTransferType, s_AddressingType => s_AddressingType, num => s_num,
VME64xBus_In => VME64xBus_in, VME64xBus_Out => VME64xBus_Out);
end loop;
-- Test Error condition: The Master can't access with s_AddressingType <= MBLT and Data transfer type /= D32
wait for 20 ns;
s_dataTransferType <= D16Byte01; -- Data transfer type is D32 also if the data width is 64!!
s_AddressingType <= A32_MBLT;
s_address <= x"0000000000000010"; --Put here a multiple of 8!!!
s_num <= "000000100"; -- max 256;
Mblt_Read(v_address => s_address, s_Buffer_MBLT => s_Buffer_MBLT, -- this procedure is for A16, A24, A32 address type
s_dataTransferType => s_dataTransferType, s_AddressingType => s_AddressingType, num => s_num,
VME64xBus_In => VME64xBus_in, VME64xBus_Out => VME64xBus_Out);
-- The master can't access at more than 256 locations (2048 Bytes)
wait for 20 ns;
s_dataTransferType <= D32; -- Data transfer type is D32 also if the data width is 64!!
s_AddressingType <= A32_MBLT;
s_address <= x"0000000000000000"; --Put here a multiple of 8!!!
s_num <= "100000001"; -- max 256;
Mblt_write(v_address => s_address, s_Buffer_MBLT => s_Buffer_MBLT, -- this procedure is for A16, A24, A32 address type
s_dataTransferType => s_dataTransferType, s_AddressingType => s_AddressingType, num => s_num,
VME64xBus_In => VME64xBus_in, VME64xBus_Out => VME64xBus_Out);
--A24 MBLT
--the master write the ADER 0:
wait for 20 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"000000" & ADER0_A24_MBLT(31 downto 24);
WriteCSR(c_address => c_FUNC1_ADER_3 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"000000" & ADER0_A24_MBLT(23 downto 16);
WriteCSR(c_address => c_FUNC1_ADER_2 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"000000" & ADER0_A24_MBLT(15 downto 8);
WriteCSR(c_address => c_FUNC1_ADER_1 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"000000" & ADER0_A24_MBLT(7 downto 0);
WriteCSR(c_address => c_FUNC1_ADER_0 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
-- ADER0 written
s_dataTransferType <= D32; -- Data transfer type is D32 also if the data width is 64!!
s_AddressingType <= A24_MBLT;
s_address <= x"0000000000000008"; --Put here a multiple of 8!!!
s_num <= "000000100"; -- max 256;
Mblt_Read(v_address => s_address, s_Buffer_MBLT => s_Buffer_MBLT, -- this procedure is for A16, A24, A32 address type
s_dataTransferType => s_dataTransferType, s_AddressingType => s_AddressingType, num => s_num,
VME64xBus_In => VME64xBus_in, VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
report "Start Test Interrupter";
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"000000" & ADER0_A32(31 downto 24);
WriteCSR(c_address => c_FUNC0_ADER_3 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"000000" & ADER0_A32(23 downto 16);
WriteCSR(c_address => c_FUNC0_ADER_2 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"000000" & ADER0_A32(15 downto 8);
WriteCSR(c_address => c_FUNC0_ADER_1 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"000000" & ADER0_A32(7 downto 0);
WriteCSR(c_address => c_FUNC0_ADER_0 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
-- The master write IRQ_Level register
wait for 10 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"00000002";
WriteCSR(c_address => c_IRQ_level , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
-- The master write IRQ_Vector register
wait for 10 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"000000b4";
--s_address <= x"0000000000000000";
WriteCSR(c_address => c_IRQ_Vector , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 10 ns;
--Test if the daisy chaine is working;
-- s_dataTransferType <= D32;
-- s_AddressingType <= A32;
-- s_dataToReceive <= x"00000003";
-- Interrupt_Handler(VME64xBus_In => VME64xBus_In,VME64xBus_Out => VME64xBus_Out,s_dataToReceive => s_dataToReceive,
-- s_dataTransferType => s_dataTransferType, s_AddressingType => s_AddressingType);
--
--The master write FREQ register in the RAM
wait for 10 ns;
s_dataTransferType <= D32;
s_AddressingType <= A32;
s_dataToSend <= x"00000010";
s_address <= x"0000000000000004";
S_Write(v_address => s_address , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
s_dataTransferType <= D32;
s_AddressingType <= A32;
s_dataToReceive <= x"00000003";
Interrupt_Handler(VME64xBus_In => VME64xBus_In,VME64xBus_Out => VME64xBus_Out,s_dataToReceive => s_dataToReceive,
s_dataTransferType => s_dataTransferType, s_AddressingType => s_AddressingType);
wait for 10 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"00000090";
--s_address <= x"0000000000000000";
WriteCSR(c_address => c_BIT_SET_REG , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 8800 ns;
-- s_dataTransferType <= D08Byte3;
--
-- s_AddressingType <= CR_CSR;
--
-- s_dataToSend <= x"000000" & ADER0_A32(31 downto 24);
-- WriteCSR(c_address => c_FUNC0_ADER_3 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
-- VME64xBus_Out => VME64xBus_Out);
--
-- wait for 20 ns;
--
-- s_dataTransferType <= D08Byte3;
--
-- s_AddressingType <= CR_CSR;
--
-- s_dataToSend <= x"000000" & ADER0_A32(23 downto 16);
-- WriteCSR(c_address => c_FUNC0_ADER_2 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
-- VME64xBus_Out => VME64xBus_Out);
--
-- wait for 20 ns;
--
-- s_dataTransferType <= D08Byte3;
-- s_AddressingType <= CR_CSR;
--
-- s_dataToSend <= x"000000" & ADER0_A32(15 downto 8);
-- WriteCSR(c_address => c_FUNC0_ADER_1 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
-- VME64xBus_Out => VME64xBus_Out);
--
-- wait for 20 ns;
--
-- s_dataTransferType <= D08Byte3;
--
-- s_AddressingType <= CR_CSR;
--
-- s_dataToSend <= x"000000" & ADER0_A32(7 downto 0);
-- WriteCSR(c_address => c_FUNC0_ADER_0 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
-- VME64xBus_Out => VME64xBus_Out);
--
--
-- wait for 100 ns;
-- s_dataTransferType <= D32;
--
-- s_AddressingType <= A32;
--
-- s_dataToSend <= x"00000010";
-- s_address <= x"0000000000000004";
--
-- S_Write(v_address => s_address , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
-- VME64xBus_Out => VME64xBus_Out);
--
--
-- -- The Master change the Int Level
-- wait for 1000 ns;
-- s_dataTransferType <= D08Byte3;
--
-- s_AddressingType <= CR_CSR;
--
-- s_dataToSend <= x"00000003";
-- --s_address <= x"0000000000000000";
--
-- WriteCSR(c_address => c_IRQ_level , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
-- VME64xBus_Out => VME64xBus_Out);
--Check if the falling edge is passed on the IACKOUT daisy chain
--_____________________________________________________________________________________________________________________________________
--TEST A64
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"00000010";
WriteCSR(c_address => c_BIT_SET_REG , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"000000" & BA;
WriteCSR(c_address => c_FUNC4_ADER_3 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"00000000";
WriteCSR(c_address => c_FUNC4_ADER_2 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"00000000";
WriteCSR(c_address => c_FUNC4_ADER_1 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"00000000";
WriteCSR(c_address => c_FUNC4_ADER_0 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"00000000";
WriteCSR(c_address => c_FUNC3_ADER_3 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"00000000";
WriteCSR(c_address => c_FUNC3_ADER_2 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"00000000";
WriteCSR(c_address => c_FUNC3_ADER_1 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"00000004";
WriteCSR(c_address => c_FUNC3_ADER_0 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
s_dataTransferType <= D32;
s_AddressingType <= A64;
s_dataToSend <= x"00000003";
s_address <= x"0000000000000008";
A64S_Write(v_address => s_address , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 10 ns;
s_dataTransferType <= D08Byte0;
s_AddressingType <= A64;
s_dataToSend <= x"00000005";
s_address <= x"000000000000000c";
A64S_Write(v_address => s_address , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 10 ns;
s_dataTransferType <= D08Byte1;
s_AddressingType <= A64;
s_dataToSend <= x"00000006";
s_address <= x"000000000000000d";
A64S_Write(v_address => s_address , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 10 ns;
s_dataTransferType <= D08Byte2;
s_AddressingType <= A64;
s_dataToSend <= x"00000007";
s_address <= x"000000000000000e";
A64S_Write(v_address => s_address , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 10 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= A64;
s_dataToSend <= x"00000008";
s_address <= x"000000000000000f";
A64S_Write(v_address => s_address , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 10 ns;
s_dataTransferType <= D32;
s_AddressingType <= A64;
s_address <= x"0000000000000008";
s_dataToReceive <= x"00000003";
A64S_Read(v_address => s_address, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 10 ns;
s_dataTransferType <= D16Byte01;
s_AddressingType <= A64;
s_address <= x"000000000000000c";
s_dataToReceive <= x"00000506";
A64S_Read(v_address => s_address, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 10 ns;
s_dataTransferType <= D16Byte23;
s_AddressingType <= A64;
s_address <= x"000000000000000e";
s_dataToReceive <= x"00000708";
A64S_Read(v_address => s_address, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
-- Test A64 BLT
s_dataTransferType <= D32; --only D32 is possible with BLT transfer
s_AddressingType <= A64_BLT;
s_address <= x"0000000000000010";
s_num <= "000000011"; --Number of access; (max 64)
A64Blt_write(v_address => s_address, s_Buffer_BLT => s_Buffer_BLT,
s_dataTransferType => s_dataTransferType, s_AddressingType => s_AddressingType,
num => s_num, VME64xBus_In => VME64xBus_In, VME64xBus_Out => VME64xBus_Out);
wait for 10 ns;
s_dataTransferType <= D32; --only D32 is possible with BLT transfer
s_AddressingType <= A64_BLT;
s_address <= x"0000000000000010";
s_num <= "000000011"; --Number of access; (max 64)
A64Blt_Read(v_address => s_address, s_Buffer_BLT => s_Buffer_BLT,
s_dataTransferType => s_dataTransferType, s_AddressingType => s_AddressingType,
num => s_num, VME64xBus_In => VME64xBus_In, VME64xBus_Out => VME64xBus_Out);
wait for 30 ns;
s_dataTransferType <= D32; -- Data transfer type is D32 also if the data width is 64!!
s_AddressingType <= A64_MBLT;
s_address <= x"0000000000000020"; --Put here a multiple of 8!!!
s_num <= "000000011"; -- max 256;
A64Mblt_write(v_address => s_address, s_Buffer_MBLT => s_Buffer_MBLT, -- this procedure is for A16, A24, A32 address type
s_dataTransferType => s_dataTransferType, s_AddressingType => s_AddressingType, num => s_num,
VME64xBus_In => VME64xBus_in, VME64xBus_Out => VME64xBus_Out);
wait for 30 ns;
s_dataTransferType <= D32; -- Data transfer type is D32 also if the data width is 64!!
s_AddressingType <= A64_MBLT;
s_address <= x"0000000000000020"; --Put here a multiple of 8!!!
s_num <= "000000011"; -- max 256;
A64Mblt_Read(v_address => s_address, s_Buffer_MBLT => s_Buffer_MBLT, -- this procedure is for A16, A24, A32 address type
s_dataTransferType => s_dataTransferType, s_AddressingType => s_AddressingType, num => s_num,
VME64xBus_In => VME64xBus_in, VME64xBus_Out => VME64xBus_Out);
wait for 30 ns;
s_dataTransferType <= D16Byte01; --only D32 is possible with BLT transfer
s_AddressingType <= A64_BLT;
s_address <= x"0000000000000010";
s_num <= "000000011"; --Number of access; (max 64)
A64Blt_write(v_address => s_address, s_Buffer_BLT => s_Buffer_BLT,
s_dataTransferType => s_dataTransferType, s_AddressingType => s_AddressingType,
num => s_num, VME64xBus_In => VME64xBus_In, VME64xBus_Out => VME64xBus_Out);
--__________________________________________________________________________________________________________________________________________
--
-- s_dataTransferType <= D08Byte3;
--
-- s_AddressingType <= CR_CSR;
--
-- s_dataToSend <= x"000000" & ADER2_A32_2eVME(31 downto 24);
-- WriteCSR(c_address => c_FUNC5_ADER_3 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
-- s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
-- VME64xBus_Out => VME64xBus_Out);
--
--
-- s_AddressingType <= A32_2eVME;
-- s_beat_count <= "00001000";
-- s_address <= x"0000000000000010";
-- TWOeVME_write(v_address => s_address, s_Buffer_MBLT => s_Buffer_MBLT,
-- s_AddressingType => s_AddressingType,
-- v_beat_count => s_beat_count, VME64xBus_In => VME64xBus_In, VME64xBus_Out => VME64xBus_Out);
--
-- wait for 30 ns;
-- s_AddressingType <= A64_2eVME;
-- s_beat_count <= "00001000";
-- s_address <= x"0000000000000010";
-- TWOeVME_read(v_address => s_address, s_Buffer_MBLT => s_Buffer_MBLT,
-- s_AddressingType => s_AddressingType,
-- v_beat_count => s_beat_count, VME64xBus_In => VME64xBus_In, VME64xBus_Out => VME64xBus_Out);
--
report "FINE///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////";
-- VME_BBSY_n_i not used in the VME Slave core...however in the reset process I drive low the VME_BBSY_n_i.
-- Inded when a master access the DTB he drives low the BBSY signals.
-- The VME_CSR_pack define an array of constants used during the initialized.
-- The two procedure above mentioned are be made for test a simple read and write in the csr.
-- I have red all the rule for a simple read and write in the VME bus specifications book and
-- the slave is working correctly and respect the timing rule.
-- Oversampled the AS, DS ecc.. signals is necessary for respect these timing rules.
-- The master can terminate the single cycle driving AS and DS high at the same time and between two
-- call to procedures it is not necessary insert a wait statement.
-- Single read and write cycles duration is: 175 ns --> about 5,7 MB/s.
-- The CSR memory is accessible by Single read and write with data type D08Byte1, D08Byte0,
-- D08Byte2, D08Byte3.
-- ControlCR --> This procedure reads the CR memory and check if the Master reads correctly
-- the values located in the VME_CR_package.
-- The CR memory is internal at the FPGA; In the VME_CR_pack are defined
-- the values of the CR's registers, and at the start up the VME slave core reads some of
-- these registers and save them in local signals; during the initialization the slave has to
-- save in the local registers only the BEG_USER_CR, END_USER_CR, BEG_CRAM, END_CRAM, BEG_USER_CSR, END_USER_CSR,
-- FUNC_AMCAP, FUNC_XAMCAP, FUNC_ADEM that are used in the decode phase.
-- The ROM is implemented by the package above mentioned and it is internal at the VME_bus
-- component; if will be used an IP core external at the VME_bus component the code has to be reported
-- at the original form, as well as before of my modifies
-- Nella CR i dati sono salvati in notazione LITTLE ENDIAN cioè i bit più significativi sono nelle locazioni di memoria più basse!!
--
-- CRAM_owner --> il master prende la ownership scrivendo il suo ID nel CRAM_OWNER e la rilascia scrivendo 0 nel bit 2 del BIT_SET_REG!!
-- Prima di scrivere nella CRAM fare scrittura ID nel CRAM_OWNER, poi leggerlo e confrontare l'ID per check ownership.
-- creare costante con ID del Master.
-- TEST CRAM ESEGUITO CORRETTAMENTE.
-- If the slave is not correct address and s_confAccess remain '0' the slave can't assert the VME_Berr line
-- becouse others slaves can be addressed!!
-- modified the assertion of VME_Berr;is important to be sure that the main fsm don't arrive at the MEMORY_REQ
-- state if there is an error; in this way the possibility of a wrong write is excluded.
-- A read in a wrong address is not dangerous for the slave and the master receiving a Berr signals don't will latch the data.
-- Transfer data from VME to WB fixed correctly for the Single mode transfer.
-- I have add some mux because he single read and write don't need of the FIFO memory.
-- So I have add a register in the DAT_i for to be sure that the pipelined modality is supported by
-- the core.
-- The BITSETREGISTER's "enable module" bit (bit 4) work correctly; with this bit not asserted the access at the wb bus is impossible.
-- In the BLT the VME_bus transfer the datas in/from the FIFO with the pipelined single write/read mode
-- (see the cyc_o signal). the transfer data from the FIFO to wb slave will be done in block read/write pipelined mode.
-- In single read and write mode if the FIFO is not initialized you can seen 'U' values in slave1_i.adr, slave1_i.sel, slave1_i.dat.
wait;
--inserire qui tutte le chiamate a procedure
end process;
-- Stimulus process------------RESET, BBSY, IACKIN, VME_GA
reset_proc: process
begin
-- hold reset state for 100 ns.
VME_RST_n_i <= '1';
VME_GA_i <= VME_GA;
wait for 50 ns;
VME_RST_n_i <= '0';
wait for 50 ns;
VME_RST_n_i <= '1';
wait;
end process;
END;
-- SPDX-FileCopyrightText: 2022 CERN (home.cern)
--
-- SPDX-License-Identifier: CERN-OHL-W-2.0+
--------------------------------------------------------------------------------
library ieee;
library std;
library work;
use ieee.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
use IEEE.numeric_std.all;
use IEEE.numeric_std.unsigned;
use work.VME_CR_pack.all;
use work.VME_CSR_pack.all;
use work.VME64xSim.all;
use work.VME64x.all;
use work.wishbone_pkg.all;
use std.textio.all;
use work.vme64x_pack.all;
entity vme64x_ddr_tb is
end vme64x_ddr_tb;
architecture behavior of vme64x_ddr_tb is
-- Component Declaration for the Unit Under Test (UUT)
------------------------------------------------------------------------------
-- Top level
------------------------------------------------------------------------------
component svec_afpga_top
generic(
g_CARRIER_TYPE : std_logic_vector(15 downto 0) := X"0002";
g_BITSTREAM_TYPE : std_logic_vector(31 downto 0) := X"00002222";
g_BITSTREAM_DATE : std_logic_vector(31 downto 0) := X"4FE9BABD";
g_SIMULATION : string := "FALSE";
g_CALIB_SOFT_IP : string := "TRUE");
port
(
------------------------------------------
-- VME interface
------------------------------------------
vme_write_n_i : in std_logic;
vme_sysreset_n_i : in std_logic;
-- vme_sysclk_i : in std_logic;
vme_retry_oe_o : out std_logic;
vme_retry_n_o : out std_logic;
vme_lword_n_b : inout std_logic;
vme_iackout_n_o : out std_logic;
vme_iackin_n_i : in std_logic;
vme_iack_n_i : in std_logic;
vme_gap_n_i : in std_logic;
vme_dtack_oe_o : out std_logic;
vme_dtack_n_o : out std_logic;
vme_ds_n_i : in std_logic_vector(1 downto 0);
vme_d_oe_n_o : out std_logic;
vme_d_dir_o : out std_logic;
vme_berr_o : out std_logic;
vme_as_n_i : in std_logic;
vme_a_oe_n_o : out std_logic;
vme_a_dir_o : out std_logic;
vme_irq_n_o : out std_logic_vector(7 downto 1);
vme_ga_i : in std_logic_vector(4 downto 0);
vme_d_b : inout std_logic_vector(31 downto 0);
vme_am_i : in std_logic_vector(5 downto 0);
vme_a_b : inout std_logic_vector(31 downto 1);
------------------------------------------
-- Clock and reset inputs
------------------------------------------
rst_n_i : in std_logic;
clk20_vcxo_i : in std_logic;
-- fpga_clk_n_i : in std_logic;
-- fpga_clk_p_i : in std_logic;
-- si57x_clk_n_i : in std_logic;
-- si57x_clk_p_i : in std_logic;
-- pll_2afpga_n_i : in std_logic;
-- pll_2afpga_p_i : in std_logic;
------------------------------------------
-- Switches and button
------------------------------------------
-- pushbutton_i : in std_logic;
-- noga_i : in std_logic_vector(4 downto 0);
-- switch_i : in std_logic_vector(1 downto 0);
-- usega_i : in std_logic;
------------------------------------------
-- Inter-FPGA lines
------------------------------------------
-- rsvd_b : inout std_logic_vector(7 downto 0);
------------------------------------------
-- PCB revision
------------------------------------------
pcbrev_i : in std_logic_vector(4 downto 0);
------------------------------------------
-- SFP slot
------------------------------------------
-- sfprx_123_n_i : in std_logic;
-- sfprx_123_p_i : in std_logic;
-- sfptx_123_n_o : out std_logic;
-- sfptx_123_p_o : out std_logic;
-- gtp_ck1_p_i : in std_logic;
-- gtp_ck1_n_i : in std_logic;
-- wr_los_i : in std_logic;
-- wr_moddef0_i : in std_logic;
-- wr_moddef1_o : out std_logic;
-- wr_moddef2_b : inout std_logic;
-- wr_rateselect_o : out std_logic;
-- wr_txdisable_o : out std_logic;
-- wr_txfault_i : in std_logic;
------------------------------------------
-- SATA connectors
------------------------------------------
-- sata1_tx_p_o : out std_logic;
-- sata1_tx_n_o : out std_logic;
-- sata1_rx_p_i : in std_logic;
-- sata1_rx_n_i : in std_logic;
-- sata0_tx_p_o : out std_logic;
-- sata0_tx_n_o : out std_logic;
-- sata0_rx_p_i : in std_logic;
-- sata0_rx_n_i : in std_logic;
-- gtp_ck0_p_i : in std_logic;
-- gtp_ck0_n_i : in std_logic;
------------------------------------------
-- PCIe interface (optional)
------------------------------------------
-- pcie_tx1_p_o : out std_logic;
-- pcie_tx1_n_o : out std_logic;
-- pcie_rx1_p_i : in std_logic;
-- pcie_rx1_n_i : in std_logic;
-- pcie_master_clk_p_i : in std_logic;
-- pcie_master_clk_n_i : in std_logic;
------------------------------------------
-- Clock controls
------------------------------------------
-- oe_si57x_o : out std_logic;
-- si57x_scl_o : out std_logic;
-- si57x_sda_b : inout std_logic;
-- si57x_tune_o : out std_logic; -- (optional)
-- pll20dac_din_o : out std_logic;
-- pll20dac_sclk_o : out std_logic;
-- pll20dac_sync_n_o : out std_logic;
-- pll25dac_din_o : out std_logic;
-- pll25dac_sclk_o : out std_logic;
-- pll25dac_sync_n_o : out std_logic;
------------------------------------------
-- UART
------------------------------------------
-- uart_rxd_o : out std_logic;
-- uart_txd_i : in std_logic;
------------------------------------------
-- USB (optional)
------------------------------------------
-- usb_clkout_i : in std_logic;
-- usb_oe_n_o : out std_logic;
-- usb_rd_n_o : out std_logic;
-- usb_rxf_n_i : in std_logic;
-- usb_siwua_i : in std_logic;
-- usb_txe_n_i : in std_logic;
-- usb_wr_n_o : out std_logic;
-- usb_d_b : inout std_logic_vector(7 downto 0);
-- io7_i : in std_logic;
------------------------------------------
-- VME P2
------------------------------------------
-- p2_data_p_b : inout std_logic_vector(19 downto 0);
-- p2_data_n_b : inout std_logic_vector(19 downto 0);
------------------------------------------
-- DDR3 (bank 4)
------------------------------------------
--ddr_we_n_o : out std_logic;
--ddr_udqs_p_b : inout std_logic;
--ddr_udqs_n_b : inout std_logic;
--ddr_udm_o : out std_logic;
--ddr_reset_n_o : out std_logic;
--ddr_ras_n_o : out std_logic;
--ddr_odt_o : out std_logic;
--ddr_ldqs_p_b : inout std_logic;
--ddr_ldqs_n_b : inout std_logic;
--ddr_ldm_o : out std_logic;
--ddr_cke_o : out std_logic;
--ddr_ck_p_o : out std_logic;
--ddr_ck_n_o : out std_logic;
--ddr_cas_n_o : out std_logic;
--ddr_dq_b : inout std_logic_vector(15 downto 0);
--ddr_ba_o : out std_logic_vector(2 downto 0);
--ddr_a_o : out std_logic_vector(13 downto 0);
--ddr_zio_b : inout std_logic;
--ddr_rzq_b : inout std_logic;
------------------------------------------
-- DDR3 (bank 5)
------------------------------------------
ddr_2_we_n_o : out std_logic;
ddr_2_udqs_p_b : inout std_logic;
ddr_2_udqs_n_b : inout std_logic;
ddr_2_udm_o : out std_logic;
ddr_2_reset_n_o : out std_logic;
ddr_2_ras_n_o : out std_logic;
ddr_2_odt_o : out std_logic;
ddr_2_ldqs_p_b : inout std_logic;
ddr_2_ldqs_n_b : inout std_logic;
ddr_2_ldm_o : out std_logic;
ddr_2_cke_o : out std_logic;
ddr_2_ck_p_o : out std_logic;
ddr_2_ck_n_o : out std_logic;
ddr_2_cas_n_o : out std_logic;
ddr_2_dq_b : inout std_logic_vector(15 downto 0);
ddr_2_ba_o : out std_logic_vector(2 downto 0);
ddr_2_a_o : out std_logic_vector(13 downto 0);
ddr_2_zio_b : inout std_logic;
ddr_2_rzq_b : inout std_logic;
------------------------------------------
-- FMC slot 1
------------------------------------------
-- fmc1_gbtclk0m2c_p_i : in std_logic;
-- fmc1_gbtclk0m2c_n_i : in std_logic;
-- fmc1_dp0m2c_p_i : in std_logic;
-- fmc1_dp0m2c_n_i : in std_logic;
-- fmc1_dp0c2m_p_o : out std_logic;
-- fmc1_dp0c2m_n_o : out std_logic;
-- fmc1_pg_c2m_o : out std_logic;
fmc1_prsntm2c_n_i : in std_logic;
-- fmc1_scl_o : out std_logic;
-- fmc1_sda_b : inout std_logic;
-- fmc1_tck_o : out std_logic;
-- fmc1_tdi_i : in std_logic;
-- fmc1_tdo_o : out std_logic;
-- fmc1_tms_o : out std_logic;
-- fmc1_clk1m2c_p_i : in std_logic;
-- fmc1_clk1m2c_n_i : in std_logic;
-- fmc1_clk0m2c_p_i : in std_logic;
-- fmc1_clk0m2c_n_I : in std_logic;
-- fmc1_la_p_b : inout std_logic_vector(33 downto 0);
-- fmc1_la_n_b : inout std_logic_vector(33 downto 0);
------------------------------------------
-- FMC slot 2
------------------------------------------
-- fmc2_gbtclk0m2c_p_i : in std_logic;
-- fmc2_gbtclk0m2c_n_i : in std_logic;
-- fmc2_dp0m2c_p_i : in std_logic;
-- fmc2_dp0m2c_n_i : in std_logic;
-- fmc2_dp0c2m_p_o : out std_logic;
-- fmc2_dp0c2m_n_o : out std_logic;
-- fmc2_pg_c2m_o : out std_logic;
fmc2_prsntm2c_n_i : in std_logic;
-- fmc2_scl_o : out std_logic;
-- fmc2_sda_b : inout std_logic;
-- fmc2_tck_o : out std_logic;
-- fmc2_tdi_i : in std_logic;
-- fmc2_tdo_o : out std_logic;
-- fmc2_tms_o : out std_logic;
-- fmc2_clk1m2c_p_i : in std_logic;
-- fmc2_clk1m2c_n_i : in std_logic;
-- fmc2_clk0m2c_p_i : in std_logic;
-- fmc2_clk0m2c_n_i : in std_logic;
-- fmc2_la_p_b : inout std_logic_vector(33 downto 0);
-- fmc2_la_n_b : inout std_logic_vector(33 downto 0);
------------------------------------------
-- I2C EEPROM
------------------------------------------
-- scl_afpga_o : out std_logic;
-- sda_afpga_b : inout std_logic;
------------------------------------------
-- Front panel IO and LEDs
------------------------------------------
fp_gpio_b : inout std_logic_vector(4 downto 1);
fpgpio1_a2b_o : out std_logic;
fpgpio2_a2b_o : out std_logic;
fpgpio34_a2b_o : out std_logic;
term_en_o : out std_logic_vector(4 downto 1);
fp_led_n_o : out std_logic_vector(7 downto 0);
------------------------------------------
-- 1-wire thermoeter + unique ID
------------------------------------------
tempid_dq_b : inout std_logic;
------------------------------------------
-- Debug LEDs
------------------------------------------
dbg_led_n_o : out std_logic_vector(4 downto 1)
);
end component svec_afpga_top;
------------------------------------------------------------------------------
-- DDR3 model
------------------------------------------------------------------------------
component ddr3
port (
rst_n : in std_logic;
ck : in std_logic;
ck_n : in std_logic;
cke : in std_logic;
cs_n : in std_logic;
ras_n : in std_logic;
cas_n : in std_logic;
we_n : in std_logic;
dm_tdqs : inout std_logic_vector(1 downto 0);
ba : in std_logic_vector(2 downto 0);
addr : in std_logic_vector(13 downto 0);
dq : inout std_logic_vector(15 downto 0);
dqs : inout std_logic_vector(1 downto 0);
dqs_n : inout std_logic_vector(1 downto 0);
tdqs_n : out std_logic_vector(1 downto 0);
odt : in std_logic
);
end component;
--Inputs
signal clk_i : std_logic := '0';
signal VME_AS_n_i : std_logic := '0';
signal VME_RST_n_i : std_logic := '0';
signal VME_WRITE_n_i : std_logic := '0';
signal VME_AM_i : std_logic_vector(5 downto 0) := (others => '0');
signal VME_DS_n_i : std_logic_vector(1 downto 0) := (others => '0');
signal VME_GA_i : std_logic_vector(5 downto 0) := (others => '0');
signal VME_BBSY_n_i : std_logic := '0';
signal VME_IACKIN_n_i : std_logic := '1';
signal VME_IACK_n_i : std_logic := '1';
signal Reset : std_logic := '1';
--BiDirs
signal VME_LWORD_n_b : std_logic;
signal VME_ADDR_b : std_logic_vector(31 downto 1);
signal VME_DATA_b : std_logic_vector(31 downto 0);
--Outputs
signal VME_BERR_o : std_logic;
signal VME_DTACK_n_o : std_logic;
signal VME_RETRY_n_o : std_logic;
signal VME_RETRY_OE_o : std_logic;
signal VME_IRQ_n_o : std_logic_vector(6 downto 0);
signal VME_IACKOUT_n_o : std_logic;
signal VME_DTACK_OE_o : std_logic;
signal VME_DATA_DIR_o : std_logic;
signal VME_DATA_OE_N_o : std_logic;
signal VME_ADDR_DIR_o : std_logic;
signal VME_ADDR_OE_N_o : std_logic;
-- Flags
signal ReadInProgress : std_logic := '0';
signal WriteInProgress : std_logic := '0';
signal s_Buffer_BLT : t_Buffer_BLT;
signal s_Buffer_MBLT : t_Buffer_MBLT;
signal s_dataTransferType : t_dataTransferType;
signal s_AddressingType : t_Addressing_Type;
-- Control signals
signal s_dataToSendOut : std_logic_vector(31 downto 0);
signal s_dataToSend : std_logic_vector(31 downto 0);
signal s_dataToReceive : std_logic_vector(31 downto 0);
signal s_address : std_logic_vector(63 downto 0);
signal localAddress : std_logic_vector(19 downto 0);
signal s_num : std_logic_vector(8 downto 0);
signal s_temp : std_logic_vector(31 downto 0);
signal s_beat_count : std_logic_vector(7 downto 0);
-- Records
signal VME64xBus_out : VME64xBusOut_Record;
signal VME64xBus_in : VME64xBusIn_Record;
-- Power-ON reset
signal rst_n_i : std_logic := '1';
-- PCB revision ID
signal pcbrev_i : std_logic_vector(4 downto 0) := "00001";
-- DDR3 on bank 5
signal ddr_2_we_n_o : std_logic;
signal ddr_2_dqs_p_b : std_logic_vector(1 downto 0) := (others => 'Z');
signal ddr_2_dqs_n_b : std_logic_vector(1 downto 0) := (others => 'Z');
signal ddr_2_dm_o : std_logic_vector(1 downto 0) := (others => 'Z');
signal ddr_2_reset_n_o : std_logic;
signal ddr_2_ras_n_o : std_logic;
signal ddr_2_odt_o : std_logic;
signal ddr_2_cke_o : std_logic;
signal ddr_2_ck_p_o : std_logic;
signal ddr_2_ck_n_o : std_logic;
signal ddr_2_cas_n_o : std_logic;
signal ddr_2_dq_b : std_logic_vector(15 downto 0) := (others => 'Z');
signal ddr_2_ba_o : std_logic_vector(2 downto 0);
signal ddr_2_a_o : std_logic_vector(13 downto 0);
signal ddr_2_zio_b : std_logic := 'Z';
signal ddr_2_rzq_b : std_logic;
-- FMC slots
signal fmc1_prsntm2c_n_i : std_logic := '1';
signal fmc2_prsntm2c_n_i : std_logic := '1';
-- Front panel
signal fp_gpio_b : std_logic_vector(4 downto 1) := (others => 'Z');
signal fpgpio1_a2b_o : std_logic;
signal fpgpio2_a2b_o : std_logic;
signal fpgpio34_a2b_o : std_logic;
signal term_en_o : std_logic_vector(4 downto 1);
signal fp_led_n_o : std_logic_vector(7 downto 0);
-- Temperature sensor
signal tempid_dq_b : std_logic := 'Z';
-- Debug LEDs
signal dbg_led_n_o : std_logic_vector(4 downto 1);
-- Clock period definitions
constant clk_i_period : time := 50 ns;
begin
-- Instantiate the Unit Under Test (UUT)
uut : svec_afpga_top
generic map(
g_CARRIER_TYPE => X"0002",
g_BITSTREAM_TYPE => X"00002222",
g_BITSTREAM_DATE => X"4FE9BABD",
g_SIMULATION => "TRUE",
g_CALIB_SOFT_IP => "TRUE")
port map(
vme_write_n_i => VME_WRITE_n_i,
vme_sysreset_n_i => VME_RST_n_i,
vme_retry_oe_o => VME_RETRY_OE_o,
vme_retry_n_o => VME_RETRY_n_o,
vme_lword_n_b => VME_LWORD_n_b,
vme_iackout_n_o => VME_IACKOUT_n_o,
vme_iackin_n_i => VME_IACKIN_n_i,
vme_iack_n_i => VME_IACK_n_i,
vme_gap_n_i => VME_GA_i(5),
vme_dtack_oe_o => VME_DTACK_OE_o,
vme_dtack_n_o => VME_DTACK_n_o,
vme_ds_n_i => VME_DS_n_i,
vme_d_oe_n_o => VME_DATA_OE_N_o,
vme_d_dir_o => VME_DATA_DIR_o,
vme_berr_o => VME_BERR_o,
vme_as_n_i => VME_AS_n_i,
vme_a_oe_n_o => VME_ADDR_OE_N_o,
vme_a_dir_o => VME_ADDR_DIR_o,
vme_irq_n_o => VME_IRQ_n_o,
vme_ga_i => VME_GA_i(4 downto 0),
vme_d_b => VME_DATA_b,
vme_am_i => VME_AM_i,
vme_a_b => VME_ADDR_b,
rst_n_i => rst_n_i,
clk20_vcxo_i => clk_i,
pcbrev_i => pcbrev_i,
ddr_2_we_n_o => ddr_2_we_n_o,
ddr_2_udqs_p_b => ddr_2_dqs_p_b(1),
ddr_2_udqs_n_b => ddr_2_dqs_n_b(1),
ddr_2_udm_o => ddr_2_dm_o(1),
ddr_2_reset_n_o => ddr_2_reset_n_o,
ddr_2_ras_n_o => ddr_2_ras_n_o,
ddr_2_odt_o => ddr_2_odt_o,
ddr_2_ldqs_p_b => ddr_2_dqs_p_b(0),
ddr_2_ldqs_n_b => ddr_2_dqs_n_b(0),
ddr_2_ldm_o => ddr_2_dm_o(0),
ddr_2_cke_o => ddr_2_cke_o,
ddr_2_ck_p_o => ddr_2_ck_p_o,
ddr_2_ck_n_o => ddr_2_ck_n_o,
ddr_2_cas_n_o => ddr_2_cas_n_o,
ddr_2_dq_b => ddr_2_dq_b,
ddr_2_ba_o => ddr_2_ba_o,
ddr_2_a_o => ddr_2_a_o,
ddr_2_zio_b => ddr_2_zio_b,
ddr_2_rzq_b => ddr_2_rzq_b,
fmc1_prsntm2c_n_i => fmc1_prsntm2c_n_i,
fmc2_prsntm2c_n_i => fmc2_prsntm2c_n_i,
fp_gpio_b => fp_gpio_b,
fpgpio1_a2b_o => fpgpio1_a2b_o,
fpgpio2_a2b_o => fpgpio2_a2b_o,
fpgpio34_a2b_o => fpgpio34_a2b_o,
term_en_o => term_en_o,
fp_led_n_o => fp_led_n_o,
tempid_dq_b => tempid_dq_b,
dbg_led_n_o => dbg_led_n_o
);
cmp_ddr3_bank5 : ddr3
port map(
rst_n => ddr_2_reset_n_o,
ck => ddr_2_ck_p_o,
ck_n => ddr_2_ck_n_o,
cke => ddr_2_cke_o,
cs_n => '0', -- Pulled down on PCB
ras_n => ddr_2_ras_n_o,
cas_n => ddr_2_cas_n_o,
we_n => ddr_2_we_n_o,
dm_tdqs => ddr_2_dm_o,
ba => ddr_2_ba_o,
addr => ddr_2_a_o,
dq => ddr_2_dq_b,
dqs => ddr_2_dqs_p_b,
dqs_n => ddr_2_dqs_n_b,
tdqs_n => open, -- dqs outputs for chaining
odt => ddr_2_odt_o
);
VME_IACKIN_n_i <= VME64xBus_out.Vme64xIACKIN;
VME_IACK_n_i <= VME64xBus_out.Vme64xIACK;
VME_AS_n_i <= VME64xBus_out.Vme64xAsN;
VME_WRITE_n_i <= VME64xBus_out.Vme64xWRITEN;
VME_AM_i <= VME64xBus_out.Vme64xAM;
VME_DS_n_i(1) <= VME64xBus_out.Vme64xDs1N;
VME_DS_n_i(0) <= VME64xBus_out.Vme64xDs0N;
VME_LWORD_n_b <= VME64xBus_out.Vme64xLWORDN when VME_ADDR_DIR_o = '0' else 'Z';
VME64xBus_in.Vme64xLWORDN <= VME_LWORD_n_b;
VME_ADDR_b <= VME64xBus_out.Vme64xADDR when VME_ADDR_DIR_o = '0' else (others => 'Z');
VME64xBus_in.Vme64xADDR <= VME_ADDR_b;
VME_DATA_b <= VME64xBus_out.Vme64xDATA when VME_DATA_DIR_o = '0' else (others => 'Z');
VME64xBus_in.Vme64xDATA <= VME_DATA_b;
VME64xBus_in.Vme64xDtackN <= VME_DTACK_n_o;
VME64xBus_in.Vme64xBerrN <= VME_BERR_o;
VME64xBus_in.Vme64xRetryN <= VME_RETRY_n_o;
VME64xBus_in.Vme64xIRQ <= VME_IRQ_n_o;
VME64xBus_in.Vme64xIACKOUT <= VME_IACKOUT_n_o;
-- Clock process definitions
p_clk : process
begin
clk_i <= '0';
wait for clk_i_period/2;
clk_i <= '1';
wait for clk_i_period/2;
end process p_clk;
-- Actual test process
p_vme64x_ddr : process
begin
wait for 8800 ns; -- wait until the initialization finish (wait more than 8705 ns)
-- Write in CSR:
VME64xBus_Out.Vme64xIACK <= '1';
VME64xBus_Out.Vme64xIACKIN <= '1';
------------------------------------------------------------------------------
-- Configure CSR space
------------------------------------------------------------------------------
report "START WRITE CSR";
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"00000000"; -- Put the data to send in the 8 lsb.
WriteCSR(c_address => c_BIT_CLR_REG , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
VME64xBus_Out => VME64xBus_Out);
report "END WRITE CSR";
wait for 10 ns;
report "START READ CSR";
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
-- Put the data to receive in the 8 lsb also if you are using D08Byte1 or D08Byte2 ecc..
s_dataToReceive <= x"00000000";
ReadCR_CSR(c_address => c_USR_BIT_SET_REG, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
VME64xBus_Out => VME64xBus_Out);
report "END READ CSR";
wait for 10 ns;
s_dataToReceive <= (others => '0');
wait for 10 ns;
------------------------------------------------------------------------------
-- Configure window to access WB bus (ADER)
------------------------------------------------------------------------------
wait for 50 ns;
report "START WRITE ADER";
-- Before the Master has to write the ADERs.
-- start write ADER0
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"000000" & ADER0_A32(31 downto 24);
WriteCSR(c_address => c_FUNC0_ADER_3 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"000000" & ADER0_A32(23 downto 16);
WriteCSR(c_address => c_FUNC0_ADER_2 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"000000" & ADER0_A32(15 downto 8);
WriteCSR(c_address => c_FUNC0_ADER_1 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"000000" & ADER0_A32(7 downto 0);
WriteCSR(c_address => c_FUNC0_ADER_0 , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
report "THE MASTER HAS WRITTEN CORRECTLY ALL THE ADERs";
wait for 20 ns;
------------------------------------------------------------------------------
-- Enables the VME64x core
------------------------------------------------------------------------------
-- Module Enabled:
s_dataTransferType <= D08Byte3;
s_AddressingType <= CR_CSR;
s_dataToSend <= x"00000010";
WriteCSR(c_address => c_BIT_SET_REG , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_in,
VME64xBus_Out => VME64xBus_Out);
wait for 20 ns;
------------------------------------------------------------------------------
-- Access to WB registers and memories
------------------------------------------------------------------------------
report "START WRITE AND READ WB REG/MEMORY";
-- Write DDR bank4 address
s_dataTransferType <= D32;
s_AddressingType <= A32;
s_dataToSend <= x"00000001";
s_address <= x"0000000000001000";
S_Write(v_address => s_address , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 100 ns;
-- Read DDR bank4 address
s_dataTransferType <= D32;
s_AddressingType <= A32;
s_address <= x"0000000000001000";
s_dataToReceive <= x"00000001";
S_Read(v_address => s_address, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 100 ns;
-- Write DDR bank4 data
s_dataTransferType <= D32;
s_AddressingType <= A32;
s_dataToSend <= x"44444444";
s_address <= x"0000000000001800";
S_Write(v_address => s_address , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 100 ns;
-- Write DDR bank4 address
s_dataTransferType <= D32;
s_AddressingType <= A32;
s_dataToSend <= x"00000001";
s_address <= x"0000000000001000";
S_Write(v_address => s_address , s_dataToSend => s_dataToSend, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 100 ns;
-- Read DDR bank4 address
s_dataTransferType <= D32;
s_AddressingType <= A32;
s_address <= x"0000000000001000";
s_dataToReceive <= x"00000001";
S_Read(v_address => s_address, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 100 ns;
-- Read DDR bank4 data
s_dataTransferType <= D32;
s_AddressingType <= A32;
s_address <= x"0000000000001800";
s_dataToReceive <= x"44444444";
S_Read(v_address => s_address, s_dataToReceive => s_dataToReceive, s_dataTransferType => s_dataTransferType,
s_AddressingType => s_AddressingType, VME64xBus_In => VME64xBus_In,
VME64xBus_Out => VME64xBus_Out);
wait for 100 ns;
assert false report "Got here!" severity failure;
wait;
end process p_vme64x_ddr;
-- Stimulus process------------RESET, BBSY, IACKIN, VME_GA
p_rst : process
begin
-- hold reset state for 100 ns.
VME_RST_n_i <= '0';
VME_GA_i <= VME_GA;
wait for 200 ns;
VME_RST_n_i <= '1';
wait;
end process p_rst;
end;
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate /vme64x_ddr_tb/rst_n_i
add wave -noupdate /vme64x_ddr_tb/VME_RST_n_i
add wave -noupdate /vme64x_ddr_tb/uut/sys_rst_n
add wave -noupdate /vme64x_ddr_tb/clk_i
add wave -noupdate -divider VME
add wave -noupdate /vme64x_ddr_tb/VME_BERR_o
add wave -noupdate /vme64x_ddr_tb/VME_DS_n_i
add wave -noupdate -radix hexadecimal /vme64x_ddr_tb/VME_DATA_b
add wave -noupdate /vme64x_ddr_tb/VME_AS_n_i
add wave -noupdate -radix hexadecimal /vme64x_ddr_tb/VME_ADDR_b
add wave -noupdate /vme64x_ddr_tb/VME_LWORD_n_b
add wave -noupdate /vme64x_ddr_tb/VME_WRITE_n_i
add wave -noupdate /vme64x_ddr_tb/VME_DTACK_n_o
add wave -noupdate -radix hexadecimal /vme64x_ddr_tb/s_dataToReceive
add wave -noupdate -divider {Master WB}
add wave -noupdate /vme64x_ddr_tb/uut/wbm_we
add wave -noupdate /vme64x_ddr_tb/uut/wbm_stb
add wave -noupdate /vme64x_ddr_tb/uut/wbm_stall
add wave -noupdate /vme64x_ddr_tb/uut/wbm_sel
add wave -noupdate -radix hexadecimal /vme64x_ddr_tb/uut/wbm_dat_o
add wave -noupdate -radix hexadecimal /vme64x_ddr_tb/uut/wbm_dat_i
add wave -noupdate /vme64x_ddr_tb/uut/wbm_cyc
add wave -noupdate -radix hexadecimal /vme64x_ddr_tb/uut/wbm_adr
add wave -noupdate /vme64x_ddr_tb/uut/wbm_ack
add wave -noupdate -divider {Slaves WB}
add wave -noupdate /vme64x_ddr_tb/uut/wb_we
add wave -noupdate /vme64x_ddr_tb/uut/wb_stb
add wave -noupdate /vme64x_ddr_tb/uut/wb_stall
add wave -noupdate /vme64x_ddr_tb/uut/wb_sel
add wave -noupdate -radix hexadecimal /vme64x_ddr_tb/uut/wb_dat_o
add wave -noupdate -radix hexadecimal /vme64x_ddr_tb/uut/wb_dat_i
add wave -noupdate /vme64x_ddr_tb/uut/wb_cyc
add wave -noupdate -radix hexadecimal /vme64x_ddr_tb/uut/wb_adr
add wave -noupdate /vme64x_ddr_tb/uut/wb_ack
add wave -noupdate -divider {DDR bank4}
add wave -noupdate /vme64x_ddr_tb/uut/sys_clk
add wave -noupdate -radix hexadecimal /vme64x_ddr_tb/uut/ddr_bank4_addr_cnt
add wave -noupdate /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank4/cmp_ddr3_ctrl_wb_0/wb_we_i
add wave -noupdate /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank4/cmp_ddr3_ctrl_wb_0/wb_we_f_edge
add wave -noupdate /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank4/cmp_ddr3_ctrl_wb_0/wb_we_d
add wave -noupdate /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank4/cmp_ddr3_ctrl_wb_0/wb_stb_i
add wave -noupdate /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank4/cmp_ddr3_ctrl_wb_0/wb_stb_f_edge
add wave -noupdate /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank4/cmp_ddr3_ctrl_wb_0/wb_stb_d
add wave -noupdate /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank4/cmp_ddr3_ctrl_wb_0/wb_cyc_r_edge
add wave -noupdate /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank4/cmp_ddr3_ctrl_wb_0/wb_cyc_i
add wave -noupdate /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank4/cmp_ddr3_ctrl_wb_0/wb_cyc_f_edge
add wave -noupdate /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank4/cmp_ddr3_ctrl_wb_0/wb_cyc_d
add wave -noupdate /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank4/cmp_ddr3_ctrl_wb_0/ddr_wr_en
add wave -noupdate -radix hexadecimal /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank4/cmp_ddr3_ctrl_wb_0/ddr_wr_data
add wave -noupdate /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank4/cmp_ddr3_ctrl_wb_0/ddr_rd_en
add wave -noupdate -radix hexadecimal /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank4/cmp_ddr3_ctrl_wb_0/ddr_rd_data_i
add wave -noupdate /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank4/cmp_ddr3_ctrl_wb_0/ddr_cmd_instr
add wave -noupdate /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank4/cmp_ddr3_ctrl_wb_0/ddr_cmd_en
add wave -noupdate -radix hexadecimal /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank4/cmp_ddr3_ctrl_wb_0/ddr_cmd_byte_addr
add wave -noupdate /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank4/cmp_ddr3_ctrl_wb_0/ddr_cmd_bl
add wave -noupdate /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank4/cmp_ddr3_ctrl_wb_0/ddr_burst_cnt
add wave -noupdate -divider {DDR bank5}
add wave -noupdate /vme64x_ddr_tb/uut/ddr_bank5_addr_cnt
add wave -noupdate /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank5/cmp_ddr3_ctrl_wb_0/wb_we_i
add wave -noupdate /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank5/cmp_ddr3_ctrl_wb_0/wb_we_f_edge
add wave -noupdate /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank5/cmp_ddr3_ctrl_wb_0/wb_we_d
add wave -noupdate /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank5/cmp_ddr3_ctrl_wb_0/wb_stb_i
add wave -noupdate /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank5/cmp_ddr3_ctrl_wb_0/wb_stb_f_edge
add wave -noupdate /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank5/cmp_ddr3_ctrl_wb_0/wb_stb_d
add wave -noupdate /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank5/cmp_ddr3_ctrl_wb_0/wb_cyc_r_edge
add wave -noupdate /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank5/cmp_ddr3_ctrl_wb_0/wb_cyc_i
add wave -noupdate /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank5/cmp_ddr3_ctrl_wb_0/wb_cyc_f_edge
add wave -noupdate /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank5/cmp_ddr3_ctrl_wb_0/wb_cyc_d
add wave -noupdate /vme64x_ddr_tb/uut/ddr3_bank5_status(0)
add wave -noupdate /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank5/cmp_ddr3_ctrl_wb_0/ddr_wr_en
add wave -noupdate -radix hexadecimal /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank5/cmp_ddr3_ctrl_wb_0/ddr_wr_data
add wave -noupdate /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank5/cmp_ddr3_ctrl_wb_0/ddr_rd_en
add wave -noupdate -radix hexadecimal /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank5/cmp_ddr3_ctrl_wb_0/ddr_rd_data_i
add wave -noupdate /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank5/cmp_ddr3_ctrl_wb_0/ddr_cmd_instr
add wave -noupdate /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank5/cmp_ddr3_ctrl_wb_0/ddr_cmd_en
add wave -noupdate -radix hexadecimal /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank5/cmp_ddr3_ctrl_wb_0/ddr_cmd_byte_addr
add wave -noupdate /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank5/cmp_ddr3_ctrl_wb_0/ddr_cmd_bl
add wave -noupdate /vme64x_ddr_tb/uut/cmp_ddr_ctrl_bank5/cmp_ddr3_ctrl_wb_0/ddr_burst_cnt
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {17413525 ps} 0}
configure wave -namecolwidth 505
configure wave -valuecolwidth 203
configure wave -justifyvalue left
configure wave -signalnamewidth 0
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 1
configure wave -griddelta 40
configure wave -timeline 0
configure wave -timelineunits ps
update
WaveRestoreZoom {17207022 ps} {17844969 ps}
// _/ _/_/
// _/_/ _/_/_/
// _/_/_/_/ _/_/_/
// _/_/_/_/_/ _/_/_/ ____________________________________________
// _/_/_/_/_/ _/_/_/ / /
// _/_/_/_/_/ _/_/_/ / M25P128 /
// _/_/_/_/_/ _/_/_/ / /
// _/_/_/_/_/_/ _/_/_/ / 128Mbit /
// _/_/_/_/_/_/ _/_/_/ / SERIAL FLASH /
// _/_/_/ _/_/_/ _/_/_/ / /
// _/_/_/ _/_/_/ _/_/_/ / Verilog Behavioral Model /
// _/_/_/ _/_/_/ _/_/_/ / Version 1.1 /
// _/_/_/ _/_/_/ _/_/_/ / /
// _/_/_/ _/_/_/_/_/_/ / Copyright (c) 2008 Numonyx B.V. /
// _/_/_/ _/_/_/_/_/ /___________________________________________/
// _/_/_/ _/_/_/_/
// _/_/ _/_/_/
//
//
// NUMONYX
`timescale 1ns/1ps
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-----------------------------------------------------------
-----------------------------------------------------------
-- --
-- TOP LEVEL MODULE --
-- --
-----------------------------------------------------------
-----------------------------------------------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
module M25Pxxx (S, C, HOLD, D, Q, Vcc, Vpp_W); //P128
`include "include/DevParam.h"
input S;
input C;
input [`VoltageRange] Vcc;
`ifdef DUAL
inout DQ0;
inout DQ1;
`else
input D;
output Q;
`endif
`ifdef Vpp_pin //M25PX32
input [`VoltageRange] Vpp; `endif
`ifdef HOLD_pin //M25PX32, M25P128
input HOLD; `endif
`ifdef W_pin //M25PE16
input W; `endif
`ifdef RESET_pin //M25PE16
input RESET; `endif
`ifdef Vpp_W_pin //M25P128
input [`VoltageRange] Vpp_W; `endif
parameter [40*8:1] memory_file = "";
//----------------------
// HOLD signal
//----------------------
`ifdef HOLD_pin
reg intHOLD=1;
always @(HOLD) if (S==0 && C==0)
intHOLD = HOLD;
always @(negedge C) if(S==0 && intHOLD!=HOLD)
intHOLD = HOLD;
always @(posedge HOLD) if(S==1)
intHOLD = 1;
always @intHOLD
if(intHOLD==0)
$display("[%0t ns] ==INFO== Hold condition enabled: communication with the device has been paused.", $time);
else if(intHOLD==1)
$display("[%0t ns] ==INFO== Hold condition disabled: communication with the device has been activated.", $time);
`endif
//-------------------------
// Internal signals
//-------------------------
reg busy=0;
reg [2:0] ck_count = 0; //clock counter (modulo 8)
reg reset_by_powerOn = 1; //reset_by_powerOn is updated in "Power Up & Voltage check" section
`ifdef RESET_pin
assign int_reset = !RESET || reset_by_powerOn;
`else
assign int_reset = reset_by_powerOn;
`endif
`ifdef HOLD_pin
assign logicOn = !int_reset && !S && intHOLD;
`else
assign logicOn = !int_reset && !S;
`endif
reg deep_power_down = 0; //updated in "Deep power down" processes
reg ReadAccessOn = 0;
wire WriteAccessOn;
// indicate type of data that will be latched by the model:
// C=command , A=address , D=data, N=none, Y=dummy, F=dual_input(F=fast)
reg [8:1] latchingMode = "N";
reg [cmdDim-1:0] cmd='h0;
reg [addrDimLatch-1:0] addrLatch='h0;
reg [addrDim-1:0] addr='h0;
reg [dataDim-1:0] data='h0;
reg [dataDim-1:0] dataOut='h0;
//---------------------------------------
// Vpp_W signal : write protect feature
//---------------------------------------
`ifdef Vpp_W_pin
assign W_int = ( Vpp_W>=Vcc_min && Vpp_W!=='hX && Vpp_W!=='hZ ) ? 1 : 0;
`endif
//----------------------------
// CUI decoders istantiation
//----------------------------
`include "include/Decoders.h"
//---------------------------
// Modules istantiations
//---------------------------
Memory mem ();
UtilFunctions f ();
Program prog ();
StatusRegister stat ();
Read read ();
LockManager lock ();
`ifdef timingChecks
`ifdef M25PX32
TimingCheck timeCheck (S, C, `D, `Q, HOLD);
`elsif M25PE16
TimingCheck timeCheck (S, C, `D, `Q, W, RESET);
`elsif M25P128
TimingCheck timeCheck (S, C, `D, `Q, W_int, HOLD);
`endif
`endif
`ifdef DUAL
DualOps dual (S, C, ck_count, `D, `Q); `endif
`ifdef OTP
OTP_memory OTP (); `endif
//----------------------------------
// Signals for latching control
//----------------------------------
integer iCmd, iAddr, iData;
always @(negedge S) begin : CP_latchInit
latchingMode = "C";
ck_count = 0;
iCmd = cmdDim - 1;
iAddr = addrDimLatch - 1;
iData = dataDim - 1;
end
always @(posedge C) if(logicOn)
ck_count = ck_count + 1;
//-------------------------
// Latching commands
//-------------------------
event cmdLatched;
always @(posedge C) if(logicOn && latchingMode=="C") begin : CP_latchCmd
cmd[iCmd] = `D;
if (iCmd>0)
iCmd = iCmd - 1;
else if(iCmd==0) begin
latchingMode = "N";
-> cmdLatched;
end
end
//-------------------------
// Latching address
//-------------------------
event addrLatched;
always @(posedge C) if (logicOn && latchingMode=="A") begin : CP_latchAddr
addrLatch[iAddr] = `D;
if (iAddr>0)
iAddr = iAddr - 1;
else if(iAddr==0) begin
latchingMode = "N";
addr = addrLatch[addrDim-1:0];
-> addrLatched;
end
end
//-----------------
// Latching data
//-----------------
event dataLatched;
always @(posedge C) if (logicOn && latchingMode=="D") begin : CP_latchData
data[iData] = `D;
if (iData>0)
iData = iData-1;
else begin
-> dataLatched;
$display(" [%0t ns] Data latched: %h", $time, data);
iData=dataDim-1;
end
end
//-----------------
// Latching dummy
//-----------------
event dummyLatched;
always @(posedge C) if (logicOn && latchingMode=="Y") begin : CP_latchDummy
data[iData] = `D;
if (iData>0)
iData = iData-1;
else begin
-> dummyLatched;
$display(" [%0t ns] Dummy byte latched.", $time);
iData=dataDim-1;
end
end
//------------------------------
// Commands recognition control
//------------------------------
event codeRecognized, seqRecognized, startCUIdec;
reg [30*8:1] cmdRecName;
always @(cmdLatched) fork : CP_cmdRecControl
-> startCUIdec; // i CUI decoders si devono attivare solo dopo
// che e' partito il presente processo
begin : ok
@(codeRecognized or seqRecognized)
disable error;
end
begin : error
#0;
#0; //wait until CUI decoders execute recognition process (2 delta time maximum)
if (busy)
$display("[%0t ns] **WARNING** Device is busy. Command not accepted.", $time);
else if (deep_power_down)
$display("[%0t ns] **WARNING** Deep power down mode. Command not accepted.", $time);
else if (!ReadAccessOn || !WriteAccessOn)
$display("[%0t ns] **WARNING** Power up is ongoing. Command not accepted.", $time);
else if (!busy)
$display("[%0t ns] **ERROR** Command Not Recognized.", $time);
disable ok;
end
join
//--------------------------
// Power Up & Voltage check
//--------------------------
//--- Reset internal logic (latching disabled when Vcc<Vcc_wi)
assign Vcc_L1 = (Vcc>=Vcc_wi) ? 1 : 0 ;
always @Vcc_L1
if (reset_by_powerOn && Vcc_L1)
reset_by_powerOn = 0;
else if (!reset_by_powerOn && !Vcc_L1)
reset_by_powerOn = 1;
//--- Read access
assign Vcc_L2 = (Vcc>=Vcc_min) ? 1 : 0 ;
always @Vcc_L2 if(Vcc_L2 && ReadAccessOn==0) fork : CP_powUp_ReadAccess
begin : p1
#read_access_power_up_delay;
$display("[%0t ns] ==INFO== Power up: read access enabled.", $time);
ReadAccessOn=1;
deep_power_down=0;
disable p2;
end
begin : p2
@Vcc_L2 if(!Vcc_L2)
disable p1;
end
join
//--- Write access
reg WriteAccessCondition = 0;
always @Vcc_L1 if (WriteAccessCondition==0 && Vcc_L1) fork : CP_powUp_WriteAccess
begin : p1
#write_access_power_up_delay;
$display("[%0t ns] ==INFO== Power up: write access enabled (device fully accessible).", $time);
WriteAccessCondition=1;
disable p2;
end
begin : p2
@Vcc_L1 if(!Vcc_L1)
disable p1;
end
join
assign WriteAccessOn = ReadAccessOn && WriteAccessCondition;
//--- Voltage drop (power down)
always @Vcc_L1 if (!Vcc_L1 && (ReadAccessOn || WriteAccessCondition)) begin : CP_powerDown
$display("[%0t ns] ==INFO== Voltage below the threshold value: device not accessible.", $time);
ReadAccessOn=0;
WriteAccessCondition=0;
end
//--- Voltage fault (used during program and erase operations)
event voltageFault; //used in Program and erase dynamic check (see also "CP_voltageCheck" process)
assign VccOk = (Vcc>=Vcc_min && Vcc<=Vcc_max) ? 1 : 0 ;
always @VccOk if (!VccOk) ->voltageFault; //check is active when device is not reset
//(this is a dynamic check used during program and erase operations)
//---------------------------------
// Vpp (auxiliary voltage) checks
//---------------------------------
`ifdef Vpp_pin
// VppOk true if Vpp is in the range allowing enhanced program/erase
assign VppOk = ( (Vpp>=Vpp_min && Vpp<=Vpp_max) && Vpp!=='dX && Vpp!=='dZ ) ?
1 : 0;
always @(VppOk) if (VppOk)
$display("[%0t ns] ==INFO== Enhanced Program Supply Voltage is OK (%0d mV).", $time, Vpp);
assign VppError = ( !( Vpp===0 || (Vpp>=Vcc_min && Vpp<=Vcc_max) || (Vpp>=Vpp_min && Vpp<=Vpp_max) ) || Vpp==='dX || Vpp==='dZ ) ?
1 : 0;
always @(VppError or ReadAccessOn) if(ReadAccessOn && VppError)
$display("[%0t ns] **WARNING** Vpp should be in VPPH range, or connected to ground, or connected in Vcc range!", $time);
`endif
`ifdef Vpp_W_pin
// VppOk true if Vpp is in the range allowing enhanced program/erase
assign VppOk = ( (Vpp_W>=Vpp_min && Vpp_W<=Vpp_max) && Vpp_W!=='dX && Vpp_W!=='dZ ) ?
1 : 0;
always @(VppOk) if (VppOk)
$display("[%0t ns] ==INFO== Enhanced Program Supply Voltage is OK (%0d mV).", $time, Vpp_W);
assign VppError = ( !( Vpp_W===0 || (Vpp_W>=Vcc_min && Vpp_W<=Vcc_max) || (Vpp_W>=Vpp_min && Vpp_W<=Vpp_max) ) || Vpp_W==='dX || Vpp_W==='dZ ) ?
1 : 0;
always @(VppError or ReadAccessOn) if(ReadAccessOn && VppError)
$display("[%0t ns] **WARNING** Vpp should be in VPPH range, or connected to ground, or connected in Vcc range!", $time);
`endif
//-----------------
// Read execution
//-----------------
reg [addrDim-1:0] readAddr;
reg bitOut='hZ;
event sendToBus;
// values assumed by `D and `Q, when they are not forced
assign `D = 1'bZ;
assign `Q = 1'bZ;
// `Q : release of values assigned with "force statement"
always @(posedge S) #tSHQZ release `Q;
// effect on `Q by HOLD signal
`ifdef HOLD_pin
reg temp;
always @(intHOLD) if(intHOLD===0) begin : CP_HOLD_out_effect
begin : out_effect
temp = `Q;
#tHLQZ;
disable guardian;
release `Q;
@(posedge intHOLD) #tHHQX force `Q=temp;
end
begin : guardian
@(posedge intHOLD)
disable out_effect;
end
end
`endif
// read with `Q out bit
always @(negedge(C)) if(logicOn) begin : CP_read
if(read.enable==1 || read.enable_fast==1) begin
if(ck_count==0) begin
readAddr = mem.memAddr;
mem.readData(dataOut); //read data and increments address
f.out_info(readAddr, dataOut);
end
bitOut = dataOut[dataDim-1-ck_count];
-> sendToBus;
end else if (stat.enable_SR_read==1) begin
if(ck_count==0) begin
dataOut = stat.SR;
f.out_info(readAddr, dataOut);
end
bitOut = dataOut[dataDim-1-ck_count];
-> sendToBus;
`ifdef LockReg
end else if (lock.enable_lockReg_read==1) begin
if(ck_count==0) begin
readAddr = f.sec(addr);
f.out_info(readAddr, dataOut);
end
// dataOut is set in LockManager module
bitOut = dataOut[dataDim-1-ck_count];
-> sendToBus;
`endif
`ifdef OTP
end else if (read.enable_OTP==1) begin
if(ck_count==0) begin
readAddr = 'h0;
readAddr = OTP.addr;
OTP.readData(dataOut); //read data and increments address
f.out_info(readAddr, dataOut);
end
bitOut = dataOut[dataDim-1-ck_count];
-> sendToBus;
`endif
end else if (read.enable_ID==1) begin
if(ck_count==0) begin
readAddr = 'h0;
readAddr = read.ID_index;
if (read.ID_index==0) dataOut=Manufacturer_ID;
else if (read.ID_index==1) dataOut=MemoryType_ID;
else if (read.ID_index==2) dataOut=MemoryCapacity_ID;
if (read.ID_index<=1) read.ID_index=read.ID_index+1;
else read.ID_index=0;
f.out_info(readAddr, dataOut);
end
bitOut = dataOut[dataDim-1-ck_count];
-> sendToBus;
end
end
always @sendToBus fork : CP_sendToBus
#tCLQX force `Q = 1'bX;
#tCLQV
force `Q = bitOut;
join
//-----------------------
// Reset Signal
//-----------------------
event resetEvent; //Activated only in devices with RESET pin.
reg resetDuringDecoding=0; //These two boolean variables are used in TimingCheck
reg resetDuringBusy=0; //entity to check tRHSL timing constraint
`ifdef RESET_pin
always @RESET if (!RESET) begin : CP_reset
->resetEvent;
if(S===0 && !busy)
resetDuringDecoding=1;
else if (busy)
resetDuringBusy=1;
release `Q;
ck_count = 0;
latchingMode = "N";
cmd='h0;
addrLatch='h0;
addr='h0;
data='h0;
dataOut='h0;
iCmd = cmdDim - 1;
iAddr = addrDimLatch - 1;
iData = dataDim - 1;
// commands waiting to be executed are disabled internally
// read enabler are resetted internally, in the read processes
// CUIdecoders are internally disabled by reset signal
#0 $display("[%0t ns] ==INFO== Reset Signal has been driven low : internal logic will be reset.", $time);
end
`endif
//-----------------------
// Deep power down
//-----------------------
`ifdef PowDown
always @seqRecognized if (cmdRecName=="Deep Power Down") fork : CP_deepPowerDown
begin : exe
@(posedge S);
disable reset;
busy=1;
$display(" [%0t ns] Device is entering in deep power down mode...",$time);
#deep_power_down_delay;
$display(" [%0t ns] ...power down mode activated.",$time);
busy=0;
deep_power_down=1;
end
begin : reset
@resetEvent;
disable exe;
end
join
always @seqRecognized if (cmdRecName=="Release Deep Power Down") fork : CP_releaseDeepPowerDown
begin : exe
@(posedge S);
disable reset;
busy=1;
$display(" [%0t ns] Release from deep power down is ongoing...",$time);
#release_power_down_delay;
$display(" [%0t ns] ...release from power down mode completed.",$time);
busy=0;
deep_power_down=0;
end
begin : reset
@resetEvent;
disable exe;
end
join
`endif
endmodule
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-----------------------------------------------------------
-----------------------------------------------------------
-- --
-- CUI DECODER --
-- --
-----------------------------------------------------------
-----------------------------------------------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
module CUIdecoder (cmdAllowed);
`include "include/DevParam.h"
input cmdAllowed;
parameter [30*8:1] cmdName = "Write Enable";
parameter [cmdDim-1:0] cmdCode = 'h06;
parameter withAddr = 1'b0; // 0 -> command with address / 1 -> without address
always @M25Pxxx.startCUIdec if (cmdAllowed && cmdCode==M25Pxxx.cmd) begin
if(!withAddr) begin
M25Pxxx.cmdRecName = cmdName;
$display("[%0t ns] COMMAND RECOGNIZED: %0s.", $time, cmdName);
-> M25Pxxx.seqRecognized;
end else if (withAddr) begin
M25Pxxx.latchingMode = "A";
$display("[%0t ns] COMMAND RECOGNIZED: %0s. Address expected ...", $time, cmdName);
-> M25Pxxx.codeRecognized;
fork : proc1
@(M25Pxxx.addrLatched) begin
if (cmdName!="Read OTP" && cmdName!="Program OTP")
$display(" [%0t ns] Address latched: %h (byte %0d of page %0d, sector %0d)", $time,
M25Pxxx.addr, f.col(M25Pxxx.addr), f.pag(M25Pxxx.addr), f.sec(M25Pxxx.addr));
else
$display(" [%0t ns] Address latched: column %0d", $time, M25Pxxx.addr);
M25Pxxx.cmdRecName = cmdName;
-> M25Pxxx.seqRecognized;
disable proc1;
end
@(posedge M25Pxxx.S) begin
$display(" - [%0t ns] S high: command aborted", $time);
disable proc1;
end
@(M25Pxxx.resetEvent or M25Pxxx.voltageFault) begin
disable proc1;
end
join
end
end
endmodule
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-----------------------------------------------------------
-----------------------------------------------------------
-- --
-- MEMORY MODULE --
-- --
-----------------------------------------------------------
-----------------------------------------------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
module Memory;
`include "include/DevParam.h"
//-----------------------------
// data structures definition
//-----------------------------
reg [dataDim-1:0] memory [0:memDim-1];
reg [dataDim-1:0] page [0:pageDim];
//------------------------------
// Memory management variables
//------------------------------
reg [addrDim-1:0] memAddr;
reg [addrDim-1:0] pageStartAddr;
reg [colAddrDim-1:0] pageIndex = 'h0;
reg [colAddrDim-1:0] zeroIndex = 'h0;
integer i;
//-----------
// Init
//-----------
initial begin
for (i=0; i<=memDim-1; i=i+1)
memory[i] = data_NP;
if ( M25Pxxx.memory_file!="" && M25Pxxx.memory_file!=" ") begin
$readmemh(M25Pxxx.memory_file, memory);
$display("[%0t ns] ==INFO== Load memory content from file: \"%0s\".", $time, M25Pxxx.memory_file);
end
end
//-----------------------------------------
// Task used in program & read operations
//-----------------------------------------
// set start address & page index
// (for program and read operations)
task setAddr;
input [addrDim-1:0] addr;
begin
memAddr = addr;
pageStartAddr = {addr[addrDim-1:pageAddr_inf], zeroIndex};
pageIndex = addr[colAddrDim-1:0];
end
endtask
// reset page with FF data
task resetPage;
for (i=0; i<=pageDim-1; i=i+1)
page[i] = data_NP;
endtask
// in program operations data latched
// are written in page buffer
task writeDataToPage;
input [dataDim-1:0] data;
reg [addrDim-1:0] destAddr;
begin
page[pageIndex] = data;
pageIndex = pageIndex + 1;
end
endtask
// page buffer is written to the memory
task programPageToMemory; //logic and between old_data and new_data
for (i=0; i<=pageDim-1; i=i+1)
memory[pageStartAddr+i] = memory[pageStartAddr+i] & page[i];
// before page program the page should be reset
endtask
// in read operations data are readed directly from the memory
task readData;
output [dataDim-1:0] data;
begin
data = memory[memAddr];
if (memAddr < memDim-1)
memAddr = memAddr + 1;
else begin
memAddr=0;
$display(" [%0t ns] **WARNING** Highest address reached. Next read will be at the beginning of the memory!", $time);
end
end
endtask
//---------------------------------------
// Tasks used for Page Write operation
//---------------------------------------
// page is written into the memory (old_data are over_written)
task writePageToMemory;
for (i=0; i<=pageDim-1; i=i+1)
memory[pageStartAddr+i] = page[i];
// before page program the page should be reset
endtask
// pageMemory is loaded into the pageBuffer
task loadPageBuffer;
for (i=0; i<=pageDim-1; i=i+1)
page[i] = memory[pageStartAddr+i];
// before page program the page should be reset
endtask
//-----------------------------
// Tasks for erase operations
//-----------------------------
task eraseSector;
input [addrDim-1:0] A;
reg [sectorAddrDim-1:0] sect;
reg [sectorAddr_inf-1:0] zeros;
reg [addrDim-1:0] mAddr;
begin
sect = f.sec(A);
zeros = 'h0;
mAddr = {sect, zeros};
for(i=mAddr; i<=(mAddr+sectorSize-1); i=i+1)
memory[i] = data_NP;
end
endtask
`ifdef SubSect
task eraseSubsector;
input [addrDim-1:0] A;
reg [subsecAddrDim-1:0] subsect;
reg [subsecAddr_inf-1:0] zeros;
reg [addrDim-1:0] mAddr;
begin
subsect = f.sub(A);
zeros = 'h0;
mAddr = {subsect, zeros};
for(i=mAddr; i<=(mAddr+subsecSize-1); i=i+1)
memory[i] = data_NP;
end
endtask
`endif
task eraseBulk;
for (i=0; i<=memDim-1; i=i+1)
memory[i] = data_NP;
endtask
task erasePage;
input [addrDim-1:0] A;
reg [pageAddrDim-1:0] page;
reg [pageAddr_inf-1:0] zeros;
reg [addrDim-1:0] mAddr;
begin
page = f.pag(A);
zeros = 'h0;
mAddr = {page, zeros};
for(i=mAddr; i<=(mAddr+pageDim-1); i=i+1)
memory[i] = data_NP;
end
endtask
endmodule
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-----------------------------------------------------------
-----------------------------------------------------------
-- --
-- UTILITY FUNCTIONS --
-- --
-----------------------------------------------------------
-----------------------------------------------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
module UtilFunctions;
`include "include/DevParam.h"
integer i;
//----------------------------------
// Utility functions for addresses
//----------------------------------
function [sectorAddrDim-1:0] sec;
input [addrDim-1:0] A;
sec = A[sectorAddr_sup:sectorAddr_inf];
endfunction
`ifdef SubSect
function [subsecAddrDim-1:0] sub;
input [addrDim-1:0] A;
sub = A[subsecAddr_sup:subsecAddr_inf];
endfunction
`endif
function [pageAddrDim-1:0] pag;
input [addrDim-1:0] A;
pag = A[pageAddr_sup:pageAddr_inf];
endfunction
function [pageAddrDim-1:0] col;
input [addrDim-1:0] A;
col = A[colAddr_sup:0];
endfunction
//----------------------------------
// Console messages
//----------------------------------
task clock_error;
$display(" [%0t ns] **WARNING** Number of clock pulse isn't multiple of eight: operation aborted!", $time);
endtask
task WEL_error;
$display(" [%0t ns] **WARNING** WEL bit not set: operation aborted!", $time);
endtask
task out_info;
input [addrDim-1:0] A;
input [dataDim-1:0] D;
if (read.enable || read.enable_fast)
$display(" [%0t ns] Data are going to be output: %h. [Read Memory. Address %h (byte %0d of page %0d, sector %0d)] ",
$time, D, A, col(A), pag(A), sec(A));
`ifdef DUAL
else if (read.enable_dual)
$display(" [%0t ns] Data are going to be output: %h. [Read Memory. Address %h (byte %0d of page %0d, sector %0d)] ",
$time, D, A, col(A), pag(A), sec(A));
`endif
else if (stat.enable_SR_read)
$display(" [%0t ns] Data are going to be output: %b. [Read Status Register]",
$time, D);
`ifdef LockReg
else if (lock.enable_lockReg_read)
$display(" [%0t ns] Data are going to be output: %h. [Read Lock Register of sector %0d]",
$time, D, A);
`endif
else if (read.enable_ID)
$display(" [%0t ns] Data are going to be output: %h. [Read ID, byte %0d]", $time, D, A);
`ifdef OTP
else if (read.enable_OTP) begin
if (A!=OTP_dim-1)
$display(" [%0t ns] Data are going to be output: %h. [Read OTP memory, column %0d]", $time, D, A);
else
$display(" [%0t ns] Data are going to be output: %b. [Read OTP memory, column %0d (control byte)]", $time, D, A);
end
`endif
endtask
//----------------------------------------------------
// Special tasks used for testing and debug the model
//----------------------------------------------------
//
// erase the whole memory, and resets pageBuffer and cacheBuffer
//
task fullErase;
begin
for (i=0; i<=memDim-1; i=i+1)
mem.memory[i] = data_NP;
$display("[%0t ns] ==INFO== The whole memory has been erased.", $time);
end
endtask
//
// unlock all sectors of the memory
//
task unlockAll;
begin
for (i=0; i<=nSector-1; i=i+1) begin
`ifdef LockReg
lock.LockReg_WL[i] = 0;
lock.LockReg_LD[i] = 0;
`endif
lock.lock_by_SR[i] = 0;
end
$display("[%0t ns] ==INFO== The whole memory has been unlocked.", $time);
end
endtask
//
// load memory file
//
task load_memory_file;
input [40*8:1] memory_file;
begin
for (i=0; i<=memDim-1; i=i+1)
mem.memory[i] = data_NP;
$readmemh(memory_file, mem.memory);
$display("[%0t ns] ==INFO== Load memory content from file: \"%0s\".", $time, M25Pxxx.memory_file);
end
endtask
endmodule
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-----------------------------------------------------------
-----------------------------------------------------------
-- --
-- PROGRAM MODULE --
-- --
-----------------------------------------------------------
-----------------------------------------------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
module Program;
`include "include/DevParam.h"
event errorCheck, error, noError;
reg [30*8:1] operation; //get the value of the command currently decoded by CUI decoders
time delay;
//----------------------------
// Page Program & Page Write
//----------------------------
reg writePage_en=0;
reg [addrDim-1:0] destAddr;
always @M25Pxxx.seqRecognized
if(M25Pxxx.cmdRecName==="Page Program" || M25Pxxx.cmdRecName==="Dual Program" || M25Pxxx.cmdRecName==="Page Write")
fork : program_ops
begin
operation = M25Pxxx.cmdRecName;
if(operation!="Page Write")
mem.resetPage;
destAddr = M25Pxxx.addr;
mem.setAddr(destAddr);
if(operation=="Page Write")
mem.loadPageBuffer;
if(operation=="Page Program" || operation=="Page Write")
M25Pxxx.latchingMode="D";
else if(operation=="Dual Program") begin
M25Pxxx.latchingMode="F";
release M25Pxxx.`Q;
end
writePage_en = 1;
end
begin : exe
@(posedge M25Pxxx.S);
disable reset;
writePage_en=0;
M25Pxxx.latchingMode="N";
M25Pxxx.busy=1;
$display(" [%0t ns] Command execution begins: %0s.", $time, operation);
if (operation!="Page Write")
delay=program_delay;
`ifdef M25PE16
else if (operation=="Page Write")
delay=page_write_delay; `endif
-> errorCheck;
@(noError) begin
mem.writePageToMemory;
$display(" [%0t ns] Command execution completed: %0s.", $time, operation);
end
end
begin : reset
@M25Pxxx.resetEvent;
writePage_en=0;
operation = "None";
disable exe;
end
join
always @M25Pxxx.dataLatched if(writePage_en) begin
mem.writeDataToPage(M25Pxxx.data);
end
//------------------------
// Write Status register
//------------------------
reg [dataDim-1:0] SR_data;
always @(M25Pxxx.seqRecognized) if (M25Pxxx.cmdRecName=="Write SR") begin : write_SR_ops
M25Pxxx.latchingMode="D";
@(posedge M25Pxxx.S) begin
operation=M25Pxxx.cmdRecName;
SR_data=M25Pxxx.data;
M25Pxxx.latchingMode="N";
M25Pxxx.busy=1;
$display(" [%0t ns] Command execution begins: Write SR.",$time);
delay=write_SR_delay;
-> errorCheck;
@(noError) begin
`ifdef M25PX32
`LOTP=SR_data[7];
`else //M25PE16, M25P128
`SRWD=SR_data[7]; `endif
`ifdef M25PX32
`TB=SR_data[5]; `endif //(TB is not used in M25PE16)
`BP2=SR_data[4];
`BP1=SR_data[3];
`BP0=SR_data[2];
`ifdef M25PX32
$display(" [%0t ns] Command execution completed: Write SR. SR=%h, (LOTP,TB,BP2,BP1,BP0)=%b",
$time, stat.SR, {`LOTP,`TB,`BP2,`BP1,`BP0} );
`else //M25PE16, M25P128
$display(" [%0t ns] Command execution completed: Write SR. SR=%h, (SRWD,BP2,BP1,BP0)=%b",
$time, stat.SR, {`SRWD,`BP2,`BP1,`BP0} );
`endif
end
end
end
//--------------
// Erase
//--------------
always @M25Pxxx.seqRecognized
if (M25Pxxx.cmdRecName==="Sector Erase" || M25Pxxx.cmdRecName==="Subsector Erase" ||
M25Pxxx.cmdRecName==="Bulk Erase" || M25Pxxx.cmdRecName==="Page Erase") fork : erase_ops
begin : exe
@(posedge M25Pxxx.S);
disable reset;
operation = M25Pxxx.cmdRecName;
destAddr = M25Pxxx.addr;
M25Pxxx.latchingMode="N";
M25Pxxx.busy = 1;
$display(" [%0t ns] Command execution begins: %0s.", $time, operation);
if (operation=="Sector Erase") delay=erase_delay;
else if (operation=="Bulk Erase") delay=erase_bulk_delay;
`ifdef M25PE16
else if (operation=="Page Erase") delay=erase_page_delay; `endif
`ifdef SubSect
else if (operation=="Subsector Erase") delay=erase_ss_delay; `endif
-> errorCheck;
@(noError) begin
if (operation=="Sector Erase") mem.eraseSector(destAddr);
else if (operation=="Bulk Erase") mem.eraseBulk;
else if (operation=="Page Erase") mem.erasePage(destAddr);
`ifdef SubSect
else if (operation=="Subsector Erase") mem.eraseSubsector(destAddr); `endif
$display(" [%0t ns] Command execution completed: %0s.", $time, operation);
end
end
begin : reset
@M25Pxxx.resetEvent;
operation = "None";
disable exe;
end
join
//---------------------------
// Program OTP (ifdef OTP)
//---------------------------
`ifdef OTP
reg write_OTP_buffer_en=0;
`define OTP_lockBit M25Pxxx.OTP.mem[OTP_dim-1][0]
always @M25Pxxx.seqRecognized if(M25Pxxx.cmdRecName=="Program OTP")
fork : OTP_prog_ops
begin
OTP.resetBuffer;
OTP.setAddr(M25Pxxx.addr);
M25Pxxx.latchingMode="D";
write_OTP_buffer_en = 1;
end
begin : exe
@(posedge M25Pxxx.S);
disable reset;
operation=M25Pxxx.cmdRecName;
write_OTP_buffer_en=0;
M25Pxxx.latchingMode="N";
M25Pxxx.busy=1;
$display(" [%0t ns] Command execution begins: OTP Program.",$time);
delay=program_delay;
-> errorCheck;
@(noError) begin
OTP.writeBufferToMemory;
$display(" [%0t ns] Command execution completed: OTP Program.",$time);
end
end
begin : reset
@M25Pxxx.resetEvent;
write_OTP_buffer_en=0;
operation = "None";
disable exe;
end
join
always @M25Pxxx.dataLatched if(write_OTP_buffer_en) begin
OTP.writeDataToBuffer(M25Pxxx.data);
end
`endif
//------------------------
// Error check
//------------------------
// This process also models
// the operation delays
always @(errorCheck) fork : errorCheck_ops
begin : static_check
if(M25Pxxx.ck_count!=0) begin
M25Pxxx.f.clock_error;
-> error;
end else if(`WEL==0) begin
M25Pxxx.f.WEL_error;
-> error;
end else if ( (operation=="Page Program" || operation=="Dual Program" || operation=="Page Write" ||
operation=="Sector Erase" || operation=="Subsector Erase" || operation=="Page Erase")
&&
(lock.isProtected_by_SR(destAddr)!==0 || lock.isProtected_by_lockReg(destAddr)!==0) ) begin
-> error;
if (lock.isProtected_by_SR(destAddr)!==0 && lock.isProtected_by_lockReg(destAddr)!==0)
$display(" [%0t ns] **WARNING** Sector locked by Status Register and by Lock Register: operation aborted.", $time);
else if (lock.isProtected_by_SR(destAddr)!==0)
$display(" [%0t ns] **WARNING** Sector locked by Status Register: operation aborted.", $time);
else if (lock.isProtected_by_lockReg(destAddr)!==0)
$display(" [%0t ns] **WARNING** Sector locked by Lock Register: operation aborted.", $time);
end else if (operation=="Bulk Erase" && lock.isAnySectorProtected(0)) begin
$display(" [%0t ns] **WARNING** Some sectors are locked: bulk erase aborted.", $time);
-> error;
end
`ifdef M25PX32
else if(operation=="Write SR" && `LOTP==1) begin
$display(" [%0t ns] **WARNING** Lock OTP bit set to 1: write SR isn't allowed!", $time);
-> error;
end
`elsif M25PE16
else if(operation=="Write SR" && `SRWD==1 && M25Pxxx.W===0) begin
$display(" [%0t ns] **WARNING** SRWD bit set to 1, and W=0: write SR isn't allowed!", $time);
-> error;
end
`elsif M25P128
else if(operation=="Write SR" && `SRWD==1 && M25Pxxx.W_int===0) begin
$display(" [%0t ns] **WARNING** SRWD bit set to 1, and W=0: write SR isn't allowed!", $time);
-> error;
end
`endif
`ifdef OTP
else if (operation=="Program OTP" && `OTP_lockBit==0) begin
$display(" [%0t ns] **WARNING** OTP is read only, because lock bit has been programmed to 0: operation aborted.", $time);
-> error;
end
`endif
end
fork : dynamicCheck
@(M25Pxxx.voltageFault) begin
$display(" [%0t ns] **WARNING** Operation Fault because of Vcc Out of Range!", $time);
-> error;
end
`ifdef RESET_pin
if (operation!="Write SR") @(M25Pxxx.resetEvent) begin
$display(" [%0t ns] **WARNING** Operation Fault because of Device Reset!", $time);
-> error;
end
`endif
#delay begin
M25Pxxx.busy=0;
-> stat.WEL_reset;
-> noError;
disable dynamicCheck;
disable errorCheck_ops;
end
join
join
always @(error) begin
M25Pxxx.busy = 0;
-> stat.WEL_reset;
disable errorCheck_ops;
if (operation=="Page Program" || operation=="Dual Program" || operation=="Page Write") disable program_ops;
else if (operation=="Sector Erase" || operation=="Subsector Erase" || operation=="Bulk Erase") disable erase_ops;
else if (operation=="Write SR") disable write_SR_ops;
`ifdef OTP
else if (operation=="Program OTP") disable OTP_prog_ops;
`endif
end
endmodule
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-----------------------------------------------------------
-----------------------------------------------------------
-- --
-- STATUS REGISTER MODULE --
-- --
-----------------------------------------------------------
-----------------------------------------------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
module StatusRegister;
`include "include/DevParam.h"
// status register
reg [7:0] SR;
//--------------
// Init
//--------------
initial begin
//see alias in DevParam.h
SR[2] = 0; // BP0 - block protect bit 0
SR[3] = 0; // BP1 - block protect bit 1
SR[4] = 0; // BP2 - block protect bit 2
SR[5] = 0; // M25PX32: TB (block protect top/bottom) -- M25PE16, M25P128: not used
SR[6] = 0; // not used
SR[7] = 0; // M25PX32: LOTP - M25PE16, M25P128: SRWD
end
always @(M25Pxxx.ReadAccessOn) if(M25Pxxx.ReadAccessOn) begin
SR[0] = 0; // WIP - write in progress
SR[1] = 0; // WEL - write enable latch
end
//----------
// WIP bit
//----------
always @(M25Pxxx.busy)
`WIP = M25Pxxx.busy;
//----------
// WEL bit
//----------
always @(M25Pxxx.seqRecognized) if (M25Pxxx.cmdRecName=="Write Enable") fork : WREN
begin : exe
@(posedge M25Pxxx.S);
disable reset;
`WEL = 1;
$display(" [%0t ns] Command execution: WEL bit set.", $time);
end
begin : reset
@M25Pxxx.resetEvent;
disable exe;
end
join
always @(M25Pxxx.seqRecognized) if (M25Pxxx.cmdRecName=="Write Disable") fork : WRDI
begin : exe
@(posedge M25Pxxx.S);
disable reset;
`WEL = 0;
$display(" [%0t ns] Command execution: WEL bit reset.", $time);
end
begin : reset
@M25Pxxx.resetEvent;
disable exe;
end
join
event WEL_reset;
always @(WEL_reset)
`WEL = 0;
//------------------------
// write status register
//------------------------
// see "Program" module
//----------------------
// read status register
//----------------------
// NB : "Read SR" operation is also modelled in M25Pxxx.module
reg enable_SR_read;
always @(M25Pxxx.seqRecognized) if (M25Pxxx.cmdRecName=="Read SR") fork
enable_SR_read=1;
@(posedge(M25Pxxx.S) or M25Pxxx.resetEvent or M25Pxxx.voltageFault)
enable_SR_read=0;
join
endmodule
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-----------------------------------------------------------
-----------------------------------------------------------
-- --
-- READ MODULE --
-- --
-----------------------------------------------------------
-----------------------------------------------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
module Read;
`include "include/DevParam.h"
reg enable, enable_fast = 0;
//--------------
// Read
//--------------
// NB : "Read" operation is also modelled in M25Pxxx.module
always @(M25Pxxx.seqRecognized) if (M25Pxxx.cmdRecName=="Read") fork
begin
enable = 1;
mem.setAddr(M25Pxxx.addr);
end
@(posedge(M25Pxxx.S) or M25Pxxx.resetEvent or M25Pxxx.voltageFault)
enable=0;
join
//--------------
// Read Fast
//--------------
always @(M25Pxxx.seqRecognized) if (M25Pxxx.cmdRecName=="Read Fast") fork
begin
mem.setAddr(M25Pxxx.addr);
$display(" [%0t ns] Dummy byte expected ...",$time);
M25Pxxx.latchingMode="Y"; //Y=dummy
@M25Pxxx.dummyLatched;
enable_fast = 1;
M25Pxxx.latchingMode="N";
end
@(posedge(M25Pxxx.S) or M25Pxxx.resetEvent or M25Pxxx.voltageFault)
enable_fast=0;
join
//-----------------
// Read ID
//-----------------
reg enable_ID;
reg [1:0] ID_index;
always @(M25Pxxx.seqRecognized) if (M25Pxxx.cmdRecName=="Read ID") fork
begin
enable_ID = 1;
ID_index=0;
end
@(posedge(M25Pxxx.S) or M25Pxxx.resetEvent or M25Pxxx.voltageFault)
enable_ID=0;
join
//-------------------------
// Dual Read (ifdef DUAL)
//-------------------------
reg enable_dual=0;
`ifdef DUAL
always @(M25Pxxx.seqRecognized) if (M25Pxxx.cmdRecName=="Dual Read") fork
begin
mem.setAddr(M25Pxxx.addr);
$display(" [%0t ns] Dummy byte expected ...",$time);
M25Pxxx.latchingMode="Y"; //Y=dummy
@M25Pxxx.dummyLatched;
enable_dual = 1;
M25Pxxx.latchingMode="N";
end
@(posedge(M25Pxxx.S) or M25Pxxx.resetEvent or M25Pxxx.voltageFault)
enable_dual=0;
join
`endif
//-------------------------
// Read OTP (ifdef OTP)
//-------------------------
// NB : "Read OTP" operation is also modelled in M25Pxxx.module
reg enable_OTP=0;
`ifdef OTP
always @(M25Pxxx.seqRecognized) if (M25Pxxx.cmdRecName=="Read OTP") fork
begin
enable_OTP = 1;
OTP.setAddr(M25Pxxx.addr);
end
@(posedge(M25Pxxx.S) or M25Pxxx.resetEvent or M25Pxxx.voltageFault)
enable_OTP=0;
join
`endif
endmodule
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-----------------------------------------------------------
-----------------------------------------------------------
-- --
-- LOCK MANAGER MODULE --
-- --
-----------------------------------------------------------
-----------------------------------------------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
module LockManager;
`include "include/DevParam.h"
//---------------------------------------------------
// Data structures for protection status modelling
//---------------------------------------------------
// array of sectors lock status (status determinated by Block Protect Status Register bits)
reg [nSector-1:0] lock_by_SR; //(1=locked)
`ifdef LockReg
// Lock Registers (there is a pair of Lock Registers for each sector)
reg LockReg_WL [nSector-1:0]; // Lock Register Write Lock bit (1=lock enabled)
reg LockReg_LD [nSector-1:0]; // Lock Register Lock Down bit (1=lock down enabled)
`endif
integer i;
//----------------------------
// Initial protection status
//----------------------------
initial
for (i=0; i<=nSector-1; i=i+1)
lock_by_SR[i] = 0;
//LockReg_WL & LockReg_LD are initialized by powerUp
//------------------------
// Reset signal effects
//------------------------
`ifdef LockReg
always @M25Pxxx.resetEvent
for (i=0; i<=nSector-1; i=i+1) begin
`ifdef M25PX32
LockReg_WL[i]=1;
`elsif M25PE16
LockReg_WL[i]=0;
`endif
LockReg_LD[i] = 0;
end
`endif
//----------------------------------
// Power up : reset lock registers
//----------------------------------
`ifdef LockReg
always @(M25Pxxx.ReadAccessOn) if(M25Pxxx.ReadAccessOn)
for (i=0; i<=nSector-1; i=i+1) begin
`ifdef M25PX32
LockReg_WL[i]=1;
`elsif M25PE16
LockReg_WL[i]=0;
`endif
LockReg_LD[i] = 0;
end
`endif
//------------------------------------------------
// Protection managed by BP status register bits
//------------------------------------------------
integer nLockedSector;
integer temp;
`ifdef M25PX32
always @(`TB or `BP2 or `BP1 or `BP0) begin
for (i=0; i<=nSector-1; i=i+1) //reset lock status of all sectors
lock_by_SR[i] = 0;
temp = {`BP2, `BP1, `BP0};
nLockedSector = 2**(temp-1);
if (nLockedSector>0 && `TB==0) // upper sectors protected
for ( i=nSector-1 ; i>=nSector-nLockedSector ; i=i-1 ) begin
lock_by_SR[i] = 1;
$display(" [%0t ns] ==INFO== Sector %0d locked", $time, i);
end
else if (nLockedSector>0 && `TB==1) // lower sectors protected
for ( i = 0 ; i <= nLockedSector-1 ; i = i+1 ) begin
lock_by_SR[i] = 1;
$display(" [%0t ns] ==INFO== Sector %0d locked", $time, i);
end
end
`else // M25PE16, M25P128
always @(`BP2 or `BP1 or `BP0) begin
for (i=0; i<=nSector-1; i=i+1) //reset lock status of all sectors
lock_by_SR[i] = 0;
temp = {`BP2, `BP1, `BP0};
nLockedSector = 2**(temp-1);
if (nLockedSector>0) // upper sectors protected
for ( i=nSector-1 ; i>=nSector-nLockedSector && i>=0 ; i=i-1 ) begin
lock_by_SR[i] = 1;
$display(" [%0t ns] ==INFO== Sector %0d locked", $time, i);
end
end
`endif
//--------------------------------------
// Protection managed by Lock Register
//--------------------------------------
reg enable_lockReg_read=0;
`ifdef LockReg
reg [sectorAddrDim-1:0] sect;
reg [dataDim-1:0] sectLockReg;
always @(M25Pxxx.seqRecognized) if (M25Pxxx.cmdRecName=="Write Lock Reg") fork : WRLR
begin : exe1
sect = f.sec(M25Pxxx.addr);
M25Pxxx.latchingMode = "D";
@(M25Pxxx.dataLatched) sectLockReg = M25Pxxx.data;
end
begin : exe2
@(posedge M25Pxxx.S);
disable exe1;
disable reset;
-> stat.WEL_reset;
if(`WEL==0)
M25Pxxx.f.WEL_error;
else if (LockReg_LD[sect]==1)
$display(" [%0t ns] **WARNING** Lock Down bit is set. Write lock register is not allowed!", $time);
else begin
LockReg_LD[sect]=sectLockReg[1];
LockReg_WL[sect]=sectLockReg[0];
$display(" [%0t ns] Command execution: lock register of sector %0d set to (%b,%b)",
$time, sect, LockReg_LD[sect], LockReg_WL[sect] );
end
end
begin : reset
@M25Pxxx.resetEvent;
disable exe1;
disable exe2;
end
join
// Read lock register
always @(M25Pxxx.seqRecognized) if (M25Pxxx.cmdRecName=="Read Lock Reg") fork
begin
sect = f.sec(M25Pxxx.addr);
M25Pxxx.dataOut = {4'b0, LockReg_LD[sect], LockReg_WL[sect]};
enable_lockReg_read=1;
end
@(posedge(M25Pxxx.S) or M25Pxxx.resetEvent or M25Pxxx.voltageFault)
enable_lockReg_read=0;
join
`endif
//-------------------------------------------
// Function to test sector protection status
//-------------------------------------------
function isProtected_by_SR;
input [addrDim-1:0] byteAddr;
reg [sectorAddrDim-1:0] sectAddr;
begin
sectAddr = f.sec(byteAddr);
isProtected_by_SR = lock_by_SR[sectAddr];
end
endfunction
function isProtected_by_lockReg;
input [addrDim-1:0] byteAddr;
reg [sectorAddrDim-1:0] sectAddr;
begin
`ifdef LockReg
sectAddr = f.sec(byteAddr);
isProtected_by_lockReg = LockReg_WL[sectAddr];
`else
isProtected_by_lockReg = 0; //if LockReg is not defined the function return always zero
`endif
end
endfunction
function isAnySectorProtected;
input required;
begin
i=0;
isAnySectorProtected=0;
while(isAnySectorProtected==0 && i<=nSector-1) begin
`ifdef LockReg
isAnySectorProtected=lock_by_SR[i] || LockReg_WL[i];
`else
isAnySectorProtected=lock_by_SR[i]; `endif
i=i+1;
end
end
endfunction
endmodule
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-----------------------------------------------------------
-----------------------------------------------------------
-- --
-- TIMING CHECK --
-- --
-----------------------------------------------------------
-----------------------------------------------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
module TimingCheck (S, C, D, Q, W, H); //P128
`include "include/DevParam.h"
input S, C, D, Q;
`ifdef HOLD_pin
input H; `endif
`ifdef W_pin
input W; `endif
`ifdef Vpp_W_pin
input W; `endif
`ifdef RESET_pin
input R; `endif
`ifdef W_pin
`define W_feature
`elsif Vpp_W_pin
`define W_feature
`endif
time delta; //used for interval measuring
//--------------------------
// Task for timing check
//--------------------------
task check;
input [8*8:1] name; //constraint check
input time interval;
input time constr;
begin
if (interval<constr)
$display("[%0t ns] --TIMING ERROR-- %0s constraint violation. Measured time: %0t ns - Constraint: %0t ns",
$time, name, interval, constr);
end
endtask
//----------------------------
// Istants to be measured
//----------------------------
parameter initialTime = -1000;
time C_high=initialTime, C_low=initialTime;
time S_low=initialTime, S_high=initialTime;
time D_valid=initialTime;
`ifdef HOLD_pin
time H_low=initialTime, H_high=initialTime; `endif
`ifdef RESET_pin
time R_low=initialTime, R_high=initialTime; `endif
`ifdef W_feature
time W_low=initialTime, W_high=initialTime; `endif
//------------------------
// C signal checks
//------------------------
always
@C if(C===0) //posedge(C)
@C if(C===1)
begin
delta = $time - C_low;
check("tCL", delta, tCL);
delta = $time - S_low;
check("tSLCH", delta, tSLCH);
delta = $time - D_valid;
check("tDVCH", delta, tDVCH);
delta = $time - S_high;
check("tSHCH", delta, tSHCH);
// clock frequency checks
delta = $time - C_high;
if (read.enable && delta<TR)
$display("[%0t ns] --TIMING ERROR-- Violation of Max clock frequency (%0d MHz) during READ operation. T_ck_measured=%0d ns, T_clock_min=%0d ns.",
$time, fR, delta, TR);
else if ( (read.enable_fast || read.enable_ID || read.enable_dual || read.enable_OTP ||
stat.enable_SR_read || lock.enable_lockReg_read )
&&
delta<TC )
//else if ( !read.enable && delta<TC ) da verificare
$display("[%0t ns] --TIMING ERROR-- Violation of Max clock frequency (%0d MHz). T_ck_measured=%0d ns, T_clock_min=%0d ns.",
$time, fC, delta, TC);
`ifdef HOLD_pin
delta = $time - H_low;
check("tHLCH", delta, tHLCH);
delta = $time - H_high;
check("tHHCH", delta, tHHCH);
`endif
C_high = $time;
end
always
@C if(C===1) //negedge(C)
@C if(C===0)
begin
delta = $time - C_high;
check("tCH", delta, tCH);
C_low = $time;
end
//------------------------
// S signal checks
//------------------------
always
@S if(S===1) //negedge(S)
@S if(S===0)
begin
delta = $time - C_high;
check("tCHSL", delta, tCHSL);
delta = $time - S_high;
check("tSHSL", delta, tSHSL);
`ifdef W_feature
delta = $time - W_high;
check("tWHSL", delta, tWHSL);
`endif
`ifdef RESET_pin
//check during decoding
if (M25Pxxx.resetDuringDecoding) begin
delta = $time - R_high;
check("tRHSL", delta, tRHSL_1);
M25Pxxx.resetDuringDecoding = 0;
end
//check during program-erase operation
else if ( M25Pxxx.resetDuringBusy && (prog.operation=="Page Program" || prog.operation=="Page Write" ||
prog.operation=="Sector Erase" || prog.operation=="Bulk Erase" || prog.operation=="Page Erase") )
begin
delta = $time - R_high;
check("tRHSL", delta, tRHSL_2);
M25Pxxx.resetDuringBusy = 0;
end
//check during subsector erase
else if ( M25Pxxx.resetDuringBusy && prog.operation=="Subsector Erase" ) begin
delta = $time - R_high;
check("tRHSL", delta, tRHSL_3);
M25Pxxx.resetDuringBusy = 0;
end
//check during WRSR
else if ( M25Pxxx.resetDuringBusy && prog.operation=="Write SR" ) begin
delta = $time - R_high;
check("tRHSL", delta, tRHSL_4);
M25Pxxx.resetDuringBusy = 0;
end
`endif
S_low = $time;
end
always
@S if(S===0) //posedge(S)
@S if(S===1)
begin
delta = $time - C_high;
check("tCHSH", delta, tCHSH);
S_high = $time;
end
//----------------------------
// D signal (data in) checks
//----------------------------
always @D
begin
delta = $time - C_high;
check("tCHDX", delta, tCHDX);
if (isValid(D)) D_valid = $time;
end
//------------------------
// Hold signal checks
//------------------------
`ifdef HOLD_pin
always
@H if(H===1) //negedge(H)
@H if(H===0)
begin
delta = $time - C_high;
check("tCHHL", delta, tCHHL);
H_low = $time;
end
always
@H if(H===0) //posedge(H)
@H if(H===1)
begin
delta = $time - C_high;
check("tCHHH", delta, tCHHH);
H_high = $time;
end
`endif
//------------------------
// W signal checks
//------------------------
`ifdef W_feature
always
@W if(W===1) //negedge(W)
@W if(W===0)
begin
delta = $time - S_high;
check("tSHWL", delta, tSHWL);
W_low = $time;
end
always
@W if(W===0) //posedge(W)
@W if(W===1)
W_high = $time;
`endif
//------------------------
// RESET signal checks
//------------------------
`ifdef RESET_pin
always
@R if(R===1) //negedge(R)
@R if(R===0)
R_low = $time;
always
@R if(R===0) //posedge(R)
@R if(R===1)
begin
delta = $time - S_high;
check("tSHRH", delta, tSHRH);
delta = $time - R_low;
check("tRLRH", delta, tRLRH);
R_high = $time;
end
`endif
//----------------
// Others tasks
//----------------
function isValid;
input bit;
if (bit!==0 && bit!==1) isValid=0;
else isValid=1;
endfunction
endmodule
`define ADDR_GLD_CSR 5'h0
`define GLD_CSR_SLOT_COUNT_OFFSET 0
`define GLD_CSR_SLOT_COUNT 32'h0000000f
`define GLD_CSR_FMC_PRESENT_OFFSET 4
`define GLD_CSR_FMC_PRESENT 32'h000000f0
`define ADDR_GLD_I2CR0 5'h4
`define GLD_I2CR0_SCL_OUT_OFFSET 0
`define GLD_I2CR0_SCL_OUT 32'h00000001
`define GLD_I2CR0_SDA_OUT_OFFSET 1
`define GLD_I2CR0_SDA_OUT 32'h00000002
`define GLD_I2CR0_SCL_IN_OFFSET 2
`define GLD_I2CR0_SCL_IN 32'h00000004
`define GLD_I2CR0_SDA_IN_OFFSET 3
`define GLD_I2CR0_SDA_IN 32'h00000008
`define ADDR_GLD_I2CR1 5'h8
`define GLD_I2CR1_SCL_OUT_OFFSET 0
`define GLD_I2CR1_SCL_OUT 32'h00000001
`define GLD_I2CR1_SDA_OUT_OFFSET 1
`define GLD_I2CR1_SDA_OUT 32'h00000002
`define GLD_I2CR1_SCL_IN_OFFSET 2
`define GLD_I2CR1_SCL_IN 32'h00000004
`define GLD_I2CR1_SDA_IN_OFFSET 3
`define GLD_I2CR1_SDA_IN 32'h00000008
`define ADDR_GLD_I2CR2 5'hc
`define GLD_I2CR2_SCL_OUT_OFFSET 0
`define GLD_I2CR2_SCL_OUT 32'h00000001
`define GLD_I2CR2_SDA_OUT_OFFSET 1
`define GLD_I2CR2_SDA_OUT 32'h00000002
`define GLD_I2CR2_SCL_IN_OFFSET 2
`define GLD_I2CR2_SCL_IN 32'h00000004
`define GLD_I2CR2_SDA_IN_OFFSET 3
`define GLD_I2CR2_SDA_IN 32'h00000008
`define ADDR_GLD_I2CR3 5'h10
`define GLD_I2CR3_SCL_OUT_OFFSET 0
`define GLD_I2CR3_SCL_OUT 32'h00000001
`define GLD_I2CR3_SDA_OUT_OFFSET 1
`define GLD_I2CR3_SDA_OUT 32'h00000002
`define GLD_I2CR3_SCL_IN_OFFSET 2
`define GLD_I2CR3_SCL_IN 32'h00000004
`define GLD_I2CR3_SDA_IN_OFFSET 3
`define GLD_I2CR3_SDA_IN 32'h00000008
`define ADDR_SXLDR_CSR 5'h0
`define SXLDR_CSR_START_OFFSET 0
`define SXLDR_CSR_START 32'h00000001
`define SXLDR_CSR_DONE_OFFSET 1
`define SXLDR_CSR_DONE 32'h00000002
`define SXLDR_CSR_ERROR_OFFSET 2
`define SXLDR_CSR_ERROR 32'h00000004
`define SXLDR_CSR_BUSY_OFFSET 3
`define SXLDR_CSR_BUSY 32'h00000008
`define SXLDR_CSR_MSBF_OFFSET 4
`define SXLDR_CSR_MSBF 32'h00000010
`define SXLDR_CSR_SWRST_OFFSET 5
`define SXLDR_CSR_SWRST 32'h00000020
`define SXLDR_CSR_EXIT_OFFSET 6
`define SXLDR_CSR_EXIT 32'h00000040
`define SXLDR_CSR_CLKDIV_OFFSET 8
`define SXLDR_CSR_CLKDIV 32'h00003f00
`define SXLDR_CSR_VERSION_OFFSET 14
`define SXLDR_CSR_VERSION 32'h003fc000
`define ADDR_SXLDR_BTRIGR 5'h4
`define ADDR_SXLDR_FAR 5'h8
`define SXLDR_FAR_DATA_OFFSET 0
`define SXLDR_FAR_DATA 32'h000000ff
`define SXLDR_FAR_XFER_OFFSET 8
`define SXLDR_FAR_XFER 32'h00000100
`define SXLDR_FAR_READY_OFFSET 9
`define SXLDR_FAR_READY 32'h00000200
`define SXLDR_FAR_CS_OFFSET 10
`define SXLDR_FAR_CS 32'h00000400
`define ADDR_SXLDR_IDR 5'hc
`define ADDR_SXLDR_FIFO_R0 5'h10
`define SXLDR_FIFO_R0_XSIZE_OFFSET 0
`define SXLDR_FIFO_R0_XSIZE 32'h00000003
`define SXLDR_FIFO_R0_XLAST_OFFSET 2
`define SXLDR_FIFO_R0_XLAST 32'h00000004
`define ADDR_SXLDR_FIFO_R1 5'h14
`define SXLDR_FIFO_R1_XDATA_OFFSET 0
`define SXLDR_FIFO_R1_XDATA 32'hffffffff
`define ADDR_SXLDR_FIFO_CSR 5'h18
`define SXLDR_FIFO_CSR_FULL_OFFSET 16
`define SXLDR_FIFO_CSR_FULL 32'h00010000
`define SXLDR_FIFO_CSR_EMPTY_OFFSET 17
`define SXLDR_FIFO_CSR_EMPTY 32'h00020000
`define SXLDR_FIFO_CSR_CLEAR_BUS_OFFSET 18
`define SXLDR_FIFO_CSR_CLEAR_BUS 32'h00040000
`define SXLDR_FIFO_CSR_USEDW_OFFSET 0
`define SXLDR_FIFO_CSR_USEDW 32'h000000ff
`timescale 1ns/1ns
module sn74vmeh22501 (
input oeab1,
oeby1_n,
a1,
output y1,
inout b1,
input oeab2,
oeby2_n,
a2,
output y2,
inout b2,
input oe_n,
input dir,
clkab,
le,
clkba,
inout [1:8] a3,
inout [1:8] b3);
assign b1 = oeab1 ? a1 : 1'bz;
assign y1 = oeby1_n ? 1'bz : b1;
assign b2 = oeab2 ? a2 : 1'bz;
assign y2 = oeby2_n ? 1'bz : b2;
reg [1:8] b3LFF;
always @(posedge clkab) if (~le) b3LFF <= #1 a3;
always @* if (le) b3LFF = a3;
assign b3 = (~oe_n && dir) ? b3LFF : 8'hz;
reg [1:8] a3LFF;
always @(posedge clkba) if (~le) a3LFF <= #1 b3;
always @* if (le) a3LFF = b3;
assign a3 = (~oe_n && ~dir) ? a3LFF : 8'hz;
endmodule
`include "components/sn74vmeh22501.v"
`include "vme64x_bfm.svh"
module bidir_buf(
a,
b,
dir, /* 0: a->b, 1: b->a */
oe_n );
parameter g_width = 1;
inout [g_width-1:0] a,b;
input dir, oe_n;
assign b = (!dir && !oe_n) ? a : 'bz;
assign a = (dir && !oe_n) ? b : 'bz;
endmodule // bidir_buf
module svec_vme_buffers (
output VME_AS_n_o,
output VME_RST_n_o,
output VME_WRITE_n_o,
output [5:0] VME_AM_o,
output [1:0] VME_DS_n_o,
output [5:0] VME_GA_o,
input VME_BERR_i,
input VME_DTACK_n_i,
input VME_RETRY_n_i,
input VME_RETRY_OE_i,
inout VME_LWORD_n_b,
inout [31:1] VME_ADDR_b,
inout [31:0] VME_DATA_b,
output VME_BBSY_n_o,
input [6:0] VME_IRQ_n_i,
output VME_IACKIN_n_o,
input VME_IACKOUT_n_i,
output VME_IACK_n_o,
input VME_DTACK_OE_i,
input VME_DATA_DIR_i,
input VME_DATA_OE_N_i,
input VME_ADDR_DIR_i,
input VME_ADDR_OE_N_i,
IVME64X.slave slave
);
pullup(slave.as_n);
pullup(slave.rst_n);
pullup(slave.irq_n[0]);
pullup(slave.irq_n[1]);
pullup(slave.irq_n[2]);
pullup(slave.irq_n[3]);
pullup(slave.irq_n[4]);
pullup(slave.irq_n[5]);
pullup(slave.irq_n[6]);
pullup(slave.iack_n);
pullup(slave.dtack_n);
pullup(slave.retry_n);
pullup(slave.ds_n[1]);
pullup(slave.ds_n[0]);
pullup(slave.lword_n);
pullup(slave.berr_n);
pullup(slave.write_n);
pulldown(slave.bbsy_n);
pullup(slave.iackin_n);
assign VME_RST_n_o = slave.rst_n;
assign VME_AS_n_o = slave.as_n;
assign VME_GA_o = slave.ga;
assign VME_WRITE_n_o = slave.write_n;
assign VME_AM_o = slave.am;
assign VME_DS_n_o = slave.ds_n;
assign VME_BBSY_n_o = slave.bbsy_n;
assign VME_IACKIN_n_o = slave.iackin_n;
assign VME_IACK_n_o = slave.iack_n;
bidir_buf #(1) b0 (slave.lword_n, VME_LWORD_n_b, VME_ADDR_DIR_i, VME_ADDR_OE_N_i);
bidir_buf #(31) b1 (slave.addr, VME_ADDR_b, VME_ADDR_DIR_i, VME_ADDR_OE_N_i);
bidir_buf #(33) b2 (slave.data, VME_DATA_b, VME_DATA_DIR_i, VME_DATA_OE_N_i);
pulldown(VME_BERR_i);
pulldown(VME_ADDR_DIR_i);
pulldown(VME_ADDR_OE_N_i);
pulldown(VME_DATA_DIR_i);
pulldown(VME_DATA_OE_N_i);
assign slave.dtack_n = VME_DTACK_n_i;
assign slave.berr_n = ~VME_BERR_i;
assign slave.retry_n = VME_RETRY_n_i;
endmodule
`define DECLARE_VME_BUFFERS(iface) \
wire VME_AS_n;\
wire VME_RST_n;\
wire VME_WRITE_n;\
wire [5:0] VME_AM;\
wire [1:0] VME_DS_n;\
wire VME_BERR;\
wire VME_DTACK_n;\
wire VME_RETRY_n;\
wire VME_RETRY_OE;\
wire VME_LWORD_n;\
wire [31:1]VME_ADDR;\
wire [31:0]VME_DATA;\
wire VME_BBSY_n;\
wire [6:0]VME_IRQ_n;\
wire VME_IACKIN_n,VME_IACK_n;\
wire VME_IACKOUT_n;\
wire VME_DTACK_OE;\
wire VME_DATA_DIR;\
wire VME_DATA_OE_N;\
wire VME_ADDR_DIR;\
wire VME_ADDR_OE_N;\
svec_vme_buffers U_VME_Bufs ( \
.VME_AS_n_o(VME_AS_n),\
.VME_RST_n_o(VME_RST_n),\
.VME_WRITE_n_o(VME_WRITE_n),\
.VME_AM_o(VME_AM),\
.VME_DS_n_o(VME_DS_n),\
.VME_BERR_i(VME_BERR),\
.VME_DTACK_n_i(VME_DTACK_n),\
.VME_RETRY_n_i(VME_RETRY_n),\
.VME_RETRY_OE_i(VME_RETRY_OE),\
.VME_LWORD_n_b(VME_LWORD_n),\
.VME_ADDR_b(VME_ADDR),\
.VME_DATA_b(VME_DATA),\
.VME_BBSY_n_o(VME_BBSY_n),\
.VME_IRQ_n_i(VME_IRQ_n),\
.VME_IACK_n_o(VME_IACK_n),\
.VME_IACKIN_n_o(VME_IACKIN_n),\
.VME_IACKOUT_n_i(VME_IACKOUT_n),\
.VME_DTACK_OE_i(VME_DTACK_OE),\
.VME_DATA_DIR_i(VME_DATA_DIR),\
.VME_DATA_OE_N_i(VME_DATA_OE_N),\
.VME_ADDR_DIR_i(VME_ADDR_DIR),\
.VME_ADDR_OE_N_i(VME_ADDR_OE_N),\
.slave(iface)\
);
function automatic bit[5:0] _gen_ga(int slot);
bit[4:0] slot_id = slot;
return {^slot_id, ~slot_id};
endfunction // _gen_ga
`define WIRE_VME_PINS(slot_id) \
.VME_AS_n_i(VME_AS_n),\
.VME_RST_n_i(VME_RST_n),\
.VME_WRITE_n_i(VME_WRITE_n),\
.VME_AM_i(VME_AM),\
.VME_DS_n_i(VME_DS_n),\
.VME_GA_i(_gen_ga(slot_id)),\
.VME_BERR_o(VME_BERR),\
.VME_DTACK_n_o(VME_DTACK_n),\
.VME_RETRY_n_o(VME_RETRY_n),\
.VME_RETRY_OE_o(VME_RETRY_OE),\
.VME_LWORD_n_b(VME_LWORD_n),\
.VME_ADDR_b(VME_ADDR),\
.VME_DATA_b(VME_DATA),\
.VME_BBSY_n_i(VME_BBSY_n),\
.VME_IRQ_n_o(VME_IRQ_n),\
.VME_IACK_n_i(VME_IACK_n),\
.VME_IACKIN_n_i(VME_IACKIN_n),\
.VME_IACKOUT_n_o(VME_IACKOUT_n),\
.VME_DTACK_OE_o(VME_DTACK_OE),\
.VME_DATA_DIR_o(VME_DATA_DIR),\
.VME_DATA_OE_N_o(VME_DATA_OE_N),\
.VME_ADDR_DIR_o(VME_ADDR_DIR),\
.VME_ADDR_OE_N_o(VME_ADDR_OE_N)
\ No newline at end of file
`ifndef __VME64X_BFM_SVH
`define __VME64X_BFM_SVH 1
`timescale 1ns/1ps
`include "simdrv_defs.svh"
`define assert_wait(name, condition, timeout) \
begin\
time t=$time;\
while(!(condition)) begin\
#1ns;\
if($time - t > timeout) begin\
$display("Wait timeout : ", `"name`"); \
// $stop;\
break;\
end\
end\
end
interface IVME64X ( input sys_rst_n_i );
wire as_n;
wire rst_n;
wire write_n;
wire [5:0] am;
wire [1:0] ds_n;
wire [5:0] ga;
wire berr_n, dtack_n;
wire retry_n;
wire lword_n;
wire [31:1] addr;
wire [31:0] data;
wire bbsy_n;
wire [6:0] irq_n;
wire iackin_n, iackout_n, iack_n;
logic q_as_n = 1'bz;
logic q_rst_n = 1'bz;
logic q_write_n = 1'bz;
logic [5:0] q_am = 6'bz;
logic [1:0] q_ds_n = 2'bz;
logic [5:0] q_ga = 6'bz;
logic q_berr_n = 1'bz, q_dtack_n = 1'bz;
logic q_retry_n = 1'bz;
logic q_lword_n = 1'bz;
logic [31:1] q_addr = 31'bz;
logic [31:0] q_data = 32'bz;
logic q_bbsy_n = 1'bz;
logic [6:0] q_irq_n = 7'bz;
logic q_iackin_n = 1'bz, q_iackout_n = 1'bz, q_iack_n = 1'bz;
/* SystemVerilog does not allow pullups inside interfaces or on logic type */
assign as_n = q_as_n;
assign rst_n = q_rst_n;
assign write_n = q_write_n;
assign am = q_am;
assign ds_n = q_ds_n;
assign ga = q_ga;
assign berr_n = q_berr_n;
assign dtack_n = q_dtack_n;
assign retry_n = q_retry_n;
assign lword_n = q_lword_n;
assign addr = q_addr;
assign data = q_data;
assign bbsy_n = q_bbsy_n;
assign irq_n = q_irq_n;
assign iackin_n = q_iackin_n;
assign iackout_n = q_iackout_n;
assign iack_n = q_iack_n;
// VME Master
modport tb
(
output as_n,
output rst_n,
output write_n,
output am,
output ds_n,
output ga,
output bbsy_n,
output iackin_n,
output iack_n,
input berr_n,
input irq_n,
input iackout_n,
inout addr,
inout data,
inout lword_n,
inout retry_n,
inout dtack_n,
input q_as_n,
input q_rst_n,
input q_write_n,
input q_am,
input q_ds_n,
input q_ga,
input q_bbsy_n,
input q_iackin_n,
input q_iack_n,
input q_berr_n,
input q_irq_n,
input q_iackout_n,
input q_addr,
input q_data,
input q_lword_n,
input q_retry_n,
input q_dtack_n
);
modport master
(
output as_n,
output rst_n,
output write_n,
output am,
output ds_n,
output ga,
output bbsy_n,
output iackin_n,
output iack_n,
input berr_n,
input irq_n,
input iackout_n,
inout addr,
inout data,
inout lword_n,
inout retry_n,
inout dtack_n);
// VME Slave
modport slave
(
input as_n,
input rst_n,
input write_n,
input am,
input ds_n,
input ga,
input bbsy_n,
input iackin_n,
input iack_n,
output berr_n,
output irq_n,
output iackout_n,
inout addr,
inout data,
inout lword_n,
inout retry_n,
inout dtack_n
);
initial forever begin
@(posedge sys_rst_n_i);
#100ns;
q_rst_n = 0;
#100ns;
q_rst_n = 1;
end
endinterface // IVME64x
const uint64_t CSR_BAR = 'h7FFFF;
const uint64_t CSR_BIT_SET_REG = 'h7FFFB;
const uint64_t CSR_BIT_CLR_REG = 'h7FFF7;
const uint64_t CSR_CRAM_OWNER = 'h7FFF3;
const uint64_t CSR_USR_BIT_SET_REG = 'h7FFEF;
const uint64_t CSR_USR_BIT_CLR_REG = 'h7FFEB;
typedef enum { DONT_CARE = 'h100,
A16 = 'h200,
A24 = 'h300,
A32 = 'h400,
A64 = 'h500
} vme_addr_size_t;
typedef enum {
SINGLE = 'h10, CR_CSR='h20, MBLT='h30, BLT='h40, LCK='h50, TwoeVME='h60, TwoeSST='h70 } vme_xfer_type_t;
typedef enum { D08Byte0='h1, D08Byte1='h2, D08Byte2='h3, D08Byte3='h4, D16Byte01='h5, D16Byte23='h6, D32='h7 } vme_data_type_t ;
class CBusAccessor_VME64x extends CBusAccessor;
const bit [3:0] dt_map [vme_data_type_t] =
'{
D08Byte0 : 4'b0101,
D08Byte1 : 4'b1001,
D08Byte2 : 4'b0111,
D08Byte3 : 4'b1011,
D16Byte01 : 4'b0001,
D16Byte23 : 4'b0011,
D32 : 4'b0000};
protected bit [7:0] m_ba;
protected bit [4:0] m_ga;
virtual IVME64X.tb vme;
function new(virtual IVME64X.tb _vme);
vme = _vme;
m_ga = 6'b010111;
vme.q_ga = m_ga;
m_ba = 8'b10000000;
endfunction // new
protected task set_address(uint64_t addr_in, vme_addr_size_t asize, vme_xfer_type_t xtype);
bit[63:0] a = addr_in;
bit [31:0] a_out;
const bit [5:0] am_map [int] =
'{
A32 | CR_CSR : 6'b101111,
A24 | CR_CSR : 6'b101111,
A16 | SINGLE: 6'b101001,
A16 | LCK : 6'b101100,
A24 | SINGLE: 6'b111001,
A24 | BLT : 6'b111011,
A24 | MBLT : 6'b111000,
A24 | LCK : 6'b110010,
A32 | SINGLE: 6'b001001,
A32 | BLT : 6'b001011,
A32 | MBLT : 6'b001000,
A32 | LCK : 6'b000101,
A64 | SINGLE: 6'b000001,
A64 | BLT : 6'b000011,
A64 | MBLT : 6'b000000,
A64 | LCK : 6'b001000,
A32 | TwoeVME : 6'b100000,
A64 | TwoeVME : 6'b100000,
A32 | TwoeSST : 6'b100000,
A64 | TwoeSST : 6'b100000};
vme.q_am = am_map[asize|xtype];
if(xtype == CR_CSR)
a_out = {8'h0, ~m_ga[4:0], a[18:0]};
else case(asize)
A16:
a_out = {16'h0, m_ba[7:3], a[10:2], 2'b00};
A24:
a_out = {8'h0, a[23:2], 2'b00};
A32:
a_out = {a[31:2], 2'b00};
endcase // case (xtype)
vme.q_addr[31:2] = a_out[31:2];
endtask // set_address
protected task release_bus();
vme.q_as_n = 1'bz;
vme.q_write_n = 1'bz;
vme.q_ds_n = 2'bzz;
vme.q_lword_n = 1'bz;
vme.q_addr = 0;
vme.q_data = 32'bz;
endtask // release_bus
/* Simple generic VME read/write: single, BLT and CSR xfers */
protected task rw_generic(bit write, uint64_t _addr, ref uint64_t _data[], input vme_addr_size_t asize, input vme_xfer_type_t xtype, vme_data_type_t dtype);
bit[3:0] dt;
int i;
`assert_wait(tmo_rws_bus_free, vme.dtack_n && vme.berr_n, 10us)
release_bus();
#10ns;
set_address(_addr, asize, xtype);
dt = dt_map[dtype];
vme.q_lword_n = dt[0];
vme.q_addr[1] = dt[1];
vme.q_write_n = !write;
#35ns;
vme.q_as_n = 0;
#10ns;
// $display("RWG %x\n", _data.size());
for(i=0;i<_data.size();i++)
begin
if(write)
vme.q_data = (dtype == D08Byte0 || dtype == D08Byte2) ? (_data[i] << 8) : (_data[i]);
#35ns;
vme.q_ds_n = dt[3:2];
`assert_wait(tmo_rws_bus_idle, !vme.dtack_n || !vme.berr_n, 4us)
if(!vme.berr_n)
$error("[rw_simple_generic]: VME bus error.");
if(!write)
_data[i] = (dtype == D08Byte0 || dtype == D08Byte2) ? (vme.data >> 8) : (vme.data);
#10ns;
end // for (i=0;i<_data.size();i++)
release_bus();
endtask // rw_generic
protected task extract_xtype(int s, ref vme_xfer_type_t xtype, vme_addr_size_t asize, vme_data_type_t dtype);
xtype = vme_xfer_type_t'( s & 'h0f0);
asize = vme_addr_size_t'( s & 'hf00);
dtype = vme_data_type_t'( s & 'h00f);
endtask // extract_xtype
protected int m_default_modifiers = A32 | SINGLE | D32;
task set_default_modifiers(int mods);
m_default_modifiers = mods;
endtask // set_default_modifiers
task writem(uint64_t addr[], uint64_t data[], input int size = m_default_modifiers, ref int result);
int i;
vme_addr_size_t asize;
vme_data_type_t dtype;
vme_xfer_type_t xtype;
extract_xtype(size, xtype, asize, dtype);
if(xtype == SINGLE || xtype == CR_CSR)
for(i=0;i<addr.size();i++)
begin
uint64_t tmp[];
tmp = new[1];
tmp[0] = data[i];
rw_generic(1, addr[i], tmp, asize, xtype, dtype);
end
else if (xtype == BLT)
rw_generic(1, addr[0], data, asize, xtype, dtype);
endtask // writem
task readm(uint64_t addr[], ref uint64_t data[], input int size = m_default_modifiers, ref int result);
int i;
vme_addr_size_t asize;
vme_data_type_t dtype;
vme_xfer_type_t xtype;
extract_xtype(size, xtype, asize, dtype);
if(xtype == SINGLE || xtype == CR_CSR)
for(i=0;i<addr.size();i++)
begin
uint64_t tmp[];
tmp=new[1];
rw_generic(0, addr[i], tmp, asize, xtype, dtype);
data[i] = tmp[0];
end
endtask // readm
task read(uint64_t addr, ref uint64_t data, input int size = m_default_modifiers, ref int result = _null);
int res;
uint64_t aa[1], da[];
da= new[1];
aa[0] = addr;
readm(aa, da, size, res);
data = da[0];
endtask
task write(uint64_t addr, uint64_t data, input int size = m_default_modifiers, ref int result = _null);
uint64_t aa[], da[];
aa=new[1];
da=new[1];
// $display("VMEWrite s %x", size);
aa[0] = addr;
da[0] = data;
writem(aa, da, size, result);
endtask
endclass // CBusAccessor_VME64x
`endif // `ifndef __VME64X_BFM_SVH
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment