Commit 352c0db5 authored by Dimitris Lampridis's avatar Dimitris Lampridis

[hdl] sanitise folder structure

parent 4d45fbd7
if target=="xilinx":
modules = {
"local" : [
"hdl/gn4124core/rtl",
"hdl/rtl",
],
}
if action == "simulation":
modules['local'].append("hdl/gn4124core/sim/gn4124_bfm")
modules['local'].append("hdl/sim/gn4124_bfm")
......@@ -8,7 +8,7 @@ vcom_opt = "-93 -mixedsvvh"
# Allow the user to override fetchto using:
# hdlmake -p "fetchto='xxx'"
if locals().get('fetchto', None) is None:
fetchto = "../../../ip_cores"
fetchto = "../../ip_cores"
include_dirs = [
"../gn4124_bfm",
......@@ -21,10 +21,9 @@ files = [
modules = {
"local" : [
"../gn4124_bfm",
"../../rtl",
"../../../",
],
"git" : [
"git://ohwr.org/hdl-core-lib/general-cores.git",
"https://ohwr.org/project/general-cores.git",
],
}
files = ["dummy_ctrl_regs.vhd",
"dummy_stat_regs.vhd",
"wb_addr_decoder.vhd"]
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for Dummy control registers
---------------------------------------------------------------------------------------
-- File : ../rtl/dummy_ctrl_regs.vhd
-- Author : auto-generated by wbgen2 from dummy_ctrl_regs_wb_slave.wb
-- Created : Fri May 13 11:28:38 2011
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE dummy_ctrl_regs_wb_slave.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity dummy_ctrl_regs_wb_slave is
port (
rst_n_i : in std_logic;
wb_clk_i : in std_logic;
wb_addr_i : in std_logic_vector(1 downto 0);
wb_data_i : in std_logic_vector(31 downto 0);
wb_data_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
-- Ports for PASS_THROUGH field: 'IRQ' in reg: 'DUMMY_1'
dummy_reg_1_o : out std_logic_vector(31 downto 0);
dummy_reg_1_wr_o : out std_logic;
-- Port for std_logic_vector field: 'Dummy register 2' in reg: 'DUMMY_2'
dummy_reg_2_o : out std_logic_vector(31 downto 0);
-- Port for std_logic_vector field: 'Dummy register 3' in reg: 'DUMMY_3'
dummy_reg_3_o : out std_logic_vector(31 downto 0);
-- Port for std_logic_vector field: 'Dummy register for LED control' in reg: 'DUMMY_LED'
dummy_reg_led_o : out std_logic_vector(31 downto 0)
);
end dummy_ctrl_regs_wb_slave;
architecture syn of dummy_ctrl_regs_wb_slave is
signal dummy_reg_2_int : std_logic_vector(31 downto 0);
signal dummy_reg_3_int : std_logic_vector(31 downto 0);
signal dummy_reg_led_int : std_logic_vector(31 downto 0);
signal ack_sreg : std_logic_vector(9 downto 0);
signal rddata_reg : std_logic_vector(31 downto 0);
signal wrdata_reg : std_logic_vector(31 downto 0);
signal bwsel_reg : std_logic_vector(3 downto 0);
signal rwaddr_reg : std_logic_vector(1 downto 0);
signal ack_in_progress : std_logic ;
signal wr_int : std_logic ;
signal rd_int : std_logic ;
signal bus_clock_int : std_logic ;
signal allones : std_logic_vector(31 downto 0);
signal allzeros : std_logic_vector(31 downto 0);
begin
-- Some internal signals assignments. For (foreseen) compatibility with other bus standards.
wrdata_reg <= wb_data_i;
bwsel_reg <= wb_sel_i;
bus_clock_int <= wb_clk_i;
rd_int <= wb_cyc_i and (wb_stb_i and (not wb_we_i));
wr_int <= wb_cyc_i and (wb_stb_i and wb_we_i);
allones <= (others => '1');
allzeros <= (others => '0');
--
-- Main register bank access process.
process (bus_clock_int, rst_n_i)
begin
if (rst_n_i = '0') then
ack_sreg <= "0000000000";
ack_in_progress <= '0';
rddata_reg <= "00000000000000000000000000000000";
dummy_reg_1_wr_o <= '0';
dummy_reg_2_int <= "00000000000000000000000000000000";
dummy_reg_3_int <= "00000000000000000000000000000000";
dummy_reg_led_int <= "00000000000000000000000000000000";
elsif rising_edge(bus_clock_int) then
-- advance the ACK generator shift register
ack_sreg(8 downto 0) <= ack_sreg(9 downto 1);
ack_sreg(9) <= '0';
if (ack_in_progress = '1') then
if (ack_sreg(0) = '1') then
dummy_reg_1_wr_o <= '0';
ack_in_progress <= '0';
else
dummy_reg_1_wr_o <= '0';
end if;
else
if ((wb_cyc_i = '1') and (wb_stb_i = '1')) then
case rwaddr_reg(1 downto 0) is
when "00" =>
if (wb_we_i = '1') then
dummy_reg_1_wr_o <= '1';
else
rddata_reg(0) <= 'X';
rddata_reg(1) <= 'X';
rddata_reg(2) <= 'X';
rddata_reg(3) <= 'X';
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
rddata_reg(13) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "01" =>
if (wb_we_i = '1') then
dummy_reg_2_int <= wrdata_reg(31 downto 0);
else
rddata_reg(31 downto 0) <= dummy_reg_2_int;
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "10" =>
if (wb_we_i = '1') then
dummy_reg_3_int <= wrdata_reg(31 downto 0);
else
rddata_reg(31 downto 0) <= dummy_reg_3_int;
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "11" =>
if (wb_we_i = '1') then
dummy_reg_led_int <= wrdata_reg(31 downto 0);
else
rddata_reg(31 downto 0) <= dummy_reg_led_int;
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when others =>
-- prevent the slave from hanging the bus on invalid address
ack_in_progress <= '1';
ack_sreg(0) <= '1';
end case;
end if;
end if;
end if;
end process;
-- Drive the data output bus
wb_data_o <= rddata_reg;
-- IRQ
-- pass-through field: IRQ in register: DUMMY_1
dummy_reg_1_o <= wrdata_reg(31 downto 0);
-- Dummy register 2
dummy_reg_2_o <= dummy_reg_2_int;
-- Dummy register 3
dummy_reg_3_o <= dummy_reg_3_int;
-- Dummy register for LED control
dummy_reg_led_o <= dummy_reg_led_int;
rwaddr_reg <= wb_addr_i;
-- ACK signal generation. Just pass the LSB of ACK counter.
wb_ack_o <= ack_sreg(0);
end syn;
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for Dummy status registers
---------------------------------------------------------------------------------------
-- File : ../../GN4124_core/hdl/gn4124core/design/rtl/dummy_stat_regs.vhd
-- Author : auto-generated by wbgen2 from ../../GN4124_core/hdl/gn4124core/design/wb_gen/dummy_stat_regs_wb_slave.wb
-- Created : Wed Nov 10 14:42:59 2010
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE ../../GN4124_core/hdl/gn4124core/design/wb_gen/dummy_stat_regs_wb_slave.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity dummy_stat_regs_wb_slave is
port (
rst_n_i : in std_logic;
wb_clk_i : in std_logic;
wb_addr_i : in std_logic_vector(1 downto 0);
wb_data_i : in std_logic_vector(31 downto 0);
wb_data_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
-- Port for std_logic_vector field: 'Dummy register 1' in reg: 'DUMMY_1'
dummy_stat_reg_1_i : in std_logic_vector(31 downto 0);
-- Port for std_logic_vector field: 'Dummy register 2' in reg: 'DUMMY_2'
dummy_stat_reg_2_i : in std_logic_vector(31 downto 0);
-- Port for std_logic_vector field: 'Dummy register 3' in reg: 'DUMMY_3'
dummy_stat_reg_3_i : in std_logic_vector(31 downto 0);
-- Port for std_logic_vector field: 'Dummy register for switch status' in reg: 'DUMMY_SWITCH'
dummy_stat_reg_switch_i : in std_logic_vector(31 downto 0)
);
end dummy_stat_regs_wb_slave;
architecture syn of dummy_stat_regs_wb_slave is
signal ack_sreg : std_logic_vector(9 downto 0);
signal rddata_reg : std_logic_vector(31 downto 0);
signal wrdata_reg : std_logic_vector(31 downto 0);
signal bwsel_reg : std_logic_vector(3 downto 0);
signal rwaddr_reg : std_logic_vector(1 downto 0);
signal ack_in_progress : std_logic ;
signal wr_int : std_logic ;
signal rd_int : std_logic ;
signal bus_clock_int : std_logic ;
signal allones : std_logic_vector(31 downto 0);
signal allzeros : std_logic_vector(31 downto 0);
begin
-- Some internal signals assignments. For (foreseen) compatibility with other bus standards.
wrdata_reg <= wb_data_i;
bwsel_reg <= wb_sel_i;
bus_clock_int <= wb_clk_i;
rd_int <= wb_cyc_i and (wb_stb_i and (not wb_we_i));
wr_int <= wb_cyc_i and (wb_stb_i and wb_we_i);
allones <= (others => '1');
allzeros <= (others => '0');
--
-- Main register bank access process.
process (bus_clock_int, rst_n_i)
begin
if (rst_n_i = '0') then
ack_sreg <= "0000000000";
ack_in_progress <= '0';
rddata_reg <= "00000000000000000000000000000000";
elsif rising_edge(bus_clock_int) then
-- advance the ACK generator shift register
ack_sreg(8 downto 0) <= ack_sreg(9 downto 1);
ack_sreg(9) <= '0';
if (ack_in_progress = '1') then
if (ack_sreg(0) = '1') then
ack_in_progress <= '0';
else
end if;
else
if ((wb_cyc_i = '1') and (wb_stb_i = '1')) then
case rwaddr_reg(1 downto 0) is
when "00" =>
if (wb_we_i = '1') then
else
rddata_reg(31 downto 0) <= dummy_stat_reg_1_i;
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "01" =>
if (wb_we_i = '1') then
else
rddata_reg(31 downto 0) <= dummy_stat_reg_2_i;
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "10" =>
if (wb_we_i = '1') then
else
rddata_reg(31 downto 0) <= dummy_stat_reg_3_i;
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "11" =>
if (wb_we_i = '1') then
else
rddata_reg(31 downto 0) <= dummy_stat_reg_switch_i;
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when others =>
-- prevent the slave from hanging the bus on invalid address
ack_in_progress <= '1';
ack_sreg(0) <= '1';
end case;
end if;
end if;
end if;
end process;
-- Drive the data output bus
wb_data_o <= rddata_reg;
-- Dummy register 1
-- Dummy register 2
-- Dummy register 3
-- Dummy register for switch status
rwaddr_reg <= wb_addr_i;
-- ACK signal generation. Just pass the LSB of ACK counter.
wb_ack_o <= ack_sreg(0);
end syn;
--------------------------------------------------------------------------------
-- --
-- CERN BE-CO-HT GN4124 core for PCIe FMC carrier --
-- http://www.ohwr.org/projects/gn4124-core --
--------------------------------------------------------------------------------
--
-- unit name: wishbone address decoder
--
-- author: Matthieu Cattin (matthieu.cattin@cern.ch)
--
-- date: 02-08-2011
--
-- version: 0.1
--
-- description: Provides a simple wishbone address decoder.
-- Splits the memory windows into equal parts.
--
-- dependencies:
--
--------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE
--------------------------------------------------------------------------------
-- This source file is free software; you can redistribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published by the
-- Free Software Foundation; either version 2.1 of the License, or (at your
-- option) any later version. This source is distributed in the hope that it
-- will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-- of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-- See the GNU Lesser General Public License for more details. You should have
-- received a copy of the GNU Lesser General Public License along with this
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html
--------------------------------------------------------------------------------
-- last changes:
--------------------------------------------------------------------------------
-- TODO:
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
use work.gn4124_core_pkg.all;
entity wb_addr_decoder is
generic
(
g_WINDOW_SIZE : integer := 18; -- Number of bits to address periph on the board (32-bit word address)
g_WB_SLAVES_NB : integer := 2
);
port
(
---------------------------------------------------------
-- GN4124 core clock and reset
clk_i : in std_logic;
rst_n_i : in std_logic;
---------------------------------------------------------
-- wishbone master interface
wbm_adr_i : in std_logic_vector(31 downto 0); -- Address
wbm_dat_i : in std_logic_vector(31 downto 0); -- Data out
wbm_sel_i : in std_logic_vector(3 downto 0); -- Byte select
wbm_stb_i : in std_logic; -- Strobe
wbm_we_i : in std_logic; -- Write
wbm_cyc_i : in std_logic; -- Cycle
wbm_dat_o : out std_logic_vector(31 downto 0); -- Data in
wbm_ack_o : out std_logic; -- Acknowledge
wbm_stall_o : out std_logic; -- Stall
---------------------------------------------------------
-- wishbone slaves interface
wb_adr_o : out std_logic_vector(31 downto 0); -- Address
wb_dat_o : out std_logic_vector(31 downto 0); -- Data out
wb_sel_o : out std_logic_vector(3 downto 0); -- Byte select
wb_stb_o : out std_logic; -- Strobe
wb_we_o : out std_logic; -- Write
wb_cyc_o : out std_logic_vector(g_WB_SLAVES_NB-1 downto 0); -- Cycle
wb_dat_i : in std_logic_vector((32*g_WB_SLAVES_NB)-1 downto 0); -- Data in
wb_ack_i : in std_logic_vector(g_WB_SLAVES_NB-1 downto 0); -- Acknowledge
wb_stall_i : in std_logic_vector(g_WB_SLAVES_NB-1 downto 0) -- Stall
);
end wb_addr_decoder;
architecture behaviour of wb_addr_decoder is
-----------------------------------------------------------------------------
-- Constants declaration
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Signals declaration
-----------------------------------------------------------------------------
-- Wishbone
signal s_wb_periph_addr : std_logic_vector(log2_ceil(g_WB_SLAVES_NB)-1 downto 0);
signal wb_periph_addr : std_logic_vector(log2_ceil(g_WB_SLAVES_NB)-1 downto 0);
signal s_wb_periph_select : std_logic_vector((2**s_wb_periph_addr'length)-1 downto 0);
signal s_wb_ack_muxed : std_logic;
signal wb_ack_t : std_logic;
signal s_wb_dat_i_muxed : std_logic_vector(31 downto 0);
signal s_wb_cyc_demuxed : std_logic_vector(g_WB_SLAVES_NB-1 downto 0);
signal wb_adr_t : std_logic_vector(g_WINDOW_SIZE-log2_ceil(g_WB_SLAVES_NB)-1 downto 0);
begin
------------------------------------------------------------------------------
-- Wishbone master address decoding
------------------------------------------------------------------------------
-- Take the first N bits of the address to select the active wb peripheral
-- g_WINDOW_SIZE represents 32-bit word address window
s_wb_periph_addr <= wbm_adr_i(g_WINDOW_SIZE-1 downto g_WINDOW_SIZE-log2_ceil(g_WB_SLAVES_NB));
-----------------------------------------------------------------------------
-- One-hot decode function, s_wb_periph_select <= onehot_decode(s_wb_periph_addr);
-----------------------------------------------------------------------------
onehot_decode : process(s_wb_periph_addr)
variable v_onehot : std_logic_vector((2**s_wb_periph_addr'length)-1 downto 0);
variable v_index : integer range 0 to (2**s_wb_periph_addr'length)-1;
begin
v_onehot := (others => '0');
v_index := 0;
for i in s_wb_periph_addr'range loop
if (s_wb_periph_addr(i) = '1') then
v_index := 2*v_index+1;
else
v_index := 2*v_index;
end if;
end loop;
v_onehot(v_index) := '1';
s_wb_periph_select <= v_onehot;
end process onehot_decode;
-- Register multiplexed ack and data + periph address
p_wb_in_regs : process (clk_i, rst_n_i)
begin
if (rst_n_i = c_RST_ACTIVE) then
wb_periph_addr <= (others => '0');
wbm_dat_o <= (others => '0');
wb_ack_t <= '0';
elsif rising_edge(clk_i) then
wb_periph_addr <= s_wb_periph_addr;
wbm_dat_o <= s_wb_dat_i_muxed;
wb_ack_t <= s_wb_ack_muxed;
end if;
end process p_wb_in_regs;
wbm_ack_o <= wb_ack_t;
-- Select ack line of the active peripheral
p_ack_mux : process (wb_ack_i, wb_periph_addr)
begin
if (to_integer(unsigned(wb_periph_addr)) < g_WB_SLAVES_NB) then
s_wb_ack_muxed <= wb_ack_i(to_integer(unsigned(wb_periph_addr)));
else
s_wb_ack_muxed <= '0';
end if;
end process p_ack_mux;
-- Select stall line of the active peripheral
p_stall_mux : process (wb_stall_i, s_wb_periph_addr)
begin
if (to_integer(unsigned(s_wb_periph_addr)) < g_WB_SLAVES_NB) then
wbm_stall_o <= wb_stall_i(to_integer(unsigned(s_wb_periph_addr)));
else
wbm_stall_o <= '0';
end if;
end process p_stall_mux;
-- Select input data of the active peripheral
p_din_mux : process (wb_dat_i, wb_periph_addr)
begin
if (to_integer(unsigned(wb_periph_addr)) < g_WB_SLAVES_NB) then
s_wb_dat_i_muxed <=
wb_dat_i(31+(32*to_integer(unsigned(wb_periph_addr))) downto 32*to_integer(unsigned(wb_periph_addr)));
else
s_wb_dat_i_muxed <= (others => 'X');
end if;
end process p_din_mux;
-- Assert the cyc line of the selected peripheral
gen_cyc_demux : for i in 0 to g_WB_SLAVES_NB-1 generate
s_wb_cyc_demuxed(i) <= wbm_cyc_i and s_wb_periph_select(i) and not(wb_ack_t);
end generate gen_cyc_demux;
-- Slaves wishbone bus outputs
wb_dat_o <= wbm_dat_i;
wb_stb_o <= wbm_stb_i;
wb_we_o <= wbm_we_i;
wb_sel_o <= wbm_sel_i;
wb_cyc_o <= s_wb_cyc_demuxed;
-- extend address bus to 32-bit
wb_adr_t <= wbm_adr_i(g_WINDOW_SIZE-log2_ceil(g_WB_SLAVES_NB)-1 downto 0);
wb_adr_o(wb_adr_t'left downto 0) <= wb_adr_t;
wb_adr_o(31 downto wb_adr_t'left+1) <= (others => '0');
end behaviour;
peripheral {
name = "Dummy control registers";
description = "Wishbone slave for test of the CSR wishbone of the GN4124 core";
hdl_entity = "dummy_ctrl_regs_wb_slave";
prefix = "dummy_reg";
reg {
name = "DUMMY_1";
prefix = "1";
field {
name = "IRQ";
description = "Generates an IRQ";
type = PASS_THROUGH;
size = 32;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "DUMMY_2";
prefix = "2";
field {
name = "Dummy register 2";
type = SLV;
size = 32;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "DUMMY_3";
prefix = "3";
field {
name = "Dummy register 3";
type = SLV;
size = 32;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "DUMMY_LED";
prefix = "led";
field {
name = "Dummy register for LED control";
type = SLV;
size = 32;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
};
peripheral {
name = "Dummy status registers";
description = "Wishbone slave for test of the CSR wishbone of the GN4124 core";
hdl_entity = "dummy_stat_regs_wb_slave";
prefix = "dummy_stat_reg";
reg {
name = "DUMMY_1";
prefix = "1";
field {
name = "Dummy register 1";
type = SLV;
size = 32;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
reg {
name = "DUMMY_2";
prefix = "2";
field {
name = "Dummy register 2";
type = SLV;
size = 32;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
reg {
name = "DUMMY_3";
prefix = "3";
field {
name = "Dummy register 3";
type = SLV;
size = 32;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
reg {
name = "DUMMY_SWITCH";
prefix = "switch";
field {
name = "Dummy register for switch status";
type = SLV;
size = 32;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
};
work/
Makefile
modelsim.ini
transcript*
vsim.wlf
usc.lst
action = "simulation"
sim_tool = "modelsim"
sim_top = "TB_SPEC"
target = "xilinx"
vcom_opt = "-93"
syn_device = "xc6slx45t"
syn_grade = "-3"
syn_package = "fgg484"
modules = {
"local" : [
"../top",
"../rtl",
"../../gn4124core/rtl",
"testbench",
],
"git" : [
"git://ohwr.org/hdl-core-lib/general-cores.git",
],
}
fetchto = "../../ip_cores"
//***********************************************************************************************
//***********************************************************************************************
//**
//** Name: cont_block_dma.c
//**
//** Description: DMA scenario for a 2MB contiguous block of memory.
//**
//**
//***********************************************************************************************
//***********************************************************************************************
//===============================================================================================
// This provides the framework for creating tests for the testbench as described in
// GN412x Simulation Test Bench User Guide
//===============================================================================================
#include "lib/maketest.c"
//===============================================================================================
// This provides the framework for creating microcode for the 3 or 4DW list type described in
// the application note: "Implementing Multi-channel DMA with the GN412x IP"
//===============================================================================================
#include "lib/vdma_service.c"
//===============================================================================================
// lambo.h contains the address map for the Lambo project
//===============================================================================================
#include "lambo.h"
//===============================================================================================
// Define the Memory Map
//===============================================================================================
#define BAR0_BASE 0xFF00000010000000ll
#define BAR1_BASE 0xFF000000A0000000ll
#define BFM_BAR0_BASE 0x87654321F0000000ll
#define BFM_BAR1_BASE 0xBB00000040000000ll
#define CHAN0_DESC_LIST_SIZE 3
#define L2P_CHAN0_SUB_DMA_LENGTH 0x1000
#define L2P_CHAN0_XFER_CTL 0x00010000
//===============================================================================================
// Define the SG List
//===============================================================================================
struct sg_entry_struct sg_list_chan0[] =
{
{ BFM_BAR0_BASE|0xFF1000C8, L2P_CHAN0_XFER_CTL | 0xF38, 1 },
{ BFM_BAR0_BASE|0xFF101000, L2P_CHAN0_XFER_CTL | (L2P_CHAN0_SUB_DMA_LENGTH & 0xFFF), 511 },
{ BFM_BAR0_BASE|0xFF300000, L2P_CHAN0_XFER_CTL | 0x0C8 | 0x80000000, 1 }, //Assert an interrupt
{ 0x0ll, 0, 0 }
};
//***********************************************************************************************
//**
//** vdma_main: This will insert the DMA microcode and data into the test script
//**
//** The last function call, vdma_process(), will cross reference all of the labels in the
//** source code so that you end up with the proper hexadecimal values that need to be written
//** to descriptor RAM.
//**
//***********************************************************************************************
void vdma_main()
{
vdma_org(0x0000); //This initializes the program address counter
data_address = 0x200; //This initializes the data space address counter
vdma_label("START");
vdma_nop(); //do nothing
//===============================================================================================
// START of the main program loop
//===============================================================================================
vdma_label("MAIN");
vdma_channel_service_4
(
"L2P_CHAN0", //label to be used for this specific channel
'l', //direction='l' for l2p or 'p' for p2l
0, //The event register bit to be used for interrupt generation
_EXT_COND_0, //External condition used for this channel
_EXT_COND_LO, //Set to either _EXT_COND_LO or _EXT_COND_HI
0, //set to non zero when the list will be updated dynamicaly
CHAN0_DESC_LIST_SIZE, //SYS_ADDR step size of list entries that have a repeat count
L2P_CHAN0_SUB_DMA_LENGTH, //Step size of list entries that have a repeat count
sg_list_chan0 //SG List itself
);
vdma_nop(); // This is not required (can be replaced with more channel servicing)
vdma_jmp(_ALWAYS, 0,"MAIN"); //loop forever
//===============================================================================================
// END of the main program loop
//===============================================================================================
//-----------------------------------------------------------------------------------------------
// Global Constants
//-----------------------------------------------------------------------------------------------
vdma_org(0x0100);
vdma_label("ZERO");
vdma_constant_n64(0); //The constant 0
vdma_label("MINUS1");
vdma_constant_n(0xFFFFFFFF); //The constant -1
vdma_label("THREE");
vdma_constant_n(3); //The constant 3
vdma_label("FOUR");
vdma_constant_n(4); //The constant 4
//===============================================================================================
// Must run vdma_process to resolve the cross-references and generate the microcode
//===============================================================================================
vdma_process(BAR0_BASE + 0x4000);
}
//***********************************************************************************************
//**
//** Main:
//**
//** Edit the program below to create your own test script.
//**
//***********************************************************************************************
main(argc,argv)
int argc;
char *argv[];
{
int offset=0, i;
//-----------------------------------------------------------------------------------------------
// Always call maketest_init at the beginning of a test program
//-----------------------------------------------------------------------------------------------
maketest_init(argc,argv);
//================================================================================================
//== START of user script
//================================================================================================
comment("-----------------------------------------------------------------------------");
comment("Generated from: simple.c - do not edit the vec file directly as it is not the source!");
comment("Short example of using the lambo TestBench");
comment("-----------------------------------------------------------------------------");
comment("Select the GN4124 Primary BFM");
model(0);
comment("Initialize the BFM to its default state");
init();
comment("\nDrive reset to the FPGA");
reset(16);
comment("\n");
comment("-----------------------------------------------------------------------------");
comment("Initialize the Primary GN412x BFM model");
comment("-----------------------------------------------------------------------------");
comment("These address ranges will generate traffic from the BFM to the FPGA");
comment("bar BAR ADDR SIZE VC TC S");
bar(0, BAR0_BASE, 0x20000000, 0, 7, 0);
bar(1, BAR1_BASE, 0x10000000, 1, 5, 0);
comment("\nThis allocates a RAM block inside the BFM for the FPGA to access");
comment("bfm_bar BAR ADDR SIZE");
bfm_bar(0, BFM_BAR0_BASE, 0x10000000);
bfm_bar(1, BFM_BAR1_BASE, 0x20000000);
comment("\nWait until the FPGA is un-reset and ready for traffic on the local bus");
wait(64);
comment("\n-------------------------------------------------------------------------------");
comment("DO some setup");
comment("-------------------------------------------------------------------------------");
comment("Lambo setup...");
rd(BAR0_BASE + DMA_SEQ_CSR_REG, 0xF, 0x00000000, 0xFFFFFFFF);
flush(0x100);
wr(BAR0_BASE + DMA_SEQ_DPTR_REG, 0xF, 0x0);
wr(BAR0_BASE + DMA_SEQ_EVENT_EN_REG, 0xF, 0x3);
wr(BAR0_BASE + DMA_SEQ_EVENT_CLR_REG, 0xF, 0xFFFFFFFF);
wr(BAR0_BASE + APP_CFG, 0xF, 0x6);
wr(BAR0_BASE + APP_CFG, 0xF, 0x0);
wr(BAR0_BASE + DMA_CFG, 0xF, 0x1F);
wr(BAR0_BASE + DMA_CFG, 0xF, 0x7);
wr(BAR0_BASE + APP_GEN_COUNT, 0xF, 0x0);
wr(BAR0_BASE + APP_RCV_COUNT, 0xF, 0x0);
wr(BAR0_BASE + APP_RCV_ERR_COUNT, 0xF, 0x0);
wr(BAR0_BASE + DMA_PAYLOAD_SIZE, 0xF, 0x8020);
comment("\n-------------------------------------------------------------------------------");
comment("Setup the DMA microcode");
comment("-------------------------------------------------------------------------------");
vdma_main();
comment("\nStart VDMA");
wr(BAR0_BASE + DMA_SEQ_CSR_REG, 0xF, 0x1);
comment("\n-------------------------------------------------------------------------------");
comment("Wait for an Interrupt for Channel 0");
comment("-------------------------------------------------------------------------------");
gpio_wait(8000, 0x0001, 0x0001);
comment("Clear the interrupt");
wr(BAR0_BASE + DMA_SEQ_EVENT_CLR_REG, 0xF, 0x00000001);
comment("\nRead VDMA idle status");
rd(BAR0_BASE + DMA_SEQ_CSR_REG, 0xF, 0x00000000, 0xFFFFFFFF);
flush(5000);
wait(16);
//================================================================================================
//== END of user script
//================================================================================================
fclose(outfp);
exit(0);
}
#define DMA_STATUS_MASK 0x0000
#define DMA_CFG 0x0004
#define DMA_SEQ_EVENT_SET_REG 0x0008
#define DMA_SEQ_EVENT_CLR_REG 0x000C
#define DMA_SEQ_EVENT_REG 0x0010
#define DMA_SEQ_EVENT_EN_REG 0x0014
#define DMA_SEQ_ADDR_LOW_REG 0x0018
#define DMA_SEQ_ADDR_HI_REG 0x001C
#define DMA_SEQ_DPTR_REG 0x0020
#define DMA_SEQ_XFER_CTRL_REG 0x0024
#define DMA_SEQ_RA_REG 0x0028
#define DMA_SEQ_RB_REG 0x002C
#define DMA_SEQ_CSR_REG 0x0030
#define DMA_PAYLOAD_SIZE 0x0034
#define DMA_STATUS 0x0038
#define DMA_STATUS_RAW 0x003C
#define APP_STATUS_MASK 0x0050
#define APP_CFG 0x0054
#define APP_GEN_COUNT 0x0058
#define APP_RCV_COUNT 0x005C
#define APP_RCV_ERR_COUNT 0x0060
#define APP_STATUS 0x0064
#define APP_STATUS_RAW 0x0068
#define DMA_SEQ_DESC_RAM 0x4000
//---------------------------------------------------------------------------
/*
* Name: vdma_gen.c
*
* Description: Main Program for Generating VDMA Sequencer Code.
*
*/
#include "stdio.h"
#include "ctype.h"
#include "string.h"
#include "stdlib.h"
//#include "malloc.h"
#include "vdma_seqcode.h"
//#include "vdma_gen_struct.h"
#define VDMA_DRAM_SIZE 2048 // Size in DW of the descriptor RAM
#define MAX_LABELS 2048 // Maximum number of labels
#define MAX_COMMENT 200
#define MAX_LABEL_SIZE 32
struct
{
DWORD data;
char *label;
char comment[MAX_COMMENT+1];
} dram[VDMA_DRAM_SIZE+1];
struct
{
char *label; // label string
int address; // Address of the label
} vdma_labels[MAX_LABELS];
int label_compare(char *string1, char *string2)
{
if((string1 == NULL) || (string2 == NULL) || (*string1 == '\0') || (*string2 == '\0'))
return(0); /* no match */
else if(strlen(string1) != strlen(string2))
return(0); /* no match */
else
return(strcmp(string1, string2) == 0);
}
int program_address = 0;
int label_pointer = 0;
char last_label[100];
char out_filename[256];
FILE *outfp;
FILE *infp;
#include "model.c"
#include "vdma_seqcode_lib.c"
#define BAR0_ADDR_H ((DWORD)0xFF000000)
#define BAR0_ADDR_L ((DWORD)0x10000000)
//================================================================================================
//
// Do Some Initialization
//
//================================================================================================
maketest_init(argc,argv)
int argc;
char *argv[];
{
int i;
char *src, *dst;
// char filename[256];
src = argv[0];
dst = out_filename;
for(i=0; i<250; i++)
{
*dst = *src;
if(*src == '\0')
{
dst[0]='.';
dst[1]='h';
dst[2]='e';
dst[3]='x';
dst[4]='\0';
break;
}
if(*src == '.')
{
dst[1]='h';
dst[2]='e';
dst[3]='x';
dst[4]='\0';
break;
}
dst++;
src++;
}
/* Open the Hex Output File */
if((outfp = fopen(out_filename,"wb")) == NULL)
{
fprintf(stderr, "Couldn't open file %s for writing\n", out_filename);
exit(-2);
}
clearerr(outfp);
fprintf(stderr, "Output file %s is open...\n", out_filename);
/* initialize the label structure */
for(i = 0; i < MAX_LABELS; i++)
{
vdma_labels[i].label = NULL;
vdma_labels[i].address = -1;
}
/* initialize the descriptor RAM structure */
for(i = 0; i < VDMA_DRAM_SIZE; i++)
{
dram[i].label = NULL;
dram[i].data = 0;
dram[i].comment[0] = '\0';
}
program_address = 0;
label_pointer = 0;
last_label[0] = '\0';
fprintf(stderr, "Initialization complete\n");
comment("***********************************************************************************");
comment("*** Warning: this file is automatically generated. ***");
comment("***********************************************************************************");
comment("*** Do not edit this file directly as it is not the source! ***");
comment("***********************************************************************************");
}
vdma_process(U64 descriptor_base)
{
int i=0;
int lines=0;
int im;
int address;
fprintf(stderr, "Pass one complete:\n");
fprintf(stderr, " Processed %d labels\n", label_pointer);
fprintf(stderr, " Ended with program address=0x%04X\n", program_address);
//---------------------------------------------------------------------------------
// 2nd Pass: Now resolve label references
//---------------------------------------------------------------------------------
for(program_address = 0; program_address < VDMA_DRAM_SIZE; program_address++)
{
if((dram[program_address].label != NULL) && (dram[program_address].label[0] != '\0')) /* resolve the label */
{
//fprintf(stderr, "Resolving label %s at address=0x%04X\n", dram[program_address].label, program_address);
if(vdma_label_lookup(dram[program_address].label, &address))
{
dram[program_address].data |= address & 0xFFFF;
}
else
{
if((dram[program_address].label[0] == '0') && (tolower(dram[program_address].label[1]) == 'x')) // case of the label being a number
{
if(sscanf(&dram[program_address].label[2], "%x", &im) == 1)
dram[program_address].data |= im & 0xFFFF;
else
fprintf(stderr, "ERROR: could not resolve label %s. Appears to be a hex value?\n", dram[program_address].label);
}
else
fprintf(stderr, "ERROR: could not resolve label %s\n", dram[program_address].label);
}
i++;
}
//fprintf(stderr, "%d\n", program_address);
if(dram[program_address].label != NULL)
{
fprintf(outfp, "0x%04X\t0x%08lX\t%s\n", program_address, dram[program_address].data, dram[program_address].comment);
fprintf(stdout, "-- 0x%04X 0x%08lX %s\n", program_address, dram[program_address].data, dram[program_address].comment);
wr(descriptor_base + (program_address*4), 0xF, dram[program_address].data);
//fprintf(stdout, "wrb %08lX%08lX F %08lX\n", 0xFF000000, program_address, dram[program_address].data);
lines++;
}
}
fprintf(outfp, "// Label Listing:\n");
// Put the label table into the output file
for(i = 0; i < label_pointer; i++)
{
fprintf(outfp, "// 0x%04X : \"%s\"\n", vdma_labels[i].address, vdma_labels[i].label);
}
// label_pointer = 0;
fprintf(stderr, "Pass two complete:\n");
fprintf(stderr, " Substituted %d references in %d words of program and data space\n", i, lines);
fprintf(stderr, " Created output file \"%s\"\n", out_filename);
}
/*----------------------------------------------------------------------------
-- model.c : Generate BFM Commands from C
--
-- This module re-directs bus model commands to specific sub modules.
--
-- For Example:
-- A system simulation that has both a pci32 model and an i960sx model
-- can drive both models from a single file as follows:
--
-- model_map(0, "i960sx"); // model #0 is an i960sx
-- model_map(1, "pci32"); // model #1 is a 32 bit PCI model
-- model(0); // Select the i960sx model
-- memw32(0x100, 0x76543210);
-- memv32(0x100);
-- model(1); // Select the PCI model
-- memw32(0x200, 0x01234567);
-- memv32(0x200);
----------------------------------------------------------------------------*/
#include <stdio.h>
//#include "emul.h"
#define U64 unsigned long long
//#define U64 unsigned long long
#define U32 unsigned long
#define U16 unsigned short
#define U8 unsigned char
#define BYTE unsigned char
#define MAX_MODEL_CHAN 20
int model_num = 0;
int current_channel = 0;
int chan_init = 1;
//extern void set_chan(int chan);
/*----------------------------------------------------------------------------
-- btype: returns an ' ' if an address is at the end of a burst
----------------------------------------------------------------------------*/
char btype(U64 address)
{
U32 mask;
int burst_length, bus_width;
burst_length = 4096;
bus_width = 32;
mask = burst_length - 1;
mask ^= bus_width/8 - 1;
if((address & mask) == mask) /* crosses a burst boundary */
return(' ');
else
return('b');
}
/*----------------------------------------------------------------------------
-- xwrite: Write on a DW boundary with byte enables
-- Primitive used for all writes
----------------------------------------------------------------------------*/
void xwrite(U64 address, BYTE be, U32 data, char burst)
{
fprintf(stdout, "wr%c %016llX %X %08lX\n", burst, address, be, data);
}
/*----------------------------------------------------------------------------
-- xread: Read primitive - reads data ion a DW boundary with byte enables
----------------------------------------------------------------------------*/
void xread(U64 address, BYTE be, U32 data, U32 mask, char burst, char mode)
{
fprintf(stdout, "rd%c %016llX %X %08lX %08lX\n", burst, address, be, data, mask);
}
/*----------------------------------------------------------------------------
-- opr_prn: prints out an array of read, write or verify commands
----------------------------------------------------------------------------*/
void opr_prn(U64 address, BYTE *be, U32 *d, U32 *m, char mode, char burst, int n)
{
int i;
char c;
for(i = 0; i < n; i++)
{
if((n == 1) && (burst == ' '))
c = ' ';
else if((i == (n-1)) && (burst != 'b'))
c = ' ';
else
c = btype(address);
if(mode == 'r')
{
xread(address, be[i], d[i], m[i], c, mode);
}
else if(mode == 'v')
{
xread(address, be[i], d[i], m[i], c, mode);
}
else
{
xwrite(address, be[i], d[i], c);
}
address += 4;
}
}
/*----------------------------------------------------------------------------
-- xopr: 32 bit operations on a 32 bit boundary with byte enables, burst and non-burst
----------------------------------------------------------------------------*/
void xopr(U64 address, BYTE be, U32 data, U32 mask, char burst, char mode)
{
U32 d[2], m[2];
char c;
BYTE b[2];
int n = 1;
/*printf("-- xopr(address=0x%08lX, be=0x%X, data=0x%08lX, masks=0x%08lX, burst=%c, mode=%c)\n", address, be, data, mask, burst, mode);*/
if(address & 3)
{
fprintf(stdout, "-- WARNING: address not 32 bit aligned and will be adjusted\n");
address &= ~3;
}
c = burst;
b[0] = be;
d[0] = data;
m[0] = mask;
opr_prn(address, b, d, m, mode, burst, n);
}
/*----------------------------------------------------------------------------
-- xwr: Write 32 bits on a 32 bit boundary with byte enables, burst and non-burst
----------------------------------------------------------------------------*/
void xwr(U64 address, BYTE be, U32 data, char burst)
{
xopr(address, be, data, 0, burst, 'w');
}
/*----------------------------------------------------------------------------
-- xrd: Read 32 bits on a 32 bit boundary with byte enables, burst and non-burst
----------------------------------------------------------------------------*/
void xrd(U64 address, BYTE be, U32 data, U32 mask, char burst)
{
xopr(address, be, data, mask, burst, 'r');
}
/*----------------------------------------------------------------------------
-- xrv: Verify 32 bits on a 32 bit boundary with byte enables, burst and non-burst
----------------------------------------------------------------------------*/
void xrv(U64 address, BYTE be, char burst)
{
xopr(address, be, 0, 0, burst, 'v');
}
//***********************************************************************************************
//**
//** Commands Specific to the Command Router
//**
//***********************************************************************************************
/*----------------------------------------------------------------------------
-- comment: put a comment in the command file.
----------------------------------------------------------------------------*/
void comment(char *str)
{
while(*str == '\n')
{
printf("\n");
str++;
}
if(*str != '\0')
{
if(*str == '-')
printf("--%s\n", str);
else
printf("-- %s\n", str);
}
}
/*----------------------------------------------------------------------------
-- sync: does the sync command.
----------------------------------------------------------------------------*/
void sync()
{
printf("sync\n");
}
/*----------------------------------------------------------------------------
-- gsync: does the gsync command.
----------------------------------------------------------------------------*/
void gsync()
{
printf("gsync\n");
}
/*----------------------------------------------------------------------------
-- model: Select a model.
----------------------------------------------------------------------------*/
void model(int model)
{
printf("model %%d%d\n", model);
}
/*----------------------------------------------------------------------------
-- ckoff: Turn off the models clock.
----------------------------------------------------------------------------*/
void ckoff()
{
printf("ckoff \n");
}
/*----------------------------------------------------------------------------
-- ckon: Turn on the models clock.
----------------------------------------------------------------------------*/
void ckon()
{
printf("ckon \n");
}
//***********************************************************************************************
//**
//** Model Commands
//**
//***********************************************************************************************
/*----------------------------------------------------------------------------
-- init: Initalize a model.
----------------------------------------------------------------------------*/
void init()
{
printf("init\n");
}
/*----------------------------------------------------------------------------
-- reset: Initalize a model.
----------------------------------------------------------------------------*/
void reset(int n)
{
printf("reset %%d%d\n", n);
}
/*----------------------------------------------------------------------------
-- lclk: lclk period.
----------------------------------------------------------------------------*/
void lclk(int n)
{
printf("lclk %%d%d\n", n);
}
/*----------------------------------------------------------------------------
-- base: base period.
----------------------------------------------------------------------------*/
void base(int n)
{
if((n==2)||(n==10)||(n==16))
{
printf("base %%d%d\n", n);
}
else
{
fprintf(stderr, "ERROR: invalid base specified: %d\n", n);
printf("--ERROR: base \%d%d\n", n);
}
}
/*----------------------------------------------------------------------------
-- bar BAR ADDR SIZE VC TC S
----------------------------------------------------------------------------*/
void bar(int bar, U64 addr, U32 size, int vc, int tc, int s)
{
if(bar != 0) bar = 1;
if(s != 0) s = 1;
if(vc != 0) vc = 1;
if((tc < 0)||(tc > 7)) tc = 0;
printf("bar %d %016llX %08X %X %X %X\n", bar, addr, size, vc, tc, s);
}
/*----------------------------------------------------------------------------
-- bfm_bar BAR ADDR SIZE
----------------------------------------------------------------------------*/
void bfm_bar(int bar, U64 addr, U32 size)
{
if(bar != 0) bar = 1;
printf("bfm_bar %d %016llX %08X\n", bar, addr, size);
}
/*----------------------------------------------------------------------------
-- wait: Do nothing for N CLK cycles
----------------------------------------------------------------------------*/
void wait(int n)
{
fprintf(stdout, "wait %%d%d\n", n);
}
/*----------------------------------------------------------------------------
-- flush: Wait until all outstanding read requests have been completed or
-- N local bus clocks, whichever comes first.
----------------------------------------------------------------------------*/
void flush(int n)
{
fprintf(stdout, "flush %%d%d\n", n);
}
/*----------------------------------------------------------------------------
-- rd_outstanding_in: Number of outstanding read commands allowed incoming to the model
--
----------------------------------------------------------------------------*/
void rd_outstanding_in(int n)
{
if((n < 1)||(n > 4)) n = 3;
fprintf(stdout, "rd_outstanding_in %%d%d\n", n);
}
/*----------------------------------------------------------------------------
-- rd_outstanding_out: Number of outstanding read before the BFM will stall
--
----------------------------------------------------------------------------*/
void rd_outstanding_out(int n)
{
if((n < 1)||(n > 4)) n = 3;
fprintf(stdout, "rd_outstanding_out %%d%d\n", n);
}
/*----------------------------------------------------------------------------
-- response_delay: Delay the return of response data by N local bus clock intervals
--
----------------------------------------------------------------------------*/
void response_delay(int n, int vc)
{
if(vc != 0) vc = 1;
fprintf(stdout, "response_delay %%d%d %d\n", n, vc);
}
/*----------------------------------------------------------------------------
-- burst_length: Sets the burst length that read/write packets will get truncated to.
--
----------------------------------------------------------------------------*/
void burst_length(int n, int bar)
{
if(bar != 0) bar = 1;
fprintf(stdout, "burst_length %%d%d %d\n", n, bar);
}
/*----------------------------------------------------------------------------
-- burst_modulo: Sets the burst length that read/write packets will get truncated to.
--
----------------------------------------------------------------------------*/
void burst_modulo(int n, int bar)
{
if(bar != 0) bar = 1;
fprintf(stdout, "burst_modulo %%d%d %d\n", n, bar);
}
/*----------------------------------------------------------------------------
-- cpl_modulo: Sets the burst length that read/write packets will get truncated to.
--
----------------------------------------------------------------------------*/
void cpl_modulo(int n)
{
fprintf(stdout, "cpl_modulo %%d%d\n", n);
}
/*----------------------------------------------------------------------------
-- cpl_order: Sets the burst length that read/write packets will get truncated to.
--
----------------------------------------------------------------------------*/
void cpl_order(int n)
{
fprintf(stdout, "cpl_order %%d%d\n", n);
}
/*----------------------------------------------------------------------------
-- iwait_random: Initiator random wait state insertion
--
----------------------------------------------------------------------------*/
void iwait_random(int p, int n)
{
if((p < 0)||(p > 100)) p = 0;
if(p==0)
fprintf(stdout, "iwait_random %%d%d 0 -- Initiator random wait states disabled\n", p);
else
fprintf(stdout, "iwait_random %%d%d %%d%d -- Initiator random wait states: probability=%d%% max duration= %d\n", p, n, p, n);
}
/*----------------------------------------------------------------------------
-- gpio_wait N P MASK: Wait for N local bus clock intervals for GPIO to reach a defined state.
--
----------------------------------------------------------------------------*/
void gpio_wait(int n, U32 p, U32 mask)
{
fprintf(stdout, "gpio_wait %%d%d %04lX %04lX -- gpio_wait N P MASK\n", n, p, mask);
}
/*----------------------------------------------------------------------------
-- l2p_rdy STATE DURATION R: Drive the L2P_RDY signal to STATE for
-- duration DURATION as a number of local bus
-- clock intervals.
--
----------------------------------------------------------------------------*/
void l2p_rdy(char state, int duration, int r)
{
fprintf(stdout, "l2p_rdy %c %%%d %%%d -- l2p_rdy STATE DURATION RESTART\n", state, duration, r);
}
/*----------------------------------------------------------------------------
-- vc VC: Set the virtual channel number for subsequent P2L read/write
-- requests on the local bus.
--
----------------------------------------------------------------------------*/
void vc(int vc)
{
fprintf(stdout, "vc %X\n", vc);
}
//l_wr_rdy FILL DRAIN
/*----------------------------------------------------------------------------
-- ************************** User Visible Functions ***********************
--
-- The following functions are to be used in the user source code
----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
-- wr: Non-Burst Write 32 bits on a 32 bit boundary with byte enables
----------------------------------------------------------------------------*/
void wr(U64 address, BYTE be, U32 data)
{
xwr(address, be, data, ' ');
}
/*----------------------------------------------------------------------------
-- rd: Non-Burst Read 32 bits on a 32 bit boundary with byte enables
----------------------------------------------------------------------------*/
void rd(U64 address, BYTE be, U32 data, U32 mask)
{
xrd(address, be, data, mask, ' ');
}
/*----------------------------------------------------------------------------
-- rv: Non-Burst Read Verify 32 bits on a 32 bit boundary with byte enables
----------------------------------------------------------------------------*/
void rv(U64 address, BYTE be)
{
xrv(address, be, ' ');
}
/*----------------------------------------------------------------------------
-- wrb: Burst Write 32 bits on a 32 bit boundary with byte enables
----------------------------------------------------------------------------*/
void wrb(U64 address, BYTE be, U32 data)
{
xwr(address, be, data, 'b');
}
/*----------------------------------------------------------------------------
-- rdb: Burst Read 32 bits on a 32 bit boundary with byte enables
----------------------------------------------------------------------------*/
void rdb(U64 address, BYTE be, U32 data, U32 mask)
{
xrd(address, be, data, mask, 'b');
}
/*----------------------------------------------------------------------------
-- rvb: Burst Read Verify 32 bits on a 32 bit boundary with byte enables
----------------------------------------------------------------------------*/
void rvb(U64 address, BYTE be)
{
xrv(address, be, 'b');
}
/*----------------------------------------------------------------------------
-- opr32: Primitive for 32 bits on any byte boundary
----------------------------------------------------------------------------*/
void opr32(U64 address, U32 data, U32 mask, char mode)
{
U32 d[2], m[2], step;
BYTE be[2];
int n, i;
char c;
step = 4;
if((address & 0x3) != 0) /* on an odd word boundary */
{
d[0] = data << (8 * (address & 3));
d[1] = data >> (8 * (4 - (address & 3)));
m[0] = mask << (8 * (address & 3));
m[1] = mask >> (8 * (4 - (address & 3)));
be[0] = (0xF << (address & 3) ) & 0xF;
be[1] = (0xF >> (4-(address & 3))) & 0xF;
address &= ~3;
n = 2;
}
else /* even boundary */
{
d[0] = data;
m[0] = mask;
be[0] = 0xF;
n = 1;
}
opr_prn(address, be, d, m, mode, ' ', n);
}
/*----------------------------------------------------------------------------
-- wr32: Write 32 bits on any byte boundary
----------------------------------------------------------------------------*/
void wr32(U64 address, U32 data)
{
opr32(address, data, 0, 'w');
}
/*----------------------------------------------------------------------------
-- rd32: Read 32 bits on any byte boundary
----------------------------------------------------------------------------*/
void rd32(U64 address, U32 data, U32 mask)
{
opr32(address, data, mask, 'r');
}
/*----------------------------------------------------------------------------
-- opr16: Primitive for 16 bit operations on any byte boundary
----------------------------------------------------------------------------*/
void opr16(U64 address, U16 data, U16 mask, char mode)
{
U32 d[2], m[2];
BYTE be[2];
int n;
if((address & 0x3) == 0x3) /* on an odd word boundary */
{
d[0] = (U32) data << 24;
d[1] = (U32) data >> 8;
m[0] = (U32) mask << 24;
m[1] = (U32) mask >> 8;
be[0] = 0x8;
be[1] = 0x1;
address &= ~3;
n = 2;
}
else /* even boundary */
{
d[0] = (U32) data << (8 * (address & 0x3));
m[0] = (U32) mask << (8 * (address & 0x3));
be[0] = 3 << (address & 0x3);
address &= ~3;
n = 1;
}
opr_prn(address, be, d, m, mode, ' ', n);
}
/*----------------------------------------------------------------------------
-- wr16: Write 16 bits on any byte boundary
----------------------------------------------------------------------------*/
void wr16(U64 address, U16 data)
{
opr16(address, data, 0, 'w');
}
/*----------------------------------------------------------------------------
-- rd16: Read 16 bits on any byte boundary
----------------------------------------------------------------------------*/
void rd16(U64 address, U16 data, U16 mask)
{
opr16(address, data, mask, 'r');
}
/*----------------------------------------------------------------------------
-- opr8: adjust 8 bits on any byte boundary
----------------------------------------------------------------------------*/
void opr8(U64 address, U16 data, U16 mask, char mode)
{
U32 a, d, m;
BYTE be;
U64 amask;
amask = 3;
d = ((U32) data & 0xFF) << (8 * (address & amask));
m = ((U32) mask & 0xFF) << (8 * (address & amask));
be = 1 << (address & amask);
a = address & (~amask);
opr_prn(a, &be, &d, &m, mode, ' ', 1);
}
/*----------------------------------------------------------------------------
-- wr8: Write 8 bits on any byte boundary
----------------------------------------------------------------------------*/
void wr8(U64 address, U16 data)
{
opr8(address, data, 0, 'w');
}
/*----------------------------------------------------------------------------
-- rd8: Read 8 bits on any byte boundary
----------------------------------------------------------------------------*/
void rd8(U64 address, U16 data, U16 mask)
{
opr8(address, data, mask, 'r');
}
/*----------------------------------------------------------------------------
-- swap8: 8 bit swap on 32 bit data
----------------------------------------------------------------------------*/
U32 swap8(U32 data)
{
data = (data << 24) | ((data << 8) & 0x00ff0000) | ((data >> 8) & 0x0000ff00) | (data >> 24);
return data;
}
/*----------------------------------------------------------------------------
-- swap16: 16 bit swap on 32 bit data
----------------------------------------------------------------------------*/
U32 swap16(U32 data)
{
data = (data << 16) | (data >> 16);
return data;
}
//---------------------------------------------------------------------------
/*
* Name: vdma_seqcode.h
*
* Description: FlexDMA sequencer instruction macros.
*
*/
#ifndef _VDMA_SEQCODE_H_
#define _VDMA_SEQCODE_H_
//Warning message during compilation to indicate macros are used
#pragma message("***** VDMA_CODE_GEN_MACRO is defined *****")
#ifndef DWORD
#define DWORD unsigned long
#endif
/*************************************************
VDMA sequencer code Definitions
*************************************************/
#define _IM (0)
#define _RA (2)
#define _RB (3)
//Condition code for JMP instruction
#define _RA_EQZ (0x8)
#define _RA_NEQZ (0)
#define _RB_EQZ (0x9)
#define _RB_NEQZ (1)
#define _ALWAYS (0xA)
#define _NEVER (0x2)
#define _C_HI (0xB)
#define _C_LO (0x3)
#define _PDM_CMD_QUEUE_FULL_HI (0xC)
#define _PDM_CMD_QUEUE_FULL_LO (0x4)
#define _LDM_CMD_QUEUE_FULL_HI (0xD)
#define _LDM_CMD_QUEUE_FULL_LO (0x5)
#define _EXT_COND_HI (0xF)
#define _EXT_COND_LO (0x7)
//External condition select code for JMP instruction
#define _PDM_IDLE (32)
#define _LDM_IDLE (33)
#define _EXT_COND_0 (34)
#define _EXT_COND_1 (35)
#define _EXT_COND_2 (36)
#define _EXT_COND_3 (37)
#define _EXT_COND_4 (38)
#define _EXT_COND_5 (39)
#define _EXT_COND_6 (40)
#define _EXT_COND_7 (41)
#define _EXT_COND_8 (42)
#define _EXT_COND_9 (43)
#define _EXT_COND_10 (44)
#define _EXT_COND_11 (45)
#define _EXT_COND_12 (46)
#define _EXT_COND_13 (47)
#define _EXT_COND_14 (48)
#define _EXT_COND_15 (49)
// VDMA instructions
#define VDMA_NOP() \
((DWORD)0x0)
#define VDMA_LOAD_SYS_ADDR(R, ADDR) \
((DWORD)0x40000000 | \
((DWORD)(R & 0x3) << 24) | \
((DWORD)(ADDR & 0xFFFF)) \
)
#define VDMA_STORE_SYS_ADDR(R, ADDR) \
((DWORD)0x50000000 | \
((DWORD)(R & 0x3) << 24) | \
((DWORD)(ADDR & 0xFFFF)) \
)
#define VDMA_ADD_SYS_ADDR(DATA) \
((DWORD)0x60000000 | \
((DWORD)(DATA & 0xFFFF)) \
)
#define VDMA_ADD_SYS_ADDR_I(ADDR) \
((DWORD)0xE0000000 | \
((DWORD)(ADDR & 0xFFFF)) \
)
#define VDMA_LOAD_XFER_CTL(R, ADDR) \
((DWORD)0xF0000000 | \
((DWORD)(R & 0x3) << 24) | \
((DWORD)(ADDR & 0xFFFF)) \
)
#define VDMA_LOAD_RA(ADDR) \
((DWORD)0x20000000 | \
((DWORD)(ADDR & 0xFFFF)) \
)
#define VDMA_ADD_RA(ADDR) \
((DWORD)0x21000000 | \
((DWORD)(ADDR & 0xFFFF)) \
)
#define VDMA_LOAD_RB(ADDR) \
((DWORD)0x24000000 | \
((DWORD)(ADDR & 0xFFFF)) \
)
#define VDMA_ADD_RB(ADDR) \
((DWORD)0x25000000 | \
((DWORD)(ADDR & 0xFFFF)) \
)
#define VDMA_STORE_RA(ADDR) \
((DWORD)0xA2000000 | \
((DWORD)(ADDR & 0xFFFF)) \
)
#define VDMA_STORE_RB(ADDR) \
((DWORD)0xA3000000 | \
((DWORD)(ADDR & 0xFFFF)) \
)
#define VDMA_JMP(C, EXT_COND, ADDR) \
((DWORD)0x10000000 | \
(DWORD)((C & 0xF) << 24) | \
(DWORD) ((EXT_COND & 0xFF) << 16) | \
((DWORD)(ADDR & 0xFFFF)) \
)
#define VDMA_SIG_EVENT(S, A, EVENT_EN) \
((DWORD)0x80000000 | \
((DWORD)(S & 0x1) << 27) | \
((DWORD)(A & 0x1) << 26) | \
((DWORD)(EVENT_EN & 0xFFFF)) \
)
#define VDMA_WAIT_EVENT(EVENT_EN, EVENT_STATE) \
((DWORD)0x90000000 | \
((DWORD)((EVENT_EN & 0xFFF) << 12)) | \
((DWORD)(EVENT_STATE & 0xFFF)) \
)
#endif
//---------------------------------------------------------------------------
/*
* Name: vdma_seqcode_lib.h
*
* Description: FlexDMA sequencer functions used for the first pass compile.
*
*/
// Data structure for a 3 or 4 word scatter/gather entry
struct sg_entry_struct
{
U64 address;
U32 vdma_xfer_ctl;
U32 vdma_xfer_rpt; /* in a 3-word SG entry this is unused */
};
//================================================================================================
//
// Note: all references are symbolic at this level
//
//================================================================================================
void next_address()
{
//fprintf(stderr, "program_address=0x%04X\n", program_address);
program_address++;
if(dram[program_address].label != NULL)
{
fprintf(stderr, "WARNING: next program_address 0x%04X has already been used\n", program_address);
}
sprintf(last_label, "%s ", "");
if(program_address >= VDMA_DRAM_SIZE)
{
fprintf(stderr, "ERROR: descriptor RAM address (%d) exceeded maximum (max=%d)\n", program_address, VDMA_DRAM_SIZE);
exit(-91);
}
}
char *r_to_string(int r)
{
switch(r)
{
case _IM:
return("_IM");
break;
case _RA:
return("_RA");
break;
case _RB:
return("_RB");
break;
default:
return("ERROR");
}
}
char *c_to_string(int c)
{
switch(c)
{
case _RA_EQZ:
return("_RA_EQZ");
break;
case _RA_NEQZ:
return("_RA_NEQZ");
break;
case _RB_EQZ:
return("_RB_EQZ");
break;
case _RB_NEQZ:
return("_RB_NEQZ");
break;
case _ALWAYS:
return("_ALWAYS");
break;
case _NEVER:
return("_NEVER");
break;
case _C_HI:
return("_C_HI");
break;
case _C_LO:
return("_C_LO");
break;
case _PDM_CMD_QUEUE_FULL_HI:
return("_PDM_CMD_QUEUE_FULL_HI");
break;
case _PDM_CMD_QUEUE_FULL_LO:
return("_PDM_CMD_QUEUE_FULL_LO");
break;
case _LDM_CMD_QUEUE_FULL_HI:
return("_LDM_CMD_QUEUE_FULL_HI");
break;
case _LDM_CMD_QUEUE_FULL_LO:
return("_LDM_CMD_QUEUE_FULL_LO");
break;
case _EXT_COND_HI:
return("_EXT_COND_HI");
break;
case _EXT_COND_LO:
return("_EXT_COND_LO");
break;
default:
return("ERROR");
}
}
char *ext_cond_to_string(int e, int c)
{
static char estr[20];
if((c == _EXT_COND_HI) || (c == _EXT_COND_LO))
{
switch(e)
{
case _PDM_IDLE:
return("_PDM_IDLE");
break;
case _LDM_IDLE:
return("_LDM_IDLE");
break;
default:
if((e >= 0) && (e <= 15))
{
sprintf(estr, "_EVENT_%d", e);
return(estr);
} else if(e >= _EXT_COND_0)
{
sprintf(estr, "_EXT_COND_%d", e - _EXT_COND_0);
return(estr);
} else
{
return("ERROR");
}
break;
}
}
return("NA");
}
//================================================================================================
//
// string_cat(char *base, char *extension): create a new string by concatenating two strings
//
//================================================================================================
char *string_cat(char *beginning, char *end)
{
char *ptr;
ptr = (char *) malloc(strlen(beginning)+strlen(end)+1);
if(ptr == NULL)
{
fprintf(stderr, "ERROR: could not allocate memory in function string_cat\n");
exit(111);
}
sprintf(ptr, "%s%s", beginning, end);
return(ptr);
}
//================================================================================================
//
// vdma_org(int address): change the program pointer to address
//
//================================================================================================
void vdma_org(int address)
{
program_address = address;
}
//================================================================================================
//
// vdma_label_lookup(char *str, int *value): find a label and store its value at *value.
//
//================================================================================================
int vdma_label_lookup(char *str, int *value)
{
int i;
for(i = 0; i < label_pointer; i++)
{
if(label_compare(str, vdma_labels[i].label))
{
*value = vdma_labels[i].address;
return(1);
}
}
return(0);
}
//================================================================================================
//
// vdma_label(char *label): set a label at the current address
//
//================================================================================================
void vdma_label(char *label)
{
int i;
fprintf(stderr, "Label[%d]: %s=0x%04X\n", label_pointer, label, program_address);
if(strlen(label) > MAX_LABEL_SIZE)
{
fprintf(stderr, "ERROR: label \"%s\" exceedes the maximum length of %d\n", label, MAX_LABEL_SIZE);
exit(-89);
}
if(label_pointer !=0)
{
/* make sure the label has not been previously declared */
for(i = 0; i < label_pointer; i++)
{
//fprintf(stderr, "label_compare(label=%s, vdma_labels[i=%d].label=%s)\n", label, i, vdma_labels[i].label);
if(label_compare(label, vdma_labels[i].label))
{
//fprintf(stderr, "label_compare(label=%s, vdma_labels[i=%d].label=%s)\n", label, i, vdma_labels[i].label);
fprintf(stderr, "ERROR: the label \"%s\" has already been declared at label[%d] with address=0x%04X\n", label, i, vdma_labels[i].address);
break;
}
}
}
vdma_labels[label_pointer].address = program_address;
vdma_labels[label_pointer].label = label;
sprintf(last_label, "%s:", label);
label_pointer++;
if(label_pointer >= MAX_LABELS)
{
fprintf(stderr, "ERROR: to many labels specified (max=%d)\n", MAX_LABELS);
exit(-90);
}
}
//================================================================================================
//
// vdma_constant_l(char *label): set a constant to equal the address value of a label
//
//================================================================================================
void vdma_constant_l(char *label)
{
dram[program_address].data = 0;
dram[program_address].label = label;
sprintf(dram[program_address].comment, "%24s vdma_constant_l(\"%s\")", last_label, label);
next_address();
}
//================================================================================================
//
// vdma_constant_n(DWORD data): set a constant to a numerical value at the current address
//
//================================================================================================
void vdma_constant_n(DWORD data)
{
dram[program_address].data = data;
dram[program_address].label = "";
sprintf(dram[program_address].comment, "%24s vdma_constant_n(0x%08lX)", last_label, data);
next_address();
}
//================================================================================================
//
// vdma_constant_n64(U64 data): same as vdma_constant_n except for 64-bit data
//
//================================================================================================
void vdma_constant_n64(U64 data)
{
DWORD d32;
d32 = data & 0xFFFFFFFF;
dram[program_address].data = d32;
dram[program_address].label = "";
sprintf(dram[program_address].comment, "%24s vdma_constant_n64(0x%016llX)", last_label, data);
next_address();
d32 = (DWORD)(data >> (U64) 32);
dram[program_address].data = d32;
dram[program_address].label = "";
sprintf(dram[program_address].comment, "%24s // vdma_constant_n64 - upper data", last_label);
next_address();
}
//================================================================================================
//
// vdma_array(DWORD data, int n): initializes an array of data at the current address with the same data
//
//================================================================================================
void vdma_array(DWORD data, int n)
{
int i;
for(i=0; i<n; i++)
{
dram[program_address].data = data;
dram[program_address].label = "";
if(i==0)
sprintf(dram[program_address].comment, "%24s vdma_array(0x%lX, %d)", last_label, data, n);
else
sprintf(dram[program_address].comment, "%24s // %s[%d]", "", vdma_labels[label_pointer-1].label, i);
next_address();
}
}
//************************************************************************************************
//
// all functions from here on map directly to the VDMA instructions documented in the
// GN412x FlexDMA Sequencer Design Guide except that all addresses are specified using labels.
//
//************************************************************************************************
void vdma_nop()
{
dram[program_address].data = VDMA_NOP();
dram[program_address].label = "";
sprintf(dram[program_address].comment, "%24s vdma_nop()", last_label);
next_address();
}
void vdma_load_sys_addr(int r, char *label)
{
dram[program_address].data = VDMA_LOAD_SYS_ADDR(r, 0);
dram[program_address].label = label;
sprintf(dram[program_address].comment, "%24s vdma_load_sys_addr(r=%s, \"%s\")", last_label, r_to_string(r), label);
next_address();
}
void vdma_store_sys_addr(int r, char *label)
{
dram[program_address].data = VDMA_STORE_SYS_ADDR(r, 0);
dram[program_address].label = label;
sprintf(dram[program_address].comment, "%24s vdma_store_sys_addr(r=%s, \"%s\")", last_label, r_to_string(r), label);
next_address();
}
void vdma_add_sys_addr(int data)
{
dram[program_address].data = VDMA_ADD_SYS_ADDR(data);
dram[program_address].label = "";
sprintf(dram[program_address].comment, "%24s vdma_add_sys_addr(%d)", last_label, data);
next_address();
}
void vdma_add_sys_addr_i(char *label)
{
dram[program_address].data = VDMA_ADD_SYS_ADDR_I(0);
dram[program_address].label = label;
sprintf(dram[program_address].comment, "%24s vdma_add_sys_addr_i(\"%s\")", last_label, label);
next_address();
}
void vdma_load_xfer_ctl(int r, char *label)
{
dram[program_address].data = VDMA_LOAD_XFER_CTL(r, 0);
dram[program_address].label = label;
sprintf(dram[program_address].comment, "%24s vdma_load_xfer_ctl(%s, \"%s\")", last_label, r_to_string(r), label);
next_address();
}
void vdma_load_ra(char *label)
{
dram[program_address].data = VDMA_LOAD_RA(0);
dram[program_address].label = label;
sprintf(dram[program_address].comment, "%24s vdma_load_ra(\"%s\")", last_label, label);
next_address();
}
void vdma_add_ra(char *label)
{
dram[program_address].data = VDMA_ADD_RA(0);
sprintf(dram[program_address].comment, "%24s vdma_add_ra(\"%s\")", last_label, label);
dram[program_address].label = label;
next_address();
}
void vdma_load_rb(char *label)
{
dram[program_address].data = VDMA_LOAD_RB(0);
dram[program_address].label = label;
sprintf(dram[program_address].comment, "%24s vdma_load_rb(\"%s\")", last_label, label);
next_address();
}
void vdma_add_rb(char *label)
{
dram[program_address].data = VDMA_ADD_RB(0);
dram[program_address].label = label;
sprintf(dram[program_address].comment, "%24s vdma_add_rb(\"%s\")", last_label, label);
next_address();
}
void vdma_store_ra(char *label)
{
dram[program_address].data = VDMA_STORE_RA(0);
dram[program_address].label = label;
sprintf(dram[program_address].comment, "%24s vdma_store_ra(\"%s\")", last_label, label);
next_address();
}
void vdma_store_rb(char *label)
{
dram[program_address].data = VDMA_STORE_RB(0);
dram[program_address].label = label;
sprintf(dram[program_address].comment, "%24s vdma_store_rb(\"%s\")", last_label, label);
next_address();
}
void vdma_jmp(int c, int ext_cond, char *label)
{
dram[program_address].data = VDMA_JMP(c, ext_cond, 0);
dram[program_address].label = label;
sprintf(dram[program_address].comment, "%24s vdma_jmp(c=%s, ext_cond=%s, \"%s\")", last_label, c_to_string(c), ext_cond_to_string(ext_cond, c), label);
next_address();
}
void vdma_sig_event(int s, int a, int event_en)
{
dram[program_address].data = VDMA_SIG_EVENT(s, a, event_en);
dram[program_address].label = "";
sprintf(dram[program_address].comment, "%24s vdma_sig_event(s=%d, a=%d, event_en=0x%04X)", last_label, s, a, event_en);
next_address();
}
void vdma_wait_event(int event_en, int event_state)
{
dram[program_address].data = VDMA_WAIT_EVENT(event_en, event_state);
dram[program_address].label = "";
sprintf(dram[program_address].comment, "%24s vdma_sig_event(event_en=0x%04X, event_state=0x%04X)", last_label, event_en, event_state);
next_address();
}
//***********************************************************************************************
//***********************************************************************************************
//**
//** Name: vdma_service.c
//**
//** Description: General-Purpose DMA Servicing Routines for a 3DW list and a 4DW list.
//**
//** The following function calls will get invoked from a main program. When the main program
//** is compiled and converted, it will result in a series of write cycles that the BFM
//** will write to the microcode descriptor memory.
//**
//***********************************************************************************************
int data_address = 0; //This will be used to track the data space
//***********************************************************************************************
//**
//** vdma_channel_service_3: This is a generic channel servicing function for 3DW list type.
//** Should be called once for each channel.
//**
//***********************************************************************************************
void vdma_channel_service_3
(
char *base_label, //label to be used for this specific channel
char direction, //direction='l' for l2p or 'p' for p2l
int event_reg, //The event register bit to be used for interrupt generation
int ext_cond, //External condition used for this channel
int condition, //Set to either _EXT_COND_LO or _EXT_COND_HI
int dynamic_list, //set to non zero when the list will be updated dynamicaly
int sg_size, //SYS_ADDR step size of list entries that have a repeat count
struct sg_entry_struct *sg_list
)
{
int cmd_queue_full;
int tmp_address;
int i;
if(direction == 'p')
cmd_queue_full = _PDM_CMD_QUEUE_FULL_HI;
else
cmd_queue_full = _LDM_CMD_QUEUE_FULL_HI;
//---------------------------------------------------------------------------------------------
// Create the program microcode for this channel
//---------------------------------------------------------------------------------------------
vdma_label(base_label);
vdma_jmp(condition, ext_cond, string_cat(base_label, "_END")); //Skip if servicing not required
vdma_jmp(cmd_queue_full, 0, string_cat(base_label, "_END")); //Skip if dma is busy
vdma_load_rb(string_cat(base_label, "_INDEX")); //Load the SG list pointer
vdma_load_sys_addr(_RB,"0x0"); //Load system address from SG entry
vdma_load_xfer_ctl(_RB,"0x2"); //Start DMA1
vdma_jmp(_C_LO, 0, string_cat(base_label, "_NO_INT")); //Need to assert an interrupt?
vdma_sig_event(0, 1, 1<<event_reg); //Assert EVENT(event_reg)
vdma_load_xfer_ctl(_IM,"ZERO"); //Clear C bit
vdma_label(string_cat(base_label, "_NO_INT"));
if(dynamic_list)
{
vdma_load_sys_addr(0,"ZERO"); //Clear the system address register
vdma_store_sys_addr(_RB,"0x1"); //Clear the VDMA_XFER_CTL entry in SG list
}
vdma_add_rb("THREE"); //Advance SG list pointer
vdma_load_ra(string_cat(base_label, "_CNT")); //Load the SG list pointer
vdma_add_ra("MINUS1"); //Subtract 1 from L2P SG list counter
vdma_jmp(_RA_NEQZ, 0, string_cat(base_label, "_UPDATE")); //See if the list needs to wrap around
vdma_load_ra(string_cat(base_label, "_SIZE")); //Restart the list counter
vdma_load_rb(string_cat(base_label, "_BASE")); //Restart the list pointer
vdma_label(string_cat(base_label, "_UPDATE"));
vdma_store_ra(string_cat(base_label, "_CNT")); //Update _CNT
vdma_store_rb(string_cat(base_label, "_INDEX")); //Update _INDEX
vdma_label(string_cat(base_label, "_END"));
//---------------------------------------------------------------------------------------------
// Create the data space for this channel
//---------------------------------------------------------------------------------------------
tmp_address = program_address; //Save away the current program address
vdma_org(data_address);
//-----------------------------------------------
// Local constants
//-----------------------------------------------
vdma_label(string_cat(base_label, "_SIZE"));
vdma_constant_n(sg_size);
vdma_label(string_cat(base_label, "_BASE"));
vdma_constant_l(string_cat(base_label, "_LIST"));
//-----------------------------------------------
// Local variables
//-----------------------------------------------
vdma_label(string_cat(base_label, "_INDEX"));
vdma_constant_l(string_cat(base_label, "_LIST"));
vdma_label(string_cat(base_label, "_CNT"));
vdma_constant_n(sg_size);
//-----------------------------------------------
// SG List storage
//-----------------------------------------------
vdma_label(string_cat(base_label, "_LIST"));
for(i=0; i<sg_size; i++)
{
vdma_constant_n64(sg_list[i].address);
vdma_constant_n( sg_list[i].vdma_xfer_ctl);
}
data_address = program_address; //Save back the current data address
vdma_org(tmp_address); //Restore the program address
}
//***********************************************************************************************
//**
//** vdma_channel_service4: This is a generic channel servicing function for use with 4DW list type.
//**
//***********************************************************************************************
void vdma_channel_service_4
(
char *base_label, //label to be used for this specific channel
char direction, //direction='l' for l2p or 'p' for p2l
int event_reg, //The event register bit to be used for interrupt generation
int ext_cond, //External condition used for this channel
int condition, //Set to either _EXT_COND_LO or _EXT_COND_HI
int dynamic_list, //set to non zero when the list will be updated dynamicaly
int sg_size, //SYS_ADDR step size of list entries that have a repeat count
int sys_addr_increment, //Step size of list entries that have a repeat count
struct sg_entry_struct *sg_list
)
{
int cmd_queue_full;
int tmp_address;
int i;
if(direction == 'p')
cmd_queue_full = _PDM_CMD_QUEUE_FULL_HI;
else
cmd_queue_full = _LDM_CMD_QUEUE_FULL_HI;
//---------------------------------------------------------------------------------------------
// Create the program microcode for this channel
//---------------------------------------------------------------------------------------------
vdma_label(base_label);
vdma_jmp(_EXT_COND_LO, ext_cond, string_cat(base_label, "_END")); //Skip if servicing not required
vdma_jmp(cmd_queue_full, 0, string_cat(base_label, "_END")); //Skip if dma is busy
vdma_load_rb(string_cat(base_label, "_INDEX")); //Load the SG list pointer
vdma_load_ra(string_cat(base_label, "_RPT")); //Load the previous repeat counter
vdma_jmp(_RA_NEQZ, 0, string_cat(base_label, "_RPT_NOT_DONE")); //jmp if previous repeat not done
vdma_load_sys_addr(_RB,"0x3"); //Load repeat count from SG entry
vdma_store_sys_addr(_IM,string_cat(base_label, "_RPT")); //Store to repeat count variable
vdma_load_ra(string_cat(base_label, "_RPT")); //Load the new repeat counter
vdma_jmp(_RA_EQZ, 0, string_cat(base_label, "_NEXT_DESC")); //jmp if the rpt=0
vdma_load_sys_addr(_RB,"0x0"); //Load system address from SG entry
vdma_store_sys_addr(_IM,string_cat(base_label, "_SYSA")); //Store sys address to local variable
vdma_label(string_cat(base_label, "_RPT_NOT_DONE"));
vdma_add_ra("MINUS1"); //Decrement the repeat counter
vdma_load_sys_addr(_IM,string_cat(base_label, "_SYSA")); //Load system address from local variable
vdma_load_xfer_ctl(_RB,"0x2"); //Start DMA1
vdma_jmp(_C_LO, 0, string_cat(base_label, "_NO_INT")); //No interrupt if C=0
vdma_jmp(_RA_NEQZ, 0, string_cat(base_label, "_NO_INT")); //No interrupt if RA!=0
vdma_sig_event(0, 1, 1<<event_reg); //Assert EVENT(event_reg)
vdma_load_xfer_ctl(_IM,"ZERO"); //Clear C bit
vdma_label(string_cat(base_label, "_NO_INT"));
vdma_store_ra(string_cat(base_label, "_RPT")); //Update _RPT
vdma_add_sys_addr(sys_addr_increment); //update the system address
vdma_store_sys_addr(_IM,string_cat(base_label, "_SYSA")); //Store updated sys address to local variable
vdma_jmp(_RA_NEQZ, 0, string_cat(base_label, "_UPDATE_B")); //jmp if repeat count not done
if(dynamic_list)
{
vdma_load_sys_addr(0,"ZERO"); //Clear the system address register
vdma_store_sys_addr(_RB,"0x2"); //Clear the VDMA_XFER_CTL entry in SG list
}
vdma_label(string_cat(base_label, "_NEXT_DESC"));
vdma_add_rb("FOUR"); //Advance SG list pointer
vdma_load_ra(string_cat(base_label, "_CNT")); //Load the SG list counter
vdma_add_ra("MINUS1"); //Subtract 1 from L2P SG list counter
vdma_jmp(_RA_NEQZ, 0, string_cat(base_label, "_UPDATE")); //See if the list needs to wrap around
vdma_load_ra(string_cat(base_label, "_SIZE")); //Restart the list counter
vdma_load_rb(string_cat(base_label, "_BASE")); //Restart the list pointer
vdma_label(string_cat(base_label, "_UPDATE"));
vdma_store_ra(string_cat(base_label, "_CNT")); //Update _CNT
vdma_label(string_cat(base_label, "_UPDATE_B"));
vdma_store_rb(string_cat(base_label, "_INDEX")); //Update _INDEX
vdma_label(string_cat(base_label, "_END"));
//---------------------------------------------------------------------------------------------
// Create the data space for this channel
//---------------------------------------------------------------------------------------------
tmp_address = program_address; //Save away the current program address
vdma_org(data_address);
//-----------------------------------------------
// Local constants
//-----------------------------------------------
vdma_label(string_cat(base_label, "_SIZE"));
vdma_constant_n(sg_size);
vdma_label(string_cat(base_label, "_BASE"));
vdma_constant_l(string_cat(base_label, "_LIST"));
//-----------------------------------------------
// Local variables
//-----------------------------------------------
vdma_label(string_cat(base_label, "_INDEX"));
vdma_constant_l(string_cat(base_label, "_LIST"));
vdma_label(string_cat(base_label, "_CNT"));
vdma_constant_n(sg_size);
vdma_label(string_cat(base_label, "_RPT"));
vdma_constant_n(0);
vdma_constant_n(0); //Need to pad out the repeat count
vdma_label(string_cat(base_label, "_SYSA"));
vdma_constant_n64(0);
//-----------------------------------------------
// SG List storage
//-----------------------------------------------
vdma_label(string_cat(base_label, "_LIST"));
for(i=0; i<sg_size; i++)
{
vdma_constant_n64(sg_list[i].address);
vdma_constant_n( sg_list[i].vdma_xfer_ctl);
vdma_constant_n( sg_list[i].vdma_xfer_rpt);
}
data_address = program_address; //Save back the current data address
vdma_org(tmp_address); //Restore the program address
}
//***********************************************************************************************
//***********************************************************************************************
//**
//** Name: simple.c
//**
//** Description: This is an example test source code used to drive the Lambo TestBench.
//**
//***********************************************************************************************
//***********************************************************************************************
#include "lib/maketest.c"
#define BAR0_BASE 0xFF00000010000000ll
#define BAR1_BASE 0xFF000000A0000000ll
#define BFM_BAR0_BASE 0x8765432120000000ll
#define BFM_BAR1_BASE 0xBB00000040000000ll
//***********************************************************************************************
//**
//** Main:
//**
//** Edit the program below to create your own test script.
//**
//***********************************************************************************************
main(argc,argv)
int argc;
char *argv[];
{
//-----------------------------------------------------------------------------------------------
// Always call maketest_init at the beginning of a test program
//-----------------------------------------------------------------------------------------------
maketest_init(argc,argv);
//================================================================================================
//== START of user script
//================================================================================================
comment("-----------------------------------------------------------------------------");
comment("Generated from: simple.c - do not edit the vec file directly as it is not the source!");
comment("Short example of using the lambo TestBench");
comment("-----------------------------------------------------------------------------");
comment("Select the GN4124 Primary BFM");
model(0);
comment("Initialize the BFM to its default state");
init();
comment("\nDrive reset to the FPGA");
reset(16);
comment("\n");
comment("-----------------------------------------------------------------------------");
comment("Initialize the Primary GN412x BFM model");
comment("-----------------------------------------------------------------------------");
comment("These address ranges will generate traffic from the BFM to the FPGA");
comment("bar BAR ADDR SIZE VC TC S");
bar(0, BAR0_BASE, 0x08000000, 0, 7, 0);
bar(1, BAR1_BASE, 0x10000000, 1, 5, 0);
comment("\nThis allocates a RAM block inside the BFM for the FPGA to access");
comment("bfm_bar BAR ADDR SIZE");
bfm_bar(0, BFM_BAR0_BASE, 0x20000000);
bfm_bar(1, BFM_BAR1_BASE, 0x20000000);
comment("\nWait until the FPGA is un-reset and ready for traffic on the local bus");
wait(64);
comment("\n-----------------------------------------------------------------------------");
comment("Access the descriptor memory in the Lambo design");
comment("-----------------------------------------------------------------------------");
comment("the following three writes will go out in a single packet");
wrb(BAR0_BASE+0x4000, 0xF, 0x87654321);
wrb(BAR0_BASE+0x4004, 0xF, 0xFEEDFACE);
wr( BAR0_BASE+0x4008, 0xF, 0xDEADBEEF);
comment("\nNow read back what was just written");
comment("the following three reads will go out as a single request");
rdb(BAR0_BASE+0x4000, 0xF, 0x87654321, 0xFFFFFFFF);
rdb(BAR0_BASE+0x4004, 0xF, 0xFEEDFACE, 0xFFFFFFFF);
rd( BAR0_BASE+0x4008, 0xF, 0xDEADBEEF, 0xFFFFFFFF);
comment("\n");
flush(256);
comment("\n");
wait(16);
comment("\n");
sync();
//================================================================================================
//== END of user script
//================================================================================================
exit(0);
}
//***********************************************************************************************
//***********************************************************************************************
//**
//** Name: sg_dma.c
//**
//** Description: This runs a scatter/gather DMA scenario for the Lambo TestBench.
//**
//**
//***********************************************************************************************
//***********************************************************************************************
//===============================================================================================
// This provides the framework for creating tests for the testbench as described in
// GN412x Simulation Test Bench User Guide
//===============================================================================================
#include "lib/maketest.c"
//===============================================================================================
// This provides the framework for creating microcode for the 3 or 4DW list type described in
// the application note: "Implementing Multi-channel DMA with the GN412x IP"
//===============================================================================================
#include "lib/vdma_service.c"
//===============================================================================================
// lambo.h contains the address map for the Lambo project
//===============================================================================================
#include "lambo.h"
//===============================================================================================
// Define the Memory Map for the Simulation
//===============================================================================================
#define BAR0_BASE 0xFF00000010000000ll
#define BAR1_BASE 0xFF000000A0000000ll
#define BFM_BAR0_BASE 0x8765432120000000ll
#define BFM_BAR1_BASE 0xBB00000040000000ll
#define CHAN0_DESC_LIST_SIZE 4
#define CHAN1_DESC_LIST_SIZE 4
#define L2P_CHAN0_DMA_LENGTH 0x080
#define L2P_CHAN0_XFER_CTL (0x00010000+L2P_CHAN0_DMA_LENGTH)
#define L2P_CHAN1_DMA_LENGTH 0x080
#define L2P_CHAN1_XFER_CTL (0x00080000+L2P_CHAN1_DMA_LENGTH)
//===============================================================================================
// Define the Memory Map for the Simulation
//===============================================================================================
struct sg_entry_struct sg_list_chan0[] =
{
{ BFM_BAR0_BASE+0x000F0000, L2P_CHAN0_XFER_CTL, 2 },
{ BFM_BAR0_BASE+0x000F1000, L2P_CHAN0_XFER_CTL, 2 },
{ BFM_BAR0_BASE+0x000F2000, L2P_CHAN0_XFER_CTL, 2 },
{ BFM_BAR0_BASE+0x000F3000, L2P_CHAN0_XFER_CTL | 0x80000000, 2 }, //Assert an interrupt
{ BFM_BAR0_BASE+0x000F4000, L2P_CHAN0_XFER_CTL, 2 },
{ BFM_BAR0_BASE+0x000F5000, L2P_CHAN0_XFER_CTL, 2 },
{ BFM_BAR0_BASE+0x000F6000, L2P_CHAN0_XFER_CTL, 2 },
{ BFM_BAR0_BASE+0x000F7000, L2P_CHAN0_XFER_CTL, 2 },
{ 0x0ll, 0, 0 }
};
struct sg_entry_struct sg_list_chan1[] =
{
{ BFM_BAR1_BASE+0x00087000, L2P_CHAN1_XFER_CTL, 1 },
{ BFM_BAR1_BASE+0x00086000, L2P_CHAN1_XFER_CTL, 1 },
{ BFM_BAR1_BASE+0x00085000, L2P_CHAN1_XFER_CTL, 1 },
{ BFM_BAR1_BASE+0x00084000, L2P_CHAN1_XFER_CTL | 0x80000000, 1 }, //Assert an interrupt
{ BFM_BAR1_BASE+0x00083000, L2P_CHAN1_XFER_CTL, 1 },
{ BFM_BAR1_BASE+0x00082000, L2P_CHAN1_XFER_CTL, 1 },
{ BFM_BAR1_BASE+0x00081000, L2P_CHAN1_XFER_CTL, 1 },
{ BFM_BAR1_BASE+0x00080000, L2P_CHAN1_XFER_CTL, 1 },
{ 0x0ll, 0, 0 }
};
//***********************************************************************************************
//**
//** vdma_main: This will insert the DMA microcode and data into the test script
//**
//** The last function call, vdma_process(), will cross reference all of the labels in the
//** source code so that you end up with the proper hexadecimal values that need to be written
//** to descriptor RAM.
//**
//***********************************************************************************************
void vdma_main()
{
vdma_org(0x0000); //This initializes the program address counter
data_address = 0x200; //This initializes the data space address counter
vdma_label("START");
vdma_nop(); //do nothing
//===============================================================================================
// START of the main program loop
//===============================================================================================
// Example source code to be compiled into VDMA binarys or test bench script
vdma_label("MAIN");
vdma_channel_service_4
(
"L2P_CHAN0", //char *base_label, //label to be used for this specific channel
'l', //char direction, //direction='l' for l2p or 'p' for p2l
0, //int event_reg, //The event register bit to be used for interrupt generation
_EXT_COND_0, //int ext_cond, //External condition used for this channel
_EXT_COND_LO, //int condition, //Set to either _EXT_COND_LO or _EXT_COND_HI
1, //int dynamic_list, //set to non zero when the list will be updated dynamicaly
CHAN0_DESC_LIST_SIZE, //int sg_size, //SYS_ADDR step size of list entries that have a repeat count
L2P_CHAN0_DMA_LENGTH, //int sys_addr_increment, //Step size of list entries that have a repeat count
sg_list_chan0 //struct sg_entry_struct *sg_list //SG List itself
);
vdma_channel_service_3
(
"L2P_CHAN1", //char *base_label, //label to be used for this specific channel
'l', //char direction, //direction='l' for l2p or 'p' for p2l
0, //int event_reg, //The event register bit to be used for interrupt generation
_EXT_COND_0, //int ext_cond, //External condition used for this channel
_EXT_COND_LO, //int condition, //Set to either _EXT_COND_LO or _EXT_COND_HI
1, //int dynamic_list, //set to non zero when the list will be updated dynamicaly
CHAN0_DESC_LIST_SIZE, //int sg_size, //SYS_ADDR step size of list entries that have a repeat count
sg_list_chan1 //struct sg_entry_struct *sg_list //SG List itself
);
// vdma_load_rb("MARKER"); //This is to ease debug
// vdma_load_ra("MARKER");
// vdma_load_sys_addr(_IM,"MARKER");
vdma_jmp(_ALWAYS, 0,"MAIN"); //loop forever
//===============================================================================================
// END of the main program loop
//===============================================================================================
//-----------------------------------------------------------------------------------------------
// Global Constants
//-----------------------------------------------------------------------------------------------
vdma_org(0x0100);
vdma_label("ZERO");
vdma_constant_n64(0); //The constant 0
vdma_label("MINUS1");
vdma_constant_n(0xFFFFFFFF); //The constant -1
vdma_label("THREE");
vdma_constant_n(3); //The constant 3
vdma_label("FOUR");
vdma_constant_n(4); //The constant 4
vdma_label("MARKER");
vdma_constant_n64(0x2222222211111111ll);
//===============================================================================================
// Must run vdma_process to resolve the cross-references and generate the memory writes
//===============================================================================================
vdma_process(BAR0_BASE + 0x4000); // This actually printfs the data to the file
}
//***********************************************************************************************
//**
//** Main:
//**
//** Edit the program below to create your own test script.
//**
//***********************************************************************************************
main(argc,argv)
int argc;
char *argv[];
{
int offset=0, i;
//-----------------------------------------------------------------------------------------------
// Always call maketest_init at the beginning of a test program
//-----------------------------------------------------------------------------------------------
maketest_init(argc,argv);
//================================================================================================
//== START of user script
//================================================================================================
comment("-----------------------------------------------------------------------------");
comment("Generated from: simple.c - do not edit the vec file directly as it is not the source!");
comment("Short example of using the lambo TestBench");
comment("-----------------------------------------------------------------------------");
comment("Select the GN4124 Primary BFM");
model(0);
comment("Initialize the BFM to its default state");
init();
comment("\nDrive reset to the FPGA");
reset(16);
comment("\n");
comment("-----------------------------------------------------------------------------");
comment("Initialize the Primary GN412x BFM model");
comment("-----------------------------------------------------------------------------");
comment("These address ranges will generate traffic from the BFM to the FPGA");
comment("bar BAR ADDR SIZE VC TC S");
bar(0, BAR0_BASE, 0x08000000, 0, 7, 0);
bar(1, BAR1_BASE, 0x10000000, 1, 5, 0);
comment("\nThis allocates a RAM block inside the BFM for the FPGA to access");
comment("bfm_bar BAR ADDR SIZE");
bfm_bar(0, BFM_BAR0_BASE, 0x20000000);
bfm_bar(1, BFM_BAR1_BASE, 0x20000000);
comment("\nWait until the FPGA is un-reset and ready for traffic on the local bus");
wait(64);
comment("\n-------------------------------------------------------------------------------");
comment("DO some setup");
comment("-------------------------------------------------------------------------------");
comment("Lambo setup...");
rd(BAR0_BASE + DMA_SEQ_CSR_REG, 0xF, 0x00000000, 0xFFFFFFFF);
flush(0x100);
wr(BAR0_BASE + DMA_SEQ_DPTR_REG, 0xF, 0x0);
wr(BAR0_BASE + DMA_SEQ_EVENT_EN_REG, 0xF, 0x3);
wr(BAR0_BASE + DMA_SEQ_EVENT_CLR_REG, 0xF, 0xFFFFFFFF);
wr(BAR0_BASE + APP_CFG, 0xF, 0x6);
wr(BAR0_BASE + APP_CFG, 0xF, 0x0);
wr(BAR0_BASE + DMA_CFG, 0xF, 0x1F);
wr(BAR0_BASE + DMA_CFG, 0xF, 0x7);
wr(BAR0_BASE + APP_GEN_COUNT, 0xF, 0x0);
wr(BAR0_BASE + APP_RCV_COUNT, 0xF, 0x0);
wr(BAR0_BASE + APP_RCV_ERR_COUNT, 0xF, 0x0);
wr(BAR0_BASE + DMA_PAYLOAD_SIZE, 0xF, 0x8020);
comment("\n-------------------------------------------------------------------------------");
comment("Setup the DMA microcode");
comment("-------------------------------------------------------------------------------");
vdma_main();
comment("\nStart VDMA");
wr(BAR0_BASE + DMA_SEQ_CSR_REG, 0xF, 0x1);
comment("\n-------------------------------------------------------------------------------");
comment("Wait for an Interrupt for Channel 0");
comment("-------------------------------------------------------------------------------");
gpio_wait(2000, 0x0001, 0x0001);
comment("Clear the interrupt");
wr(BAR0_BASE + DMA_SEQ_EVENT_CLR_REG, 0xF, 0x00000001);
//After the interrupt, it is safe to reuse SG list for channel 0
vdma_label_lookup("L2P_CHAN0_LIST", &offset); //This looks up the offset to the SG list for channel 0
printf("-- L2P_CHAN0_LIST=0x%04X which eqates to byte address=0x%08X\n", offset, offset*4);
// for(i=0; i<CHAN0_DESC_LIST_SIZE; i++)
// {
// if(sg_list_chan0[i+4].address == 0) break;
// wrb(BAR0_BASE + 0x4000 + (offset + (i*3))*4, 0xF, (U32) (sg_list_chan0[i+4].address & 0xFFFFFFFF) );
// wrb(BAR0_BASE + 0x4000 + (offset + (i*3))*4 + 4, 0xF, (U32) (sg_list_chan0[i+4].address >> 32) );
// wr( BAR0_BASE + 0x4000 + (offset + (i*3))*4 + 8, 0xF, (U32) sg_list_chan0[i+4].vdma_xfer_ctl );
// }
// wait(100);
comment("\nRead VDMA idle status");
rd(BAR0_BASE + DMA_SEQ_CSR_REG, 0xF, 0x00000000, 0xFFFFFFFF);
flush(256);
wait(16);
wr32(BAR0_BASE + 0x5001, 0x87654321);
wr16(BAR0_BASE + 0x5013, 0x2211);
//================================================================================================
//== END of user script
//================================================================================================
fclose(outfp);
exit(0);
}
//***********************************************************************************************
//***********************************************************************************************
//**
//** Name: simple.c
//**
//** Description: This is an example test source code used to drive the Lambo TestBench.
//**
//***********************************************************************************************
//***********************************************************************************************
#include "lib/maketest.c"
#define BAR0_BASE 0xFF00000010000000ll
#define BAR1_BASE 0xFF000000A0000000ll
#define BFM_BAR0_BASE 0x8765432120000000ll
#define BFM_BAR1_BASE 0xBB00000040000000ll
//***********************************************************************************************
//**
//** Main:
//**
//** Edit the program below to create your own test script.
//**
//***********************************************************************************************
main(argc,argv)
int argc;
char *argv[];
{
//-----------------------------------------------------------------------------------------------
// Always call maketest_init at the beginning of a test program
//-----------------------------------------------------------------------------------------------
maketest_init(argc,argv);
//================================================================================================
//== START of user script
//================================================================================================
comment("-----------------------------------------------------------------------------");
comment("Generated from: simple.c - do not edit the vec file directly as it is not the source!");
comment("Short example of using the lambo TestBench");
comment("-----------------------------------------------------------------------------");
comment("Select the GN4124 Primary BFM");
model(0);
comment("Initialize the BFM to its default state");
init();
comment("\nDrive reset to the FPGA");
reset(16);
comment("\n");
comment("-----------------------------------------------------------------------------");
comment("Initialize the Primary GN412x BFM model");
comment("-----------------------------------------------------------------------------");
comment("These address ranges will generate traffic from the BFM to the FPGA");
comment("bar BAR ADDR SIZE VC TC S");
bar(0, BAR0_BASE, 0x08000000, 0, 7, 0);
bar(1, BAR1_BASE, 0x10000000, 1, 5, 0);
comment("\nThis allocates a RAM block inside the BFM for the FPGA to access");
comment("bfm_bar BAR ADDR SIZE");
bfm_bar(0, BFM_BAR0_BASE, 0x20000000);
bfm_bar(1, BFM_BAR1_BASE, 0x20000000);
comment("\nWait until the FPGA is un-reset and ready for traffic on the local bus");
wait(64);
comment("\n-----------------------------------------------------------------------------");
comment("Access the descriptor memory in the Lambo design");
comment("-----------------------------------------------------------------------------");
comment("the following three writes will go out in a single packet");
wrb(BAR0_BASE+0x4000, 0xF, 0x87654321);
wrb(BAR0_BASE+0x4004, 0xF, 0xFEEDFACE);
wr( BAR0_BASE+0x4008, 0xF, 0xDEADBEEF);
comment("\nNow read back what was just written");
comment("the following three reads will go out as a single request");
rdb(BAR0_BASE+0x4000, 0xF, 0x87654321, 0xFFFFFFFF);
rdb(BAR0_BASE+0x4004, 0xF, 0xFEEDFACE, 0xFFFFFFFF);
rd( BAR0_BASE+0x4008, 0xF, 0xDEADBEEF, 0xFFFFFFFF);
comment("\n");
flush(256);
comment("\n");
wait(16);
comment("\n");
sync();
//================================================================================================
//== END of user script
//================================================================================================
exit(0);
}
-------------------------------------------------------------------------------
-- Generated from: simple.c - do not edit the vec file directly as it is not the source!
-- Short example of using the lambo TestBench
-------------------------------------------------------------------------------
-- Select the GN4124 Primary BFM
model %d0
-- Initialize the BFM to its default state
init
-- Drive reset to the FPGA
reset %d16
-------------------------------------------------------------------------------
-- Initialize the Primary GN412x BFM model
-------------------------------------------------------------------------------
-- These address ranges will generate traffic from the BFM to the FPGA
-- bar BAR ADDR SIZE VC TC S
bar 0 FF00000010000000 08000000 0 7 0
bar 1 FF000000A0000000 10000000 1 5 0
-- This allocates a RAM block inside the BFM for the FPGA to access
-- bfm_bar BAR ADDR SIZE
bfm_bar 0 8765432120000000 20000000
bfm_bar 1 BB00000040000000 20000000
-- Wait until the FPGA is un-reset and ready for traffic on the local bus
wait %d64
-------------------------------------------------------------------------------
-- Access the descriptor memory in the Lambo design
-------------------------------------------------------------------------------
-- the following three writes will go out in a single packet
wrb FF00000010004000 F 87654321
wrb FF00000010004004 F FEEDFACE
wr FF00000010004008 F DEADBEEF
-- Now read back what was just written
-- the following three reads will go out as a single request
rdb FF00000010004000 F 87654321 FFFFFFFF
rdb FF00000010004004 F FEEDFACE FFFFFFFF
rd FF00000010004008 F DEADBEEF FFFFFFFF
flush %d256
wait %d16
sync
//***********************************************************************************************
//***********************************************************************************************
//**
//** Name: simple_dma.c
//**
//** Description: This is an example test source code used to drive the Lambo TestBench.
//**
//**
//***********************************************************************************************
//***********************************************************************************************
#include "lib/maketest.c" //This inserts the Test_Builder C framework
#include "lambo.h" //This is for the project specific registers
//===============================================================================================
// Define the Memory Map for the Simulation
//===============================================================================================
#define BAR0_BASE 0xFF00000010000000ll //rd/wr here generate LB cycles
#define BAR1_BASE 0xFF000000A0000000ll
#define BFM_BAR0_BASE 0x8765432120000000ll //rd/wr here accesses internal BFM memory
#define BFM_BAR1_BASE 0xBB00000040000000ll
#define VDMA_DRAM_BASE (BAR0_BASE + 0x4000ll) //This is where the microcode will be written
//***********************************************************************************************
//**
//** VDMA Sequencer Microcode:
//**
//** The following microcode will get compiled and converted into a series of write cycles
//** so that the BFM will write the microcode into descriptor memory. The last function call
//** vdma_process() will cross reference all of the labels in the source code so that you
//** end up with the proper hexadecimal values that need to be written to descriptor RAM.
//**
//***********************************************************************************************
void vdma_main()
{
//===============================================================================================
// START of the main program loop
//===============================================================================================
// Example source code to be compiled into VDMA binarys or test bench script
vdma_org(0x0000);
vdma_label("MAIN");
vdma_nop();
vdma_label("DO_L2P0");
vdma_load_sys_addr(_IM,"L2P0_SYS_ADDR"); //Load system address from SG entry
vdma_load_xfer_ctl(_IM,"L2P0_XFER_CTL"); //Start DMA0
vdma_label("DO_L2P1");
vdma_load_sys_addr(_IM,"L2P1_SYS_ADDR"); //Load system address from SG entry
vdma_load_xfer_ctl(_IM,"L2P1_XFER_CTL"); //Start DMA1
vdma_label("WAIT4IDLE");
vdma_jmp(_EXT_COND_LO,_LDM_IDLE,"WAIT4IDLE"); //Loop until DMA idle
vdma_sig_event(0, 1, 0x0001);
vdma_label("FOREVER");
vdma_nop();
vdma_jmp(_ALWAYS, 0,"FOREVER"); //Loop forever
//===============================================================================================
// END of the main program loop
//===============================================================================================
//
//-----------------------------------------------------------------------------------------------
// Constants
//-----------------------------------------------------------------------------------------------
vdma_org(0x0100);
vdma_label("L2P0_SYS_ADDR");
vdma_constant_n64(BFM_BAR0_BASE+0x200); //L2P0 system address low/hi
vdma_label("L2P0_XFER_CTL");
vdma_constant_n(0x00010080); //L2P0 transfer control: 128B, STREAM_ID=1
vdma_label("L2P1_SYS_ADDR");
vdma_constant_n64(BFM_BAR1_BASE+0x200); //L2P1 system address low/hi
vdma_label("L2P1_XFER_CTL");
vdma_constant_n(0x00040080); //L2P1 transfer control: 128B, STREAM_ID=4
//===============================================================================================
// Must run vdma_process to resolve the cross-references and generate the memory writes
//===============================================================================================
vdma_process(VDMA_DRAM_BASE); // This actually printfs the data to the file
}
//***********************************************************************************************
//**
//** Main:
//**
//** Edit the program below to create your own test script.
//**
//***********************************************************************************************
main(argc,argv)
int argc;
char *argv[];
{
//-----------------------------------------------------------------------------------------------
// Always call maketest_init at the beginning of a test program
//-----------------------------------------------------------------------------------------------
maketest_init(argc,argv);
//================================================================================================
//== START of user script
//================================================================================================
comment("-----------------------------------------------------------------------------");
comment("Generated from: simple.c - do not edit the vec file directly as it is not the source!");
comment("Short example of using the lambo TestBench");
comment("-----------------------------------------------------------------------------");
comment("Select the GN4124 Primary BFM");
model(0);
comment("Initialize the BFM to its default state");
init();
comment("\nDrive reset to the FPGA");
reset(16);
comment("\n");
comment("-----------------------------------------------------------------------------");
comment("Initialize the Primary GN412x BFM model");
comment("-----------------------------------------------------------------------------");
comment("These address ranges will generate traffic from the BFM to the FPGA");
comment("bar BAR ADDR SIZE VC TC S");
bar(0, BAR0_BASE, 0x08000000, 0, 7, 0);
bar(1, BAR1_BASE, 0x10000000, 1, 5, 0);
comment("\nThis allocates a RAM block inside the BFM for the FPGA to access");
comment("bfm_bar BAR ADDR SIZE");
bfm_bar(0, BFM_BAR0_BASE, 0x20000000);
bfm_bar(1, BFM_BAR1_BASE, 0x20000000);
comment("\nWait until the FPGA is un-reset and ready for traffic on the local bus");
wait(64);
comment("\n-------------------------------------------------------------------------------");
comment("DO some setup");
comment("-------------------------------------------------------------------------------");
comment("Lambo setup...");
rd(BAR0_BASE + DMA_SEQ_CSR_REG, 0xF, 0x00000000, 0xFFFFFFFF);
flush(0x100);
wr(BAR0_BASE + DMA_SEQ_DPTR_REG, 0xF, 0x0);
wr(BAR0_BASE + DMA_SEQ_EVENT_EN_REG, 0xF, 0x1);
wr(BAR0_BASE + DMA_SEQ_EVENT_CLR_REG, 0xF, 0xFFFFFFFF);
wr(BAR0_BASE + APP_CFG, 0xF, 0x6);
wr(BAR0_BASE + APP_CFG, 0xF, 0x0);
wr(BAR0_BASE + DMA_CFG, 0xF, 0x1F);
wr(BAR0_BASE + DMA_CFG, 0xF, 0x7);
wr(BAR0_BASE + APP_GEN_COUNT, 0xF, 0x0);
wr(BAR0_BASE + APP_RCV_COUNT, 0xF, 0x0);
wr(BAR0_BASE + APP_RCV_ERR_COUNT, 0xF, 0x0);
wr(BAR0_BASE + DMA_PAYLOAD_SIZE, 0xF, 0x8020);
comment("\n-------------------------------------------------------------------------------");
comment("Setup the DMA microcode");
comment("-------------------------------------------------------------------------------");
vdma_main();
comment("\nStart VDMA");
wr(BAR0_BASE + DMA_SEQ_CSR_REG, 0xF, 0x1);
gpio_wait(300, 0x0001, 0x0001);
comment("\nRead VDMA idle status");
rd(BAR0_BASE + DMA_SEQ_CSR_REG, 0xF, 0x00000000, 0xFFFFFFFF);
flush(256);
wait(16);
//================================================================================================
//== END of user script
//================================================================================================
fclose(outfp);
exit(0);
}
0x0000 0x00000000 MAIN: vdma_nop()
0x0001 0x40000100 DO_L2P0: vdma_load_sys_addr(r=_IM, "L2P0_SYS_ADDR")
0x0002 0xF0000102 vdma_load_xfer_ctl(_IM, "L2P0_XFER_CTL")
0x0003 0x40000103 DO_L2P1: vdma_load_sys_addr(r=_IM, "L2P1_SYS_ADDR")
0x0004 0xF0000105 vdma_load_xfer_ctl(_IM, "L2P1_XFER_CTL")
0x0005 0x17210005 WAIT4IDLE: vdma_jmp(c=_EXT_COND_LO, ext_cond=_LDM_IDLE, "WAIT4IDLE")
0x0006 0x84000001 vdma_sig_event(s=0, a=1, event_en=0x0001)
0x0007 0x00000000 FOREVER: vdma_nop()
0x0008 0x1A000007 vdma_jmp(c=_ALWAYS, ext_cond=NA, "FOREVER")
0x0100 0x20000200 L2P0_SYS_ADDR: vdma_constant_n64(0x8765432120000200)
0x0101 0x87654321 // vdma_constant_n64 - upper data
0x0102 0x00010080 L2P0_XFER_CTL: vdma_constant_n(0x00010080)
0x0103 0x40000200 L2P1_SYS_ADDR: vdma_constant_n64(0xBB00000040000200)
0x0104 0xBB000000 // vdma_constant_n64 - upper data
0x0105 0x00040080 L2P1_XFER_CTL: vdma_constant_n(0x00040080)
// Label Listing:
// 0x0000 : "MAIN"
// 0x0001 : "DO_L2P0"
// 0x0003 : "DO_L2P1"
// 0x0005 : "WAIT4IDLE"
// 0x0007 : "FOREVER"
// 0x0100 : "L2P0_SYS_ADDR"
// 0x0102 : "L2P0_XFER_CTL"
// 0x0103 : "L2P1_SYS_ADDR"
// 0x0105 : "L2P1_XFER_CTL"
TESTBENCH = testbench
DDRMODEL = sim_models/2048Mb_ddr3
SPEC = ../rtl
GNCORE = ../../../../GN4124_core/hdl/gn4124core/rtl
GNCORE_IP = ../../../../GN4124_core/hdl/spec/ip_cores
DDRCORE = ../../../../ddr3_ctrl_core/hdl/rtl
DDRCORE_IP = ../../../../ddr3_ctrl_core/hdl/spec/ip_cores/ddr_ctrl_bank3/user_design/rtl
# These are the technology specific files
#GLBL = unisims
#FPGA = unisims
VHDL_LIB = testbench
MK = mk
# Change VCOM and VLOG for use with other simulation tools
VCOM = vcom
VLOG = vlog
TOUCH = echo "" > $@
spec : $(MK)/tb_spec.mk
bfm : $(MK)/tb_gn412x.mk
clean :
rm -f $(MK)/*.mk
vdel -lib work -all
vlib work
##################################################################################################
# SPEC Test Bench Project
##################################################################################################
$(MK)/tb_spec.mk : $(TESTBENCH)/tb_spec.vhd $(MK)/spec_ddr_test.mk $(MK)/gn412x_bfm.mk $(MK)/cmd_router.mk \
$(MK)/ddr3.mk
$(VCOM) $(TESTBENCH)/tb_spec.vhd
$(TOUCH)
##################################################################################################
# SPEC Project
##################################################################################################
$(MK)/spec_ddr_test.mk : $(SPEC)/spec_ddr_test.vhd $(MK)/gn4124_core.mk \
$(MK)/gpio_regs.mk $(MK)/ddr3_ctrl.mk
$(VCOM) $(SPEC)/spec_ddr_test.vhd
$(TOUCH)
$(MK)/gpio_regs.mk : $(SPEC)/gpio_regs.vhd
$(VCOM) $(SPEC)/gpio_regs.vhd
$(TOUCH)
# GN4124 core
$(MK)/gn4124_core.mk : $(GNCORE)/spartan6/gn4124_core.vhd $(MK)/gn4124_core_pkg.mk $(MK)/p2l_des.mk \
$(MK)/p2l_decode32.mk $(MK)/wbmaster32.mk $(MK)/l2p_arbiter.mk $(MK)/l2p_ser.mk \
$(MK)/dma_controller.mk $(MK)/l2p_dma_master.mk $(MK)/p2l_dma_master.mk \
$(MK)/serdes_1_to_n_clk_pll_s2_diff.mk
$(VCOM) $(GNCORE)/spartan6/gn4124_core.vhd
$(TOUCH)
$(MK)/gn4124_core_pkg.mk : $(GNCORE)/spartan6/gn4124_core_pkg.vhd
$(VCOM) $(GNCORE)/spartan6/gn4124_core_pkg.vhd
$(TOUCH)
$(MK)/p2l_des.mk : $(GNCORE)/spartan6/p2l_des.vhd $(MK)/serdes_1_to_n_data_s2_se.mk
$(VCOM) $(GNCORE)/spartan6/p2l_des.vhd
$(TOUCH)
$(MK)/p2l_decode32.mk : $(GNCORE)/p2l_decode32.vhd
$(VCOM) $(GNCORE)/p2l_decode32.vhd
$(TOUCH)
$(MK)/wbmaster32.mk : $(GNCORE)/wbmaster32.vhd $(MK)/fifo_32x512.mk $(MK)/fifo_64x512.mk
$(VCOM) $(GNCORE)/wbmaster32.vhd
$(TOUCH)
$(MK)/l2p_arbiter.mk : $(GNCORE)/l2p_arbiter.vhd
$(VCOM) $(GNCORE)/l2p_arbiter.vhd
$(TOUCH)
$(MK)/dma_controller.mk : $(GNCORE)/dma_controller.vhd $(MK)/dma_controller_wb_slave.mk
$(VCOM) $(GNCORE)/dma_controller.vhd
$(TOUCH)
$(MK)/l2p_dma_master.mk : $(GNCORE)/l2p_dma_master.vhd $(MK)/fifo_32x512.mk
$(VCOM) $(GNCORE)/l2p_dma_master.vhd
$(TOUCH)
$(MK)/p2l_dma_master.mk : $(GNCORE)/p2l_dma_master.vhd $(MK)/fifo_64x512.mk
$(VCOM) $(GNCORE)/p2l_dma_master.vhd
$(TOUCH)
$(MK)/dma_controller_wb_slave.mk : $(GNCORE)/dma_controller_wb_slave.vhd
$(VCOM) $(GNCORE)/dma_controller_wb_slave.vhd
$(TOUCH)
$(MK)/l2p_ser.mk : $(GNCORE)/spartan6/l2p_ser.vhd $(MK)/serdes_n_to_1_s2_se.mk \
$(MK)/serdes_n_to_1_s2_diff.mk
$(VCOM) $(GNCORE)/spartan6/l2p_ser.vhd
$(TOUCH)
$(MK)/serdes_1_to_n_clk_pll_s2_diff.mk : $(GNCORE)/spartan6/serdes_1_to_n_clk_pll_s2_diff.vhd
$(VCOM) $(GNCORE)/spartan6/serdes_1_to_n_clk_pll_s2_diff.vhd
$(TOUCH)
$(MK)/serdes_1_to_n_data_s2_se.mk : $(GNCORE)/spartan6/serdes_1_to_n_data_s2_se.vhd
$(VCOM) $(GNCORE)/spartan6/serdes_1_to_n_data_s2_se.vhd
$(TOUCH)
$(MK)/serdes_n_to_1_s2_se.mk : $(GNCORE)/spartan6/serdes_n_to_1_s2_se.vhd
$(VCOM) $(GNCORE)/spartan6/serdes_n_to_1_s2_se.vhd
$(TOUCH)
$(MK)/serdes_n_to_1_s2_diff.mk : $(GNCORE)/spartan6/serdes_n_to_1_s2_diff.vhd
$(VCOM) $(GNCORE)/spartan6/serdes_n_to_1_s2_diff.vhd
$(TOUCH)
$(MK)/fifo_32x512.mk : $(GNCORE_IP)/fifo_32x512.vhd
$(VCOM) $(GNCORE_IP)/fifo_32x512.vhd
$(TOUCH)
$(MK)/fifo_64x512.mk : $(GNCORE_IP)/fifo_64x512.vhd
$(VCOM) $(GNCORE_IP)/fifo_64x512.vhd
$(TOUCH)
# DDR3 core
$(MK)/ddr3_ctrl.mk : $(DDRCORE)/ddr3_ctrl.vhd $(MK)/ddr3_ctrl_wb.mk $(MK)/ddr3_ctrl_wrapper.mk
$(VCOM) $(DDRCORE)/ddr3_ctrl.vhd
$(TOUCH)
$(MK)/ddr3_ctrl_wb.mk : $(DDRCORE)/ddr3_ctrl_wb.vhd
$(VCOM) $(DDRCORE)/ddr3_ctrl_wb.vhd
$(TOUCH)
$(MK)/ddr3_ctrl_wrapper.mk : $(DDRCORE)/../spec/rtl/ddr3_ctrl_wrapper.vhd $(MK)/ddr_ctrl_bank3.mk
$(VCOM) $(DDRCORE)/../spec/rtl/ddr3_ctrl_wrapper.vhd
$(TOUCH)
$(MK)/ddr_ctrl_bank3.mk : $(DDRCORE_IP)/ddr_ctrl_bank3.vhd $(MK)/memc3_infrastructure.mk $(MK)/memc3_wrapper.mk
$(VCOM) $(DDRCORE_IP)/ddr_ctrl_bank3.vhd
$(TOUCH)
$(MK)/memc3_infrastructure.mk : $(DDRCORE_IP)/memc3_infrastructure.vhd
$(VCOM) $(DDRCORE_IP)/memc3_infrastructure.vhd
$(TOUCH)
$(MK)/memc3_wrapper.mk : $(DDRCORE_IP)/memc3_wrapper.vhd $(MK)/mcb_raw_wrapper.mk
$(VCOM) $(DDRCORE_IP)/memc3_wrapper.vhd
$(TOUCH)
$(MK)/mcb_raw_wrapper.mk : $(DDRCORE_IP)/mcb_raw_wrapper.vhd $(MK)/mcb_soft_calibration_top.mk
$(VCOM) $(DDRCORE_IP)/mcb_raw_wrapper.vhd
$(TOUCH)
$(MK)/mcb_soft_calibration_top.mk : $(DDRCORE_IP)/mcb_soft_calibration_top.vhd $(MK)/mcb_soft_calibration.mk
$(VCOM) $(DDRCORE_IP)/mcb_soft_calibration_top.vhd
$(TOUCH)
$(MK)/mcb_soft_calibration.mk : $(DDRCORE_IP)/mcb_soft_calibration.vhd $(MK)/iodrp_controller.mk \
$(MK)/iodrp_mcb_controller.mk
$(VCOM) $(DDRCORE_IP)/mcb_soft_calibration.vhd
$(TOUCH)
$(MK)/iodrp_controller.mk : $(DDRCORE_IP)/iodrp_controller.vhd
$(VCOM) $(DDRCORE_IP)/iodrp_controller.vhd
$(TOUCH)
$(MK)/iodrp_mcb_controller.mk : $(DDRCORE_IP)/iodrp_mcb_controller.vhd
$(VCOM) $(DDRCORE_IP)/iodrp_mcb_controller.vhd
$(TOUCH)
##################################################################################################
# Test Bench Project
##################################################################################################
$(MK)/tb_gn412x.mk : $(TESTBENCH)/tb_gn412x.vhd $(MK)/gn412x_bfm.mk $(MK)/cmd_router.mk
$(VCOM) $(TESTBENCH)/tb_gn412x.vhd
$(TOUCH)
$(MK)/gn412x_bfm.mk : $(TESTBENCH)/gn412x_bfm.vhd $(MK)/textutil.mk $(MK)/mem_model.mk
$(VCOM) $(TESTBENCH)/gn412x_bfm.vhd
$(TOUCH)
$(MK)/mem_model.mk : $(VHDL_LIB)/mem_model.vhd
$(VCOM) -87 $(VHDL_LIB)/mem_model.vhd
$(TOUCH)
$(MK)/textutil.mk : $(VHDL_LIB)/textutil.vhd $(MK)/util.mk
$(VCOM) $(VHDL_LIB)/textutil.vhd
$(TOUCH)
$(MK)/util.mk : $(VHDL_LIB)/util.vhd
$(VCOM) $(VHDL_LIB)/util.vhd
$(TOUCH)
$(MK)/cmd_router.mk : $(TESTBENCH)/cmd_router.vhd $(MK)/cmd_router1.mk $(MK)/textutil.mk
$(VCOM) $(TESTBENCH)/cmd_router.vhd
$(TOUCH)
$(MK)/cmd_router1.mk : $(TESTBENCH)/cmd_router1.vhd $(MK)/textutil.mk
$(VCOM) $(TESTBENCH)/cmd_router1.vhd
$(TOUCH)
# DDR3 model
$(MK)/ddr3.mk : $(DDRMODEL)/ddr3.v
$(VLOG) +incdir+$(DDRMODEL) +define+sg15E +define+x16 $(DDRMODEL)/ddr3.v
$(TOUCH)
-- ***********************************************************************************
-- *** Warning: this file is automatically generated. ***
-- ***********************************************************************************
-- *** Do not edit this file directly as it is not the source! ***
-- ***********************************************************************************
-------------------------------------------------------------------------------
-- Generated from: simple.c - do not edit the vec file directly as it is not the source!
-- Short example of using the lambo TestBench
-------------------------------------------------------------------------------
-- Select the GN4124 Primary BFM
model %d0
-- Initialize the BFM to its default state
init
-- Drive reset to the FPGA
reset %d16
-------------------------------------------------------------------------------
-- Initialize the Primary GN412x BFM model
-------------------------------------------------------------------------------
-- These address ranges will generate traffic from the BFM to the FPGA
-- bar BAR ADDR SIZE VC TC S
bar 0 FF00000000000000 08000000 0 7 0
--bar 1 FF000000A0000000 10000000 1 5 0
-- This allocates a RAM block inside the BFM for the FPGA to access
-- bfm_bar BAR ADDR SIZE
bfm_bar 0 0000000040000000 20000000
bfm_bar 1 0000000020000000 20000000
-- bfm_bar 0 BB00000040000000 20000000
-- bfm_bar 1 00000000123456f8 20000000
-- Wait until the FPGA is un-reset and ready for traffic on the local bus
wait %d64
-------------------------------------------------------------------------------
-- Access the descriptor memory in the Lambo design
-------------------------------------------------------------------------------
-- the following three writes will go out in a single packet
wr 0000000040000000 F C0FFEE82
wr 0000000040000004 F 00000001
wr 0000000040000008 F 00000002
wr 000000004000000C F 00000003
wr 0000000040000010 F 00000004
wr 0000000040000014 F 00000005
wr 0000000040000018 F 00000006
wr 000000004000001C F 00000007
wr 0000000040000020 F 00000008
wr 0000000040000024 F 00000009
wr 0000000040000028 F 0000000A
wr 000000004000002C F 0000000B
wr 0000000040000030 F 0000000C
wr 0000000040000034 F 0000000D
wr 0000000040000038 F 0000000E
wr 000000004000003C F 0000000F
wr 0000000040000040 F 00000010
wr 0000000040000044 F 00000011
wr 0000000040000048 F 00000012
wr 000000004000004C F 00000013
wr 0000000040000050 F 00000014
wr 0000000040000054 F 00000015
wr 0000000040000058 F 00000016
wr 000000004000005C F 00000017
wr 0000000040000060 F 00000018
wr 0000000040000064 F 00000019
wr 0000000040000068 F 0000001A
wr 000000004000006C F 0000001B
wr 0000000040000070 F 0000001C
wr 0000000040000074 F 0000001D
wr 0000000040000078 F 0000001E
wr 000000004000007C F 0000001F
wr 0000000040000080 F 00000020
wr 0000000040000084 F 00000021
wr 0000000040000088 F 00000022
wr 000000004000008C F 00000023
wr 0000000040000090 F 00000024
wr 0000000040000094 F 00000025
wr 0000000040000098 F 00000026
wr 000000004000009C F 00000027
wr 00000000400000A0 F 00000028
wr 00000000400000A4 F 00000029
wr 00000000400000A8 F 0000002A
wr 00000000400000AC F 0000002B
wr 00000000400000B0 F 0000002C
wr 00000000400000B4 F 0000002D
wr 00000000400000B8 F 0000002E
wr 00000000400000BC F 0000002F
wr 00000000400000C0 F 00000030
wr 0000000040000F00 F 00000F00
wr 0000000040000F04 F 00000F01
wr 0000000040000F08 F 00000F02
wr 0000000040000F0C F 00000F03
wr 0000000040000F10 F 00000F04
wr 0000000040000F14 F 00000F05
wr 0000000040000F18 F 00000F06
wr 0000000040000F1C F 00000F07
wr 0000000040000F20 F 00000F08
wr 0000000040000F24 F 00000F09
wr 0000000040000F28 F 00000F0A
wr 0000000040000F2C F 00000F0B
wr 0000000040000F30 F 00000F0C
wr 0000000040000F34 F 00000F0D
wr 0000000040000F38 F 00000F0E
wr 0000000040000F3C F 00000F0F
wr 0000000040000F40 F 00000F10
wr 0000000040000F44 F 00000F11
wr 0000000040000F48 F 00000F12
wr 0000000040000F4C F 00000F13
wr 0000000040000F50 F 00000F14
wr 0000000040000F54 F 00000F15
wr 0000000040000F58 F 00000F16
wr 0000000040000F5C F 00000F17
wr 0000000040000F60 F 00000F18
wr 0000000040000F64 F 00000F19
wr 0000000040000F68 F 00000F1A
wr 0000000040000F6C F 00000F1B
wr 0000000040000F70 F 00000F1C
wr 0000000040000F74 F 00000F1D
wr 0000000040000F78 F 00000F1E
wr 0000000040000F7C F 00000F1F
wr 0000000040000F80 F 00000F20
wr 0000000040000F84 F 00000F21
wr 0000000040000F88 F 00000F22
wr 0000000040000F8C F 00000F23
wr 0000000040000F90 F 00000F24
wr 0000000040000F94 F 00000F25
wr 0000000040000F98 F 00000F26
wr 0000000040000F9C F 00000F27
wr 0000000040000FA0 F 00000F28
wr 0000000040000FA4 F 00000F29
wr 0000000040000FA8 F 00000F2A
wr 0000000040000FAC F 00000F2B
wr 0000000040000FB0 F 00000F2C
wr 0000000040000FB4 F 00000F2D
wr 0000000040000FB8 F 00000F2E
wr 0000000040000FBC F 00000F2F
-- CSR wishbone test
rd FF00000000040000 F DEAD0000 FFFF0000
wr FF0000000008000C F 00000003
rd FF0000000008000C F 00000003 FFFFFFFF
wait %d640
-- DDR access trough CSR wishbone
--wr FF000000000C0004 F DEADC0DE
--wait %d300
--rd FF000000000C0004 F DEADC0DE FFFFFFFF
wait %d300
-- DDR access trough DMA wishbone
wr 0000000020000000 F 00000000
wr 0000000020000004 F 40000000
wr 0000000020000008 F 00000000
-- DMA length
wr 000000002000000C F 00000004
wr 0000000020000010 F 00000000
wr 0000000020000014 F 00000000
wr 0000000020000018 F 00000000
-- wrb FF00000010004004 F 00000000
wr FF00000000000008 F 00000000
wr FF0000000000000C F 40000000
wr FF00000000000010 F 00000000
-- DMA length
wr FF00000000000014 F 00000004
wr FF00000000000018 F 20000000
wr FF0000000000001C F 00000000
wr FF00000000000020 F 00000003
wr FF00000000000000 F 00000001
-- Now read back what was just written
-- the following three reads will go out as a single request
--rdb FF00000010004004 F FEEDFACE FFFFFFFF
--rdb FF00000010004008 F DBDBDBDB FFFFFFFF
--rd FF00000010004008 F DEADBEEF FFFFFFFF
--wrb FF0000001000401C F 00000000
--wrb FF00000010004024 F 00000000
--wr FF00000010004000 F 00000001
--rdb FF00000010004000 F 00000002 FFFFFFFF
--rdb FF00000010004004 F 00000000 FFFFFFFF
--rdb FF00000010004008 F 5A5A5A5A FFFFFFFF
--rdb FF0000001000400C F 12345678 FFFFFFFF
--rdb FF00000010004010 F 00000000 FFFFFFFF
--rdb FF00000010004014 F 00000010 FFFFFFFF
--rdb FF00000010004018 F 00000000 FFFFFFFF
--rdb FF0000001000401C F 00000000 FFFFFFFF
--rd FF00000010004020 F 00000000 FFFFFFFF
wait %d160
--wr FF00000010004000 F 00000001
--rd FF0000001000400C F DEADBEEF FFFFFFFF
--rd FF00000010004008 F ABABABAB FFFFFFFF
wait %d
flush %d256
wait %d16
sync
m255
K3
13
cModel Technology
Z0 d/home/mcattin/projects/GN4124_core/hdl_trunk/spec/sim
Exilinx_dummy_sim
w1311674401
Z1 d/home/mcattin/projects/GN4124_core/hdl_trunk/spec/sim
8../../gn4124core/ip_cores/general-cores/modules/genrams/xilinx/sim_stub/dummy.vhd
F../../gn4124core/ip_cores/general-cores/modules/genrams/xilinx/sim_stub/dummy.vhd
l0
L1
VKd8^[`j@TZDeV[[hfDI:J0
!s100 nF<;LZ6J0iDiIE_]ATjaA3
Z2 OE;C;6.6e_1;45
32
o-quiet -work fifo_generator_v6_1
Z3 tExplicit 1
vsim -novopt -t 1ps tb_spec
log -r /*
do wave.do
view wave
view transcript
run 15000 ns
##run 25057 ns
##force -freeze sim:/tb_lambo/l2p_rdy 0 0 -cancel {80 ns}
##run 1 us
files = [
"gn412x_bfm.vhd",
"cmd_router.vhd",
"textutil.vhd",
"mem_model.vhd",
"util.vhd",
"tb_spec.vhd",
"cmd_router1.vhd",
]
library IEEE;
use IEEE.std_logic_1164.all;
use std.textio.all;
--library std_developerskit;
--use std_developerskit.std_iopak.all;
use work.util.all;
use work.textutil.all;
--==========================================================================--
--
-- *MODULE << cmd_router >>
--
-- *Description : This module routes commands to all command driven modules
-- in the simulation. It instanciates N_FILES instances of
-- cmd_router1 and agregates the outputs to control N_BFM BFMs.
--
-- *History: M. Alford (originaly created 1993 with subsequent updates)
--
--==========================================================================--
--==========================================================================--
-- Operation
--
-- This module opens a text file and passes commands to individual vhdl models.
--
--==========================================================================--
entity cmd_router is
generic( N_BFM : integer := 8;
N_FILES : integer := 3;
FIFO_DEPTH : integer := 16;
STRING_MAX : integer := 256
);
port( CMD : out string(1 to STRING_MAX);
CMD_REQ : out bit_vector(N_BFM-1 downto 0);
CMD_ACK : in bit_vector(N_BFM-1 downto 0);
CMD_ERR : in bit_vector(N_BFM-1 downto 0);
CMD_CLOCK_EN : out boolean
);
end cmd_router;
architecture MODEL of cmd_router is
component cmd_router1
generic( N_BFM : integer := 8;
FIFO_DEPTH : integer := 8;
STRING_MAX : integer := 256;
FILENAME : string :="cmdfile.vec"
);
port( CMD : out STRING(1 to STRING_MAX);
CMD_REQ : out bit_vector(N_BFM-1 downto 0);
CMD_ACK : in bit_vector(N_BFM-1 downto 0);
CMD_ERR : in bit_vector(N_BFM-1 downto 0);
CMD_CLOCK_EN : out boolean;
CMD_DONE_IN : in boolean;
CMD_DONE_OUT : out boolean
);
end component; -- cmd_router1
type FILE_ARRAY is array (natural range <>) of string(1 to 8);
type CMD_ARRAY is array (natural range <>) of string(CMD'range);
type CMD_REQ_ARRAY is array (natural range <>) of bit_vector(N_BFM-1 downto 0);
type integer_vector is array (natural range <>) of integer;
type boolean_vector is array (natural range <>) of boolean;
constant MAX_FILES : integer := 10;
constant FILENAMES : FILE_ARRAY(0 to MAX_FILES-1) := ( "cmd0.vec", "cmd1.vec",
"cmd2.vec", "cmd3.vec",
"cmd4.vec", "cmd5.vec",
"cmd6.vec", "cmd7.vec",
"cmd8.vec", "cmd9.vec" );
signal CMDo : CMD_ARRAY(N_FILES-1 downto 0);
signal REQ : bit_vector(CMD_REQ'range);
signal CMD_REQo : CMD_REQ_ARRAY(N_FILES-1 downto 0);
signal CMD_ACKi : CMD_REQ_ARRAY(N_FILES-1 downto 0);
signal CMD_ACK_MASK : CMD_REQ_ARRAY(N_FILES-1 downto 0); -- 1 bit_vector per file to mask CMD_ACK
signal CMD_CLOCK_ENo : boolean_vector(N_FILES-1 downto 0);
signal CMD_ALL_DONE : boolean;
signal CMD_DONE_OUT : boolean_vector(N_FILES-1 downto 0);
function or_reduce(ARG: bit_vector) return bit is
variable result: bit;
begin
result := '0';
for i in ARG'range loop
result := result or ARG(i);
end loop;
return result;
end;
function or_reduce(ARG: boolean_vector) return boolean is
variable result: boolean;
begin
result := FALSE;
for i in ARG'range loop
result := result or ARG(i);
end loop;
return result;
end;
function and_reduce(ARG: boolean_vector) return boolean is
variable result: boolean;
begin
result := TRUE;
for i in ARG'range loop
result := result and ARG(i);
end loop;
return result;
end;
begin
-----------------------------------------------------------------------------
-- Instanciate 1 cmd_router1 per file to be processed
-----------------------------------------------------------------------------
G1 : for i in 0 to N_FILES-1 generate
U1 : cmd_router1
generic map
( N_BFM => N_BFM,
FIFO_DEPTH => FIFO_DEPTH,
STRING_MAX => STRING_MAX,
FILENAME => FILENAMES(i)
)
port map
( CMD => CMDo(i),
CMD_REQ => CMD_REQo(i),
CMD_ACK => CMD_ACKi(i),
CMD_ERR => CMD_ERR,
CMD_CLOCK_EN => CMD_CLOCK_ENo(i),
CMD_DONE_IN => CMD_ALL_DONE,
CMD_DONE_OUT => CMD_DONE_OUT(i)
);
end generate;
-----------------------------------------------------------------------------
-- Multiplex the commands from the cmd_router1 modules
-----------------------------------------------------------------------------
process
variable vDONE : boolean;
begin
CMD <= (others => '0');
wait on CMD_REQo;
vDONE := FALSE;
while(not vDONE) loop
vDONE := TRUE;
for i in 0 to N_FILES-1 loop -- Loop on each file
if(or_reduce(CMD_REQo(i)) = '1') then -- this file wants to do a command
vDONE := FALSE;
--
-- if the ACK is already on from another cmd_router1
--
while(or_reduce(CMD_REQo(i) and CMD_ACK) = '1') loop
wait on CMD_ACK;
end loop;
--
-- Do the request
--
CMD <= CMDo(i);
REQ <= CMD_REQo(i);
--
-- Wait for the ACK
--
wait until(CMD_ACK'event and (or_reduce(CMD_ACK and REQ) = '1'));
--
-- send the ack to the proper file
--
for j in 0 to N_FILES-1 loop
if(i = j) then -- enable this one
CMD_ACK_MASK(j) <= CMD_ACK_MASK(j) or REQ;
else
CMD_ACK_MASK(j) <= CMD_ACK_MASK(j) and not REQ;
end if;
end loop;
--
-- Wait for the request to de-assert
--
while(or_reduce(CMD_REQo(i) and REQ) = '1') loop
wait on CMD_REQo;
end loop;
REQ <= (others => '0');
end if;
end loop;
end loop;
end process;
process(CMD_ACK, CMD_ACK_MASK)
begin
for i in 0 to N_FILES-1 loop -- Loop on each file
CMD_ACKi(i) <= CMD_ACK and CMD_ACK_MASK(i);
end loop;
end process;
CMD_REQ <= REQ;
CMD_ALL_DONE <= and_reduce(CMD_DONE_OUT);
CMD_CLOCK_EN <= CMD_CLOCK_ENo(0);
end MODEL;
library IEEE;
use IEEE.std_logic_1164.all;
use std.textio.all;
--library std_developerskit;
--use std_developerskit.std_iopak.all;
use work.util.all;
use work.textutil.all;
--==========================================================================--
--
-- *MODULE << model1 >>
--
-- *Description : This module routes commands to all command driven modules
-- in the simulation.
--
-- *History: M. Alford (originaly created 1993 with subsequent updates)
--
--==========================================================================--
--==========================================================================--
-- Operation
--
-- This module opens a text file and passes commands to individual vhdl models.
--
--==========================================================================--
entity cmd_router1 is
generic( N_BFM : integer := 8;
FIFO_DEPTH : integer := 8;
STRING_MAX : integer := 256;
FILENAME : string :="cmdfile.vec"
);
port( CMD : out STRING(1 to STRING_MAX);
CMD_REQ : out bit_vector(N_BFM-1 downto 0);
CMD_ACK : in bit_vector(N_BFM-1 downto 0);
CMD_ERR : in bit_vector(N_BFM-1 downto 0);
CMD_CLOCK_EN : out boolean;
CMD_DONE_IN : in boolean;
CMD_DONE_OUT : out boolean
);
end cmd_router1;
architecture MODEL of cmd_router1 is
type STRING_ARRAY is array (FIFO_DEPTH-1 downto 0) of STRING(1 to STRING_MAX);
type FD_ARRAY is array (N_BFM-1 downto 0) of STRING_ARRAY;
type integer_vector is array (natural range <>) of integer;
signal FD : FD_ARRAY;
signal ERR_CNT : integer;
signal PUSH_PTR : integer_vector(N_BFM-1 downto 0);
signal POP_PTR : integer_vector(N_BFM-1 downto 0);
signal SET_CHAN : std_ulogic;
signal POP_INIT : std_ulogic;
signal CMD_REQo : bit_vector(CMD_REQ'range);
signal LINE_NUM : integer;
begin
PUSH_PROCESS : process
file FOUT : text open write_mode is "usc.lst";
file stim_file : text open read_mode is FILENAME;
file out_file : text open write_mode is "STD_OUTPUT";
-------- For VHDL-87
-- file stim_file : text is in FILENAME;
-- file out_file : text is out "STD_OUTPUT";
variable input_line : line;
variable output_line : line;
variable tmp_lout : line;
variable command : string(1 to 8);
variable tmp_str : string(1 to STRING_MAX);
variable input_str : string(1 to STRING_MAX);
variable i : integer;
variable CHANNEL : integer;
variable S_PTR : integer;
variable vLINE_NUM : integer;
variable vPUSH_PTR : integer_vector(N_BFM-1 downto 0);
variable DONE : boolean;
variable EOS : integer;
variable ERR : integer;
begin
-----------------------------------------------------------------------------
-- Main Loop
-----------------------------------------------------------------------------
vLINE_NUM := 0;
PUSH_PTR <= (others => 0);
vPUSH_PTR := (others => 0);
CHANNEL := 0;
CMD_CLOCK_EN <= TRUE;
SET_CHAN <= '0';
CMD_DONE_OUT <= FALSE;
if(POP_INIT /= '1') then
wait until(POP_INIT'event and (POP_INIT = '1'));
end if;
ST_LOOP: while not endfile(stim_file) loop
readline(stim_file, input_line);
S_PTR := 1;
vLINE_NUM := vLINE_NUM + 1;
LINE_NUM <= vLINE_NUM;
-- Copy the line
input_str := (others => ' ');
input_str(1 to 6) := To_Strn(vLINE_NUM, 6);
input_str(7 to 8) := string'(": ");
input_str(9 to input_line'length+8) := string'(input_line.all);
while(input_str(S_PTR) /= ':') loop
S_PTR := S_PTR + 1;
end loop;
S_PTR := S_PTR + 1;
sget_token(input_str, S_PTR, command);
SET_CHAN <= '1';
for j in STRING_MAX downto 1 loop
if(input_str(j) /= ' ') then
EOS := j;
exit;
end if;
end loop;
---------------------------
-- "model" command ?
---------------------------
if(command(1 to 5) = "model") then
sget_int(input_str, S_PTR, i);
write(tmp_lout, FILENAME);
write(tmp_lout, input_str(1 to EOS));
writeline(out_file, tmp_lout);
if((i >= N_BFM) or (i < 0)) then
CHANNEL := N_BFM-1;
write(tmp_lout, string'("ERROR: Invalid Channel "));
write(tmp_lout, i);
writeline(out_file, tmp_lout);
else
CHANNEL := i;
end if;
---------------------------
-- "sync" command ?
---------------------------
elsif(command(1 to 4) = "sync") then
loop
DONE := TRUE;
for i in PUSH_PTR'reverse_range loop
if((vPUSH_PTR(i) /= POP_PTR(i)) or (CMD_ACK(i) /= '0')) then
DONE := FALSE;
end if;
end loop;
if(DONE) then
exit;
end if;
wait on POP_PTR, CMD_ACK;
end loop;
write(tmp_lout, FILENAME);
write(tmp_lout, input_str(1 to EOS));
writeline(out_file, tmp_lout);
---------------------------
-- "gsync" and "ckoff" command ?
---------------------------
elsif((command(1 to 5) = "gsync") or (command(1 to 5) = "ckoff")) then
write(tmp_lout, FILENAME);
write(tmp_lout, string'(": entering the gsync command"));
writeline(out_file, tmp_lout);
loop
DONE := TRUE;
for i in PUSH_PTR'reverse_range loop
if((vPUSH_PTR(i) /= POP_PTR(i)) or (CMD_ACK(i) /= '0')) then
DONE := FALSE;
end if;
end loop;
if(DONE) then
exit;
end if;
wait on POP_PTR, CMD_ACK;
end loop;
CMD_DONE_OUT <= TRUE;
-- wait for the external CMD_DONE_IN to be done
while (not CMD_DONE_IN) loop
wait on CMD_DONE_IN;
end loop;
CMD_DONE_OUT <= FALSE;
write(tmp_lout, FILENAME);
write(tmp_lout, input_str(1 to EOS));
writeline(out_file, tmp_lout);
if (command(1 to 5) = "ckoff") then
CMD_CLOCK_EN <= FALSE;
end if;
write(tmp_lout, FILENAME);
write(tmp_lout, string'(": gsync command is DONE"));
writeline(out_file, tmp_lout);
--------------------
-- ckon
--------------------
elsif (command(1 to 4) = "ckon") then
CMD_CLOCK_EN <= TRUE;
write(tmp_lout, FILENAME);
write(tmp_lout, input_str(1 to EOS));
writeline(out_file, tmp_lout);
---------------------------
-- put the line in the FIFO
---------------------------
else
FD(CHANNEL)(vPUSH_PTR(CHANNEL)) <= input_str;
vPUSH_PTR(CHANNEL) := vPUSH_PTR(CHANNEL) + 1;
if(vPUSH_PTR(CHANNEL) >= FIFO_DEPTH) then
vPUSH_PTR(CHANNEL) := 0;
end if;
if(vPUSH_PTR(CHANNEL) = POP_PTR(CHANNEL)) then -- The FIFO is full
wait until(POP_PTR'event and (vPUSH_PTR(CHANNEL) /= POP_PTR(CHANNEL)));
end if;
PUSH_PTR(CHANNEL) <= vPUSH_PTR(CHANNEL);
end if;
end loop;
loop
DONE := TRUE;
for i in POP_PTR'reverse_range loop
if((POP_PTR(i) /= vPUSH_PTR(i)) or (CMD_ACK(i) = '1')) then -- FIFO channel not empty
DONE := FALSE;
end if;
end loop;
if(DONE) then
exit;
end if;
wait on CMD_ACK, POP_PTR;
end loop;
CMD_DONE_OUT <= TRUE;
write(output_line, string'("******************************* Test Finished *******************************"));
writeline(out_file, output_line);
write(output_line, string'("* Total Errors for "));
write(output_line, FILENAME);
write(output_line, string'(": "));
write(output_line, err_cnt);
writeline(out_file, output_line);
write(output_line, string'("*****************************************************************************"));
writeline(out_file, output_line);
file_close(stim_file); -- Close File
loop
wait for 100000 us;
end loop;
end process;
-----------------------------------------------------------------------------
-- POP Process
-----------------------------------------------------------------------------
POP_PROCESS : process
variable vPOP_PTR : integer_vector(POP_PTR'range);
variable DONE : boolean;
file out_file : text open write_mode is "STD_OUTPUT";
-------- For VHDL-87
-- file out_file : text is out "STD_OUTPUT";
variable tmp_lout : line;
variable CHAR_PTR : integer;
variable EOS : integer;
begin
CHAR_PTR := 1;
ERR_CNT <= 0;
POP_PTR <= (others => 0);
vPOP_PTR := (others => 0);
CMD_REQo <= (others => '0');
POP_INIT <= '1';
if(SET_CHAN /= '1') then
wait until(SET_CHAN'event and (SET_CHAN = '1'));
end if;
loop
DONE := FALSE;
loop
DONE := TRUE;
for i in POP_PTR'reverse_range loop
if((vPOP_PTR(i) /= PUSH_PTR(i)) and (CMD_ACK(i) = '0')) then -- FIFO channel not empty
CMD <= FD(i)(vPOP_PTR(i));
CMD_REQo(i) <= '1';
for j in STRING_MAX downto 1 loop
if(FD(i)(vPOP_PTR(i))(j) /= ' ') then
EOS := j;
exit;
end if;
end loop;
write(tmp_lout, FILENAME);
write(tmp_lout, FD(i)(vPOP_PTR(i))(1 to EOS));
writeline(out_file, tmp_lout);
if(CMD_ACK(i) /= '1') then
wait until(CMD_ACK'event and (CMD_ACK(i) = '1'));
end if;
CMD_REQo(i) <= '0';
DONE := FALSE;
vPOP_PTR(i) := vPOP_PTR(i) + 1;
if(vPOP_PTR(i) >= FIFO_DEPTH) then
vPOP_PTR(i) := 0;
end if;
POP_PTR(i) <= vPOP_PTR(i);
end if;
end loop;
if(DONE) then
exit;
end if;
end loop;
wait on PUSH_PTR, CMD_ACK;
end loop;
end process;
CMD_REQ <= CMD_REQo;
end MODEL;
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
library IEEE;
use IEEE.std_logic_1164.all;
use std.textio.all;
--library std_developerskit;
--use std_developerskit.std_iopak.all;
use work.util.all;
use work.textutil.all;
--############################################################################
--############################################################################
--==========================================================================--
--
-- *Module : tb_lambo
--
-- *Description : Test Bench for the GN4124 BFM + Lambo Design
--
-- *History
--
--==========================================================================--
--############################################################################
--############################################################################
entity TB_LAMBO is
generic
(
T_LCLK : time := 30 ns -- Default LCLK Clock Period
);
end TB_LAMBO;
architecture TEST of TB_LAMBO is
--###########################################################################
--###########################################################################
--##
--## Component Declairations
--##
--###########################################################################
--###########################################################################
-----------------------------------------------------------------------------
-- GN4124 Local Bus Model
-----------------------------------------------------------------------------
component GN412X_BFM
generic
(
STRING_MAX : integer := 256; -- Command string maximum length
T_LCLK : time := 10 ns; -- Local Bus Clock Period
T_P2L_CLK_DLY : time := 2 ns; -- Delay from LCLK to P2L_CLK
INSTANCE_LABEL : string := "GN412X_BFM"; -- Label string to be used as a prefix for messages from the model
MODE_PRIMARY : boolean := TRUE -- TRUE for BFM acting as GN412x, FALSE for BFM acting as the DUT
);
port
(
--=========================================================--
-------------------------------------------------------------
-- CMD_ROUTER Interface
--
CMD : in STRING(1 to STRING_MAX);
CMD_REQ : in BIT;
CMD_ACK : out BIT;
CMD_CLOCK_EN : in boolean;
--=========================================================--
-------------------------------------------------------------
-- GN412x Signal I/O
-------------------------------------------------------------
-- This is the reset input to the BFM
--
RSTINn : in std_logic;
-------------------------------------------------------------
-- Reset outputs to DUT
--
RSTOUT18n : out std_logic;
RSTOUT33n : out std_logic;
-------------------------------------------------------------
----------------- Local Bus Clock ---------------------------
------------------------------------------------------------- __ Direction for primary mode
-- / \
LCLK, LCLKn : inout std_logic; -- Out
-------------------------------------------------------------
----------------- Local-to-PCI Dataflow ---------------------
-------------------------------------------------------------
-- Transmitter Source Synchronous Clock.
--
L2P_CLKp, L2P_CLKn : inout std_logic; -- In
-------------------------------------------------------------
-- L2P DDR Link
--
L2P_DATA : inout std_logic_vector(15 downto 0); -- In -- Parallel Transmit Data.
L2P_DFRAME : inout std_logic; -- In -- Transmit Data Frame.
L2P_VALID : inout std_logic; -- In -- Transmit Data Valid.
L2P_EDB : inout std_logic; -- In -- End-of-Packet Bad Flag.
-------------------------------------------------------------
-- L2P SDR Controls
--
L_WR_RDY : inout std_logic_vector( 1 downto 0); -- Out -- Local-to-PCIe Write.
P_RD_D_RDY : inout std_logic_vector( 1 downto 0); -- Out -- PCIe-to-Local Read Response Data Ready.
L2P_RDY : inout std_logic; -- Out -- Tx Buffer Full Flag.
TX_ERROR : inout std_logic; -- Out -- Transmit Error.
-------------------------------------------------------------
----------------- PCIe-to-Local Dataflow ---------------------
-------------------------------------------------------------
-- Transmitter Source Synchronous Clock.
--
P2L_CLKp, P2L_CLKn : inout std_logic; -- Out -- P2L Source Synchronous Clock.
-------------------------------------------------------------
-- P2L DDR Link
--
P2L_DATA : inout std_logic_vector(15 downto 0); -- Out -- Parallel Receive Data.
P2L_DFRAME : inout std_logic; -- Out -- Receive Frame.
P2L_VALID : inout std_logic; -- Out -- Receive Data Valid.
-------------------------------------------------------------
-- P2L SDR Controls
--
P2L_RDY : inout std_logic; -- In -- Rx Buffer Full Flag.
P_WR_REQ : inout std_logic_vector( 1 downto 0); -- Out -- PCIe Write Request.
P_WR_RDY : inout std_logic_vector( 1 downto 0); -- In -- PCIe Write Ready.
RX_ERROR : inout std_logic; -- In -- Receive Error.
VC_RDY : inout std_logic_vector( 1 downto 0); -- Out -- Virtual Channel Ready Status.
-------------------------------------------------------------
-- GPIO signals
--
GPIO : inout std_logic_vector(15 downto 0)
);
end component; --GN412X_BFM;
-----------------------------------------------------------------------------
-- CMD_ROUTER component
-----------------------------------------------------------------------------
component cmd_router
generic( N_BFM : integer := 8;
N_FILES : integer := 3;
FIFO_DEPTH : integer := 8;
STRING_MAX : integer := 256
);
port( CMD : out string(1 to STRING_MAX);
CMD_REQ : out bit_vector(N_BFM-1 downto 0);
CMD_ACK : in bit_vector(N_BFM-1 downto 0);
CMD_ERR : in bit_vector(N_BFM-1 downto 0);
CMD_CLOCK_EN : out boolean
);
end component; --cmd_router;
-----------------------------------------------------------------------------
-- CMD_ROUTER component
-----------------------------------------------------------------------------
component simple
port(
clk : in std_logic;
d : in std_logic_vector(15 downto 0);
q : out std_logic_vector(15 downto 0)
);
end component;
-----------------------------------------------------------------------------
-- The lambo design
-----------------------------------------------------------------------------
component lambo
generic
(
TAR_ADDR_WDTH : integer := 13
);
port
(
-- From ASIC Local bus
l_clkp : in std_logic; -- Running at 200 Mhz
l_clkn : in std_logic; -- Running at 200 Mhz
l_rst_n : in std_logic;
l_rst33_n : in std_logic;
sys_clkb : in std_logic; -- Running at 161 Mhz (for the SDRAM)
sys_clk : in std_logic; -- Running at 161 Mhz (for the SDRAM)
reset_in_n : in std_logic;
-- General Purpose Interface
gpio : inout std_logic_vector(15 downto 0); -- General Purpose Input/Output
-- PCIe to Local [Inbound Data] - RX
p2l_rdy : out std_logic; -- Rx Buffer Full Flag
p2l_clkn : in std_logic; -- Receiver Source Synchronous Clock-
p2l_clkp : in std_logic; -- Receiver Source Synchronous Clock+
p2l_data : in std_logic_vector(15 downto 0); -- Parallel receive data
p2l_dframe : in std_logic; -- Receive Frame
p2l_valid : in std_logic; -- Receive Data Valid
-- Inbound Buffer Request/Status
p_wr_req : in std_logic_vector(1 downto 0); -- PCIe Write Request
p_wr_rdy : out std_logic_vector(1 downto 0); -- PCIe Write Ready
rx_error : out std_logic; -- Receive Error
-- Local to Parallel [Outbound Data] - TX
l2p_data : out std_logic_vector(15 downto 0); -- Parallel transmit data
l2p_dframe : out std_logic; -- Transmit Data Frame
l2p_valid : out std_logic; -- Transmit Data Valid
l2p_clkn : out std_logic; -- Transmitter Source Synchronous Clock-
l2p_clkp : out std_logic; -- Transmitter Source Synchronous Clock+
l2p_edb : out std_logic; -- Packet termination and discard
-- Outbound Buffer Status
l2p_rdy : in std_logic; -- Tx Buffer Full Flag
l_wr_rdy : in std_logic_vector(1 downto 0); -- Local-to-PCIe Write
p_rd_d_rdy : in std_logic_vector(1 downto 0); -- PCIe-to-Local Read Response Data Ready
tx_error : in std_logic; -- Transmit Error
vc_rdy : in std_logic_vector(1 downto 0); -- Channel ready
-- DDR2 SDRAM Interface
cntrl0_ddr2_dq : inout std_logic_vector(31 downto 0);
cntrl0_ddr2_a : out std_logic_vector(12 downto 0);
cntrl0_ddr2_ba : out std_logic_vector( 1 downto 0);
cntrl0_ddr2_cke : out std_logic;
cntrl0_ddr2_cs_n : out std_logic;
cntrl0_ddr2_ras_n : out std_logic;
cntrl0_ddr2_cas_n : out std_logic;
cntrl0_ddr2_we_n : out std_logic;
cntrl0_ddr2_odt : out std_logic;
cntrl0_ddr2_dm : out std_logic_vector(3 downto 0);
cntrl0_rst_dqs_div_in : in std_logic;
cntrl0_rst_dqs_div_out : out std_logic;
cntrl0_ddr2_dqs : inout std_logic_vector(3 downto 0);
cntrl0_ddr2_dqs_n : inout std_logic_vector(3 downto 0);
cntrl0_ddr2_ck : out std_logic_vector(1 downto 0);
cntrl0_ddr2_ck_n : out std_logic_vector(1 downto 0);
mic_clka : out std_logic;
mic_clkb : out std_logic;
mic_data : out std_logic_vector(31 downto 0);
-- GN1559 related
ser : out std_logic_vector(19 downto 0);
ser_h : out std_logic;
ser_v : out std_logic;
ser_f : out std_logic;
ser_smpte_bypass : out std_logic;
ser_dvb_asi : out std_logic;
ser_sdhdn : out std_logic;
-- GN1531 de-serializer
des : in std_logic_vector(19 downto 0);
des_pclk : in std_logic;
des_h : in std_logic;
des_v : in std_logic;
des_f : in std_logic;
des_smpte_bypass : inout std_logic;
des_dvb_asi : inout std_logic;
des_sdhdn : inout std_logic;
-- GN4911 Timing Generator
syncseperator_h_timing : in std_logic;
syncseperator_v_timing : in std_logic;
syncseperator_f_timing : in std_logic;
-- I2C
sda : inout std_logic;
scl : in std_logic;
-- Debug Switches
debug : in std_logic_vector(7 downto 0);
led : out std_logic_vector(7 downto 0);
-- SPI
spi_sck : in std_logic;
spi_ss : in std_logic_vector(4 downto 0);
spi_mosi : in std_logic;
spi_miso : out std_logic;
pclk_4911_1531 : in std_logic; -- requested by Jared
gs4911_host_b : out std_logic;
gs4911_sclk : out std_logic;
gs4911_sdin : out std_logic;
gs4911_sdout : in std_logic;
gs4911_csb : out std_logic;
gs4911_lock_lost : in std_logic; -- requested by Jared
gs4911_ref_lost : in std_logic -- requested by Jared
);
end component; --lambo;
--###########################################################################
--###########################################################################
--##
--## Constants
--##
--###########################################################################
--###########################################################################
--
-- Number of Models receiving commands
constant N_BFM : integer := 2; -- 0 : GN412X_BFM in Model Mode
-- -- 1 : GN412X_BFM in DUT mode
-- Number of files to feed BFMs
constant N_FILES : integer := 2;
--
-- Depth of the command FIFO for each model
constant FIFO_DEPTH : integer := 16;
--
-- Maximum width of a command string
constant STRING_MAX : integer := 256;
--
--###########################################################################
--###########################################################################
--##
--## Signals
--##
--###########################################################################
--###########################################################################
-----------------------------------------------------------------------------
-- Command Router Signals
-----------------------------------------------------------------------------
signal CMD : STRING(1 to STRING_MAX);
signal CMD_REQ : BIT_VECTOR(N_BFM-1 downto 0);
signal CMD_ACK : BIT_VECTOR(N_BFM-1 downto 0);
signal CMD_ERR : BIT_VECTOR(N_BFM-1 downto 0);
signal CMD_CLOCK_EN : boolean;
-----------------------------------------------------------------------------
-- GN412x BFM Signals
-----------------------------------------------------------------------------
signal RSTINn : std_logic;
signal RSTOUT18n : std_logic;
signal RSTOUT33n : std_logic;
signal LCLK, LCLKn : std_logic;
signal L2P_CLKp, L2P_CLKn : std_logic;
signal L2P_DATA : std_logic_vector(15 downto 0);
signal L2P_DATA_32 : std_logic_vector(31 downto 0); -- For monitoring use
signal L2P_DFRAME : std_logic;
signal L2P_VALID : std_logic;
signal L2P_EDB : std_logic;
signal L_WR_RDY : std_logic_vector( 1 downto 0);
signal P_RD_D_RDY : std_logic_vector( 1 downto 0);
signal L2P_RDY : std_logic;
signal TX_ERROR : std_logic;
signal P2L_CLKp, P2L_CLKn : std_logic;
signal P2L_DATA : std_logic_vector(15 downto 0);
signal P2L_DATA_32 : std_logic_vector(31 downto 0); -- For monitoring use
signal P2L_DFRAME : std_logic;
signal P2L_VALID : std_logic;
signal P2L_RDY : std_logic;
signal P_WR_REQ : std_logic_vector( 1 downto 0);
signal P_WR_RDY : std_logic_vector( 1 downto 0);
signal RX_ERROR : std_logic;
signal VC_RDY : std_logic_vector( 1 downto 0);
-----------------------------------------------------------------------------
-- Unused Signals
-----------------------------------------------------------------------------
signal GPIO : std_logic_vector(15 downto 0);
-- Lambo
-- DDR2 SDRAM Interface
signal cntrl0_ddr2_dq : std_logic_vector(31 downto 0);
signal cntrl0_ddr2_a : std_logic_vector(12 downto 0);
signal cntrl0_ddr2_ba : std_logic_vector( 1 downto 0);
signal cntrl0_ddr2_cke : std_logic;
signal cntrl0_ddr2_cs_n : std_logic;
signal cntrl0_ddr2_ras_n : std_logic;
signal cntrl0_ddr2_cas_n : std_logic;
signal cntrl0_ddr2_we_n : std_logic;
signal cntrl0_ddr2_odt : std_logic;
signal cntrl0_ddr2_dm : std_logic_vector(3 downto 0);
signal cntrl0_rst_dqs_div_in : std_logic;
signal cntrl0_rst_dqs_div_out : std_logic;
signal cntrl0_ddr2_dqs : std_logic_vector(3 downto 0);
signal cntrl0_ddr2_dqs_n : std_logic_vector(3 downto 0);
signal cntrl0_ddr2_ck : std_logic_vector(1 downto 0);
signal cntrl0_ddr2_ck_n : std_logic_vector(1 downto 0);
signal mic_clka : std_logic;
signal mic_clkb : std_logic;
signal mic_data : std_logic_vector(31 downto 0);
-- GN1559 related
signal ser : std_logic_vector(19 downto 0);
signal ser_h : std_logic;
signal ser_v : std_logic;
signal ser_f : std_logic;
signal ser_smpte_bypass : std_logic;
signal ser_dvb_asi : std_logic;
signal ser_sdhdn : std_logic;
-- GN1531 de-serializer
signal des : std_logic_vector(19 downto 0);
signal des_pclk : std_logic;
signal des_h : std_logic;
signal des_v : std_logic;
signal des_f : std_logic;
signal des_smpte_bypass : std_logic;
signal des_dvb_asi : std_logic;
signal des_sdhdn : std_logic;
-- GN4911 Timing Generator
signal syncseperator_h_timing : std_logic;
signal syncseperator_v_timing : std_logic;
signal syncseperator_f_timing : std_logic;
-- I2C
signal sda : std_logic;
signal scl : std_logic;
-- Debug Switches
signal debug : std_logic_vector(7 downto 0);
signal led : std_logic_vector(7 downto 0);
-- SPI
signal spi_sck : std_logic;
signal spi_ss : std_logic_vector(4 downto 0);
signal spi_mosi : std_logic;
signal spi_miso : std_logic;
signal pclk_4911_1531 : std_logic; -- requested by Jared
signal gs4911_host_b : std_logic;
signal gs4911_sclk : std_logic;
signal gs4911_sdin : std_logic;
signal gs4911_sdout : std_logic;
signal gs4911_csb : std_logic;
signal gs4911_lock_lost : std_logic; -- requested by Jared
signal gs4911_ref_lost : std_logic; -- requested by Jared
-----------------------------------------------------------------------------
-- Bus Monitor Signals
-----------------------------------------------------------------------------
signal Q_P2L_DFRAME : std_logic;
signal SIMPLE_TEST : std_logic_vector(15 downto 0);
--###########################################################################
--###########################################################################
--##
--## Start of Code
--##
--###########################################################################
--###########################################################################
begin
-----------------------------------------------------------------------------
-- MODEL Component
-----------------------------------------------------------------------------
CMD_ERR <= (others => '0');
UC : cmd_router
generic map
( N_BFM => N_BFM,
N_FILES => N_FILES,
FIFO_DEPTH => FIFO_DEPTH,
STRING_MAX => STRING_MAX
)
port map
( CMD => CMD,
CMD_REQ => CMD_REQ,
CMD_ACK => CMD_ACK,
CMD_ERR => CMD_ERR,
CMD_CLOCK_EN => CMD_CLOCK_EN
);
-----------------------------------------------------------------------------
-- GN412x BFM - PRIMARY
-----------------------------------------------------------------------------
U0 : gn412x_bfm
generic map
(
STRING_MAX => STRING_MAX,
T_LCLK => 10 ns,
T_P2L_CLK_DLY => 2 ns,
INSTANCE_LABEL => "U0(Primary GN412x): ",
MODE_PRIMARY => TRUE
)
port map
(
--=========================================================--
-------------------------------------------------------------
-- CMD_ROUTER Interface
--
CMD => CMD,
CMD_REQ => CMD_REQ(0),
CMD_ACK => CMD_ACK(0),
CMD_CLOCK_EN => CMD_CLOCK_EN,
--=========================================================--
-------------------------------------------------------------
-- GN412x Signal I/O
-------------------------------------------------------------
-- This is the reset input to the BFM
--
RSTINn => RSTINn,
-------------------------------------------------------------
-- Reset outputs to DUT
--
RSTOUT18n => RSTOUT18n,
RSTOUT33n => RSTOUT33n,
-------------------------------------------------------------
----------------- Local Bus Clock ---------------------------
-------------------------------------------------------------
--
LCLK => LCLK,
LCLKn => LCLKn,
-------------------------------------------------------------
----------------- Local-to-PCI Dataflow ---------------------
-------------------------------------------------------------
-- Transmitter Source Synchronous Clock.
--
L2P_CLKp => L2P_CLKp,
L2P_CLKn => L2P_CLKn,
-------------------------------------------------------------
-- L2P DDR Link
--
L2P_DATA => L2P_DATA,
L2P_DFRAME => L2P_DFRAME,
L2P_VALID => L2P_VALID,
L2P_EDB => L2P_EDB,
-------------------------------------------------------------
-- L2P SDR Controls
--
L_WR_RDY => L_WR_RDY,
P_RD_D_RDY => P_RD_D_RDY,
L2P_RDY => L2P_RDY,
TX_ERROR => TX_ERROR,
-------------------------------------------------------------
----------------- PCIe-to-Local Dataflow ---------------------
-------------------------------------------------------------
-- Transmitter Source Synchronous Clock.
--
P2L_CLKp => P2L_CLKp,
P2L_CLKn => P2L_CLKn,
-------------------------------------------------------------
-- P2L DDR Link
--
P2L_DATA => P2L_DATA,
P2L_DFRAME => P2L_DFRAME,
P2L_VALID => P2L_VALID,
-------------------------------------------------------------
-- P2L SDR Controls
--
P2L_RDY => P2L_RDY,
P_WR_REQ => P_WR_REQ,
P_WR_RDY => P_WR_RDY,
RX_ERROR => RX_ERROR,
VC_RDY => VC_RDY,
GPIO => gpio
); -- GN412X_BFM;
-----------------------------------------------------------------------------
-- Lambo FPGA IP
-----------------------------------------------------------------------------
U1 : lambo
port map
(
-- From ASIC Local bus
l_clkp => LCLK, -- Running at 200 Mhz
l_clkn => LCLKn, -- Running at 200 Mhz
l_rst_n => RSTOUT18n,
l_rst33_n => RSTOUT33n,
sys_clkb => '1', -- Running at 161 Mhz (for the SDRAM)
sys_clk => '0', -- Running at 161 Mhz (for the SDRAM)
reset_in_n => RSTOUT18n,
-- General Purpose Interface
gpio => GPIO, -- General Purpose Input/Output
-- PCIe to Local [Inbound Data] - RX
p2l_rdy => P2L_RDY, -- Rx Buffer Full Flag
p2l_clkn => P2L_CLKn, -- Receiver Source Synchronous Clock-
p2l_clkp => P2L_CLKp, -- Receiver Source Synchronous Clock+
p2l_data => P2L_DATA, -- Parallel receive data
p2l_dframe => P2L_DFRAME, -- Receive Frame
p2l_valid => P2L_VALID, -- Receive Data Valid
-- Inbound Buffer Request/Status
p_wr_req => P_WR_REQ, -- PCIe Write Request
p_wr_rdy => P_WR_RDY, -- PCIe Write Ready
rx_error => RX_ERROR, -- Receive Error
-- Local to Parallel [Outbound Data] - TX
l2p_data => L2P_DATA, -- Parallel transmit data
l2p_dframe => L2P_DFRAME, -- Transmit Data Frame
l2p_valid => L2P_VALID, -- Transmit Data Valid
l2p_clkn => L2P_CLKn, -- Transmitter Source Synchronous Clock-
l2p_clkp => L2P_CLKp, -- Transmitter Source Synchronous Clock+
l2p_edb => L2P_EDB, -- Packet termination and discard
-- Outbound Buffer Status
l2p_rdy => L2P_RDY, -- Tx Buffer Full Flag
l_wr_rdy => L_WR_RDY, -- Local-to-PCIe Write
p_rd_d_rdy => P_RD_D_RDY, -- PCIe-to-Local Read Response Data Ready
tx_error => TX_ERROR, -- Transmit Error
vc_rdy => VC_RDY, -- Channel ready
-- DDR2 SDRAM Interface
cntrl0_ddr2_dq => cntrl0_ddr2_dq,
cntrl0_ddr2_a => cntrl0_ddr2_a,
cntrl0_ddr2_ba => cntrl0_ddr2_ba,
cntrl0_ddr2_cke => cntrl0_ddr2_cke,
cntrl0_ddr2_cs_n => cntrl0_ddr2_cs_n,
cntrl0_ddr2_ras_n => cntrl0_ddr2_ras_n,
cntrl0_ddr2_cas_n => cntrl0_ddr2_cas_n,
cntrl0_ddr2_we_n => cntrl0_ddr2_we_n,
cntrl0_ddr2_odt => cntrl0_ddr2_odt,
cntrl0_ddr2_dm => cntrl0_ddr2_dm,
cntrl0_rst_dqs_div_in => cntrl0_rst_dqs_div_in,
cntrl0_rst_dqs_div_out => cntrl0_rst_dqs_div_out,
cntrl0_ddr2_dqs => cntrl0_ddr2_dqs,
cntrl0_ddr2_dqs_n => cntrl0_ddr2_dqs_n,
cntrl0_ddr2_ck => cntrl0_ddr2_ck,
cntrl0_ddr2_ck_n => cntrl0_ddr2_ck_n,
mic_clka => mic_clka,
mic_clkb => mic_clkb,
mic_data => mic_data,
-- GN1559 related
ser => ser,
ser_h => ser_h,
ser_v => ser_v,
ser_f => ser_f,
ser_smpte_bypass => ser_smpte_bypass,
ser_dvb_asi => ser_dvb_asi,
ser_sdhdn => ser_sdhdn,
-- GN1531 de-serializer
des => des,
des_pclk => des_pclk,
des_h => des_h,
des_v => des_v,
des_f => des_f,
des_smpte_bypass => des_smpte_bypass,
des_dvb_asi => des_dvb_asi,
des_sdhdn => des_sdhdn,
-- GN4911 Timing Generator
syncseperator_h_timing => syncseperator_h_timing,
syncseperator_v_timing => syncseperator_v_timing,
syncseperator_f_timing => syncseperator_f_timing,
-- I2C
sda => sda,
scl => scl,
-- Debug Switches
debug => debug,
led => led,
-- SPI
spi_sck => spi_sck,
spi_ss => spi_ss,
spi_mosi => spi_mosi,
spi_miso => spi_miso,
pclk_4911_1531 => pclk_4911_1531,
gs4911_host_b => gs4911_host_b,
gs4911_sclk => gs4911_sclk,
gs4911_sdin => gs4911_sdin,
gs4911_sdout => gs4911_sdout,
gs4911_csb => gs4911_csb,
gs4911_lock_lost => gs4911_lock_lost,
gs4911_ref_lost => gs4911_ref_lost
);
process
variable vP2L_DATA_LOW : std_logic_vector(P2L_DATA'range);
begin
wait until(P2L_CLKp'event and (P2L_CLKp = '1'));
vP2L_DATA_LOW := P2L_DATA;
loop
wait on P2L_DATA, P2L_CLKp;
P2L_DATA_32 <= P2L_DATA & vP2L_DATA_LOW;
if(P2L_CLKp = '0') then
exit;
end if;
end loop;
end process;
end TEST;
library IEEE;
use IEEE.std_logic_1164.all;
use std.textio.all;
--library std_developerskit;
--use std_developerskit.std_iopak.all;
use work.util.all;
use work.textutil.all;
--############################################################################
--############################################################################
--==========================================================================--
--
-- *Module : tb_pfc
--
-- *Description : Test Bench for the GN4124 BFM + PFC Design
--
-- *History
--
--==========================================================================--
--############################################################################
--############################################################################
entity TB_PFC is
generic
(
T_LCLK : time := 30 ns -- Default LCLK Clock Period
);
end TB_PFC;
architecture TEST of TB_PFC is
--###########################################################################
--###########################################################################
--##
--## Component Declairations
--##
--###########################################################################
--###########################################################################
-----------------------------------------------------------------------------
-- GN4124 Local Bus Model
-----------------------------------------------------------------------------
component GN412X_BFM
generic
(
STRING_MAX : integer := 256; -- Command string maximum length
T_LCLK : time := 10 ns; -- Local Bus Clock Period
T_P2L_CLK_DLY : time := 2 ns; -- Delay from LCLK to P2L_CLK
INSTANCE_LABEL : string := "GN412X_BFM"; -- Label string to be used as a prefix for messages from the model
MODE_PRIMARY : boolean := true -- TRUE for BFM acting as GN412x, FALSE for BFM acting as the DUT
);
port
(
--=========================================================--
-------------------------------------------------------------
-- CMD_ROUTER Interface
--
CMD : in string(1 to STRING_MAX);
CMD_REQ : in bit;
CMD_ACK : out bit;
CMD_CLOCK_EN : in boolean;
--=========================================================--
-------------------------------------------------------------
-- GN412x Signal I/O
-------------------------------------------------------------
-- This is the reset input to the BFM
--
RSTINn : in std_logic;
-------------------------------------------------------------
-- Reset outputs to DUT
--
RSTOUT18n : out std_logic;
RSTOUT33n : out std_logic;
-------------------------------------------------------------
----------------- Local Bus Clock ---------------------------
------------------------------------------------------------- __ Direction for primary mode
-- / \
LCLK, LCLKn : inout std_logic; -- Out
-------------------------------------------------------------
----------------- Local-to-PCI Dataflow ---------------------
-------------------------------------------------------------
-- Transmitter Source Synchronous Clock.
--
L2P_CLKp, L2P_CLKn : inout std_logic; -- In
-------------------------------------------------------------
-- L2P DDR Link
--
L2P_DATA : inout std_logic_vector(15 downto 0); -- In -- Parallel Transmit Data.
L2P_DFRAME : inout std_logic; -- In -- Transmit Data Frame.
L2P_VALID : inout std_logic; -- In -- Transmit Data Valid.
L2P_EDB : inout std_logic; -- In -- End-of-Packet Bad Flag.
-------------------------------------------------------------
-- L2P SDR Controls
--
L_WR_RDY : inout std_logic_vector(1 downto 0); -- Out -- Local-to-PCIe Write.
P_RD_D_RDY : inout std_logic_vector(1 downto 0); -- Out -- PCIe-to-Local Read Response Data Ready.
L2P_RDY : inout std_logic; -- Out -- Tx Buffer Full Flag.
TX_ERROR : inout std_logic; -- Out -- Transmit Error.
-------------------------------------------------------------
----------------- PCIe-to-Local Dataflow ---------------------
-------------------------------------------------------------
-- Transmitter Source Synchronous Clock.
--
P2L_CLKp, P2L_CLKn : inout std_logic; -- Out -- P2L Source Synchronous Clock.
-------------------------------------------------------------
-- P2L DDR Link
--
P2L_DATA : inout std_logic_vector(15 downto 0); -- Out -- Parallel Receive Data.
P2L_DFRAME : inout std_logic; -- Out -- Receive Frame.
P2L_VALID : inout std_logic; -- Out -- Receive Data Valid.
-------------------------------------------------------------
-- P2L SDR Controls
--
P2L_RDY : inout std_logic; -- In -- Rx Buffer Full Flag.
P_WR_REQ : inout std_logic_vector(1 downto 0); -- Out -- PCIe Write Request.
P_WR_RDY : inout std_logic_vector(1 downto 0); -- In -- PCIe Write Ready.
RX_ERROR : inout std_logic; -- In -- Receive Error.
VC_RDY : inout std_logic_vector(1 downto 0); -- Out -- Virtual Channel Ready Status.
-------------------------------------------------------------
-- GPIO signals
--
GPIO : inout std_logic_vector(15 downto 0)
);
end component; --GN412X_BFM;
-----------------------------------------------------------------------------
-- CMD_ROUTER component
-----------------------------------------------------------------------------
component cmd_router
generic(N_BFM : integer := 8;
N_FILES : integer := 3;
FIFO_DEPTH : integer := 8;
STRING_MAX : integer := 256
);
port(CMD : out string(1 to STRING_MAX);
CMD_REQ : out bit_vector(N_BFM-1 downto 0);
CMD_ACK : in bit_vector(N_BFM-1 downto 0);
CMD_ERR : in bit_vector(N_BFM-1 downto 0);
CMD_CLOCK_EN : out boolean
);
end component; --cmd_router;
-----------------------------------------------------------------------------
-- CMD_ROUTER component
-----------------------------------------------------------------------------
component simple
port(
clk : in std_logic;
d : in std_logic_vector(15 downto 0);
q : out std_logic_vector(15 downto 0)
);
end component;
-----------------------------------------------------------------------------
-- Design top entity
-----------------------------------------------------------------------------
component pfc_top
generic(
g_SIMULATION : string := "FALSE";
g_CALIB_SOFT_IP : string := "TRUE"
);
port
(
-- Global ports
SYS_CLK_P : in std_logic; -- 25MHz system clock
SYS_CLK_N : in std_logic; -- 25MHz system clock
-- From GN4124 Local bus
L_CLKp : in std_logic; -- Local bus clock (frequency set in GN4124 config registers)
L_CLKn : in std_logic; -- Local bus clock (frequency set in GN4124 config registers)
L_RST_N : in std_logic; -- Reset from GN4124 (RSTOUT18_N)
-- General Purpose Interface
GPIO : inout std_logic_vector(1 downto 0); -- GPIO[0] -> GN4124 GPIO8
-- GPIO[1] -> GN4124 GPIO9
-- PCIe to Local [Inbound Data] - RX
P2L_RDY : out std_logic; -- Rx Buffer Full Flag
P2L_CLKn : in std_logic; -- Receiver Source Synchronous Clock-
P2L_CLKp : in std_logic; -- Receiver Source Synchronous Clock+
P2L_DATA : in std_logic_vector(15 downto 0); -- Parallel receive data
P2L_DFRAME : in std_logic; -- Receive Frame
P2L_VALID : in std_logic; -- Receive Data Valid
-- Inbound Buffer Request/Status
P_WR_REQ : in std_logic_vector(1 downto 0); -- PCIe Write Request
P_WR_RDY : out std_logic_vector(1 downto 0); -- PCIe Write Ready
RX_ERROR : out std_logic; -- Receive Error
-- Local to Parallel [Outbound Data] - TX
L2P_DATA : out std_logic_vector(15 downto 0); -- Parallel transmit data
L2P_DFRAME : out std_logic; -- Transmit Data Frame
L2P_VALID : out std_logic; -- Transmit Data Valid
L2P_CLKn : out std_logic; -- Transmitter Source Synchronous Clock-
L2P_CLKp : out std_logic; -- Transmitter Source Synchronous Clock+
L2P_EDB : out std_logic; -- Packet termination and discard
-- Outbound Buffer Status
L2P_RDY : in std_logic; -- Tx Buffer Full Flag
L_WR_RDY : in std_logic_vector(1 downto 0); -- Local-to-PCIe Write
P_RD_D_RDY : in std_logic_vector(1 downto 0); -- PCIe-to-Local Read Response Data Ready
TX_ERROR : in std_logic; -- Transmit Error
VC_RDY : in std_logic_vector(1 downto 0); -- Channel ready
-- Font panel LEDs
LED_RED : out std_logic;
LED_GREEN : out std_logic;
-- User IO (eSATA connector)
USER_IO_0_P : out std_logic;
USER_IO_0_N : out std_logic;
USER_IO_1_P : out std_logic;
USER_IO_1_N : out std_logic;
-- FMC connector management signals
PRSNT_M2C_L : in std_logic;
PG_C2M : out std_logic;
M2C_DIR : in std_logic; -- HPC only
FPGA_SDA : inout std_logic;
FPGA_SCL : out std_logic;
TMS_TO_FMC_P1V8 : out std_logic;
TDO_FROM_FMC_P1V8 : in std_logic;
TDI_TO_FMC_P1V8 : out std_logic;
TCK_TO_FMC_P1V8 : out std_logic;
-- FMC connector clock inputs
CLK1_M2C_P : in std_logic;
CLK1_M2C_N : in std_logic;
CLK0_M2C_P : in std_logic;
CLK0_M2C_N : in std_logic;
-- FMC connector user defined signals
LA33_P : out std_logic;
LA33_N : out std_logic;
LA32_P : out std_logic;
LA32_N : out std_logic;
LA31_P : out std_logic;
LA31_N : out std_logic;
LA30_P : out std_logic;
LA30_N : out std_logic;
LA29_P : out std_logic;
LA29_N : out std_logic;
LA28_P : out std_logic;
LA28_N : out std_logic;
LA27_P : out std_logic;
LA27_N : out std_logic;
LA26_P : out std_logic;
LA26_N : out std_logic;
LA25_P : out std_logic;
LA25_N : out std_logic;
LA24_P : out std_logic;
LA24_N : out std_logic;
LA23_P : out std_logic;
LA23_N : out std_logic;
LA22_P : out std_logic;
LA22_N : out std_logic;
LA21_P : out std_logic;
LA21_N : out std_logic;
LA20_P : out std_logic;
LA20_N : out std_logic;
LA19_P : out std_logic;
LA19_N : out std_logic;
LA18_P : out std_logic;
LA18_N : out std_logic;
LA17_P : out std_logic;
LA17_N : out std_logic;
LA16_P : out std_logic;
LA16_N : out std_logic;
LA15_P : out std_logic;
LA15_N : out std_logic;
LA14_P : out std_logic;
LA14_N : out std_logic;
LA13_P : out std_logic;
LA13_N : out std_logic;
LA12_P : out std_logic;
LA12_N : out std_logic;
LA11_P : out std_logic;
LA11_N : out std_logic;
LA10_P : in std_logic;
LA10_N : out std_logic;
LA09_P : out std_logic;
LA09_N : out std_logic;
LA08_P : out std_logic;
LA08_N : out std_logic;
LA07_P : out std_logic;
LA07_N : out std_logic;
LA06_P : out std_logic;
LA06_N : out std_logic;
LA05_P : out std_logic;
LA05_N : out std_logic;
LA04_P : out std_logic;
LA04_N : out std_logic;
LA03_P : out std_logic;
LA03_N : out std_logic;
LA02_P : out std_logic;
LA02_N : out std_logic;
LA01_P : in std_logic;
LA01_N : out std_logic;
LA00_P : out std_logic;
LA00_N : out std_logic;
-- SPI interface
SCLK_V_MON_P1V8 : out std_logic;
DIN_V_MON : out std_logic;
CSVR_V_MON_P1V8 : out std_logic; -- Digital potentiometer for VADJ
-- Power supplies control
ENABLE_VADJ : out std_logic;
-- DDR3 interface
ddr3_a_o : out std_logic_vector(13 downto 0);
ddr3_ba_o : out std_logic_vector(2 downto 0);
ddr3_cas_n_o : out std_logic;
ddr3_clk_p_o : out std_logic;
ddr3_clk_n_o : out std_logic;
ddr3_cke_o : out std_logic;
ddr3_dm_o : out std_logic;
ddr3_dq_b : inout std_logic_vector(15 downto 0);
ddr3_dqs_p_b : inout std_logic;
ddr3_dqs_n_b : inout std_logic;
ddr3_odt_o : out std_logic;
ddr3_ras_n_o : out std_logic;
ddr3_rst_n_o : out std_logic;
ddr3_udm_o : out std_logic;
ddr3_udqs_p_b : inout std_logic;
ddr3_udqs_n_b : inout std_logic;
ddr3_we_n_o : out std_logic;
ddr3_rzq_b : inout std_logic;
ddr3_zio_b : inout std_logic
);
end component; --pfc_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;
--###########################################################################
--###########################################################################
--##
--## Constants
--##
--###########################################################################
--###########################################################################
--
-- Number of Models receiving commands
constant N_BFM : integer := 2; -- 0 : GN412X_BFM in Model Mode
-- -- 1 : GN412X_BFM in DUT mode
-- Number of files to feed BFMs
constant N_FILES : integer := 2;
--
-- Depth of the command FIFO for each model
constant FIFO_DEPTH : integer := 16;
--
-- Maximum width of a command string
constant STRING_MAX : integer := 256;
--
--###########################################################################
--###########################################################################
--##
--## Signals
--##
--###########################################################################
--###########################################################################
-----------------------------------------------------------------------------
-- Command Router Signals
-----------------------------------------------------------------------------
signal CMD : string(1 to STRING_MAX);
signal CMD_REQ : bit_vector(N_BFM-1 downto 0);
signal CMD_ACK : bit_vector(N_BFM-1 downto 0);
signal CMD_ERR : bit_vector(N_BFM-1 downto 0);
signal CMD_CLOCK_EN : boolean;
-----------------------------------------------------------------------------
-- GN412x BFM Signals
-----------------------------------------------------------------------------
signal RSTINn : std_logic;
signal RSTOUT18n : std_logic;
signal RSTOUT33n : std_logic;
signal LCLK, LCLKn : std_logic;
signal L2P_CLKp, L2P_CLKn : std_logic;
signal L2P_DATA : std_logic_vector(15 downto 0);
signal L2P_DATA_32 : std_logic_vector(31 downto 0); -- For monitoring use
signal L2P_DFRAME : std_logic;
signal L2P_VALID : std_logic;
signal L2P_EDB : std_logic;
signal L_WR_RDY : std_logic_vector(1 downto 0);
signal P_RD_D_RDY : std_logic_vector(1 downto 0);
signal L2P_RDY : std_logic;
signal TX_ERROR : std_logic;
signal P2L_CLKp, P2L_CLKn : std_logic;
signal P2L_DATA : std_logic_vector(15 downto 0);
signal P2L_DATA_32 : std_logic_vector(31 downto 0); -- For monitoring use
signal P2L_DFRAME : std_logic;
signal P2L_VALID : std_logic;
signal P2L_RDY : std_logic;
signal P_WR_REQ : std_logic_vector(1 downto 0);
signal P_WR_RDY : std_logic_vector(1 downto 0);
signal RX_ERROR : std_logic;
signal VC_RDY : std_logic_vector(1 downto 0);
signal GPIO : std_logic_vector(15 downto 0);
-- Font panel LEDs
signal LED_RED : std_logic;
signal LED_GREEN : std_logic;
-- User IO (eSATA connector)
signal USER_IO_0_P : std_logic;
signal USER_IO_0_N : std_logic;
signal USER_IO_1_P : std_logic;
signal USER_IO_1_N : std_logic;
-- FMC connector management signals
signal PRSNT_M2C_L : std_logic := '0';
signal PG_C2M : std_logic;
signal M2C_DIR : std_logic := '0';
signal FPGA_SDA : std_logic := 'Z';
signal FPGA_SCL : std_logic;
signal TMS_TO_FMC_P1V8 : std_logic;
signal TDO_FROM_FMC_P1V8 : std_logic := '0';
signal TDI_TO_FMC_P1V8 : std_logic;
signal TCK_TO_FMC_P1V8 : std_logic;
-- FMC connector clock inputs
signal CLK1_M2C_P : std_logic := '0';
signal CLK1_M2C_N : std_logic := '0';
signal CLK0_M2C_P : std_logic := '0';
signal CLK0_M2C_N : std_logic := '0';
-- FMC connector user defined signals
signal LA33_P : std_logic;
signal LA33_N : std_logic;
signal LA32_P : std_logic;
signal LA32_N : std_logic;
signal LA31_P : std_logic;
signal LA31_N : std_logic;
signal LA30_P : std_logic;
signal LA30_N : std_logic;
signal LA29_P : std_logic;
signal LA29_N : std_logic;
signal LA28_P : std_logic;
signal LA28_N : std_logic;
signal LA27_P : std_logic;
signal LA27_N : std_logic;
signal LA26_P : std_logic;
signal LA26_N : std_logic;
signal LA25_P : std_logic;
signal LA25_N : std_logic;
signal LA24_P : std_logic;
signal LA24_N : std_logic;
signal LA23_P : std_logic;
signal LA23_N : std_logic;
signal LA22_P : std_logic;
signal LA22_N : std_logic;
signal LA21_P : std_logic;
signal LA21_N : std_logic;
signal LA20_P : std_logic;
signal LA20_N : std_logic;
signal LA19_P : std_logic;
signal LA19_N : std_logic;
signal LA18_P : std_logic;
signal LA18_N : std_logic;
signal LA17_P : std_logic;
signal LA17_N : std_logic;
signal LA16_P : std_logic;
signal LA16_N : std_logic;
signal LA15_P : std_logic;
signal LA15_N : std_logic;
signal LA14_P : std_logic;
signal LA14_N : std_logic;
signal LA13_P : std_logic;
signal LA13_N : std_logic;
signal LA12_P : std_logic;
signal LA12_N : std_logic;
signal LA11_P : std_logic;
signal LA11_N : std_logic;
signal LA10_P : std_logic := '0';
signal LA10_N : std_logic;
signal LA09_P : std_logic;
signal LA09_N : std_logic;
signal LA08_P : std_logic;
signal LA08_N : std_logic;
signal LA07_P : std_logic;
signal LA07_N : std_logic;
signal LA06_P : std_logic;
signal LA06_N : std_logic;
signal LA05_P : std_logic;
signal LA05_N : std_logic;
signal LA04_P : std_logic;
signal LA04_N : std_logic;
signal LA03_P : std_logic;
signal LA03_N : std_logic;
signal LA02_P : std_logic;
signal LA02_N : std_logic;
signal LA01_P : std_logic := '0';
signal LA01_N : std_logic;
signal LA00_P : std_logic;
signal LA00_N : std_logic;
-- SPI interface
signal SCLK_V_MON_P1V8 : std_logic;
signal DIN_V_MON : std_logic;
signal CSVR_V_MON_P1V8 : std_logic;
-- Power supplies control
signal ENABLE_VADJ : std_logic;
-- DDR3 interface
signal ddr3_a_o : std_logic_vector(13 downto 0);
signal ddr3_ba_o : std_logic_vector(2 downto 0);
signal ddr3_cas_n_o : std_logic;
signal ddr3_clk_p_o : std_logic;
signal ddr3_clk_n_o : std_logic;
signal ddr3_cke_o : std_logic;
signal ddr3_dm_b : std_logic_vector(1 downto 0) := (others => 'Z');
signal ddr3_dq_b : std_logic_vector(15 downto 0) := (others => 'Z');
signal ddr3_dqs_p_b : std_logic_vector(1 downto 0) := (others => 'Z');
signal ddr3_dqs_n_b : std_logic_vector(1 downto 0) := (others => 'Z');
signal ddr3_odt_o : std_logic;
signal ddr3_ras_n_o : std_logic;
signal ddr3_rst_n_o : std_logic;
signal ddr3_dm_o : std_logic;
signal ddr3_udm_o : std_logic;
--signal ddr3_udqs_p_b : std_logic := 'Z';
--signal ddr3_udqs_n_b : std_logic := 'Z';
signal ddr3_we_n_o : std_logic;
signal ddr3_rzq_b : std_logic;
signal ddr3_zio_b : std_logic := 'Z';
-- 25MHz system clock
signal SYS_CLK_P : std_logic;
signal SYS_CLK_N : std_logic;
-----------------------------------------------------------------------------
-- Bus Monitor Signals
-----------------------------------------------------------------------------
signal Q_P2L_DFRAME : std_logic;
signal SIMPLE_TEST : std_logic_vector(15 downto 0);
--###########################################################################
--###########################################################################
--##
--## Start of Code
--##
--###########################################################################
--###########################################################################
begin
-----------------------------------------------------------------------------
-- MODEL Component
-----------------------------------------------------------------------------
CMD_ERR <= (others => '0');
UC : cmd_router
generic map
(N_BFM => N_BFM,
N_FILES => N_FILES,
FIFO_DEPTH => FIFO_DEPTH,
STRING_MAX => STRING_MAX
)
port map
(CMD => CMD,
CMD_REQ => CMD_REQ,
CMD_ACK => CMD_ACK,
CMD_ERR => CMD_ERR,
CMD_CLOCK_EN => CMD_CLOCK_EN
);
-----------------------------------------------------------------------------
-- GN412x BFM - PRIMARY
-----------------------------------------------------------------------------
U0 : gn412x_bfm
generic map
(
STRING_MAX => STRING_MAX,
T_LCLK => 10 ns,
T_P2L_CLK_DLY => 2 ns,
INSTANCE_LABEL => "U0(Primary GN412x): ",
MODE_PRIMARY => true
)
port map
(
--=========================================================--
-------------------------------------------------------------
-- CMD_ROUTER Interface
--
CMD => CMD,
CMD_REQ => CMD_REQ(0),
CMD_ACK => CMD_ACK(0),
CMD_CLOCK_EN => CMD_CLOCK_EN,
--=========================================================--
-------------------------------------------------------------
-- GN412x Signal I/O
-------------------------------------------------------------
-- This is the reset input to the BFM
--
RSTINn => RSTINn,
-------------------------------------------------------------
-- Reset outputs to DUT
--
RSTOUT18n => RSTOUT18n,
RSTOUT33n => RSTOUT33n,
-------------------------------------------------------------
----------------- Local Bus Clock ---------------------------
-------------------------------------------------------------
--
LCLK => LCLK,
LCLKn => LCLKn,
-------------------------------------------------------------
----------------- Local-to-PCI Dataflow ---------------------
-------------------------------------------------------------
-- Transmitter Source Synchronous Clock.
--
L2P_CLKp => L2P_CLKp,
L2P_CLKn => L2P_CLKn,
-------------------------------------------------------------
-- L2P DDR Link
--
L2P_DATA => L2P_DATA,
L2P_DFRAME => L2P_DFRAME,
L2P_VALID => L2P_VALID,
L2P_EDB => L2P_EDB,
-------------------------------------------------------------
-- L2P SDR Controls
--
L_WR_RDY => L_WR_RDY,
P_RD_D_RDY => P_RD_D_RDY,
L2P_RDY => L2P_RDY,
TX_ERROR => TX_ERROR,
-------------------------------------------------------------
----------------- PCIe-to-Local Dataflow ---------------------
-------------------------------------------------------------
-- Transmitter Source Synchronous Clock.
--
P2L_CLKp => P2L_CLKp,
P2L_CLKn => P2L_CLKn,
-------------------------------------------------------------
-- P2L DDR Link
--
P2L_DATA => P2L_DATA,
P2L_DFRAME => P2L_DFRAME,
P2L_VALID => P2L_VALID,
-------------------------------------------------------------
-- P2L SDR Controls
--
P2L_RDY => P2L_RDY,
P_WR_REQ => P_WR_REQ,
P_WR_RDY => P_WR_RDY,
RX_ERROR => RX_ERROR,
VC_RDY => VC_RDY,
GPIO => gpio
); -- GN412X_BFM;
-----------------------------------------------------------------------------
-- UUT
-----------------------------------------------------------------------------
U1 : pfc_top
generic map (
g_SIMULATION => "TRUE",
g_CALIB_SOFT_IP => "FALSE")
port map (
-- Global ports
SYS_CLK_P => SYS_CLK_P,
SYS_CLK_N => SYS_CLK_N,
-- From GN4124 Local bus
l_clkp => LCLK, -- Running at 200 Mhz
l_clkn => LCLKn, -- Running at 200 Mhz
l_rst_n => RSTOUT18n,
-- General Purpose Interface
gpio => GPIO(9 downto 8), -- General Purpose Input/Output
-- PCIe to Local [Inbound Data] - RX
p2l_rdy => P2L_RDY, -- Rx Buffer Full Flag
p2l_clkn => P2L_CLKn, -- Receiver Source Synchronous Clock-
p2l_clkp => P2L_CLKp, -- Receiver Source Synchronous Clock+
p2l_data => P2L_DATA, -- Parallel receive data
p2l_dframe => P2L_DFRAME, -- Receive Frame
p2l_valid => P2L_VALID, -- Receive Data Valid
-- Inbound Buffer Request/Status
p_wr_req => P_WR_REQ, -- PCIe Write Request
p_wr_rdy => P_WR_RDY, -- PCIe Write Ready
rx_error => RX_ERROR, -- Receive Error
-- Local to Parallel [Outbound Data] - TX
l2p_data => L2P_DATA, -- Parallel transmit data
l2p_dframe => L2P_DFRAME, -- Transmit Data Frame
l2p_valid => L2P_VALID, -- Transmit Data Valid
l2p_clkn => L2P_CLKn, -- Transmitter Source Synchronous Clock-
l2p_clkp => L2P_CLKp, -- Transmitter Source Synchronous Clock+
l2p_edb => L2P_EDB, -- Packet termination and discard
-- Outbound Buffer Status
l2p_rdy => L2P_RDY, -- Tx Buffer Full Flag
l_wr_rdy => L_WR_RDY, -- Local-to-PCIe Write
p_rd_d_rdy => P_RD_D_RDY, -- PCIe-to-Local Read Response Data Ready
tx_error => TX_ERROR, -- Transmit Error
vc_rdy => VC_RDY, -- Channel ready
-- Font panel LEDs
LED_RED => LED_RED,
LED_GREEN => LED_GREEN,
-- User IO (eSATA connector)
USER_IO_0_P => USER_IO_0_P,
USER_IO_0_N => USER_IO_0_N,
USER_IO_1_P => USER_IO_1_P,
USER_IO_1_N => USER_IO_1_N,
-- FMC connector management signals
PRSNT_M2C_L => PRSNT_M2C_L,
PG_C2M => PG_C2M,
M2C_DIR => M2C_DIR,
FPGA_SDA => FPGA_SDA,
FPGA_SCL => FPGA_SCL,
TMS_TO_FMC_P1V8 => TMS_TO_FMC_P1V8,
TDO_FROM_FMC_P1V8 => TDO_FROM_FMC_P1V8,
TDI_TO_FMC_P1V8 => TDI_TO_FMC_P1V8,
TCK_TO_FMC_P1V8 => TCK_TO_FMC_P1V8,
-- FMC connector clock inputs
CLK1_M2C_P => CLK1_M2C_P,
CLK1_M2C_N => CLK1_M2C_N,
CLK0_M2C_P => CLK0_M2C_P,
CLK0_M2C_N => CLK0_M2C_N,
-- FMC connector user defined signals
LA33_P => LA33_P,
LA33_N => LA33_N,
LA32_P => LA32_P,
LA32_N => LA32_N,
LA31_P => LA31_P,
LA31_N => LA31_N,
LA30_P => LA30_P,
LA30_N => LA30_N,
LA29_P => LA29_P,
LA29_N => LA29_N,
LA28_P => LA28_P,
LA28_N => LA28_N,
LA27_P => LA27_P,
LA27_N => LA27_N,
LA26_P => LA26_P,
LA26_N => LA26_N,
LA25_P => LA25_P,
LA25_N => LA25_N,
LA24_P => LA24_P,
LA24_N => LA24_N,
LA23_P => LA23_P,
LA23_N => LA23_N,
LA22_P => LA22_P,
LA22_N => LA22_N,
LA21_P => LA21_P,
LA21_N => LA21_N,
LA20_P => LA20_P,
LA20_N => LA20_N,
LA19_P => LA19_P,
LA19_N => LA19_N,
LA18_P => LA18_P,
LA18_N => LA18_N,
LA17_P => LA17_P,
LA17_N => LA17_N,
LA16_P => LA16_P,
LA16_N => LA16_N,
LA15_P => LA15_P,
LA15_N => LA15_N,
LA14_P => LA14_P,
LA14_N => LA14_N,
LA13_P => LA13_P,
LA13_N => LA13_N,
LA12_P => LA12_P,
LA12_N => LA12_N,
LA11_P => LA11_P,
LA11_N => LA11_N,
LA10_P => LA10_P,
LA10_N => LA10_N,
LA09_P => LA09_P,
LA09_N => LA09_N,
LA08_P => LA08_P,
LA08_N => LA08_N,
LA07_P => LA07_P,
LA07_N => LA07_N,
LA06_P => LA06_P,
LA06_N => LA06_N,
LA05_P => LA05_P,
LA05_N => LA05_N,
LA04_P => LA04_P,
LA04_N => LA04_N,
LA03_P => LA03_P,
LA03_N => LA03_N,
LA02_P => LA02_P,
LA02_N => LA02_N,
LA01_P => LA01_P,
LA01_N => LA01_N,
LA00_P => LA00_P,
LA00_N => LA00_N,
-- SPI interface
SCLK_V_MON_P1V8 => SCLK_V_MON_P1V8,
DIN_V_MON => DIN_V_MON,
CSVR_V_MON_P1V8 => CSVR_V_MON_P1V8,
-- Power supplies control
ENABLE_VADJ => ENABLE_VADJ,
-- DDR3 interface
ddr3_a_o => ddr3_a_o,
ddr3_ba_o => ddr3_ba_o,
ddr3_cas_n_o => ddr3_cas_n_o,
ddr3_clk_p_o => ddr3_clk_p_o,
ddr3_clk_n_o => ddr3_clk_n_o,
ddr3_cke_o => ddr3_cke_o,
ddr3_dm_o => ddr3_dm_b(0),
ddr3_dq_b => ddr3_dq_b,
ddr3_dqs_p_b => ddr3_dqs_p_b(0),
ddr3_dqs_n_b => ddr3_dqs_n_b(0),
ddr3_odt_o => ddr3_odt_o,
ddr3_ras_n_o => ddr3_ras_n_o,
ddr3_rst_n_o => ddr3_rst_n_o,
ddr3_udm_o => ddr3_dm_b(1),
ddr3_udqs_p_b => ddr3_dqs_p_b(1),
ddr3_udqs_n_b => ddr3_dqs_n_b(1),
ddr3_we_n_o => ddr3_we_n_o,
ddr3_rzq_b => ddr3_rzq_b,
ddr3_zio_b => ddr3_zio_b
);
cmp_ddr3_model : ddr3
port map(
rst_n => ddr3_rst_n_o,
ck => ddr3_clk_p_o,
ck_n => ddr3_clk_n_o,
cke => ddr3_cke_o,
cs_n => '0', -- Pulled down on PCB
ras_n => ddr3_ras_n_o,
cas_n => ddr3_cas_n_o,
we_n => ddr3_we_n_o,
dm_tdqs => ddr3_dm_b,
ba => ddr3_ba_o,
addr => ddr3_a_o,
dq => ddr3_dq_b,
dqs => ddr3_dqs_p_b,
dqs_n => ddr3_dqs_n_b,
tdqs_n => open, -- dqs outputs for chaining
odt => ddr3_odt_o
);
process
variable vP2L_DATA_LOW : std_logic_vector(P2L_DATA'range);
begin
wait until(P2L_CLKp'event and (P2L_CLKp = '1'));
vP2L_DATA_LOW := P2L_DATA;
loop
wait on P2L_DATA, P2L_CLKp;
P2L_DATA_32 <= P2L_DATA & vP2L_DATA_LOW;
if(P2L_CLKp = '0') then
exit;
end if;
end loop;
end process;
sys_clk : process
begin
SYS_CLK_P <= '1';
SYS_CLK_N <= '0';
wait for 20 ns;
SYS_CLK_P <= '0';
SYS_CLK_N <= '1';
wait for 20 ns;
end process sys_clk;
end TEST;
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.NUMERIC_STD.all;
use std.textio.all;
--library std_developerskit;
--use std_developerskit.std_iopak.all;
use work.util.all;
use work.textutil.all;
--############################################################################
--############################################################################
--==========================================================================--
--
-- *Module : tb_spec
--
-- *Description : Test Bench for the GN4124 BFM + SPEC Design
--
-- *History
--
--==========================================================================--
--############################################################################
--############################################################################
entity TB_SPEC is
generic
(
T_LCLK : time := 30 ns -- Default LCLK Clock Period
);
end TB_SPEC;
architecture TEST of TB_SPEC is
--###########################################################################
--###########################################################################
--##
--## Component Declairations
--##
--###########################################################################
--###########################################################################
-----------------------------------------------------------------------------
-- GN4124 Local Bus Model
-----------------------------------------------------------------------------
component GN412X_BFM
generic
(
STRING_MAX : integer := 256; -- Command string maximum length
T_LCLK : time := 10 ns; -- Local Bus Clock Period
T_P2L_CLK_DLY : time := 2 ns; -- Delay from LCLK to P2L_CLK
INSTANCE_LABEL : string := "GN412X_BFM"; -- Label string to be used as a prefix for messages from the model
MODE_PRIMARY : boolean := true -- TRUE for BFM acting as GN412x, FALSE for BFM acting as the DUT
);
port
(
--=========================================================--
-------------------------------------------------------------
-- CMD_ROUTER Interface
--
CMD : in string(1 to STRING_MAX);
CMD_REQ : in bit;
CMD_ACK : out bit;
CMD_CLOCK_EN : in boolean;
--=========================================================--
-------------------------------------------------------------
-- GN412x Signal I/O
-------------------------------------------------------------
-- This is the reset input to the BFM
--
RSTINn : in std_logic;
-------------------------------------------------------------
-- Reset outputs to DUT
--
RSTOUT18n : out std_logic;
RSTOUT33n : out std_logic;
-------------------------------------------------------------
----------------- Local Bus Clock ---------------------------
------------------------------------------------------------- __ Direction for primary mode
-- / \
LCLK, LCLKn : inout std_logic; -- Out
-------------------------------------------------------------
----------------- Local-to-PCI Dataflow ---------------------
-------------------------------------------------------------
-- Transmitter Source Synchronous Clock.
--
L2P_CLKp, L2P_CLKn : inout std_logic; -- In
-------------------------------------------------------------
-- L2P DDR Link
--
L2P_DATA : inout std_logic_vector(15 downto 0); -- In -- Parallel Transmit Data.
L2P_DFRAME : inout std_logic; -- In -- Transmit Data Frame.
L2P_VALID : inout std_logic; -- In -- Transmit Data Valid.
L2P_EDB : inout std_logic; -- In -- End-of-Packet Bad Flag.
-------------------------------------------------------------
-- L2P SDR Controls
--
L_WR_RDY : inout std_logic_vector(1 downto 0); -- Out -- Local-to-PCIe Write.
P_RD_D_RDY : inout std_logic_vector(1 downto 0); -- Out -- PCIe-to-Local Read Response Data Ready.
L2P_RDY : inout std_logic; -- Out -- Tx Buffer Full Flag.
TX_ERROR : inout std_logic; -- Out -- Transmit Error.
-------------------------------------------------------------
----------------- PCIe-to-Local Dataflow ---------------------
-------------------------------------------------------------
-- Transmitter Source Synchronous Clock.
--
P2L_CLKp, P2L_CLKn : inout std_logic; -- Out -- P2L Source Synchronous Clock.
-------------------------------------------------------------
-- P2L DDR Link
--
P2L_DATA : inout std_logic_vector(15 downto 0); -- Out -- Parallel Receive Data.
P2L_DFRAME : inout std_logic; -- Out -- Receive Frame.
P2L_VALID : inout std_logic; -- Out -- Receive Data Valid.
-------------------------------------------------------------
-- P2L SDR Controls
--
P2L_RDY : inout std_logic; -- In -- Rx Buffer Full Flag.
P_WR_REQ : inout std_logic_vector(1 downto 0); -- Out -- PCIe Write Request.
P_WR_RDY : inout std_logic_vector(1 downto 0); -- In -- PCIe Write Ready.
RX_ERROR : inout std_logic; -- In -- Receive Error.
VC_RDY : inout std_logic_vector(1 downto 0); -- Out -- Virtual Channel Ready Status.
-------------------------------------------------------------
-- GPIO signals
--
GPIO : inout std_logic_vector(15 downto 0)
);
end component; --GN412X_BFM;
-----------------------------------------------------------------------------
-- CMD_ROUTER component
-----------------------------------------------------------------------------
component cmd_router
generic(N_BFM : integer := 8;
N_FILES : integer := 3;
FIFO_DEPTH : integer := 8;
STRING_MAX : integer := 256
);
port(CMD : out string(1 to STRING_MAX);
CMD_REQ : out bit_vector(N_BFM-1 downto 0);
CMD_ACK : in bit_vector(N_BFM-1 downto 0);
CMD_ERR : in bit_vector(N_BFM-1 downto 0);
CMD_CLOCK_EN : out boolean
);
end component; --cmd_router;
-----------------------------------------------------------------------------
-- CMD_ROUTER component
-----------------------------------------------------------------------------
component simple
port(
clk : in std_logic;
d : in std_logic_vector(15 downto 0);
q : out std_logic_vector(15 downto 0)
);
end component;
-----------------------------------------------------------------------------
-- Design top entity
-----------------------------------------------------------------------------
component spec_gn4124_test
port
(
-- Local oscillator
clk20_vcxo_i : in std_logic; -- 20MHz VCXO clock
-- Carrier font panel LEDs
LED_RED_O : out std_logic;
LED_GREEN_O : out std_logic;
-- Auxiliary pins
AUX_LEDS_O : out std_logic_vector(3 downto 0);
AUX_BUTTONS_I : in std_logic_vector(1 downto 0);
-- GN4124 interface
L_CLKp : in std_logic; -- Local bus clock (frequency set in GN4124 config registers)
L_CLKn : in std_logic; -- Local bus clock (frequency set in GN4124 config registers)
L_RST_N : in std_logic; -- Reset from GN4124 (RSTOUT18_N)
P2L_RDY : out std_logic; -- Rx Buffer Full Flag
P2L_CLKn : in std_logic; -- Receiver Source Synchronous Clock-
P2L_CLKp : in std_logic; -- Receiver Source Synchronous Clock+
P2L_DATA : in std_logic_vector(15 downto 0); -- Parallel receive data
P2L_DFRAME : in std_logic; -- Receive Frame
P2L_VALID : in std_logic; -- Receive Data Valid
P_WR_REQ : in std_logic_vector(1 downto 0); -- PCIe Write Request
P_WR_RDY : out std_logic_vector(1 downto 0); -- PCIe Write Ready
RX_ERROR : out std_logic; -- Receive Error
L2P_DATA : out std_logic_vector(15 downto 0); -- Parallel transmit data
L2P_DFRAME : out std_logic; -- Transmit Data Frame
L2P_VALID : out std_logic; -- Transmit Data Valid
L2P_CLKn : out std_logic; -- Transmitter Source Synchronous Clock-
L2P_CLKp : out std_logic; -- Transmitter Source Synchronous Clock+
L2P_EDB : out std_logic; -- Packet termination and discard
L2P_RDY : in std_logic; -- Tx Buffer Full Flag
L_WR_RDY : in std_logic_vector(1 downto 0); -- Local-to-PCIe Write
P_RD_D_RDY : in std_logic_vector(1 downto 0); -- PCIe-to-Local Read Response Data Ready
TX_ERROR : in std_logic; -- Transmit Error
VC_RDY : in std_logic_vector(1 downto 0); -- Channel ready
GPIO : inout std_logic_vector(1 downto 0); -- GPIO[0] -> GN4124 GPIO8
-- GPIO[1] -> GN4124 GPIO9
-- PCB version
pcb_ver_i : in std_logic_vector(3 downto 0)
);
end component spec_gn4124_test;
--###########################################################################
--###########################################################################
--##
--## Constants
--##
--###########################################################################
--###########################################################################
--
-- Number of Models receiving commands
constant N_BFM : integer := 2; -- 0 : GN412X_BFM in Model Mode
-- -- 1 : GN412X_BFM in DUT mode
-- Number of files to feed BFMs
constant N_FILES : integer := 2;
--
-- Depth of the command FIFO for each model
constant FIFO_DEPTH : integer := 16;
--
-- Maximum width of a command string
constant STRING_MAX : integer := 256;
--###########################################################################
--###########################################################################
--##
--## Signals
--##
--###########################################################################
--###########################################################################
-----------------------------------------------------------------------------
-- Command Router Signals
-----------------------------------------------------------------------------
signal CMD : string(1 to STRING_MAX);
signal CMD_REQ : bit_vector(N_BFM-1 downto 0);
signal CMD_ACK : bit_vector(N_BFM-1 downto 0);
signal CMD_ERR : bit_vector(N_BFM-1 downto 0);
signal CMD_CLOCK_EN : boolean;
-----------------------------------------------------------------------------
-- GN412x BFM Signals
-----------------------------------------------------------------------------
-- System signals
signal clk20_vcxo_i : std_logic := '0'; -- 20MHz VCXO clock
-- GN4124 interface
signal RSTINn : std_logic;
signal RSTOUT18n : std_logic;
signal RSTOUT33n : std_logic;
signal LCLK, LCLKn : std_logic;
signal L2P_CLKp, L2P_CLKn : std_logic;
signal L2P_DATA : std_logic_vector(15 downto 0);
signal L2P_DATA_32 : std_logic_vector(31 downto 0); -- For monitoring use
signal L2P_DFRAME : std_logic;
signal L2P_VALID : std_logic;
signal L2P_EDB : std_logic;
signal L_WR_RDY : std_logic_vector(1 downto 0);
signal P_RD_D_RDY : std_logic_vector(1 downto 0);
signal L2P_RDY : std_logic;
signal TX_ERROR : std_logic;
signal P2L_CLKp, P2L_CLKn : std_logic;
signal P2L_DATA : std_logic_vector(15 downto 0);
signal P2L_DATA_32 : std_logic_vector(31 downto 0); -- For monitoring use
signal P2L_DFRAME : std_logic;
signal P2L_VALID : std_logic;
signal P2L_RDY : std_logic;
signal P_WR_REQ : std_logic_vector(1 downto 0);
signal P_WR_RDY : std_logic_vector(1 downto 0);
signal RX_ERROR : std_logic;
signal VC_RDY : std_logic_vector(1 downto 0);
signal GPIO : std_logic_vector(15 downto 0);
-- Aux signals
signal LED_RED : std_logic;
signal LED_GREEN : std_logic;
signal AUX_BUTTONS : std_logic_vector(1 downto 0);
signal AUX_LEDS : std_logic_vector(3 downto 0);
signal PCB_VER : std_logic_vector(3 downto 0) := "0011";
-----------------------------------------------------------------------------
-- Bus Monitor Signals
-----------------------------------------------------------------------------
signal Q_P2L_DFRAME : std_logic;
signal SIMPLE_TEST : std_logic_vector(15 downto 0);
--###########################################################################
--###########################################################################
--##
--## Start of Code
--##
--###########################################################################
--###########################################################################
begin
-----------------------------------------------------------------------------
-- MODEL Component
-----------------------------------------------------------------------------
CMD_ERR <= (others => '0');
UC : cmd_router
generic map
(N_BFM => N_BFM,
N_FILES => N_FILES,
FIFO_DEPTH => FIFO_DEPTH,
STRING_MAX => STRING_MAX
)
port map
(CMD => CMD,
CMD_REQ => CMD_REQ,
CMD_ACK => CMD_ACK,
CMD_ERR => CMD_ERR,
CMD_CLOCK_EN => CMD_CLOCK_EN
);
-----------------------------------------------------------------------------
-- GN412x BFM - PRIMARY
-----------------------------------------------------------------------------
U0 : gn412x_bfm
generic map
(
STRING_MAX => STRING_MAX,
T_LCLK => 6.25 ns,
T_P2L_CLK_DLY => 2 ns,
INSTANCE_LABEL => "U0(Primary GN412x): ",
MODE_PRIMARY => true
)
port map
(
--=========================================================--
-------------------------------------------------------------
-- CMD_ROUTER Interface
--
CMD => CMD,
CMD_REQ => CMD_REQ(0),
CMD_ACK => CMD_ACK(0),
CMD_CLOCK_EN => CMD_CLOCK_EN,
--=========================================================--
-------------------------------------------------------------
-- GN412x Signal I/O
-------------------------------------------------------------
-- This is the reset input to the BFM
--
RSTINn => RSTINn,
-------------------------------------------------------------
-- Reset outputs to DUT
--
RSTOUT18n => RSTOUT18n,
RSTOUT33n => RSTOUT33n,
-------------------------------------------------------------
----------------- Local Bus Clock ---------------------------
-------------------------------------------------------------
--
LCLK => LCLK,
LCLKn => LCLKn,
-------------------------------------------------------------
----------------- Local-to-PCI Dataflow ---------------------
-------------------------------------------------------------
-- Transmitter Source Synchronous Clock.
--
L2P_CLKp => L2P_CLKp,
L2P_CLKn => L2P_CLKn,
-------------------------------------------------------------
-- L2P DDR Link
--
L2P_DATA => L2P_DATA,
L2P_DFRAME => L2P_DFRAME,
L2P_VALID => L2P_VALID,
L2P_EDB => L2P_EDB,
-------------------------------------------------------------
-- L2P SDR Controls
--
L_WR_RDY => L_WR_RDY,
P_RD_D_RDY => P_RD_D_RDY,
L2P_RDY => L2P_RDY,
TX_ERROR => TX_ERROR,
-------------------------------------------------------------
----------------- PCIe-to-Local Dataflow ---------------------
-------------------------------------------------------------
-- Transmitter Source Synchronous Clock.
--
P2L_CLKp => P2L_CLKp,
P2L_CLKn => P2L_CLKn,
-------------------------------------------------------------
-- P2L DDR Link
--
P2L_DATA => P2L_DATA,
P2L_DFRAME => P2L_DFRAME,
P2L_VALID => P2L_VALID,
-------------------------------------------------------------
-- P2L SDR Controls
--
P2L_RDY => P2L_RDY,
P_WR_REQ => P_WR_REQ,
P_WR_RDY => P_WR_RDY,
RX_ERROR => RX_ERROR,
VC_RDY => VC_RDY,
GPIO => gpio
); -- GN412X_BFM;
-----------------------------------------------------------------------------
-- UUT
-----------------------------------------------------------------------------
U1 : spec_gn4124_test
port map (
clk20_vcxo_i => clk20_vcxo_i,
LED_RED_O => LED_RED,
LED_GREEN_O => LED_GREEN,
AUX_LEDS_O => AUX_LEDS,
AUX_BUTTONS_I => AUX_BUTTONS,
-- GN4124 interface
l_clkp => LCLK, -- Running at 200 Mhz
l_clkn => LCLKn, -- Running at 200 Mhz
l_rst_n => RSTOUT18n,
p2l_rdy => P2L_RDY, -- Rx Buffer Full Flag
p2l_clkn => P2L_CLKn, -- Receiver Source Synchronous Clock-
p2l_clkp => P2L_CLKp, -- Receiver Source Synchronous Clock+
p2l_data => P2L_DATA, -- Parallel receive data
p2l_dframe => P2L_DFRAME, -- Receive Frame
p2l_valid => P2L_VALID, -- Receive Data Valid
p_wr_req => P_WR_REQ, -- PCIe Write Request
p_wr_rdy => P_WR_RDY, -- PCIe Write Ready
rx_error => RX_ERROR, -- Receive Error
l2p_data => L2P_DATA, -- Parallel transmit data
l2p_dframe => L2P_DFRAME, -- Transmit Data Frame
l2p_valid => L2P_VALID, -- Transmit Data Valid
l2p_clkn => L2P_CLKn, -- Transmitter Source Synchronous Clock-
l2p_clkp => L2P_CLKp, -- Transmitter Source Synchronous Clock+
l2p_edb => L2P_EDB, -- Packet termination and discard
l2p_rdy => L2P_RDY, -- Tx Buffer Full Flag
l_wr_rdy => L_WR_RDY, -- Local-to-PCIe Write
p_rd_d_rdy => P_RD_D_RDY, -- PCIe-to-Local Read Response Data Ready
tx_error => TX_ERROR, -- Transmit Error
vc_rdy => VC_RDY, -- Channel ready
gpio => GPIO(9 downto 8), -- General Purpose Input/Output
pcb_ver_i => PCB_VER
);
process
variable vP2L_DATA_LOW : std_logic_vector(P2L_DATA'range);
begin
wait until(P2L_CLKp'event and (P2L_CLKp = '1'));
vP2L_DATA_LOW := P2L_DATA;
loop
wait on P2L_DATA, P2L_CLKp;
P2L_DATA_32 <= P2L_DATA & vP2L_DATA_LOW;
if(P2L_CLKp = '0') then
exit;
end if;
end loop;
end process;
sys_clk : process
begin
clk20_vcxo_i <= '1';
wait for 25 ns;
clk20_vcxo_i <= '0';
wait for 25 ns;
end process sys_clk;
end TEST;
library IEEE;
use IEEE.std_logic_1164.all;
use std.textio.all;
use work.util.all;
-----------------------------------------------------------------------------
-- *Module : textutil
--
-- *Description : Improved Free-format string and line manipulation
--
-- *History: M. Alford (originaly created 1993 with subsequent updates)
-----------------------------------------------------------------------------
package textutil is
procedure read_token(L : inout line; X : out STRING);
procedure sget_token(S : in string; P : inout integer; X : out STRING);
procedure sget_vector(S : in string; P : inout integer; VEC : out STD_ULOGIC_VECTOR);
procedure sget_vector_64(S : in string; P : inout integer; VEC : out STD_ULOGIC_VECTOR);
procedure sget_int(S : in string; P : inout integer; X : out integer);
function hex_char_to_vector(C : in character) return STD_ULOGIC_VECTOR;
function vector_to_hex_char(V : in STD_ULOGIC_VECTOR) return character;
function is_hex(C : in character) return BOOLEAN;
function hex_char_to_int(C : in character) return integer;
procedure read_vector(L : inout line; VEC : out STD_ULOGIC_VECTOR);
procedure read_int(L : inout line; I : out integer);
procedure write_hex_vector(L : inout line; V : in STD_ULOGIC_VECTOR);
function to_str(constant V: in STD_ULOGIC_VECTOR) return STRING;
function to_str(constant V: in STD_ULOGIC) return STRING;
function to_str(constant val : in INTEGER) return STRING;
function to_strn(constant val : in INTEGER; constant n : in INTEGER) return STRING;
end textutil;
package body textutil is
-----------------------------------------------------------------------------
-- *Module : read_token
--
-- *Description : Skip over spaces then load a token string from a line
-- until either the string is full or the token is finished
-- (i.e. another space). The output string is padded out
-- with blanks at the end if the token length is less then
-- the full string length.
-----------------------------------------------------------------------------
procedure read_token(L : inout line; X : out STRING) is
variable char : character;
begin
if(L'length > 0) then
char := ' ';
while((char = ' ') and (L'length > 0)) loop -- Skip spaces
read(L, char);
end loop;
for i in X'low to X'high loop
X(i) := char;
if(char /= ' ') then
if(L'length > 0) then
read(L, char);
else
char := ' ';
end if;
end if;
end loop;
else
assert false report "Couldn't read a token from file"
severity error;
end if;
end read_token;
-----------------------------------------------------------------------------
-- *Module : sget_token
--
-- *Description : Same as read_token except for strings.
-----------------------------------------------------------------------------
procedure sget_token(S : in string; P : inout integer; X : out STRING) is
variable char : character;
begin
if(S'length > P) then
char := ' ';
while((char = ' ') and (S'length >= P)) loop -- Skip spaces
char := S(P);
P := P + 1;
end loop;
for i in X'low to X'high loop
X(i) := char;
if(char /= ' ') then
if(S'length > P) then
char := S(P);
P := P + 1;
else
char := ' ';
end if;
end if;
end loop;
else
assert false report "Couldn't read a token from a string"
severity error;
end if;
end sget_token;
-----------------------------------------------------------------------------
-- *Module : hex_char_to_vector
--
-- *Description : Convert a hex character to a vector
-----------------------------------------------------------------------------
function hex_char_to_vector(C : in character) return STD_ULOGIC_VECTOR is
variable X : STD_ULOGIC_VECTOR( 3 downto 0);
begin
case C is
when '0' => X := "0000";
when '1' => X := "0001";
when '2' => X := "0010";
when '3' => X := "0011";
when '4' => X := "0100";
when '5' => X := "0101";
when '6' => X := "0110";
when '7' => X := "0111";
when '8' => X := "1000";
when '9' => X := "1001";
when 'A' => X := "1010";
when 'B' => X := "1011";
when 'C' => X := "1100";
when 'D' => X := "1101";
when 'E' => X := "1110";
when 'F' => X := "1111";
when 'a' => X := "1010";
when 'b' => X := "1011";
when 'c' => X := "1100";
when 'd' => X := "1101";
when 'e' => X := "1110";
when 'f' => X := "1111";
when others =>
X := "0000";
assert false report "Invalid Hex Character"
severity error;
end case;
return(X);
end hex_char_to_vector;
-----------------------------------------------------------------------------
-- *Module : vector_to_hex_char
--
-- *Description : Convert a vector to a hex character. Only uses low 4 bits.
-----------------------------------------------------------------------------
function vector_to_hex_char(V : in STD_ULOGIC_VECTOR) return character is
variable C : character;
variable VV : STD_ULOGIC_VECTOR(3 downto 0);
begin
if(V'length < 4) then
VV := To_X01(V(V'low + 3 downto V'low));
else
VV := To_X01(V(V'low + V'length - 1 downto V'low));
end if;
case VV is
when "0000" => C := '0';
when "0001" => C := '1';
when "0010" => C := '2';
when "0011" => C := '3';
when "0100" => C := '4';
when "0101" => C := '5';
when "0110" => C := '6';
when "0111" => C := '7';
when "1000" => C := '8';
when "1001" => C := '9';
when "1010" => C := 'A';
when "1011" => C := 'B';
when "1100" => C := 'C';
when "1101" => C := 'D';
when "1110" => C := 'E';
when "1111" => C := 'F';
when others => C := 'X';
end case;
return(C);
end vector_to_hex_char;
-----------------------------------------------------------------------------
-- *Module : is_hex
--
-- *Description : report if a char is ASCII hex
-----------------------------------------------------------------------------
function is_hex(C : in character) return BOOLEAN is
variable X : boolean;
begin
case C is
when '0' => X := TRUE;
when '1' => X := TRUE;
when '2' => X := TRUE;
when '3' => X := TRUE;
when '4' => X := TRUE;
when '5' => X := TRUE;
when '6' => X := TRUE;
when '7' => X := TRUE;
when '8' => X := TRUE;
when '9' => X := TRUE;
when 'A' => X := TRUE;
when 'B' => X := TRUE;
when 'C' => X := TRUE;
when 'D' => X := TRUE;
when 'E' => X := TRUE;
when 'F' => X := TRUE;
when 'a' => X := TRUE;
when 'b' => X := TRUE;
when 'c' => X := TRUE;
when 'd' => X := TRUE;
when 'e' => X := TRUE;
when 'f' => X := TRUE;
when others =>
X := FALSE;
end case;
return(X);
end is_hex;
-----------------------------------------------------------------------------
-- *Module : hex_char_to_int
--
-- *Description : Convert a hex character to an integer
-----------------------------------------------------------------------------
function hex_char_to_int(C : in character) return integer is
variable X : integer;
begin
case C is
when '0' => X := 0;
when '1' => X := 1;
when '2' => X := 2;
when '3' => X := 3;
when '4' => X := 4;
when '5' => X := 5;
when '6' => X := 6;
when '7' => X := 7;
when '8' => X := 8;
when '9' => X := 9;
when 'A' => X := 10;
when 'B' => X := 11;
when 'C' => X := 12;
when 'D' => X := 13;
when 'E' => X := 14;
when 'F' => X := 15;
when 'a' => X := 10;
when 'b' => X := 11;
when 'c' => X := 12;
when 'd' => X := 13;
when 'e' => X := 14;
when 'f' => X := 15;
when others =>
X := 0;
assert false report "Invalid Hex Character"
severity error;
end case;
return(X);
end hex_char_to_int;
-----------------------------------------------------------------------------
-- *Module : read_vector
--
-- *Description : load a vector from the input line in a free floating format
-----------------------------------------------------------------------------
procedure read_vector(L : inout line; VEC : out STD_ULOGIC_VECTOR) is
variable char : character;
variable base : integer;
variable q : integer;
variable v : STD_ULOGIC_VECTOR(31 downto 0);
begin
if(L'length > 0) then
char := ' ';
while(char = ' ') loop -- Skip spaces
read(L, char);
end loop;
base := 16; -- Hex is the default
if(char = '%') then -- determine base
read(L, char);
if(char = 'b' or char = 'B') then
base := 2;
elsif(char = 'x' or char = 'X') then
base := 16;
elsif(char = 'd' or char = 'D') then
base := 10;
else
assert false report "Unsupported Base detected when reading a Vector"
severity error;
end if;
read(L, char);
end if;
q := 0;
if(is_hex(char)) then
q := q * base + hex_char_to_int(char);
while(is_hex(char) and not (L'length = 0)) loop
read(L, char);
if(is_hex(char)) then
q := q * base + hex_char_to_int(char);
end if;
end loop;
end if;
if(q < 0) then
q := q-2147483648;
V(30 downto 0) := to_vector(q, 31);
V(31) := '1';
else
V(30 downto 0) := to_vector(q, 31);
V(31) := '0';
end if;
VEC := V((VEC'high - VEC'low) downto 0);
else
assert false report "Couldn't read a vector"
severity error;
end if;
end read_vector;
-----------------------------------------------------------------------------
-- *Module : sget_vector
--
-- *Description : Same as sget_vector except for strings
-----------------------------------------------------------------------------
procedure sget_vector(S : in string; P : inout integer; VEC : out STD_ULOGIC_VECTOR) is
variable char : character;
variable base : integer;
variable q : integer;
variable v : STD_ULOGIC_VECTOR(31 downto 0);
begin
while(S(P) = ' ') loop -- Skip spaces
if(P >= S'length) then
P := S'length;
exit;
end if;
P := P + 1;
end loop;
if(S'length > P) then
char := S(P);
if(char = '"') then -- read in as a literal
q := v'high;
v := (others => 'U');
VEC := v(VEC'range);
char := ' ';
P := P + 1;
while((char /= '"') and not (S'length = P)) loop
char := S(P);
P := P + 1;
case char is
when '0' =>
v(q) := '0';
when '1' =>
v(q) := '1';
when 'L' | 'l' =>
v(q) := 'L';
when 'H' | 'h' =>
v(q) := 'H';
when 'Z' | 'z' =>
v(q) := 'Z';
when 'X' | 'x' =>
v(q) := 'X';
when 'U' | 'u' =>
v(q) := 'U';
when others =>
-- char := '"';
exit;
end case;
q := q - 1;
end loop;
if(v'high-q < 2) then -- only a single bit was read
VEC(VEC'low) := v(v'high);
elsif((v'high - q) > VEC'length) then -- too many bits
VEC := v(q+VEC'length downto q+1);
else -- the number of bits read is same or less than required
VEC(v'high-q-1+VEC'low downto VEC'low) := v(v'high downto q+1);
end if;
else
base := 16; -- Hex is the default
if(char = '%') then -- determine base
P := P + 1;
char := S(P);
P := P + 1;
if(char = 'b' or char = 'B') then
base := 2;
elsif(char = 'x' or char = 'X') then
base := 16;
elsif(char = 'd' or char = 'D') then
base := 10;
else
assert false report "Unsupported Base detected when reading a Vector"
severity error;
end if;
elsif((char = '0') and ((S(P+1) = 'x') or (S(P+1) = 'X'))) then
P := P + 2;
end if;
q := 0;
char := S(P);
if(is_hex(char)) then
while(is_hex(char) and not (S'length = P)) loop
if(is_hex(char)) then
q := q * base + hex_char_to_int(char);
end if;
P := P + 1;
char := S(P);
end loop;
end if;
if(q < 0) then
q := q-2147483648;
V(30 downto 0) := to_vector(q, 31);
V(31) := '1';
else
V(30 downto 0) := to_vector(q, 31);
V(31) := '0';
end if;
VEC := V((VEC'high - VEC'low) downto 0);
end if;
else
assert false report "Couldn't read a vector"
severity error;
V := (others => '0');
VEC := V((VEC'high - VEC'low) downto 0);
end if;
end sget_vector;
-----------------------------------------------------------------------------
-- *Module : sget_vector_64
--
-- *Description : Same as sget_vector except can handle 64 bit quantities and hex or binary base (no base 10)
-----------------------------------------------------------------------------
procedure sget_vector_64(S : in string; P : inout integer; VEC : out STD_ULOGIC_VECTOR) is
variable char : character;
variable base : integer;
variable q : integer;
variable v : STD_ULOGIC_VECTOR(63 downto 0);
begin
while(S(P) = ' ') loop -- Skip spaces
if(P >= S'length) then
P := S'length;
exit;
end if;
P := P + 1;
end loop;
if(S'length > P) then
char := S(P);
if(char = '"') then -- read in as a literal
q := v'high;
v := (others => 'U');
VEC := v(VEC'range);
char := ' ';
P := P + 1;
while((char /= '"') and not (S'length = P)) loop
char := S(P);
P := P + 1;
case char is
when '0' =>
v(q) := '0';
when '1' =>
v(q) := '1';
when 'L' | 'l' =>
v(q) := 'L';
when 'H' | 'h' =>
v(q) := 'H';
when 'Z' | 'z' =>
v(q) := 'Z';
when 'X' | 'x' =>
v(q) := 'X';
when 'U' | 'u' =>
v(q) := 'U';
when others =>
-- char := '"';
exit;
end case;
q := q - 1;
end loop;
if(v'high-q < 2) then -- only a single bit was read
VEC(VEC'low) := v(v'high);
elsif((v'high - q) > VEC'length) then -- too many bits
VEC := v(q+VEC'length downto q+1);
else -- the number of bits read is same or less than required
VEC(v'high-q-1+VEC'low downto VEC'low) := v(v'high downto q+1);
end if;
else
base := 16; -- Hex is the default
if(char = '%') then -- determine base
P := P + 1;
char := S(P);
P := P + 1;
if(char = 'b' or char = 'B') then
base := 2;
elsif(char = 'x' or char = 'X') then
base := 16;
else
assert false report "Unsupported Base detected when reading a Vector"
severity error;
end if;
char := S(P);
-- P := P + 1;
elsif((char = '0') and ((S(P+1) = 'x') or (S(P+1) = 'X'))) then
P := P + 2;
end if;
v := (others => '0');
char := S(P);
if(base = 2) then
while(((char = '0') or (char = '1')) and not (P > S'length)) loop
if(char = '0') then
v := v(v'high-1 downto 0) & '0';
else
v := v(v'high-1 downto 0) & '1';
end if;
P := P + 1;
char := S(P);
end loop;
else
while(is_hex(char) and not (P > S'length)) loop
if(is_hex(char)) then
v := v(v'high-4 downto 0) & hex_char_to_vector(char);
end if;
P := P + 1;
char := S(P);
end loop;
end if;
VEC := V((VEC'high - VEC'low) downto 0);
end if;
else
assert false report "Couldn't read a vector"
severity error;
V := (others => '0');
VEC := V((VEC'high - VEC'low) downto 0);
end if;
end sget_vector_64;
-----------------------------------------------------------------------------
-- *Module : read_int
--
-- *Description : load an integer from the input line in a free floating format
-----------------------------------------------------------------------------
procedure read_int(L : inout line; I : out integer) is
variable char : character;
variable base : integer;
variable q : integer;
begin
if(L'length > 0) then
char := ' ';
while(char = ' ') loop -- Skip spaces
read(L, char);
end loop;
base := 16; -- Hex is the default
if(char = '%') then -- determine base
read(L, char);
if(char = 'b' or char = 'B') then
base := 2;
elsif(char = 'x' or char = 'X') then
base := 16;
elsif(char = 'd' or char = 'D') then
base := 10;
else
assert false report "Unsupported Base detected when reading an integer"
severity error;
end if;
read(L, char);
end if;
q := 0;
if(is_hex(char)) then
q := q * base + hex_char_to_int(char);
while(is_hex(char) and not (L'length = 0)) loop
read(L, char);
if(is_hex(char)) then
q := q * base + hex_char_to_int(char);
end if;
end loop;
end if;
I := q;
else
assert false report "Couldn't read an integer"
severity error;
end if;
end read_int;
-----------------------------------------------------------------------------
-- *Module : sget_int
--
-- *Description : Same as read_int except for strings
-----------------------------------------------------------------------------
procedure sget_int(S : in string; P : inout integer; X : out integer) is
variable char : character;
variable base : integer;
variable q : integer;
begin
if(S'length > P) then
char := ' ';
while(char = ' ') loop -- Skip spaces
char := S(P);
P := P + 1;
end loop;
base := 16; -- Hex is the default
if(char = '%') then -- determine base
char := S(P);
P := P + 1;
if(char = 'b' or char = 'B') then
base := 2;
elsif(char = 'x' or char = 'X') then
base := 16;
elsif(char = 'd' or char = 'D') then
base := 10;
else
assert false report "Unsupported Base detected when reading an integer"
severity error;
end if;
char := S(P);
P := P + 1;
end if;
q := 0;
if(is_hex(char)) then
q := q * base + hex_char_to_int(char);
while(is_hex(char) and not (S'length = P)) loop
char := S(P);
P := P + 1;
if(is_hex(char)) then
q := q * base + hex_char_to_int(char);
end if;
end loop;
end if;
X := q;
else
assert false report "Couldn't read an integer"
severity error;
end if;
end sget_int;
-----------------------------------------------------------------------------
-- *Module : write_hex_vector
--
-- *Description : writes out a vector as hex
-----------------------------------------------------------------------------
procedure write_hex_vector(L : inout line; V : in STD_ULOGIC_VECTOR) is
variable C : character;
variable VV : STD_ULOGIC_VECTOR(((V'length + 3)/4) * 4 - 1 downto 0);
begin
VV := (others => '0');
VV(V'length -1 downto 0) := V;
for i in VV'length/4 - 1 downto 0 loop
C := vector_to_hex_char(VV(i*4+3 downto i*4));
write(L, C);
end loop;
end write_hex_vector;
-----------------------------------------------------------------------------
-- *Module : to_str
--
-- *Description : Converts a STD_ULOGIC_VECTOR to a string of the same length
-----------------------------------------------------------------------------
function to_str(constant V: in STD_ULOGIC_VECTOR) return STRING is
variable S : STRING(1 to V'length);
variable sp : integer;
begin
sp := 1;
for i in V'range loop
case V(i) is
when '1' | 'H' =>
S(sp) := '1';
when '0' | 'L' =>
S(sp) := '0';
when others =>
S(sp) := 'X';
end case;
sp := sp + 1;
end loop;
return(S);
end to_str;
-----------------------------------------------------------------------------
-- *Module : to_str
--
-- *Description : Converts a STD_ULOGIC to a string
-----------------------------------------------------------------------------
function to_str(constant V: in STD_ULOGIC) return STRING is
-- variable S : STRING(1);
begin
case V is
when '1' | 'H' =>
return("1");
when '0' | 'L' =>
return("0");
when others =>
return("X");
end case;
return("X");
end to_str;
-----------------------------------------------------------------------------
-- *Module : to_str
--
-- *Description : Converts a integer to a string
-----------------------------------------------------------------------------
function to_str(constant val : in INTEGER) return STRING is
variable result : STRING(11 downto 1) := "-2147483648"; -- smallest integer and longest string
variable tmp : INTEGER;
variable pos : NATURAL := 1;
variable digit : NATURAL;
begin
-- for the smallest integer MOD does not seem to work...
--if val = -2147483648 then : compilation error with Xilinx tools...
if val < -2147483647 then
pos := 12;
else
tmp := abs(val);
loop
digit := abs(tmp MOD 10);
tmp := tmp / 10;
result(pos) := character'val(character'pos('0') + digit);
pos := pos + 1;
exit when tmp = 0;
end loop;
if val < 0 then
result(pos) := '-';
pos := pos + 1;
end if;
end if;
return result((pos-1) downto 1);
end to_str;
-----------------------------------------------------------------------------
-- *Module : to_strn
--
-- *Description : Converts an integer to a string of length N
-----------------------------------------------------------------------------
function to_strn(constant val : in INTEGER; constant n : in INTEGER) return STRING is
variable result : STRING(11 downto 1) := "-2147483648"; -- smallest integer and longest string
variable tmp : INTEGER;
variable pos : NATURAL := 1;
variable digit : NATURAL;
begin
-- for the smallest integer MOD does not seem to work...
--if val = -2147483648 then : compilation error with Xilinx tools...
if val < -2147483647 then
pos := 12;
else
result := (others => ' ');
tmp := abs(val);
loop
digit := abs(tmp MOD 10);
tmp := tmp / 10;
result(pos) := character'val(character'pos('0') + digit);
pos := pos + 1;
exit when tmp = 0;
end loop;
if val < 0 then
result(pos) := '-';
pos := pos + 1;
end if;
end if;
return result(n downto 1);
end to_strn;
end textutil;
library ieee;
use ieee.std_logic_1164.all;
--library synopsys;
--use synopsys.arithmetic.all;
package UTIL is
function to_mvl ( b: in boolean ) return STD_ULOGIC;
function to_mvl ( i: in integer ) return STD_ULOGIC;
function to_vector(input,num_bits:integer) return STD_ULOGIC_VECTOR;
-- function to_signed( b: in std_ulogic_vector ) return signed;
-- function to_std_ulogic_vector( b: in signed ) return std_ulogic_vector;
-- function std_logic_to_std_ulogic( b: in std_logic ) return std_ulogic;
-- function std_ulogic_to_std_logic( b: in std_ulogic ) return std_logic;
function "and"(l: STD_ULOGIC_VECTOR; r: STD_ULOGIC) return STD_ULOGIC_VECTOR;
function "and"(l: STD_ULOGIC; r: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
function "and"(l: STD_ULOGIC_VECTOR; r: BOOLEAN) return STD_ULOGIC_VECTOR;
function "and"(l: BOOLEAN; r: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
function "and"(l: BOOLEAN; r: STD_ULOGIC) return STD_ULOGIC;
function "and"(l: STD_ULOGIC; r: BOOLEAN) return STD_ULOGIC;
function exp(input: STD_ULOGIC; num_bits: integer) return STD_ULOGIC_VECTOR;
function exp(input: STD_ULOGIC_VECTOR; num_bits: integer) return STD_ULOGIC_VECTOR;
function conv_integer ( ARG: in STD_ULOGIC_VECTOR ) return integer;
function "+"(l: STD_ULOGIC_VECTOR; r: STD_ULOGIC) return STD_ULOGIC_VECTOR;
-- function "+"(l: STD_ULOGIC_VECTOR; r: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
-- function "-"(l: STD_ULOGIC_VECTOR; r: STD_ULOGIC) return STD_ULOGIC_VECTOR;
-- function "-"(l: STD_ULOGIC_VECTOR; r: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
function to_int(l: std_ulogic_vector) return natural;
function to_int(l: std_ulogic) return natural;
function and_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC;
function nand_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC;
function or_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC;
function nor_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC;
function xor_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC;
function xnor_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC;
function ge ( l, r : STD_ULOGIC_VECTOR ) return BOOLEAN;
function gt ( l, r : STD_ULOGIC_VECTOR ) return BOOLEAN;
function lt ( l, r : STD_ULOGIC_VECTOR ) return BOOLEAN;
function eq ( l, r : STD_ULOGIC_VECTOR ) return BOOLEAN;
function maximum ( arg1, arg2 : INTEGER) return INTEGER;
function minimum ( arg1, arg2 : INTEGER) return INTEGER;
procedure keep(signal X: inout STD_LOGIC);
function log2(A: in integer) return integer;
-------------------------------------------------------------------
-- Declaration of Synthesis directive attributes
-------------------------------------------------------------------
ATTRIBUTE synthesis_return : string ;
end UTIL;
package body UTIL is
--------------------------------------------------------------------
-- function to_signed ( b: in std_ulogic_vector ) return signed is
-- variable result : signed(b'range);
-- begin
-- for i in b'range loop
-- result(i) := b(i);
-- end loop;
-- return result;
-- end to_signed;
--------------------------------------------------------------------
-- function to_std_ulogic_vector ( b: in signed ) return std_ulogic_vector is
-- variable result : std_ulogic_vector(b'range);
-- begin
-- for i in b'range loop
-- result(i) := b(i);
-- end loop;
-- return result;
-- end to_std_ulogic_vector;
--------------------------------------------------------------------
function to_mvl ( b: in boolean ) return STD_ULOGIC is
begin
if ( b = TRUE ) then
return( '1' );
else
return( '0' );
end if;
end to_mvl;
--------------------------------------------------------------------
function to_mvl ( i: in integer ) return STD_ULOGIC is
begin
if ( i = 1 ) then
return( '1' );
else
return( '0' );
end if;
end to_mvl;
--------------------------------------------------------------------
function "and"(l: STD_ULOGIC; r: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
variable rr: STD_ULOGIC_vector(r'range);
begin
if (l = '1') then
rr := r;
else
rr := (others => '0');
end if;
return(rr);
end;
--------------------------------------------------------------------
function "and"(l: STD_ULOGIC_VECTOR; r: STD_ULOGIC) return STD_ULOGIC_VECTOR is
variable ll: STD_ULOGIC_vector(l'range);
begin
if (r = '1') then
ll := l;
else
ll := (others => '0');
end if;
return(ll);
end;
--------------------------------------------------------------------
function "and"(l: BOOLEAN; r: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
variable rr: STD_ULOGIC_vector(r'range);
begin
if (l) then
rr := r;
else
rr := (others => '0');
end if;
return(rr);
end;
--------------------------------------------------------------------
function "and"(l: STD_ULOGIC_VECTOR; r: BOOLEAN) return STD_ULOGIC_VECTOR is
variable ll: STD_ULOGIC_vector(l'range);
begin
if (r) then
ll := l;
else
ll := (others => '0');
end if;
return(ll);
end;
--------------------------------------------------------------------
function "and"(l: BOOLEAN; r: STD_ULOGIC) return STD_ULOGIC is
variable ll: STD_ULOGIC;
begin
if (l) then
ll := r;
else
ll := '0';
end if;
return(ll);
end;
--------------------------------------------------------------------
function "and"(l: STD_ULOGIC; r: BOOLEAN) return STD_ULOGIC is
variable ll: STD_ULOGIC;
begin
if (r) then
ll := l;
else
ll := '0';
end if;
return(ll);
end;
--------------------------------------------------------------------
-- function std_ulogic_to_std_logic(b : std_ulogic) return std_logic is
-- variable result: std_logic;
-- begin
-- result := b;
-- return result;
-- end;
--------------------------------------------------------------------
-- function std_logic_to_std_ulogic(b : std_logic) return std_ulogic is
-- variable result: std_ulogic;
-- begin
-- result := b;
-- return result;
-- end;
--------------------------------------------------------------------
function to_vector(input,num_bits: integer) return std_ulogic_vector is
variable vec: std_ulogic_vector(num_bits-1 downto 0);
variable a: integer;
begin
a := input;
for i in 0 to num_bits-1 loop
if ((a mod 2) = 1) then
vec(i) := '1';
else
vec(i) := '0';
end if;
a := a / 2;
end loop;
return vec;
end to_vector;
-- FUNCTION to_vector(input,num_bits:integer) RETURN STD_ULOGIC_VECTOR IS
-- VARIABLE result:STD_ULOGIC_VECTOR(num_bits-1 DOWNTO 0);
-- VARIABLE weight:integer;
-- VARIABLE temp:integer;
-- BEGIN
-- weight := 2**(num_bits-1);
-- temp := input;
-- FOR i in result'HIGH DOWNTO result'LOW LOOP
-- IF temp >= weight THEN
-- result(i) := '1';
-- temp := temp - weight;
-- ELSE
-- result(i) := '0';
-- END IF;
-- weight := weight/2;
-- END LOOP;
-- RETURN result;
-- END to_vector;
--------------------------------------------------------------------
-- exp: Expand one bit into many
--------------------------------------------------------------------
FUNCTION exp(input:STD_ULOGIC; num_bits:integer) RETURN STD_ULOGIC_VECTOR IS
VARIABLE result:STD_ULOGIC_VECTOR(num_bits-1 DOWNTO 0);
BEGIN
FOR i in result'HIGH DOWNTO result'LOW LOOP
result(i) := input;
END LOOP;
RETURN result;
END exp;
--------------------------------------------------------------------
-- exp: Expand n bits into m bits
--------------------------------------------------------------------
FUNCTION exp(input:STD_ULOGIC_VECTOR; num_bits:integer) RETURN STD_ULOGIC_VECTOR IS
VARIABLE result:STD_ULOGIC_VECTOR(num_bits-1 DOWNTO 0);
BEGIN
result(input'high-input'low downto 0) := input;
result(num_bits-1 downto input'high-input'low+1) := (others => '0');
RETURN result;
END exp;
--------------------------------------------------------------------
-- conv_integer
--------------------------------------------------------------------
function conv_integer ( ARG: in STD_ULOGIC_VECTOR ) return integer is
variable result: INTEGER;
begin
assert ARG'length <= 31
report "ARG is too large in CONV_INTEGER"
severity FAILURE;
result := 0;
for i in ARG'range loop
result := result * 2;
if(ARG(i) = 'H' or ARG(i) = '1') then
result := result + 1;
end if;
end loop;
return result;
end;
--------------------------------------------------------------------
-- "+" Increment function
--------------------------------------------------------------------
function "+"(L: STD_ULOGIC_VECTOR; R: STD_ULOGIC) return STD_ULOGIC_VECTOR is
variable Q: STD_ULOGIC_VECTOR(L'range);
variable A: STD_ULOGIC;
begin
A := R;
for i in L'low to L'high loop
Q(i) := L(i) xor A;
A := A and L(i);
end loop;
return Q;
end;
--------------------------------------------------------------------
-- "+" adder function
--------------------------------------------------------------------
-- function "+"(L: STD_ULOGIC_VECTOR; R: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
-- variable Q : SIGNED(L'range);
-- variable result: STD_ULOGIC_VECTOR(L'range);
-- begin
-- Q := to_signed(L) + to_signed(R);
-- result := to_std_ulogic_vector(Q);
-- return result;
-- end;
--------------------------------------------------------------------
-- "-" Decrement function
--------------------------------------------------------------------
-- function "-"(L: STD_ULOGIC_VECTOR; R: STD_ULOGIC) return STD_ULOGIC_VECTOR is
-- variable Q: STD_ULOGIC_VECTOR(L'range);
-- variable A: STD_ULOGIC;
-- begin
-- A := R;
-- for i in L'low to L'high loop
-- Q(i) := L(i) xor A;
-- A := A and not L(i);
-- end loop;
-- return Q;
-- end;
--------------------------------------------------------------------
-- "-" subtractor function
--------------------------------------------------------------------
-- function "-"(L: STD_ULOGIC_VECTOR; R: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
-- variable Q : SIGNED(L'range);
-- variable result: STD_ULOGIC_VECTOR(L'range);
-- begin
-- Q := to_signed(L) - to_signed(R);
-- result := to_std_ulogic_vector(Q);
-- return result;
-- end;
--------------------------------------------------------------------
-- to_int : Convert std_ulogic_vector to an integer
--------------------------------------------------------------------
function to_int(l: std_ulogic_vector) return natural is
variable result: natural := 0;
begin
for t1 in l'range loop
result := result * 2;
if (l(t1) = '1') or (l(t1) = 'H') then
result := result + 1;
end if;
end loop;
return result;
end to_int;
--------------------------------------------------------------------
-- to_int : Convert std_ulogic_vector to an integer
--------------------------------------------------------------------
function to_int(l: std_ulogic) return natural is
variable result: natural := 0;
begin
if (l = '1') or (l = 'H') then
result := 1;
else
result := 0;
end if;
return result;
end to_int;
--------------------------------------------------------------------
-- Reduce Functions
--------------------------------------------------------------------
function and_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC is
variable result: STD_ULOGIC;
begin
result := '1';
for i in ARG'range loop
result := result and ARG(i);
end loop;
return result;
end;
function nand_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC is
begin
return not and_reduce(ARG);
end;
function or_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC is
variable result: STD_ULOGIC;
begin
result := '0';
for i in ARG'range loop
result := result or ARG(i);
end loop;
return result;
end;
function nor_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC is
begin
return not or_reduce(ARG);
end;
function xor_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC is
variable result: STD_ULOGIC;
begin
result := '0';
for i in ARG'range loop
result := result xor ARG(i);
end loop;
return result;
end;
function xnor_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC is
begin
return not xor_reduce(ARG);
end;
--------------------------------------------------------------------
-- Some useful generic functions
--------------------------------------------------------------------
--//// Zero Extend ////
--
-- Function zxt
--
FUNCTION zxt( q : STD_ULOGIC_VECTOR; i : INTEGER ) RETURN STD_ULOGIC_VECTOR IS
VARIABLE qs : STD_ULOGIC_VECTOR (1 TO i);
VARIABLE qt : STD_ULOGIC_VECTOR (1 TO q'length);
-- Hidden function. Synthesis directives are present in its callers
BEGIN
qt := q;
IF i < q'length THEN
qs := qt( (q'length-i+1) TO qt'right);
ELSIF i > q'length THEN
qs := (OTHERS=>'0');
qs := qs(1 TO (i-q'length)) & qt;
ELSE
qs := qt;
END IF;
RETURN qs;
END;
FUNCTION maximum (arg1,arg2:INTEGER) RETURN INTEGER IS
BEGIN
IF(arg1 > arg2) THEN
RETURN(arg1) ;
ELSE
RETURN(arg2) ;
END IF;
END ;
FUNCTION minimum (arg1,arg2:INTEGER) RETURN INTEGER IS
BEGIN
IF(arg1 < arg2) THEN
RETURN(arg1) ;
ELSE
RETURN(arg2) ;
END IF;
END ;
--------------------------------------------------------------------
-- Comparision functions
--------------------------------------------------------------------
--
-- Equal functions.
--
TYPE stdlogic_boolean_table IS ARRAY(std_ulogic, std_ulogic) OF BOOLEAN;
CONSTANT eq_table : stdlogic_boolean_table := (
--
----------------------------------------------------------------------------
-- | U X 0 1 Z W L H D | |
--
----------------------------------------------------------------------------
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | U |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | X |
( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | 0 |
( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | 1 |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | Z |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | W |
( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | L |
( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | H |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ) -- | D |
);
FUNCTION eq ( l, r : STD_LOGIC ) RETURN BOOLEAN IS
-- Equal for two logic types
VARIABLE result : BOOLEAN ;
ATTRIBUTE synthesis_return OF result:VARIABLE IS "EQ" ;
BEGIN
result := eq_table( l, r );
RETURN result ;
END;
FUNCTION eq ( l,r : STD_ULOGIC_VECTOR ) RETURN BOOLEAN IS
CONSTANT ml : INTEGER := maximum( l'length, r'length );
VARIABLE lt : STD_ULOGIC_VECTOR ( 1 TO ml );
VARIABLE rt : STD_ULOGIC_VECTOR ( 1 TO ml );
-- Arithmetic Equal for two Unsigned vectors
VARIABLE result : BOOLEAN ;
ATTRIBUTE synthesis_return OF result:VARIABLE IS "EQ" ;
BEGIN
lt := zxt( l, ml );
rt := zxt( r, ml );
FOR i IN lt'range LOOP
IF NOT eq( lt(i), rt(i) ) THEN
result := FALSE;
RETURN result ;
END IF;
END LOOP;
RETURN TRUE;
END;
TYPE std_ulogic_fuzzy_state IS ('U', 'X', 'T', 'F', 'N');
TYPE std_ulogic_fuzzy_state_table IS ARRAY ( std_ulogic, std_ulogic ) OF std_ulogic_fuzzy_state;
CONSTANT ge_fuzzy_table : std_ulogic_fuzzy_state_table := (
-- ----------------------------------------------------
-- | U X 0 1 Z W L H D | |
-- ----------------------------------------------------
( 'U', 'U', 'N', 'U', 'U', 'U', 'N', 'U', 'U' ), -- | U |
( 'U', 'X', 'N', 'X', 'X', 'X', 'N', 'X', 'X' ), -- | X |
( 'U', 'X', 'N', 'F', 'X', 'X', 'N', 'F', 'X' ), -- | 0 |
( 'N', 'N', 'T', 'N', 'N', 'N', 'T', 'N', 'N' ), -- | 1 |
( 'U', 'X', 'N', 'X', 'X', 'X', 'N', 'X', 'X' ), -- | Z |
( 'U', 'X', 'N', 'X', 'X', 'X', 'N', 'X', 'X' ), -- | W |
( 'U', 'X', 'N', 'F', 'X', 'X', 'N', 'F', 'X' ), -- | L |
( 'N', 'N', 'T', 'N', 'N', 'N', 'T', 'N', 'N' ), -- | H |
( 'U', 'X', 'N', 'X', 'X', 'X', 'N', 'X', 'X' ) -- | D |
);
FUNCTION ge ( L,R : std_ulogic_vector ) RETURN boolean IS
CONSTANT ml : integer := maximum( L'LENGTH, R'LENGTH );
VARIABLE lt : std_ulogic_vector ( 1 to ml );
VARIABLE rt : std_ulogic_vector ( 1 to ml );
VARIABLE res : std_ulogic_fuzzy_state;
-- Greater-than-or-equal for two Unsigned vectors
VARIABLE result : BOOLEAN ;
ATTRIBUTE synthesis_return OF result:VARIABLE IS "GTE" ;
begin
lt := zxt( l, ml );
rt := zxt( r, ml );
FOR i IN lt'RANGE LOOP
res := ge_fuzzy_table( lt(i), rt(i) );
CASE res IS
WHEN 'U' => RETURN FALSE;
WHEN 'X' => RETURN FALSE;
WHEN 'T' => RETURN TRUE;
WHEN 'F' => RETURN FALSE;
WHEN OTHERS => null;
END CASE;
END LOOP;
result := TRUE ;
RETURN result;
end ;
--
-- Greater Than functions.
--
CONSTANT gtb_table : stdlogic_boolean_table := (
--
----------------------------------------------------------------------------
-- | U X 0 1 Z W L H D | |
--
----------------------------------------------------------------------------
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | U |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | X |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | 0 |
( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | 1 |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | Z |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | W |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | L |
( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | H |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ) -- | D |
);
FUNCTION gt ( l, r : std_logic ) RETURN BOOLEAN IS
-- Greater-than for two logic types
VARIABLE result : BOOLEAN ;
ATTRIBUTE synthesis_return OF result:VARIABLE IS "GT" ;
BEGIN
result := gtb_table( l, r );
RETURN result ;
END ;
FUNCTION gt ( l,r : STD_ULOGIC_VECTOR ) RETURN BOOLEAN IS
CONSTANT ml : INTEGER := maximum( l'length, r'length );
VARIABLE lt : STD_ULOGIC_VECTOR ( 1 TO ml );
VARIABLE rt : STD_ULOGIC_VECTOR ( 1 TO ml );
-- Greater-than for two logic unsigned vectors
VARIABLE result : BOOLEAN ;
ATTRIBUTE synthesis_return OF result:VARIABLE IS "GT" ;
BEGIN
lt := zxt( l, ml );
rt := zxt( r, ml );
FOR i IN lt'range LOOP
IF NOT eq( lt(i), rt(i) ) THEN
result := gt( lt(i), rt(i) );
RETURN result ;
END IF;
END LOOP;
RETURN FALSE;
END;
--
-- Less Than functions.
--
CONSTANT ltb_table : stdlogic_boolean_table := (
--
----------------------------------------------------------------------------
-- | U X 0 1 Z W L H D | |
--
----------------------------------------------------------------------------
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | U |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | X |
( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | 0 |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | 1 |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | Z |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | W |
( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | L |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | H |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ) -- | D |
);
FUNCTION lt ( l, r : STD_LOGIC ) RETURN BOOLEAN IS
-- Less-than for two logic types
VARIABLE result : BOOLEAN ;
ATTRIBUTE synthesis_return OF result:VARIABLE IS "LT" ;
BEGIN
result := ltb_table( l, r );
RETURN result ;
END;
FUNCTION lt ( l,r : STD_ULOGIC_VECTOR ) RETURN BOOLEAN IS
CONSTANT ml : INTEGER := maximum( l'length, r'length );
VARIABLE ltt : STD_ULOGIC_VECTOR ( 1 TO ml );
VARIABLE rtt : STD_ULOGIC_VECTOR ( 1 TO ml );
-- Less-than for two Unsigned vectors
VARIABLE result : BOOLEAN ;
ATTRIBUTE synthesis_return OF result:VARIABLE IS "LT" ;
BEGIN
ltt := zxt( l, ml );
rtt := zxt( r, ml );
FOR i IN ltt'range LOOP
IF NOT eq( ltt(i), rtt(i) ) THEN
result := lt( ltt(i), rtt(i) );
RETURN result ;
END IF;
END LOOP;
RETURN FALSE;
END;
--------------------------------------------------------------------
-- "keep" Retain Last value when floated
--------------------------------------------------------------------
procedure keep(signal X: inout STD_LOGIC) is
begin
if(X = 'Z') then
if(X'last_value = '0') then
X <= 'L';
elsif(X'last_value = '1') then
X <= 'H';
else
X <= 'Z';
end if;
else
X <= 'Z';
end if;
end keep;
---------------------------------------------------------------------
-- log base 2 function
---------------------------------------------------------------------
function log2 ( A: in integer ) return integer is
variable B : integer;
begin
B := 1;
for i in 0 to 31 loop
if not ( A > B ) then
return ( i );
exit;
end if;
B := B * 2;
end loop;
end log2;
end UTIL;
-------------------------------------------------------------------------------
-- simple.vec
-- Short example of using the lambo TestBench
-------------------------------------------------------------------------------
-- Select the GN4124 Primary BFM
model 0
-- Initialize the BFM to its default state
init
-- Drive reset to the FPGA
reset 10
-------------------------------------------------------------------------------
-- Initialize the Primary GN412x BFM model
-------------------------------------------------------------------------------
-- These address ranges will generate traffic from the Primary to the Secondary BFM
-- bar BAR ADDR SIZE VC TC S
bar 0 FF00000010000000 08000000 0 7 0
bar 1 FF000000A0000000 10000000 1 5 0
-- This allocates a RAM block inside the BFM for the FPGA to access
-- bfm_bar BAR ADDR SIZE
bfm_bar 0 8765432120000000 20000000
bfm_bar 1 BB00000040000000 20000000
-- Wait until the FPGA is un-reset and ready for traffic on the local bus
wait 40
-------------------------------------------------------------------------------
-- Access the descriptor memory in the Lambo design
-------------------------------------------------------------------------------
-- the following three writes will go out in a single packet
wrb FF00000010004000 F 87654321
wrb FF00000010004004 F FEEDFACE
wr FF00000010004008 F DEADBEEF
-- Now read back what was just written
-- the following three reads will go out as a single request
rdb FF00000010004000 F 87654321 FFFFFFFF
rdb FF00000010004004 F FEEDFACE FFFFFFFF
rd FF00000010004008 F DEADBEEF FFFFFFFF
flush 100
wait 10
sync
-------------------------------------------------------------------------------
-- File: simple.vec
-- Short example of using the lambo TestBench
-------------------------------------------------------------------------------
-- Select the GN4124 Primary BFM
model %d0
-- Initialize the BFM to its default state
init
-- Drive reset to the FPGA
reset %d16
-------------------------------------------------------------------------------
-- Initialize the Primary GN412x BFM model
-------------------------------------------------------------------------------
-- These address ranges will generate traffic from the BFM to the FPGA
-- bar BAR ADDR SIZE VC TC S
bar 0 FF00000010000000 08000000 0 7 0
bar 1 FF000000A0000000 10000000 1 5 0
-- This allocates a RAM block inside the BFM for the FPGA to access
-- bfm_bar BAR ADDR SIZE
bfm_bar 0 8765432120000000 20000000
bfm_bar 1 BB00000040000000 20000000
-- Wait until the FPGA is un-reset and ready for traffic on the local bus
wait %d64
-------------------------------------------------------------------------------
-- Access the descriptor memory in the Lambo design
-------------------------------------------------------------------------------
-- the following three writes will go out in a single packet
wrb FF00000010004000 F 87654321
wrb FF00000010004004 F FEEDFACE
wr FF00000010004008 F DEADBEEF
-- Now read back what was just written
-- the following three reads will go out as a single request
rdb FF00000010004000 F 87654321 FFFFFFFF
rdb FF00000010004004 F FEEDFACE FFFFFFFF
rd FF00000010004008 F DEADBEEF FFFFFFFF
flush %d256
wait %d16
sync
-------------------------------------------------------------------------------
-- A simple Lambo DMA Test
-------------------------------------------------------------------------------
-- Select the GN4124 Primary BFM
model %d0
init
reset %d16
-------------------------------------------------------------------------------
-- Initialize the Primary GN412x BFM model
-------------------------------------------------------------------------------
-- These address ranges will generate traffic from the Primary to the Secondary BFM
-- bar BAR ADDR SIZE VC TC S
bar 0 FF00000010000000 08000000 0 7 0
bar 1 FF000000A0000000 10000000 1 5 0
-- This allocates a RAM block inside the BFM for the FPGA to access
-- bfm_bar BAR ADDR SIZE
bfm_bar 0 8765432120000000 20000000
bfm_bar 1 BB00000040000000 20000000
cpl_modulo %d32
sync
wait 40
-------------------------------------------------------------------------------
-- DO some setup
-------------------------------------------------------------------------------
-- Lambo setup...
rd FF00000010000030 0xf 0x00000000
flush 100
wr FF00000010000020 0xf 0x0
wr FF00000010000014 0xf 0x0
wr FF0000001000000c 0xf 0xffffffff
wr FF00000010000054 0xf 0x6
wr FF00000010000054 0xf 0x0
wr FF00000010000004 0xf 0x1f
wr FF00000010000004 0xf 0x7
wr FF00000010000058 0xf 0x0
wr FF0000001000005c 0xf 0x0
wr FF00000010000060 0xf 0x0
wr FF00000010000034 0xf 0x8020
-------------------------------------------------------------------------------
-- Do some DMA (this comes from the VDMA builder utility)
-------------------------------------------------------------------------------
-- 0x0000 0x00000000 MAIN: vdma_nop()
wrb FF00000010004000 F 00000000
-- 0x0001 0x40000100 DO_L2P0: vdma_load_sys_addr(r=_IM, "L2P0_SYS_ADDR")
wrb FF00000010004004 F 40000100
-- 0x0002 0xF0000102 vdma_load_xfer_ctl(_IM, "L2P0_XFER_CTL")
wrb FF00000010004008 F F0000102
-- 0x0003 0x40000103 DO_L2P1: vdma_load_sys_addr(r=_IM, "L2P1_SYS_ADDR")
wrb FF0000001000400C F 40000103
-- 0x0004 0xF0000105 vdma_load_xfer_ctl(_IM, "L2P1_XFER_CTL")
wrb FF00000010004010 F F0000105
-- 0x0005 0x17210005 WAIT4IDLE: vdma_jmp(c=_EXT_COND_LO, ext_cond=_LDM_IDLE, "WAIT4IDLE")
wrb FF00000010004014 F 17210005
-- 0x0006 0x00000000 FOREVER: vdma_nop()
wrb FF00000010004018 F 00000000
-- 0x0007 0x1A000006 vdma_jmp(c=_ALWAYS, ext_cond=NA, "FOREVER")
wrb FF0000001000401C F 1A000006
-- 0x0100 0x20012000 L2P0_SYS_ADDR: vdma_constant_n(0x20012000)
wrb FF00000010004400 F 20012000
-- 0x0101 0x87654321 vdma_constant_n(0x87654321)
wrb FF00000010004404 F 87654321
-- 0x0102 0x00010080 L2P0_XFER_CTL: vdma_constant_n(0x10080)
wrb FF00000010004408 F 00010080
-- 0x0103 0x40034000 L2P1_SYS_ADDR: vdma_constant_n(0x40034000)
wrb FF0000001000440C F 40034000
-- 0x0104 0xBB000000 vdma_constant_n(0xBB000000)
wrb FF00000010004410 F BB000000
-- 0x0105 0x00040080 L2P1_XFER_CTL: vdma_constant_n(0x40080)
wrb FF00000010004414 F 00040080
-- Start VDMA
wr FF00000010000030 F 1
-- Read VDMA idle status
rd FF00000010000030 F 0
flush 100
wait 10
sync
-------------------------------------------------------------------------------
-- A simple Lambo DMA Test
-------------------------------------------------------------------------------
-- Select the GN4124 Primary BFM
model 0
init
reset 10
-------------------------------------------------------------------------------
-- Initialize the Primary GN412x BFM model
-------------------------------------------------------------------------------
-- These address ranges will generate traffic from the Primary to the Secondary BFM
-- bar BAR ADDR SIZE VC TC S
bar 0 FF00000010000000 08000000 0 7 0
bar 1 FF000000A0000000 10000000 1 5 0
-- This allocates a RAM block inside the BFM for the FPGA to access
-- bfm_bar BAR ADDR SIZE
bfm_bar 0 8765432120000000 20000000
bfm_bar 1 BB00000040000000 20000000
cpl_modulo %d32
sync
wait 40
-------------------------------------------------------------------------------
-- DO some setup
-------------------------------------------------------------------------------
-- Lambo setup...
rd FF00000010000030 0xf 0x00000000
flush 100
wr FF00000010000020 0xf 0x0
wr FF00000010000014 0xf 0x0
wr FF0000001000000c 0xf 0xffffffff
wr FF00000010000054 0xf 0x6
wr FF00000010000054 0xf 0x0
wr FF00000010000004 0xf 0x1f
wr FF00000010000004 0xf 0x7
wr FF00000010000058 0xf 0x0
wr FF0000001000005c 0xf 0x0
wr FF00000010000060 0xf 0x0
wr FF00000010000034 0xf 0x8020
-------------------------------------------------------------------------------
-- Do some DMA (this comes from the VDMA builder utility)
-------------------------------------------------------------------------------
-- 0x0000 0x00000000 MAIN: vdma_nop()
wrb FF00000010004000 F 00000000
-- 0x0001 0x40000100 DO_L2P0: vdma_load_sys_addr(r=_IM, "L2P0_SYS_ADDR")
wrb FF00000010004004 F 40000100
-- 0x0002 0xF0000102 vdma_load_xfer_ctl(_IM, "L2P0_XFER_CTL")
wrb FF00000010004008 F F0000102
-- 0x0003 0x40000103 DO_L2P1: vdma_load_sys_addr(r=_IM, "L2P1_SYS_ADDR")
wrb FF0000001000400C F 40000103
-- 0x0004 0xF0000105 vdma_load_xfer_ctl(_IM, "L2P1_XFER_CTL")
wrb FF00000010004010 F F0000105
-- 0x0005 0x17210005 WAIT4IDLE: vdma_jmp(c=_EXT_COND_LO, ext_cond=_LDM_IDLE, "WAIT4IDLE")
wrb FF00000010004014 F 17210005
-- 0x0006 0x00000000 FOREVER: vdma_nop()
wrb FF00000010004018 F 00000000
-- 0x0007 0x1A000006 vdma_jmp(c=_ALWAYS, ext_cond=NA, "FOREVER")
wrb FF0000001000401C F 1A000006
-- 0x0100 0x20012000 L2P0_SYS_ADDR: vdma_constant_n(0x20012000)
wrb FF00000010004400 F 20012000
-- 0x0101 0x87654321 vdma_constant_n(0x87654321)
wrb FF00000010004404 F 87654321
-- 0x0102 0x00010080 L2P0_XFER_CTL: vdma_constant_n(0x10080)
wrb FF00000010004408 F 00010080
-- 0x0103 0x40034000 L2P1_SYS_ADDR: vdma_constant_n(0x40034000)
wrb FF0000001000440C F 40034000
-- 0x0104 0xBB000000 vdma_constant_n(0xBB000000)
wrb FF00000010004410 F BB000000
-- 0x0105 0x00040080 L2P1_XFER_CTL: vdma_constant_n(0x40080)
wrb FF00000010004414 F 00040080
-- Start VDMA
wr FF00000010000030 F 1
-- Read VDMA idle status
rd FF00000010000030 F 0
flush 100
wait 10
sync
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate -divider {Local bus}
add wave -noupdate -radix hexadecimal /tb_spec/u1/l2p_clkp
add wave -noupdate -radix hexadecimal /tb_spec/u1/l2p_clkn
add wave -noupdate -radix hexadecimal /tb_spec/u1/l2p_data
add wave -noupdate -radix hexadecimal /tb_spec/u1/l2p_valid
add wave -noupdate -radix hexadecimal /tb_spec/u1/l2p_dframe
add wave -noupdate -radix hexadecimal /tb_spec/u1/l2p_edb
add wave -noupdate -radix hexadecimal /tb_spec/u1/l2p_rdy
add wave -noupdate -radix hexadecimal /tb_spec/u1/l_wr_rdy
add wave -noupdate -radix hexadecimal /tb_spec/u1/p2l_clkn
add wave -noupdate -radix hexadecimal /tb_spec/u1/p2l_clkp
add wave -noupdate -radix hexadecimal /tb_spec/u1/p2l_data
add wave -noupdate -radix hexadecimal /tb_spec/u1/p2l_valid
add wave -noupdate -radix hexadecimal /tb_spec/u1/p2l_dframe
add wave -noupdate -radix hexadecimal /tb_spec/u1/p2l_pll_locked
add wave -noupdate -radix hexadecimal /tb_spec/u1/p2l_rdy
add wave -noupdate -radix hexadecimal /tb_spec/u1/p_rd_d_rdy
add wave -noupdate -radix hexadecimal /tb_spec/u1/p_wr_rdy
add wave -noupdate -radix hexadecimal /tb_spec/u1/p_wr_req
add wave -noupdate -radix hexadecimal /tb_spec/u1/rx_error
add wave -noupdate -radix hexadecimal /tb_spec/u1/tx_error
add wave -noupdate -radix hexadecimal /tb_spec/u1/vc_rdy
add wave -noupdate -divider {P2L des}
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/cmp_p2l_des/p2l_data_i
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/cmp_p2l_des/p2l_dframe_i
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/cmp_p2l_des/p2l_valid_i
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/cmp_p2l_des/p2l_data_o
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/cmp_p2l_des/p2l_dframe_o
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/cmp_p2l_des/p2l_valid_o
add wave -noupdate -divider {L2P ser}
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/cmp_l2p_ser/rst_n_i
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/cmp_l2p_ser/l2p_data_i
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/cmp_l2p_ser/l2p_dframe_i
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/cmp_l2p_ser/l2p_valid_i
add wave -noupdate /tb_spec/u1/cmp_gn4124_core/cmp_l2p_ser/l2p_clk_p_o
add wave -noupdate /tb_spec/u1/cmp_gn4124_core/cmp_l2p_ser/l2p_clk_n_o
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/cmp_l2p_ser/l2p_data_o
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/cmp_l2p_ser/l2p_valid_o
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/cmp_l2p_ser/l2p_dframe_o
add wave -noupdate -divider {Gennum core arbiter}
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/pdm_arb_req
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/pdm_arb_data
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/pdm_arb_dframe
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/pdm_arb_valid
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/ldm_arb_req
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/ldm_arb_data
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/ldm_arb_dframe
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/ldm_arb_valid
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/wbm_arb_req
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/wbm_arb_data
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/wbm_arb_dframe
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/wbm_arb_valid
add wave -noupdate -divider {CSR wishbone master}
add wave -noupdate /tb_spec/u1/cmp_gn4124_core/cmp_wbmaster32/wishbone_current_state
add wave -noupdate -radix hexadecimal /tb_spec/u1/wbm_ack
add wave -noupdate -radix hexadecimal /tb_spec/u1/wbm_adr
add wave -noupdate -radix hexadecimal /tb_spec/u1/wbm_cyc
add wave -noupdate -radix hexadecimal /tb_spec/u1/wbm_dat_i
add wave -noupdate -radix hexadecimal /tb_spec/u1/wbm_dat_o
add wave -noupdate -radix hexadecimal /tb_spec/u1/wbm_sel
add wave -noupdate -radix hexadecimal /tb_spec/u1/wbm_stall
add wave -noupdate -radix hexadecimal /tb_spec/u1/wbm_stb
add wave -noupdate -radix hexadecimal /tb_spec/u1/wbm_we
add wave -noupdate -divider {Wishbone address decoder}
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_csr_wb_addr_decoder/s_wb_periph_addr
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_csr_wb_addr_decoder/wb_periph_addr
add wave -noupdate /tb_spec/u1/cmp_csr_wb_addr_decoder/s_wb_periph_select
add wave -noupdate /tb_spec/u1/cmp_csr_wb_addr_decoder/s_wb_ack_muxed
add wave -noupdate /tb_spec/u1/cmp_csr_wb_addr_decoder/s_wb_cyc_demuxed
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_csr_wb_addr_decoder/s_wb_dat_i_muxed
add wave -noupdate -divider {CSR wishbone}
add wave -noupdate -radix hexadecimal /tb_spec/u1/wb_ack(0)
add wave -noupdate -radix hexadecimal /tb_spec/u1/wb_ack(1)
add wave -noupdate /tb_spec/u1/wb_ack(2)
add wave -noupdate -radix hexadecimal /tb_spec/u1/wb_adr
add wave -noupdate -radix hexadecimal /tb_spec/u1/wb_cyc(0)
add wave -noupdate -radix hexadecimal /tb_spec/u1/wb_cyc(1)
add wave -noupdate /tb_spec/u1/wb_cyc(2)
add wave -noupdate -radix hexadecimal /tb_spec/u1/wb_dat_i
add wave -noupdate -radix hexadecimal /tb_spec/u1/wb_dat_o
add wave -noupdate -radix hexadecimal /tb_spec/u1/wb_sel
add wave -noupdate -radix hexadecimal /tb_spec/u1/wb_stb
add wave -noupdate -radix hexadecimal /tb_spec/u1/wb_we
add wave -noupdate /tb_spec/u1/wb_stall(0)
add wave -noupdate /tb_spec/u1/wb_stall(1)
add wave -noupdate /tb_spec/u1/wb_stall(2)
add wave -noupdate -divider {DMA wishbone}
add wave -noupdate -radix hexadecimal /tb_spec/u1/dma_dat_i
add wave -noupdate -radix hexadecimal /tb_spec/u1/dma_dat_o
add wave -noupdate -divider {DMA ctrl}
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/cmp_dma_controller/dma_ctrl_current_state
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/cmp_dma_controller/dma_done_irq
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/cmp_dma_controller/dma_error_irq
add wave -noupdate -divider L2P_DMA
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/cmp_l2p_dma_master/l2p_lbe_header
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/cmp_l2p_dma_master/l2p_len_header
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/cmp_l2p_dma_master/s_l2p_header
add wave -noupdate /tb_spec/u1/cmp_gn4124_core/cmp_l2p_dma_master/ldm_arb_dframe_o
add wave -noupdate /tb_spec/u1/cmp_gn4124_core/cmp_l2p_dma_master/ldm_arb_valid_o
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/cmp_l2p_dma_master/ldm_arb_data_o
add wave -noupdate -divider P2L_DMA
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/cmp_p2l_dma_master/l2p_lbe_header
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/cmp_p2l_dma_master/l2p_len_header
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/cmp_p2l_dma_master/s_l2p_header
add wave -noupdate /tb_spec/u1/cmp_gn4124_core/cmp_p2l_dma_master/pdm_arb_dframe_o
add wave -noupdate /tb_spec/u1/cmp_gn4124_core/cmp_p2l_dma_master/pdm_arb_valid_o
add wave -noupdate -radix hexadecimal /tb_spec/u1/cmp_gn4124_core/cmp_p2l_dma_master/pdm_arb_data_o
add wave -noupdate -divider LEDs
add wave -noupdate -radix hexadecimal /tb_spec/u1/led_green_o
add wave -noupdate /tb_spec/u1/led_red_o
add wave -noupdate -radix hexadecimal /tb_spec/u1/aux_leds_o
add wave -noupdate -radix hexadecimal /tb_spec/u1/led_cnt
add wave -noupdate -radix hexadecimal /tb_spec/u1/led_en
add wave -noupdate -radix hexadecimal /tb_spec/u1/led_k2000
add wave -noupdate -radix hexadecimal /tb_spec/u1/led_pps
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {631250 ps} 0}
configure wave -namecolwidth 395
configure wave -valuecolwidth 120
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 ns
update
WaveRestoreZoom {581738 ps} {643262 ps}
*
!*.ucf
!README
!.gitignore
!Manifest.py
target = "xilinx"
action = "synthesis"
syn_device = "xc6slx45t"
syn_grade = "-3"
syn_package = "fgg484"
syn_top = "spec_gn4124_test"
syn_project = "spec_gn4124_test.xise"
syn_tool = "ise"
files = [
"spec_gn4124_test.ucf",
]
modules = {
"local" : [
"../top",
"../rtl",
"../../gn4124core/rtl",
],
"git" : [
"git://ohwr.org/hdl-core-lib/general-cores.git",
],
}
fetchto = "../../ip_cores"
This example project was last tested on March 18st 2016,
using hdlmake (develop branch).
A binary of the generated gateware (spec_gn4124_test.bin) is stored in the
files section of the project:
http://www.ohwr.org/projects/gn4124-core/files
Procedure to generate the gateware binary:
$ cd <gn4124 core dir>/hdl/spec/syn/
$ hdlmake fetch
$ hdlmake
$ make
Memory map:
0x00000 : GN4124 DMA configuration registers
-> See GN4124 doc for register mapping.
0x40000 : Status registers
0 : 0xDEADBABE
4 : 0xBEEFFACE
8 : 0x12345678
C : Bit 0 = P2L PLL lock status (1=pll locked)
0x80000 : Control regiters
0 : Not connected internally, can be used to perform r/w
4 : Not connected internally, can be used to perform r/w
8 : Not connected internally, can be used to perform r/w
C : Bits 0 and 1 connected to SPEC front-panel LEDs (1=LED ON)
#===============================================================================
# The IO Location Constraints
#===============================================================================
#----------------------------------------
# Clock inputs
#----------------------------------------
NET "clk20_vcxo_i" LOC = H12; # CLK25_VCXO
NET "clk20_vcxo_i" IOSTANDARD = "LVCMOS25";
#NET "clk_125m_pllref_n_i" LOC = F10;
#NET "clk_125m_pllref_n_i" IOSTANDARD = "LVDS_25";
#NET "clk_125m_pllref_p_i" LOC = G9;
#NET "clk_125m_pllref_p_i" IOSTANDARD = "LVDS_25";
#----------------------------------------
# SFP slot
# !! SFP_TX_DISABLE and SFP_MOD_DEF1 are swapped in V1.1 schematics for control signals
#----------------------------------------
#NET "SFPRX_123_N" LOC = C15;
#NET "SFPRX_123_N" IOSTANDARD = "LVCMOS25";
#NET "SFPRX_123_P" LOC = D15;
#NET "SFPRX_123_P" IOSTANDARD = "LVCMOS25";
#NET "SFPTX_123_N" LOC = A16;
#NET "SFPTX_123_N" IOSTANDARD = "LVCMOS25";
#NET "SFPTX_123_P" LOC = B16;
#NET "SFPTX_123_P" IOSTANDARD = "LVCMOS25";
#NET "SFP_TX_FAULT" LOC = B18;
#NET "SFP_TX_FAULT" IOSTANDARD = "LVCMOS25";
#NET "SFP_TX_DISABLE" LOC = F17;
#NET "SFP_TX_DISABLE" IOSTANDARD = "LVCMOS25";
#NET "SFP_LOS" LOC = D18;
#NET "SFP_LOS" IOSTANDARD = "LVCMOS25";
#NET "SFP_MOD_DEF1" LOC = C17;
#NET "SFP_MOD_DEF1" IOSTANDARD = "LVCMOS25";
#NET "SFP_MOD_DEF0" LOC = G15;
#NET "SFP_MOD_DEF0" IOSTANDARD = "LVCMOS25";
#NET "SFP_MOD_DEF2" LOC = G16;
#NET "SFP_MOD_DEF2" IOSTANDARD = "LVCMOS25";
#NET "SFP_RATE_SELECT" LOC = H14;
#NET "SFP_RATE_SELECT" IOSTANDARD = "LVCMOS25";
#----------------------------------------
# DAC interface (for VCXO)
#----------------------------------------
#NET "PLL25DAC1_SYNC_N" LOC = A3;
#NET "PLL25DAC1_SYNC_N" IOSTANDARD = "LVCMOS25";
#NET "PLL25DAC2_SYNC_N" LOC = B3;
#NET "PLL25DAC2_SYNC_N" IOSTANDARD = "LVCMOS25";
#NET "PLL25DAC_DIN" LOC = C4;
#NET "PLL25DAC_DIN" IOSTANDARD = "LVCMOS25";
#NET "PLL25DAC_SCLK" LOC = A4;
#NET "PLL25DAC_SCLK" IOSTANDARD = "LVCMOS25";
#----------------------------------------
# 1-wire thermometer w/ ID
#----------------------------------------
#NET "THERMO_ID" LOC = D4;
#NET "THERMO_ID" IOSTANDARD = "LVCMOS25";
#----------------------------------------
# I2C interface
#----------------------------------------
#NET "FPGA_SCL" LOC = F7;
#NET "FPGA_SCL" IOSTANDARD = "LVCMOS25";
#NET "FPGA_SDA" LOC = F8;
#NET "FPGA_SDA" IOSTANDARD = "LVCMOS25";
#----------------------------------------
# GN4124 interface
#----------------------------------------
NET "L_RST_N" LOC = N20;
NET "L_RST_N" IOSTANDARD = "LVCMOS18";
NET "L2P_CLKN" LOC = K22;
NET "L2P_CLKN" IOSTANDARD = "DIFF_SSTL18_I";
NET "L2P_CLKP" LOC = K21;
NET "L2P_CLKP" IOSTANDARD = "DIFF_SSTL18_I";
NET "L2P_DFRAME" LOC = U22;
NET "L2P_DFRAME" IOSTANDARD = "SSTL18_I";
NET "L2P_EDB" LOC = U20;
NET "L2P_EDB" IOSTANDARD = "SSTL18_I";
NET "L2P_RDY" LOC = U19;
NET "L2P_RDY" IOSTANDARD = "SSTL18_I";
NET "L2P_VALID" LOC = T18;
NET "L2P_VALID" IOSTANDARD = "SSTL18_I";
NET "L_WR_RDY[0]" LOC = R20;
NET "L_WR_RDY[0]" IOSTANDARD = "SSTL18_I";
NET "L_WR_RDY[1]" LOC = T22;
NET "L_WR_RDY[1]" IOSTANDARD = "SSTL18_I";
NET "L_CLKN" LOC = N19;
NET "L_CLKN" IOSTANDARD = "DIFF_SSTL18_I";
NET "L_CLKP" LOC = P20;
NET "L_CLKP" IOSTANDARD = "DIFF_SSTL18_I";
NET "P2L_CLKN" LOC = M19;
NET "P2L_CLKN" IOSTANDARD = "DIFF_SSTL18_I";
NET "P2L_CLKP" LOC = M20;
NET "P2L_CLKP" IOSTANDARD = "DIFF_SSTL18_I";
NET "P2L_DFRAME" LOC = J22;
NET "P2L_DFRAME" IOSTANDARD = "SSTL18_I";
NET "P2L_RDY" LOC = J16;
NET "P2L_RDY" IOSTANDARD = "SSTL18_I";
NET "P2L_VALID" LOC = L19;
NET "P2L_VALID" IOSTANDARD = "SSTL18_I";
NET "P_RD_D_RDY[0]" LOC = N16;
NET "P_RD_D_RDY[0]" IOSTANDARD = "SSTL18_I";
NET "P_RD_D_RDY[1]" LOC = P19;
NET "P_RD_D_RDY[1]" IOSTANDARD = "SSTL18_I";
NET "P_WR_RDY[0]" LOC = L15;
NET "P_WR_RDY[0]" IOSTANDARD = "SSTL18_I";
NET "P_WR_RDY[1]" LOC = K16;
NET "P_WR_RDY[1]" IOSTANDARD = "SSTL18_I";
NET "P_WR_REQ[0]" LOC = M22;
NET "P_WR_REQ[0]" IOSTANDARD = "SSTL18_I";
NET "P_WR_REQ[1]" LOC = M21;
NET "P_WR_REQ[1]" IOSTANDARD = "SSTL18_I";
NET "RX_ERROR" LOC = J17;
NET "RX_ERROR" IOSTANDARD = "SSTL18_I";
NET "TX_ERROR" LOC = M17;
NET "TX_ERROR" IOSTANDARD = "SSTL18_I";
NET "VC_RDY[0]" LOC = B21;
NET "VC_RDY[0]" IOSTANDARD = "SSTL18_I";
NET "VC_RDY[1]" LOC = B22;
NET "VC_RDY[1]" IOSTANDARD = "SSTL18_I";
NET "L2P_DATA[0]" LOC = P16;
NET "L2P_DATA[0]" IOSTANDARD = "SSTL18_I";
NET "L2P_DATA[1]" LOC = P21;
NET "L2P_DATA[1]" IOSTANDARD = "SSTL18_I";
NET "L2P_DATA[2]" LOC = P18;
NET "L2P_DATA[2]" IOSTANDARD = "SSTL18_I";
NET "L2P_DATA[3]" LOC = T20;
NET "L2P_DATA[3]" IOSTANDARD = "SSTL18_I";
NET "L2P_DATA[4]" LOC = V21;
NET "L2P_DATA[4]" IOSTANDARD = "SSTL18_I";
NET "L2P_DATA[5]" LOC = V19;
NET "L2P_DATA[5]" IOSTANDARD = "SSTL18_I";
NET "L2P_DATA[6]" LOC = W22;
NET "L2P_DATA[6]" IOSTANDARD = "SSTL18_I";
NET "L2P_DATA[7]" LOC = Y22;
NET "L2P_DATA[7]" IOSTANDARD = "SSTL18_I";
NET "L2P_DATA[8]" LOC = P22;
NET "L2P_DATA[8]" IOSTANDARD = "SSTL18_I";
NET "L2P_DATA[9]" LOC = R22;
NET "L2P_DATA[9]" IOSTANDARD = "SSTL18_I";
NET "L2P_DATA[10]" LOC = T21;
NET "L2P_DATA[10]" IOSTANDARD = "SSTL18_I";
NET "L2P_DATA[11]" LOC = T19;
NET "L2P_DATA[11]" IOSTANDARD = "SSTL18_I";
NET "L2P_DATA[12]" LOC = V22;
NET "L2P_DATA[12]" IOSTANDARD = "SSTL18_I";
NET "L2P_DATA[13]" LOC = V20;
NET "L2P_DATA[13]" IOSTANDARD = "SSTL18_I";
NET "L2P_DATA[14]" LOC = W20;
NET "L2P_DATA[14]" IOSTANDARD = "SSTL18_I";
NET "L2P_DATA[15]" LOC = Y21;
NET "L2P_DATA[15]" IOSTANDARD = "SSTL18_I";
NET "P2L_DATA[0]" LOC = K20;
NET "P2L_DATA[0]" IOSTANDARD = "SSTL18_I";
NET "P2L_DATA[1]" LOC = H22;
NET "P2L_DATA[1]" IOSTANDARD = "SSTL18_I";
NET "P2L_DATA[2]" LOC = H21;
NET "P2L_DATA[2]" IOSTANDARD = "SSTL18_I";
NET "P2L_DATA[3]" LOC = L17;
NET "P2L_DATA[3]" IOSTANDARD = "SSTL18_I";
NET "P2L_DATA[4]" LOC = K17;
NET "P2L_DATA[4]" IOSTANDARD = "SSTL18_I";
NET "P2L_DATA[5]" LOC = G22;
NET "P2L_DATA[5]" IOSTANDARD = "SSTL18_I";
NET "P2L_DATA[6]" LOC = G20;
NET "P2L_DATA[6]" IOSTANDARD = "SSTL18_I";
NET "P2L_DATA[7]" LOC = K18;
NET "P2L_DATA[7]" IOSTANDARD = "SSTL18_I";
NET "P2L_DATA[8]" LOC = K19;
NET "P2L_DATA[8]" IOSTANDARD = "SSTL18_I";
NET "P2L_DATA[9]" LOC = H20;
NET "P2L_DATA[9]" IOSTANDARD = "SSTL18_I";
NET "P2L_DATA[10]" LOC = J19;
NET "P2L_DATA[10]" IOSTANDARD = "SSTL18_I";
NET "P2L_DATA[11]" LOC = E22;
NET "P2L_DATA[11]" IOSTANDARD = "SSTL18_I";
NET "P2L_DATA[12]" LOC = E20;
NET "P2L_DATA[12]" IOSTANDARD = "SSTL18_I";
NET "P2L_DATA[13]" LOC = F22;
NET "P2L_DATA[13]" IOSTANDARD = "SSTL18_I";
NET "P2L_DATA[14]" LOC = F21;
NET "P2L_DATA[14]" IOSTANDARD = "SSTL18_I";
NET "P2L_DATA[15]" LOC = H19;
NET "P2L_DATA[15]" IOSTANDARD = "SSTL18_I";
NET "GPIO[0]" LOC = U16;
NET "GPIO[0]" IOSTANDARD = "LVCMOS25";
NET "GPIO[1]" LOC = AB19;
NET "GPIO[1]" IOSTANDARD = "LVCMOS25";
#----------------------------------------
# FMC slot
#----------------------------------------
#NET "ext_trigger_n_i" LOC = AB13; # LA17_N
#NET "ext_trigger_n_i" IOSTANDARD = "LVDS_25";
#NET "ext_trigger_p_i" LOC = Y13; # LA17_P
#NET "ext_trigger_p_i" IOSTANDARD = "LVDS_25";
# dco_p and dco_n are swapped compared to the FMC ADC schematics
# this is to be coherent in the hdl design
#NET "adc_dco_n_i" LOC = AB11; # LA00_N
#NET "adc_dco_n_i" IOSTANDARD = "LVDS_25";
#NET "adc_dco_p_i" LOC = Y11; # LA00_P
#NET "adc_dco_p_i" IOSTANDARD = "LVDS_25";
# fr_p and fr_n are swapped compared to the FMC ADC schematics
# this is to be coherent in the hdl design
#NET "adc_fr_n_i" LOC = AB12; # LA01_N
#NET "adc_fr_n_i" IOSTANDARD = "LVDS_25";
#NET "adc_fr_p_i" LOC = AA12; # LA01_P
#NET "adc_fr_p_i" IOSTANDARD = "LVDS_25";
#NET "adc_outa_n_i[0]" LOC = AB4; # LA14_N
#NET "adc_outa_n_i[0]" IOSTANDARD = "LVDS_25";
#NET "adc_outa_p_i[0]" LOC = AA4; # LA14_P
#NET "adc_outa_p_i[0]" IOSTANDARD = "LVDS_25";
#NET "adc_outb_n_i[0]" LOC = W11; # LA15_N
#NET "adc_outb_n_i[0]" IOSTANDARD = "LVDS_25";
#NET "adc_outb_p_i[0]" LOC = V11; # LA15_P
#NET "adc_outb_p_i[0]" IOSTANDARD = "LVDS_25";
#NET "adc_outa_n_i[1]" LOC = Y12; # LA16_N
#NET "adc_outa_n_i[1]" IOSTANDARD = "LVDS_25";
#NET "adc_outa_p_i[1]" LOC = W12; # LA16_P
#NET "adc_outa_p_i[1]" IOSTANDARD = "LVDS_25";
#NET "adc_outb_n_i[1]" LOC = AB9; # LA13_N
#NET "adc_outb_n_i[1]" IOSTANDARD = "LVDS_25";
#NET "adc_outb_p_i[1]" LOC = Y9; # LA13_P
#NET "adc_outb_p_i[1]" IOSTANDARD = "LVDS_25";
#NET "adc_outa_n_i[2]" LOC = AB8; # LA10_N
#NET "adc_outa_n_i[2]" IOSTANDARD = "LVDS_25";
#NET "adc_outa_p_i[2]" LOC = AA8; # LA10_P
#NET "adc_outa_p_i[2]" IOSTANDARD = "LVDS_25";
#NET "adc_outb_n_i[2]" LOC = AB7; # LA09_N
#NET "adc_outb_n_i[2]" IOSTANDARD = "LVDS_25";
#NET "adc_outb_p_i[2]" LOC = Y7; # LA09_P
#NET "adc_outb_p_i[2]" IOSTANDARD = "LVDS_25";
#NET "adc_outa_n_i[3]" LOC = V9; # LA07_N
#NET "adc_outa_n_i[3]" IOSTANDARD = "LVDS_25";
#NET "adc_outa_p_i[3]" LOC = U9; # LA07_P
#NET "adc_outa_p_i[3]" IOSTANDARD = "LVDS_25";
#NET "adc_outb_n_i[3]" LOC = AB6; # LA05_N
#NET "adc_outb_n_i[3]" IOSTANDARD = "LVDS_25";
#NET "adc_outb_p_i[3]" LOC = AA6; # LA05_P
#NET "adc_outb_p_i[3]" IOSTANDARD = "LVDS_25";
#NET "spi_din_i" LOC = T15; # LA25_P
#NET "spi_din_i" IOSTANDARD = "LVCMOS25";
#NET "spi_dout_o" LOC = C18; # LA31_N
#NET "spi_dout_o" IOSTANDARD = "LVCMOS25";
#NET "spi_sck_o" LOC = D17; # LA31_P
#NET "spi_sck_o" IOSTANDARD = "LVCMOS25";
#NET "spi_cs_adc_n_o" LOC = V17; # LA30_P
#NET "spi_cs_adc_n_o" IOSTANDARD = "LVCMOS25";
#NET "spi_cs_dac1_n_o" LOC = B20; # LA32_P
#NET "spi_cs_dac1_n_o" IOSTANDARD = "LVCMOS25";
#NET "spi_cs_dac2_n_o" LOC = A20; # LA32_N
#NET "spi_cs_dac2_n_o" IOSTANDARD = "LVCMOS25";
#NET "spi_cs_dac3_n_o" LOC = C19; # LA33_P
#NET "spi_cs_dac3_n_o" IOSTANDARD = "LVCMOS25";
#NET "spi_cs_dac4_n_o" LOC = A19; # LA33_N
#NET "spi_cs_dac4_n_o" IOSTANDARD = "LVCMOS25";
#NET "gpio_dac_clr_n_o" LOC = W18; # LA30_N
#NET "gpio_dac_clr_n_o" IOSTANDARD = "LVCMOS25";
#NET "gpio_led_power_o" LOC = W15; # LA28_N
#NET "gpio_led_power_o" IOSTANDARD = "LVCMOS25";
#NET "gpio_led_trigger_o" LOC = Y16; # LA28_P
#NET "gpio_led_trigger_o" IOSTANDARD = "LVCMOS25";
#NET "gpio_ssr_ch1_o[0]" LOC = Y17; # LA26_P
#NET "gpio_ssr_ch1_o[0]" IOSTANDARD = "LVCMOS25";
#NET "gpio_ssr_ch1_o[1]" LOC = AB17; # LA26_N
#NET "gpio_ssr_ch1_o[1]" IOSTANDARD = "LVCMOS25";
#NET "gpio_ssr_ch1_o[2]" LOC = AB18; # LA27_N
#NET "gpio_ssr_ch1_o[2]" IOSTANDARD = "LVCMOS25";
#NET "gpio_ssr_ch1_o[3]" LOC = U15; # LA25_N
#NET "gpio_ssr_ch1_o[3]" IOSTANDARD = "LVCMOS25";
#NET "gpio_ssr_ch1_o[4]" LOC = W14; # LA24_P
#NET "gpio_ssr_ch1_o[4]" IOSTANDARD = "LVCMOS25";
#NET "gpio_ssr_ch1_o[5]" LOC = Y14; # LA24_N
#NET "gpio_ssr_ch1_o[5]" IOSTANDARD = "LVCMOS25";
#NET "gpio_ssr_ch1_o[6]" LOC = W17; # LA29_P
#NET "gpio_ssr_ch1_o[6]" IOSTANDARD = "LVCMOS25";
#NET "gpio_ssr_ch2_o[0]" LOC = R11; # LA20_P
#NET "gpio_ssr_ch2_o[0]" IOSTANDARD = "LVCMOS25";
#NET "gpio_ssr_ch2_o[1]" LOC = AB15; # LA19_N
#NET "gpio_ssr_ch2_o[1]" IOSTANDARD = "LVCMOS25";
#NET "gpio_ssr_ch2_o[2]" LOC = R13; # LA22_P
#NET "gpio_ssr_ch2_o[2]" IOSTANDARD = "LVCMOS25";
#NET "gpio_ssr_ch2_o[3]" LOC = T14; # LA22_N
#NET "gpio_ssr_ch2_o[3]" IOSTANDARD = "LVCMOS25";
#NET "gpio_ssr_ch2_o[4]" LOC = V13; # LA21_P
#NET "gpio_ssr_ch2_o[4]" IOSTANDARD = "LVCMOS25";
#NET "gpio_ssr_ch2_o[5]" LOC = AA18; # LA27_P
#NET "gpio_ssr_ch2_o[5]" IOSTANDARD = "LVCMOS25";
#NET "gpio_ssr_ch2_o[6]" LOC = W13; # LA21_N
#NET "gpio_ssr_ch2_o[6]" IOSTANDARD = "LVCMOS25";
#NET "gpio_ssr_ch3_o[0]" LOC = R9; # LA08_P
#NET "gpio_ssr_ch3_o[0]" IOSTANDARD = "LVCMOS25";
#NET "gpio_ssr_ch3_o[1]" LOC = R8; # LA08_N
#NET "gpio_ssr_ch3_o[1]" IOSTANDARD = "LVCMOS25";
#NET "gpio_ssr_ch3_o[2]" LOC = T10; # LA12_P
#NET "gpio_ssr_ch3_o[2]" IOSTANDARD = "LVCMOS25";
#NET "gpio_ssr_ch3_o[3]" LOC = U10; # LA12_N
#NET "gpio_ssr_ch3_o[3]" IOSTANDARD = "LVCMOS25";
#NET "gpio_ssr_ch3_o[4]" LOC = W10; # LA11_P
#NET "gpio_ssr_ch3_o[4]" IOSTANDARD = "LVCMOS25";
#NET "gpio_ssr_ch3_o[5]" LOC = Y10; # LA11_N
#NET "gpio_ssr_ch3_o[5]" IOSTANDARD = "LVCMOS25";
#NET "gpio_ssr_ch3_o[6]" LOC = T11; # LA20_N
#NET "gpio_ssr_ch3_o[6]" IOSTANDARD = "LVCMOS25";
#NET "gpio_ssr_ch4_o[0]" LOC = W6; # LA02_P
#NET "gpio_ssr_ch4_o[0]" IOSTANDARD = "LVCMOS25";
#NET "gpio_ssr_ch4_o[1]" LOC = Y6; # LA02_N
#NET "gpio_ssr_ch4_o[1]" IOSTANDARD = "LVCMOS25";
#NET "gpio_ssr_ch4_o[2]" LOC = V7; # LA03_P
#NET "gpio_ssr_ch4_o[2]" IOSTANDARD = "LVCMOS25";
#NET "gpio_ssr_ch4_o[3]" LOC = W8; # LA03_N
#NET "gpio_ssr_ch4_o[3]" IOSTANDARD = "LVCMOS25";
#NET "gpio_ssr_ch4_o[4]" LOC = T8; # LA04_P
#NET "gpio_ssr_ch4_o[4]" IOSTANDARD = "LVCMOS25";
#NET "gpio_ssr_ch4_o[5]" LOC = Y5; # LA06_P
#NET "gpio_ssr_ch4_o[5]" IOSTANDARD = "LVCMOS25";
#NET "gpio_ssr_ch4_o[6]" LOC = U8; # LA04_N
#NET "gpio_ssr_ch4_o[6]" IOSTANDARD = "LVCMOS25";
#NET "gpio_si570_oe_o" LOC = AB5; # LA06_N
#NET "gpio_si570_oe_o" IOSTANDARD = "LVCMOS25";
#NET "si570_thermo_scl_b" LOC = U12; # LA18_N
#NET "si570_thermo_scl_b" IOSTANDARD = "LVCMOS25";
#NET "si570_thermo_sda_b" LOC = T12; # LA18_P
#NET "si570_thermo_sda_b" IOSTANDARD = "LVCMOS25";
#NET "prsnt_m2c_n_i" LOC = AB14; # PRSNT_M2C_L
#NET "prsnt_m2c_n_i" IOSTANDARD = "LVCMOS25";
#----------------------------------------
# FMC slot (unused pins)
#----------------------------------------
#NET "PG_C2M" LOC = AA14;
#NET "PG_C2M" IOSTANDARD = "LVCMOS25";
#NET "LA19_P" LOC = Y15;
#NET "LA19_P" IOSTANDARD = "LVCMOS25";
#NET "LA23_N" LOC = AB16;
#NET "LA23_N" IOSTANDARD = "LVCMOS25";
#NET "LA23_P" LOC = AA16;
#NET "LA23_P" IOSTANDARD = "LVCMOS25";
#NET "LA29_N" LOC = Y18;
#NET "LA29_N" IOSTANDARD = "LVCMOS25";
#NET "TDO_FROM_FMC" LOC = F9;
#NET "TDO_FROM_FMC" IOSTANDARD = "LVCMOS25";
#NET "TCK_TO_FMC" LOC = G8;
#NET "TCK_TO_FMC" IOSTANDARD = "LVCMOS25";
#NET "TDI_TO_FMC" LOC = H11;
#NET "TDI_TO_FMC" IOSTANDARD = "LVCMOS25";
#NET "TMS_TO_FMC" LOC = H10;
#NET "TMS_TO_FMC" IOSTANDARD = "LVCMOS25";
#NET "TRST_TO_FMC" LOC = E6;
#NET "TRST_TO_FMC" IOSTANDARD = "LVCMOS25";
#NET "CLK0_M2C_P" LOC = E16;
#NET "CLK0_M2C_P" IOSTANDARD = "LVDS_25";
#NET "CLK0_M2C_N" LOC = F16;
#NET "CLK0_M2C_N" IOSTANDARD = "LVDS_25";
#NET "CLK1_M2C_P" LOC = L20;
#NET "CLK1_M2C_P" IOSTANDARD = "LVDS_18";
#NET "CLK1_M2C_N" LOC = L22;
#NET "CLK1_M2C_N" IOSTANDARD = "LVDS_18";
#----------------------------------------
# SI57x interface
#----------------------------------------
#NET "SI57X_SCL" LOC = A18;
#NET "SI57X_SCL" IOSTANDARD = "LVCMOS25";
#NET "SI57X_SDA" LOC = A17;
#NET "SI57X_SDA" IOSTANDARD = "LVCMOS25";
#NET "SI57X_OE" LOC = H13;
#NET "SI57X_OE" IOSTANDARD = "LVCMOS25";
#NET "SI57X_CLK_N" LOC = F15;
#NET "SI57X_CLK_N" IOSTANDARD = "LVDS_25";
#NET "SI57X_CLK_P" LOC = F14;
#NET "SI57X_CLK_P" IOSTANDARD = "LVDS_25";
#----------------------------------------
# Carrier front panel LEDs
#----------------------------------------
NET "led_red_o" LOC = D5;
NET "led_red_o" IOSTANDARD = "LVCMOS25";
NET "led_green_o" LOC = E5;
NET "led_green_o" IOSTANDARD = "LVCMOS25";
#----------------------------------------
# PCB version number (coded with resistors)
#----------------------------------------
NET "pcb_ver_i[0]" LOC = P5;
NET "pcb_ver_i[0]" IOSTANDARD = "LVCMOS15";
NET "pcb_ver_i[1]" LOC = P4;
NET "pcb_ver_i[1]" IOSTANDARD = "LVCMOS15";
NET "pcb_ver_i[2]" LOC = AA2;
NET "pcb_ver_i[2]" IOSTANDARD = "LVCMOS15";
NET "pcb_ver_i[3]" LOC = AA1;
NET "pcb_ver_i[3]" IOSTANDARD = "LVCMOS15";
#----------------------------------------
# DDR3 interface
#----------------------------------------
#NET "DDR3_CAS_N" LOC = M4;
#NET "DDR3_CAS_N" IOSTANDARD = "SSTL15_II";
#NET "DDR3_CK_N" LOC = K3;
#NET "DDR3_CK_N" IOSTANDARD = "DIFF_SSTL15_II";
#NET "DDR3_CK_P" LOC = K4;
#NET "DDR3_CK_P" IOSTANDARD = "DIFF_SSTL15_II";
#NET "DDR3_CKE" LOC = F2;
#NET "DDR3_CKE" IOSTANDARD = "SSTL15_II";
#NET "DDR3_LDM" LOC = N4;
#NET "DDR3_LDM" IOSTANDARD = "SSTL15_II";
#NET "DDR3_LDQS_N" LOC = N1;
#NET "DDR3_LDQS_N" IOSTANDARD = "DIFF_SSTL15_II";
#NET "DDR3_LDQS_P" LOC = N3;
#NET "DDR3_LDQS_P" IOSTANDARD = "DIFF_SSTL15_II";
#NET "DDR3_ODT" LOC = L6;
#NET "DDR3_ODT" IOSTANDARD = "SSTL15_II";
#NET "DDR3_RAS_N" LOC = M5;
#NET "DDR3_RAS_N" IOSTANDARD = "SSTL15_II";
#NET "DDR3_RESET_N" LOC = E3;
#NET "DDR3_RESET_N" IOSTANDARD = "SSTL15_II";
#NET "DDR3_UDM" LOC = P3;
#NET "DDR3_UDM" IOSTANDARD = "SSTL15_II";
#NET "DDR3_UDQS_N" LOC = V1;
#NET "DDR3_UDQS_N" IOSTANDARD = "DIFF_SSTL15_II";
#NET "DDR3_UDQS_P" LOC = V2;
#NET "DDR3_UDQS_P" IOSTANDARD = "DIFF_SSTL15_II";
#NET "DDR3_WE_N" LOC = H2;
#NET "DDR3_WE_N" IOSTANDARD = "SSTL15_II";
#NET "DDR3_RZQ" LOC = K7;
#NET "DDR3_RZQ" IOSTANDARD = "SSTL15_II";
#NET "DDR3_ZIO" LOC = M7;
#NET "DDR3_ZIO" IOSTANDARD = "SSTL15_II";
#NET "DDR3_A[0]" LOC = K2;
#NET "DDR3_A[0]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_A[1]" LOC = K1;
#NET "DDR3_A[1]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_A[2]" LOC = K5;
#NET "DDR3_A[2]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_A[3]" LOC = M6;
#NET "DDR3_A[3]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_A[4]" LOC = H3;
#NET "DDR3_A[4]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_A[5]" LOC = M3;
#NET "DDR3_A[5]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_A[6]" LOC = L4;
#NET "DDR3_A[6]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_A[7]" LOC = K6;
#NET "DDR3_A[7]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_A[8]" LOC = G3;
#NET "DDR3_A[8]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_A[9]" LOC = G1;
#NET "DDR3_A[9]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_A[10]" LOC = J4;
#NET "DDR3_A[10]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_A[11]" LOC = E1;
#NET "DDR3_A[11]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_A[12]" LOC = F1;
#NET "DDR3_A[12]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_A[13]" LOC = J6;
#NET "DDR3_A[13]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_A[14]" LOC = H5;
#NET "DDR3_A[14]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_BA[0]" LOC = J3;
#NET "DDR3_BA[0]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_BA[1]" LOC = J1;
#NET "DDR3_BA[1]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_BA[2]" LOC = H1;
#NET "DDR3_BA[2]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_DQ[0]" LOC = R3;
#NET "DDR3_DQ[0]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_DQ[1]" LOC = R1;
#NET "DDR3_DQ[1]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_DQ[2]" LOC = P2;
#NET "DDR3_DQ[2]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_DQ[3]" LOC = P1;
#NET "DDR3_DQ[3]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_DQ[4]" LOC = L3;
#NET "DDR3_DQ[4]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_DQ[5]" LOC = L1;
#NET "DDR3_DQ[5]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_DQ[6]" LOC = M2;
#NET "DDR3_DQ[6]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_DQ[7]" LOC = M1;
#NET "DDR3_DQ[7]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_DQ[8]" LOC = T2;
#NET "DDR3_DQ[8]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_DQ[9]" LOC = T1;
#NET "DDR3_DQ[9]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_DQ[10]" LOC = U3;
#NET "DDR3_DQ[10]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_DQ[11]" LOC = U1;
#NET "DDR3_DQ[11]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_DQ[12]" LOC = W3;
#NET "DDR3_DQ[12]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_DQ[13]" LOC = W1;
#NET "DDR3_DQ[13]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_DQ[14]" LOC = Y2;
#NET "DDR3_DQ[14]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_DQ[15]" LOC = Y1;
#NET "DDR3_DQ[15]" IOSTANDARD = "SSTL15_II";
#----------------------------------------
# UART
#----------------------------------------
#NET "UART_TXD" LOC = A2; # FPGA input
#NET "UART_TXD" IOSTANDARD = "LVCMOS25";
#NET "UART_RXD" LOC = B2; # FPGA output
#NET "UART_RXD" IOSTANDARD = "LVCMOS25";
#----------------------------------------
# Buttons and LEDs
#----------------------------------------
NET "AUX_BUTTONS_I[0]" LOC = C22;
NET "AUX_BUTTONS_I[0]" IOSTANDARD = "LVCMOS18";
NET "AUX_BUTTONS_I[1]" LOC = D21;
NET "AUX_BUTTONS_I[1]" IOSTANDARD = "LVCMOS18";
NET "AUX_LEDS_O[0]" LOC = G19;
NET "AUX_LEDS_O[0]" IOSTANDARD = "LVCMOS18";
NET "AUX_LEDS_O[1]" LOC = F20;
NET "AUX_LEDS_O[1]" IOSTANDARD = "LVCMOS18";
NET "AUX_LEDS_O[2]" LOC = F18;
NET "AUX_LEDS_O[2]" IOSTANDARD = "LVCMOS18";
NET "AUX_LEDS_O[3]" LOC = C20;
NET "AUX_LEDS_O[3]" IOSTANDARD = "LVCMOS18";
#===============================================================================
# IOBs
#===============================================================================
INST "cmp_gn4124_core/l2p_rdy_t" IOB=FALSE;
INST "cmp_gn4124_core/l_wr_rdy_t*" IOB=FALSE;
#INST "cmp_fmc_spi/shift/s_out" IOB=FALSE;
#INST "cmp_fmc_spi/clgen/clk_out" IOB=FALSE;
#===============================================================================
# Terminations
#===============================================================================
# DDR3
#NET "DDR3_DQ[*]" IN_TERM = NONE;
#NET "DDR3_LDQS_P" IN_TERM = NONE;
#NET "DDR3_LDQS_N" IN_TERM = NONE;
#NET "DDR3_UDQS_P" IN_TERM = NONE;
#NET "DDR3_UDQS_N" IN_TERM = NONE;
#===============================================================================
# Clock constraints
#===============================================================================
# GN4124
NET "L_CLKp" TNM_NET = "l_clkp_grp";
TIMESPEC TS_l_clkp = PERIOD "l_clkp_grp" 5 ns HIGH 50%;
NET "P2L_CLKp" TNM_NET = "p2l_clkp_grp";
TIMESPEC TS_p2l_clkp = PERIOD "p2l_clkp_grp" 5 ns HIGH 50%;
NET "P2L_CLKn" TNM_NET = "p2l_clkn_grp";
TIMESPEC TS_p2l_clkn = PERIOD "p2l_clkn_grp" 5 ns HIGH 50%;
# System clock
NET "clk20_vcxo_i" TNM_NET = "clk20_vcxo_i_grp";
TIMESPEC TS_clk20_vcxo_i = PERIOD "clk20_vcxo_i_grp" 50 ns HIGH 50%;
# DDR3
#NET "cmp_ddr_ctrl/cmp_ddr_controller/memc3_infrastructure_inst/sys_clk_ibufg" TNM_NET = "SYS_CLK5";
#TIMESPEC "TS_SYS_CLK5" = PERIOD "SYS_CLK5" 3.0 ns HIGH 50 %;
# ADC
#NET "adc_dco_n_i" TNM_NET = adc_dco_n_i;
#TIMESPEC TS_adc_dco_n_i = PERIOD "adc_dco_n_i" 2 ns HIGH 50%;
#===============================================================================
# False Path
#===============================================================================
# GN4124
NET "l_rst_n" TIG;
NET "cmp_gn4124_core/rst_*" TIG;
# DDR3
#NET "cmp_ddr_ctrl/cmp_ddr_controller/memc3_wrapper_inst/memc3_mcb_raw_wrapper_inst/selfrefresh_mcb_mode" TIG;
#NET "cmp_ddr_ctrl/cmp_ddr_controller/c3_pll_lock" TIG;
#NET "cmp_ddr_ctrl/cmp_ddr_controller/memc3_wrapper_inst/memc3_mcb_raw_wrapper_inst/hard_done_cal" TIG;
#NET "cmp_ddr_ctrl/cmp_ddr_controller/memc3_wrapper_inst/memc3_mcb_raw_wrapper_inst/gen_term_calib.mcb_soft_calibration_top_inst/mcb_soft_calibration_inst/DONE_SOFTANDHARD_CAL" TIG;
files = ["spec_gn4124_test.vhd"]
--------------------------------------------------------------------------------
-- --
-- CERN BE-CO-HT GN4124 core for PCIe FMC carrier --
-- http://www.ohwr.org/projects/gn4124-core --
--------------------------------------------------------------------------------
--
-- unit name: spec_gn4124_test (spec_gn4124_test.vhd)
--
-- author: Matthieu Cattin (matthieu.cattin@cern.ch)
--
-- date: 07-07-2011
--
-- version: 0.1
--
-- description: Wrapper for the GN4124 core to drop into the FPGA on the
-- SPEC (Simple PCIe FMC Carrier) board
--
-- dependencies:
--
--------------------------------------------------------------------------------
-- last changes: see svn log.
--------------------------------------------------------------------------------
-- TODO: -
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
use work.gn4124_core_pkg.all;
use work.genram_pkg.all;
library UNISIM;
use UNISIM.vcomponents.all;
entity spec_gn4124_test is
port
(
-- On board 20MHz oscillator
clk20_vcxo_i : in std_logic;
-- From GN4124 Local bus
L_CLKp : in std_logic; -- Local bus clock (frequency set in GN4124 config registers)
L_CLKn : in std_logic; -- Local bus clock (frequency set in GN4124 config registers)
L_RST_N : in std_logic; -- Reset from GN4124 (RSTOUT18_N)
-- General Purpose Interface
GPIO : inout std_logic_vector(1 downto 0); -- GPIO[0] -> GN4124 GPIO8
-- GPIO[1] -> GN4124 GPIO9
-- PCIe to Local [Inbound Data] - RX
P2L_RDY : out std_logic; -- Rx Buffer Full Flag
P2L_CLKn : in std_logic; -- Receiver Source Synchronous Clock-
P2L_CLKp : in std_logic; -- Receiver Source Synchronous Clock+
P2L_DATA : in std_logic_vector(15 downto 0); -- Parallel receive data
P2L_DFRAME : in std_logic; -- Receive Frame
P2L_VALID : in std_logic; -- Receive Data Valid
-- Inbound Buffer Request/Status
P_WR_REQ : in std_logic_vector(1 downto 0); -- PCIe Write Request
P_WR_RDY : out std_logic_vector(1 downto 0); -- PCIe Write Ready
RX_ERROR : out std_logic; -- Receive Error
-- Local to Parallel [Outbound Data] - TX
L2P_DATA : out std_logic_vector(15 downto 0); -- Parallel transmit data
L2P_DFRAME : out std_logic; -- Transmit Data Frame
L2P_VALID : out std_logic; -- Transmit Data Valid
L2P_CLKn : out std_logic; -- Transmitter Source Synchronous Clock-
L2P_CLKp : out std_logic; -- Transmitter Source Synchronous Clock+
L2P_EDB : out std_logic; -- Packet termination and discard
-- Outbound Buffer Status
L2P_RDY : in std_logic; -- Tx Buffer Full Flag
L_WR_RDY : in std_logic_vector(1 downto 0); -- Local-to-PCIe Write
P_RD_D_RDY : in std_logic_vector(1 downto 0); -- PCIe-to-Local Read Response Data Ready
TX_ERROR : in std_logic; -- Transmit Error
VC_RDY : in std_logic_vector(1 downto 0); -- Channel ready
-- Font panel LEDs
led_red_o : out std_logic;
led_green_o : out std_logic;
-- Auxiliary pins
AUX_LEDS_O : out std_logic_vector(3 downto 0);
AUX_BUTTONS_I : in std_logic_vector(1 downto 0);
-- PCB version
pcb_ver_i : in std_logic_vector(3 downto 0)
);
end spec_gn4124_test;
architecture rtl of spec_gn4124_test is
------------------------------------------------------------------------------
-- Components declaration
------------------------------------------------------------------------------
component wb_addr_decoder
generic
(
g_WINDOW_SIZE : integer := 18; -- Number of bits to address periph on the board (32-bit word address)
g_WB_SLAVES_NB : integer := 2
);
port
(
---------------------------------------------------------
-- GN4124 core clock and reset
clk_i : in std_logic;
rst_n_i : in std_logic;
---------------------------------------------------------
-- wishbone master interface
wbm_adr_i : in std_logic_vector(31 downto 0); -- Address
wbm_dat_i : in std_logic_vector(31 downto 0); -- Data out
wbm_sel_i : in std_logic_vector(3 downto 0); -- Byte select
wbm_stb_i : in std_logic; -- Strobe
wbm_we_i : in std_logic; -- Write
wbm_cyc_i : in std_logic; -- Cycle
wbm_dat_o : out std_logic_vector(31 downto 0); -- Data in
wbm_ack_o : out std_logic; -- Acknowledge
wbm_stall_o : out std_logic; -- Stall
---------------------------------------------------------
-- wishbone slaves interface
wb_adr_o : out std_logic_vector(31 downto 0); -- Address
wb_dat_o : out std_logic_vector(31 downto 0); -- Data out
wb_sel_o : out std_logic_vector(3 downto 0); -- Byte select
wb_stb_o : out std_logic; -- Strobe
wb_we_o : out std_logic; -- Write
wb_cyc_o : out std_logic_vector(g_WB_SLAVES_NB-1 downto 0); -- Cycle
wb_dat_i : in std_logic_vector((32*g_WB_SLAVES_NB)-1 downto 0); -- Data in
wb_ack_i : in std_logic_vector(g_WB_SLAVES_NB-1 downto 0); -- Acknowledge
wb_stall_i : in std_logic_vector(g_WB_SLAVES_NB-1 downto 0) -- Stall
);
end component wb_addr_decoder;
component dummy_stat_regs_wb_slave
port (
rst_n_i : in std_logic;
wb_clk_i : in std_logic;
wb_addr_i : in std_logic_vector(1 downto 0);
wb_data_i : in std_logic_vector(31 downto 0);
wb_data_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
dummy_stat_reg_1_i : in std_logic_vector(31 downto 0);
dummy_stat_reg_2_i : in std_logic_vector(31 downto 0);
dummy_stat_reg_3_i : in std_logic_vector(31 downto 0);
dummy_stat_reg_switch_i : in std_logic_vector(31 downto 0)
);
end component;
component dummy_ctrl_regs_wb_slave
port (
rst_n_i : in std_logic;
wb_clk_i : in std_logic;
wb_addr_i : in std_logic_vector(1 downto 0);
wb_data_i : in std_logic_vector(31 downto 0);
wb_data_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
dummy_reg_1_o : out std_logic_vector(31 downto 0);
dummy_reg_2_o : out std_logic_vector(31 downto 0);
dummy_reg_3_o : out std_logic_vector(31 downto 0);
dummy_reg_led_o : out std_logic_vector(31 downto 0)
);
end component;
------------------------------------------------------------------------------
-- Constants declaration
------------------------------------------------------------------------------
constant c_BAR0_APERTURE : integer := 18; -- nb of bits for 32-bit word address
constant c_CSR_WB_SLAVES_NB : integer := 3;
------------------------------------------------------------------------------
-- Signals declaration
------------------------------------------------------------------------------
-- System clock
signal sys_clk : std_logic;
-- LCLK from GN4124 used as system clock
signal l_clk : std_logic;
-- P2L colck PLL status
signal p2l_pll_locked : std_logic;
-- GN4124 status
signal gn4124_status : std_logic_vector(31 downto 0);
-- CSR wishbone bus (master)
signal wbm_adr : std_logic_vector(31 downto 0);
signal wbm_dat_i : std_logic_vector(31 downto 0);
signal wbm_dat_o : std_logic_vector(31 downto 0);
signal wbm_sel : std_logic_vector(3 downto 0);
signal wbm_cyc : std_logic;
signal wbm_stb : std_logic;
signal wbm_we : std_logic;
signal wbm_ack : std_logic;
signal wbm_stall : std_logic;
signal wbm_err : std_logic;
signal wbm_rty : std_logic;
-- CSR wishbone bus (slaves)
signal wb_adr : std_logic_vector(31 downto 0);
signal wb_dat_i : std_logic_vector((32*c_CSR_WB_SLAVES_NB)-1 downto 0);
signal wb_dat_o : std_logic_vector(31 downto 0);
signal wb_sel : std_logic_vector(3 downto 0);
signal wb_cyc : std_logic_vector(c_CSR_WB_SLAVES_NB-1 downto 0);
signal wb_stb : std_logic;
signal wb_we : std_logic;
signal wb_ack : std_logic_vector(c_CSR_WB_SLAVES_NB-1 downto 0);
signal wb_stall : std_logic_vector(c_CSR_WB_SLAVES_NB-1 downto 0);
-- DMA wishbone bus
signal dma_adr : std_logic_vector(31 downto 0);
signal dma_dat_i : std_logic_vector(31 downto 0);
signal dma_dat_o : std_logic_vector(31 downto 0);
signal dma_sel : std_logic_vector(3 downto 0);
signal dma_cyc : std_logic;
signal dma_stb : std_logic;
signal dma_we : std_logic;
signal dma_ack : std_logic;
signal dma_stall : std_logic;
signal dma_err : std_logic;
signal dma_rty : std_logic;
signal ram_we : std_logic;
-- Interrupts stuff
signal irq_sources : std_logic_vector(1 downto 0);
signal irq_to_gn4124 : std_logic;
-- CSR whisbone slaves for test
signal dummy_stat_reg_1 : std_logic_vector(31 downto 0);
signal dummy_stat_reg_2 : std_logic_vector(31 downto 0);
signal dummy_stat_reg_3 : std_logic_vector(31 downto 0);
signal dummy_stat_reg_switch : std_logic_vector(31 downto 0);
signal dummy_ctrl_reg_1 : std_logic_vector(31 downto 0);
signal dummy_ctrl_reg_2 : std_logic_vector(31 downto 0);
signal dummy_ctrl_reg_3 : std_logic_vector(31 downto 0);
signal dummy_ctrl_reg_led : std_logic_vector(31 downto 0);
-- FOR TESTS
signal debug : std_logic_vector(7 downto 0);
signal clk_div_cnt : unsigned(3 downto 0);
signal clk_div : std_logic;
-- LED
signal led_cnt : unsigned(24 downto 0);
signal led_en : std_logic;
signal led_k2000 : unsigned(2 downto 0);
signal led_pps : std_logic;
signal leds : std_logic_vector(3 downto 0);
begin
------------------------------------------------------------------------------
-- Local clock from gennum LCLK
------------------------------------------------------------------------------
cmp_l_clk_buf : IBUFDS
generic map (
DIFF_TERM => false, -- Differential Termination
IBUF_LOW_PWR => true, -- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards
IOSTANDARD => "DEFAULT")
port map (
O => l_clk, -- Buffer output
I => L_CLKp, -- Diff_p buffer input (connect directly to top-level port)
IB => L_CLKn -- Diff_n buffer input (connect directly to top-level port)
);
------------------------------------------------------------------------------
-- GN4124 interface
------------------------------------------------------------------------------
cmp_gn4124_core : gn4124_core
port map
(
---------------------------------------------------------
-- Control and status
rst_n_a_i => L_RST_N,
status_o => gn4124_status,
---------------------------------------------------------
-- P2L Direction
--
-- Source Sync DDR related signals
p2l_clk_p_i => P2L_CLKp,
p2l_clk_n_i => P2L_CLKn,
p2l_data_i => P2L_DATA,
p2l_dframe_i => P2L_DFRAME,
p2l_valid_i => P2L_VALID,
-- P2L Control
p2l_rdy_o => P2L_RDY,
p_wr_req_i => P_WR_REQ,
p_wr_rdy_o => P_WR_RDY,
rx_error_o => RX_ERROR,
---------------------------------------------------------
-- L2P Direction
--
-- Source Sync DDR related signals
l2p_clk_p_o => L2P_CLKp,
l2p_clk_n_o => L2P_CLKn,
l2p_data_o => L2P_DATA,
l2p_dframe_o => L2P_DFRAME,
l2p_valid_o => L2P_VALID,
l2p_edb_o => L2P_EDB,
-- L2P Control
l2p_rdy_i => L2P_RDY,
l_wr_rdy_i => L_WR_RDY,
p_rd_d_rdy_i => P_RD_D_RDY,
tx_error_i => TX_ERROR,
vc_rdy_i => VC_RDY,
---------------------------------------------------------
-- Interrupt interface
dma_irq_o => irq_sources,
irq_p_i => irq_to_gn4124,
irq_p_o => GPIO(0),
---------------------------------------------------------
-- DMA registers wishbone interface (slave classic)
dma_reg_clk_i => l_clk,
dma_reg_adr_i => wb_adr,
dma_reg_dat_i => wb_dat_o,
dma_reg_sel_i => wb_sel,
dma_reg_stb_i => wb_stb,
dma_reg_we_i => wb_we,
dma_reg_cyc_i => wb_cyc(0),
dma_reg_dat_o => wb_dat_i(31 downto 0),
dma_reg_ack_o => wb_ack(0),
dma_reg_stall_o => wb_stall(0),
---------------------------------------------------------
-- CSR wishbone interface (master pipelined)
csr_clk_i => l_clk,
csr_adr_o => wbm_adr,
csr_dat_o => wbm_dat_o,
csr_sel_o => wbm_sel,
csr_stb_o => wbm_stb,
csr_we_o => wbm_we,
csr_cyc_o => wbm_cyc,
csr_dat_i => wbm_dat_i,
csr_ack_i => wbm_ack,
csr_stall_i => wbm_stall,
csr_err_i => wbm_err,
csr_rty_i => wbm_rty,
---------------------------------------------------------
-- DMA wishbone interface (master pipelined)
dma_clk_i => l_clk,
dma_adr_o => dma_adr,
dma_dat_o => dma_dat_o,
dma_sel_o => dma_sel,
dma_stb_o => dma_stb,
dma_we_o => dma_we,
dma_cyc_o => dma_cyc,
dma_dat_i => dma_dat_i,
dma_ack_i => dma_ack,
dma_stall_i => dma_stall,
dma_err_i => dma_err,
dma_rty_i => dma_rty
);
p2l_pll_locked <= gn4124_status(0);
------------------------------------------------------------------------------
-- CSR wishbone address decoder
-- 0x00000 : DMA configuration registers
-- 0x40000 : Status registers
-- 0x80000 : Control regiters
------------------------------------------------------------------------------
cmp_csr_wb_addr_decoder : wb_addr_decoder
generic map (
g_WINDOW_SIZE => c_BAR0_APERTURE,
g_WB_SLAVES_NB => c_CSR_WB_SLAVES_NB
)
port map (
---------------------------------------------------------
-- GN4124 core clock and reset
clk_i => l_clk,
rst_n_i => L_RST_N,
---------------------------------------------------------
-- wishbone master interface
wbm_adr_i => wbm_adr,
wbm_dat_i => wbm_dat_o,
wbm_sel_i => wbm_sel,
wbm_stb_i => wbm_stb,
wbm_we_i => wbm_we,
wbm_cyc_i => wbm_cyc,
wbm_dat_o => wbm_dat_i,
wbm_ack_o => wbm_ack,
wbm_stall_o => wbm_stall,
---------------------------------------------------------
-- wishbone slaves interface
wb_adr_o => wb_adr,
wb_dat_o => wb_dat_o,
wb_sel_o => wb_sel,
wb_stb_o => wb_stb,
wb_we_o => wb_we,
wb_cyc_o => wb_cyc,
wb_dat_i => wb_dat_i,
wb_ack_i => wb_ack,
wb_stall_i => wb_stall
);
wbm_err <= '0';
wbm_rty <= '0';
------------------------------------------------------------------------------
-- CSR wishbone bus slaves
------------------------------------------------------------------------------
cmp_dummy_stat_regs : dummy_stat_regs_wb_slave
port map(
rst_n_i => L_RST_N,
wb_clk_i => l_clk,
wb_addr_i => wb_adr(1 downto 0),
wb_data_i => wb_dat_o,
wb_data_o => wb_dat_i(63 downto 32),
wb_cyc_i => wb_cyc(1),
wb_sel_i => wb_sel,
wb_stb_i => wb_stb,
wb_we_i => wb_we,
wb_ack_o => wb_ack(1),
dummy_stat_reg_1_i => dummy_stat_reg_1,
dummy_stat_reg_2_i => dummy_stat_reg_2,
dummy_stat_reg_3_i => dummy_stat_reg_3,
dummy_stat_reg_switch_i => dummy_stat_reg_switch
);
wb_stall(1) <= '0' when wb_cyc(1) = '0' else not(wb_ack(1));
wb_stall(2) <= '0' when wb_cyc(2) = '0' else not(wb_ack(2));
dummy_stat_reg_1 <= X"DEADBABE";
dummy_stat_reg_2 <= X"BEEFFACE";
dummy_stat_reg_3 <= X"12345678";
dummy_stat_reg_switch <= X"0000000" & "000" & p2l_pll_locked;
cmp_dummy_ctrl_regs : dummy_ctrl_regs_wb_slave
port map(
rst_n_i => L_RST_N,
wb_clk_i => l_clk,
wb_addr_i => wb_adr(1 downto 0),
wb_data_i => wb_dat_o,
wb_data_o => wb_dat_i(95 downto 64),
wb_cyc_i => wb_cyc(2),
wb_sel_i => wb_sel,
wb_stb_i => wb_stb,
wb_we_i => wb_we,
wb_ack_o => wb_ack(2),
dummy_reg_1_o => dummy_ctrl_reg_1,
dummy_reg_2_o => dummy_ctrl_reg_2,
dummy_reg_3_o => dummy_ctrl_reg_3,
dummy_reg_led_o => dummy_ctrl_reg_led
);
led_red_o <= dummy_ctrl_reg_led(0);
led_green_o <= dummy_ctrl_reg_led(1);
------------------------------------------------------------------------------
-- DMA wishbone bus connected to a DPRAM
------------------------------------------------------------------------------
process (l_clk, L_RST_N)
begin
if (L_RST_N = '0') then
dma_ack <= '0';
elsif rising_edge(l_clk) then
if (dma_cyc = '1' and dma_stb = '1') then
dma_ack <= '1';
else
dma_ack <= '0';
end if;
end if;
end process;
dma_stall <= '0';
ram_we <= dma_we and dma_cyc and dma_stb;
cmp_test_ram : generic_spram
generic map(
g_data_width => 32,
g_size => 2048,
g_with_byte_enable => false,
g_addr_conflict_resolution => "write_first"
)
port map(
rst_n_i => L_RST_N,
clk_i => l_clk,
bwe_i => "0000",
we_i => ram_we,
a_i => dma_adr(10 downto 0),
d_i => dma_dat_o,
q_o => dma_dat_i
);
dma_err <= '0';
dma_rty <= '0';
------------------------------------------------------------------------------
-- Interrupt stuff
------------------------------------------------------------------------------
-- just forward irq pulses for test
irq_to_gn4124 <= irq_sources(1) or irq_sources(0);
------------------------------------------------------------------------------
-- FOR TEST
------------------------------------------------------------------------------
p_div_clk : process (l_clk, L_RST_N)
begin
if L_RST_N = '0' then
clk_div <= '0';
clk_div_cnt <= (others => '0');
elsif rising_edge(l_clk) then
if clk_div_cnt = 4 then
clk_div <= not (clk_div);
clk_div_cnt <= (others => '0');
else
clk_div_cnt <= clk_div_cnt + 1;
end if;
end if;
end process p_div_clk;
p_led_cnt : process (L_RST_N, l_clk)
begin
if L_RST_N = '0' then
led_cnt <= (others => '1');
led_en <= '1';
elsif rising_edge(l_clk) then
led_cnt <= led_cnt - 1;
led_en <= led_cnt(23);
end if;
end process p_led_cnt;
led_pps <= led_cnt(23) and not(led_en);
p_led_k2000 : process (l_clk, L_RST_N)
begin
if L_RST_N = '0' then
led_k2000 <= (others => '0');
leds <= "0001";
elsif rising_edge(l_clk) then
if led_pps = '1' then
if led_k2000(2) = '0' then
if leds /= "1000" then
leds <= leds(2 downto 0) & '0';
end if;
else
if leds /= "0001" then
leds <= '0' & leds(3 downto 1);
end if;
end if;
led_k2000 <= led_k2000 + 1;
end if;
end if;
end process p_led_k2000;
AUX_LEDS_O <= not(leds);
--AUX_LEDS_O(0) <= led_en;
--AUX_LEDS_O(1) <= not(led_en);
--AUX_LEDS_O(2) <= '1';
--AUX_LEDS_O(3) <= '0';
end rtl;
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