7
mirror of https://github.com/parallella/parallella-hw.git synced 2025-04-22 19:33:42 +00:00

New Vivado-friendly modules, testbench for elink gold-vs-new.

This commit is contained in:
Fred Huettig 2014-11-19 12:02:18 -05:00
parent 250a9e28ca
commit 635227356a
127 changed files with 29398 additions and 83 deletions
.gitignore
fpga
hdl/elink-gold
src
test

2
.gitignore vendored
View File

@ -10,6 +10,8 @@
*~
.*.swp
.*.swo
*#
*.bak
#######################
# Log files

View File

@ -20,6 +20,9 @@
along with this program (see the file COPYING). If not, see
<http://www.gnu.org/licenses/>.
*/
`include "fpga_constants.v"
module axi_elink_if (/*AUTOARG*/
// Outputs
reset_chip, reset_fpga, emaxi_access_outb, emaxi_write_outb,

View File

@ -23,6 +23,8 @@
//# Limitations:
//# 1. Read burst cannot cross single core boundaries
`include "fpga_constants.v"
module axi_slave_rd (/*AUTOARG*/
// Outputs
arready, rid, rdata, rresp, rlast, rvalid, emesh_access_inb,

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,4 @@
version:1
70726f6a656374:706c616e5f61686561645f75736167655c6a6176615f636f6d6d616e645f68616e646c657273:636c6f736570726f6a656374:32:00:00
70726f6a656374:706c616e5f61686561645f75736167655c6a6176615f636f6d6d616e645f68616e646c657273:6f70656e70726f6a656374:2d31:00:00
eof:2926369565

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8" ?>
<document>
<!--The data in this file is primarily intended for consumption by Xilinx tools.
The structure and the elements are likely to change over the next few releases.
This means code written to parse this file will need to be revisited each subsequent release.-->
<application name="pa" timeStamp="Tue Nov 4 18:14:40 2014">
<section name="Project Information" visible="false">
<property name="ProjectID" value="b95e42fdeace47d28a6387fdcc5f12f4" type="ProjectID"/>
<property name="ProjectIteration" value="1" type="ProjectIteration"/>
</section>
<section name="PlanAhead Usage" visible="true">
<item name="Project Data">
<property name="SrcSetCount" value="1" type="SrcSetCount"/>
<property name="ConstraintSetCount" value="1" type="ConstraintSetCount"/>
<property name="DesignMode" value="RTL" type="DesignMode"/>
<property name="SynthesisStrategy" value="Vivado Synthesis Defaults" type="SynthesisStrategy"/>
<property name="ImplStrategy" value="Vivado Implementation Defaults" type="ImplStrategy"/>
</item>
<item name="Java Command Handlers">
<property name="CloseProject" value="2" type="JavaHandler"/>
<property name="OpenProject" value="-1" type="JavaHandler"/>
</item>
<item name="Other">
<property name="GuiMode" value="14" type="GuiMode"/>
<property name="BatchMode" value="0" type="BatchMode"/>
<property name="TclMode" value="10" type="TclMode"/>
</item>
</section>
</application>
</document>

View File

@ -0,0 +1,263 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Product Version: Vivado v2014.3 (64-bit) -->
<!-- -->
<!-- Copyright 1986-2014 Xilinx, Inc. All Rights Reserved. -->
<Project Version="7" Minor="2" Path="/mnt/windowsC/Adapteva/Parallella/parallella-hwelink/fpga/hdl/elink-gold/elink_gold_ip.xpr">
<DefaultLaunch Dir="$PRUNDIR"/>
<Configuration>
<Option Name="Id" Val="c379566cb00149c1838828331eb39ced"/>
<Option Name="Part" Val="xc7z020clg400-1"/>
<Option Name="CompiledLibDir" Val="$PCACHEDIR/compile_simlib"/>
<Option Name="BoardPart" Val=""/>
<Option Name="ActiveSimSet" Val="sim_1"/>
<Option Name="DefaultLib" Val="xil_defaultlib"/>
<Option Name="IPRepoPath" Val="$PPRDIR/."/>
<Option Name="IPRepoPath" Val="$PPRDIR/../../test/test_bench/ip_repo"/>
<Option Name="IPRepoPath" Val="$PPRDIR/../ip_repo/interfaces"/>
</Configuration>
<FileSets Version="1" Minor="31">
<FileSet Name="sources_1" Type="DesignSrcs" RelSrcDir="$PSRCDIR/sources_1">
<Filter Type="Srcs"/>
<File Path="$PPRDIR/fpga_constants.v">
<FileInfo SFType="VHeader">
<Attr Name="IsGlobalInclude" Val="1"/>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/version.v">
<FileInfo SFType="VHeader">
<Attr Name="IsGlobalInclude" Val="1"/>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/fifo_empty_block.v">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/fifo_full_block.v">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/fifo_mem.v">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/synchronizer.v">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/fifo.v">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/toggle2pulse.v">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/pulse2toggle.v">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/axi_slave_addrch.v">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/ewrapper_link_rxi.v">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/ewrapper_link_txo.v">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/mux4.v">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/pulse2pulse.v">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/axi_master_rd.v">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/axi_master_wr.v">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/axi_slave_rd.v">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/axi_slave_wr.v">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/ewrapper_io_rx_slow.v">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/ewrapper_io_tx_slow.v">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/ewrapper_link_receiver.v">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/ewrapper_link_transmitter.v">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/fpgacfg.v">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/io_clock_gen_600mhz.v">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/ewrapper_link_top.v">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/axi_elink_if.v">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/axi_master.v">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/axi_slave.v">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/elink_ip_top.v">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/component.xml">
<FileInfo SFType="IPXACT"/>
</File>
<Config>
<Option Name="DesignMode" Val="RTL"/>
<Option Name="TopModule" Val="elink_ip_top"/>
<Option Name="TopRTLFile" Val="$PPRDIR/elink_ip_top.v"/>
</Config>
</FileSet>
<FileSet Name="constrs_1" Type="Constrs" RelSrcDir="$PSRCDIR/constrs_1">
<Filter Type="Constrs"/>
<Config>
<Option Name="ConstrsType" Val="XDC"/>
</Config>
</FileSet>
<FileSet Name="sim_1" Type="SimulationSrcs" RelSrcDir="$PSRCDIR/sim_1">
<Filter Type="Srcs"/>
<Config>
<Option Name="DesignMode" Val="RTL"/>
<Option Name="TopModule" Val="elink_ip_top"/>
<Option Name="TopLib" Val="xil_defaultlib"/>
<Option Name="TopAutoSet" Val="TRUE"/>
<Option Name="SrcSet" Val="sources_1"/>
</Config>
</FileSet>
</FileSets>
<Simulators>
<Simulator Name="XSim">
<Option Name="Description" Val="Vivado Simulator"/>
</Simulator>
<Simulator Name="ModelSim">
<Option Name="Description" Val="QuestaSim/ModelSim Simulator"/>
</Simulator>
<Simulator Name="IES">
<Option Name="Description" Val="Incisive Enterprise Simulator (IES)"/>
</Simulator>
<Simulator Name="VCS">
<Option Name="Description" Val="Verilog Compiler Simulator (VCS)"/>
</Simulator>
</Simulators>
<Runs Version="1" Minor="9">
<Run Id="synth_1" Type="Ft3:Synth" SrcSet="sources_1" Part="xc7z020clg400-1" ConstrsSet="constrs_1" Description="Vivado Synthesis Defaults" State="current">
<Strategy Version="1" Minor="2">
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2014"/>
<Step Id="synth_design"/>
</Strategy>
</Run>
<Run Id="impl_1" Type="Ft2:EntireDesign" Part="xc7z020clg400-1" ConstrsSet="constrs_1" Description="Vivado Implementation Defaults" State="current" SynthRun="synth_1">
<Strategy Version="1" Minor="2">
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2014"/>
<Step Id="init_design"/>
<Step Id="opt_design"/>
<Step Id="power_opt_design"/>
<Step Id="place_design"/>
<Step Id="post_place_power_opt_design"/>
<Step Id="phys_opt_design"/>
<Step Id="route_design"/>
<Step Id="post_route_phys_opt_design"/>
<Step Id="write_bitstream"/>
</Strategy>
</Run>
</Runs>
</Project>

View File

@ -0,0 +1,678 @@
/*
File: parallella.v
This file is part of the Parallella FPGA Reference Design.
Copyright (C) 2013 Adapteva, Inc.
Contributed by Roman Trogan <support@adapteva.com>
Vivado IP version by Fred Huettig <fred@adapteva.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program (see the file COPYING). If not, see
<http://www.gnu.org/licenses/>.
*/
`include "fpga_constants.v"
module elink_ip_top (/*AUTOARG*/
// Outputs
csysack, cactive, reset_chip, reset_fpga, tx_data_p, tx_data_n,
tx_frame_p, tx_frame_n, tx_lclk_p, tx_lclk_n, rx_wr_wait_p,
rx_wr_wait_n, rx_rd_wait_p, rx_rd_wait_n, rx_cclk_p,
rx_cclk_n, emaxi_awid, emaxi_awaddr, emaxi_awlen, emaxi_awsize,
emaxi_awburst, emaxi_awlock, emaxi_awcache, emaxi_awprot,
emaxi_awvalid, esaxi_awready, emaxi_wid, emaxi_wdata, emaxi_wstrb,
emaxi_wlast, emaxi_wvalid, esaxi_wready, emaxi_bready, esaxi_bid,
esaxi_bresp, esaxi_bvalid, emaxi_arid, emaxi_araddr, emaxi_arlen,
emaxi_arsize, emaxi_arburst, emaxi_arlock, emaxi_arcache,
emaxi_arprot, emaxi_arvalid, esaxi_arready, emaxi_rready,
esaxi_rid, esaxi_rdata, esaxi_rresp, esaxi_rlast, esaxi_rvalid,
emaxi_awqos, emaxi_arqos,
// Inputs
clkin_100, esaxi_aclk, emaxi_aclk, resetn, esaxi_aresetn,
emaxi_aresetn, csysreq, rx_data_p, rx_data_n, rx_frame_p,
rx_frame_n, rx_lclk_p, rx_lclk_n, tx_wr_wait_p, tx_wr_wait_n,
tx_rd_wait_p, tx_rd_wait_n, emaxi_awready, esaxi_awid,
esaxi_awaddr, esaxi_awlen, esaxi_awsize, esaxi_awburst,
esaxi_awlock, esaxi_awcache, esaxi_awprot, esaxi_awvalid,
emaxi_wready, esaxi_wid, esaxi_wdata, esaxi_wstrb, esaxi_wlast,
esaxi_wvalid, emaxi_bid, emaxi_bresp, emaxi_bvalid, esaxi_bready,
emaxi_arready, esaxi_arid, esaxi_araddr, esaxi_arlen, esaxi_arsize,
esaxi_arburst, esaxi_arlock, esaxi_arcache, esaxi_arprot,
esaxi_arvalid, emaxi_rid, emaxi_rdata, emaxi_rresp, emaxi_rlast,
emaxi_rvalid, esaxi_rready, esaxi_awqos, esaxi_arqos
);
parameter SIDW = 12; //ID Width
parameter SAW = 32; //Address Bus Width
parameter SDW = 32; //Data Bus Width
parameter SSTW = 4; // Number of strobes
parameter MIDW = 6; //ID Width
parameter MAW = 32; //Address Bus Width
parameter MDW = 64; //Data Bus Width
parameter MSTW = 8; //Number of strobes
//#########
//# Inputs
//#########
// global signals
input clkin_100; // 100MHz input clock
input esaxi_aclk; // clock source of the axi bus for slave port
input emaxi_aclk; // clock source of the axi bus for master port
input resetn; // system reset, active low
input esaxi_aresetn; // reset of axi bus for slave port
input emaxi_aresetn; // reset of axi bus for master port
input csysreq; // system exit low-power state request
// LVDS FMC Port
input [7:0] rx_data_p;
input [7:0] rx_data_n;
input rx_frame_p;
input rx_frame_n;
input rx_lclk_p;
input rx_lclk_n;
input tx_wr_wait_p;
input tx_wr_wait_n;
input tx_rd_wait_p;
input tx_rd_wait_n;
//########################
//# Write address channel
//########################
// Master Port
input emaxi_awready; //write address ready
// Slave Port
input [SAW-1:0] esaxi_awaddr; //write address
input [3:0] esaxi_awlen; //burst lenght (the number of data transfers)
input [2:0] esaxi_awsize; //burst size (the size of each transfer)
input [1:0] esaxi_awburst; //burst type
input [1:0] esaxi_awlock; //lock type (atomic characteristics)
input [3:0] esaxi_awcache; //memory type
input [2:0] esaxi_awprot; //protection type
input esaxi_awvalid; //write address valid
//########################,
//# Write data channel
//########################
// Master Port
input emaxi_wready;//write ready
// Slave Port
input [SDW-1:0] esaxi_wdata; //write data
input [SSTW-1:0] esaxi_wstrb; //write strobes
input esaxi_wlast; //write last. Indicates last transfer in burst
input esaxi_wvalid;//write valid
//########################
// Write response channel
//########################
// Master Port
input [1:0] emaxi_bresp; //write response
input emaxi_bvalid;//write response valid
// Slave Port
input esaxi_bready;//response ready
//########################
//# Read address channel
//########################
// Master Port
input emaxi_arready;//read address ready
// Slave Port
input [SAW-1:0] esaxi_araddr; //read address
input [3:0] esaxi_arlen; //burst lenght (the number of data transfers)
input [2:0] esaxi_arsize; //burst size (the size of each transfer)
input [1:0] esaxi_arburst; //burst type
input [1:0] esaxi_arlock; //lock type (atomic characteristics)
input [3:0] esaxi_arcache; //memory type
input [2:0] esaxi_arprot; //protection type
input esaxi_arvalid; //write address valid
//########################
//# Read data channel
//########################
// Master Port
input [MDW-1:0] emaxi_rdata; //read data
input [1:0] emaxi_rresp; //read response
input emaxi_rlast; //read last, indicates last transfer in burst
input emaxi_rvalid;//read valid
// Slave Port
input esaxi_rready; //read ready
//##########
//# Outputs
//##########
// global signals
output csysack;//exit low-power state acknowledgement
output cactive;//clock active
output reset_chip;
output reset_fpga;
// LVDS FMC Port
output [7:0] tx_data_p;
output [7:0] tx_data_n;
output tx_frame_p;
output tx_frame_n;
output tx_lclk_p;
output tx_lclk_n;
output rx_wr_wait_p;
output rx_wr_wait_n;
output rx_rd_wait_p;
output rx_rd_wait_n;
output rx_cclk_p;
output rx_cclk_n;
//########################
//# Write address channel
//########################
// Master Port
output [MAW-1:0] emaxi_awaddr; //write address
output [3:0] emaxi_awlen; //burst length (number of data transfers)
output [2:0] emaxi_awsize; //burst size (the size of each transfer)
output [1:0] emaxi_awburst; //burst type
output [1:0] emaxi_awlock; //lock type (atomic characteristics)
output [3:0] emaxi_awcache; //memory type
output [2:0] emaxi_awprot; //protection type
output emaxi_awvalid; //write address valid
// Slave Port
output esaxi_awready; //write address ready
//########################
//# Write data channel
//########################
// Master Port
output [MDW-1:0] emaxi_wdata; //write data
output [MSTW-1:0] emaxi_wstrb; //write strobes
output emaxi_wlast; //write last, indicates last transfer in burst
output emaxi_wvalid;//write valid
// Slave Port
output esaxi_wready;//write ready
//########################
// Write response channel
//########################
// Master Port
output emaxi_bready;//response ready
// Slave Port
output [1:0] esaxi_bresp; //write response
output esaxi_bvalid;//write response valid
//########################
//# Read address channel
//########################
// Master Port
output [MAW-1:0] emaxi_araddr; //read address
output [3:0] emaxi_arlen; //burst lenght (number of data transfers)
output [2:0] emaxi_arsize; //burst size (the size of each transfer)
output [1:0] emaxi_arburst; //burst type
output [1:0] emaxi_arlock; //lock type (atomic characteristics)
output [3:0] emaxi_arcache; //memory type
output [2:0] emaxi_arprot; //protection type
output emaxi_arvalid; //write address valid
// Slave Port
output esaxi_arready; //read address ready
//########################
//# Read data channel
//########################
// Master Port
output emaxi_rready; //read ready
// Slave Port
output [SDW-1:0] esaxi_rdata; //read data
output [1:0] esaxi_rresp; //read response
output esaxi_rlast; //read last, indicates last transfer in burst
output esaxi_rvalid;//read valid
//#######################################################################
//# The following features are not supported (AXI4 only)
//# If un-commented, those signals have to be driven with default values
//#######################################################################
// input emaxi_buser; //user signal
// input emaxi_ruser; //user signal
output [3:0] emaxi_awqos; //quality of service default 4'b0000
// output [3:0] emaxi_awregion;//region identifier
// output emaxi_awuser; //user signal
// output emaxi_wuser; //user signal
output [3:0] emaxi_arqos; //quality of service default 4'b0000
// output [3:0] emaxi_arregion;//region identifier
// output emaxi_aruser; //user signal
input [3:0] esaxi_awqos; //Quality of Service default 4'b0000
// input [3:0] awregion; //region identifier
// input awuser; //user signal
// input wuser; //user signal
input [3:0] esaxi_arqos; //quality of service default 4'b0000
// input [3:0] arregion; //region identifier (AXI4 only)
// input aruser; //user signal (AXI4 only)
// output buser; //user signal (AXI4 only)
// output ruser; //user signal (AXI4 only)
//#######################################################################
//# The following features are not supported (AXI3 only)
//# If commented, the slave signals have to be driven with default values
//#######################################################################
input [SIDW-1:0] esaxi_awid; //write address ID
input [SIDW-1:0] esaxi_wid; //write ID tag (supported only in AXI3)
input [MIDW-1:0] emaxi_bid; //response ID tag
input [SIDW-1:0] esaxi_arid; //read address ID
input [MIDW-1:0] emaxi_rid; //read ID tag
output [MIDW-1:0] emaxi_awid; //write address ID
output [MIDW-1:0] emaxi_wid; //write ID tag (supported only in AXI3)
output [SIDW-1:0] esaxi_bid; //response ID tag
output [MIDW-1:0] emaxi_arid; //read address ID
output [SIDW-1:0] esaxi_rid; //read ID tag (must match arid of transaction)
// wire [SIDW-1:0] esaxi_awid = SIDW'd0; //write address ID
// wire [SIDW-1:0] esaxi_wid = SIDW'd0; //write ID tag (supported only in AXI3)
// wire [MIDW-1:0] emaxi_bid; //response ID tag
// wire [SIDW-1:0] esaxi_arid = SIDW'd0; //read address ID
// wire [MIDW-1:0] emaxi_rid; //read ID tag
// wire [MIDW-1:0] emaxi_awid; //write address ID
// wire [MIDW-1:0] emaxi_wid; //write ID tag (supported only in AXI3)
// wire [SIDW-1:0] esaxi_bid = SIDW'd0; //response ID tag
// wire [MIDW-1:0] emaxi_arid; //read address ID
// wire [SIDW-1:0] esaxi_rid = SIDW'd0; //read ID tag (must match arid of transaction)
/*AUTOINPUT*/
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire elink_access_inb; // From ewrapper_link_top of ewrapper_link_top.v
wire elink_access_outb; // From axi_elink_if of axi_elink_if.v
wire elink_cclk_enb; // From axi_elink_if of axi_elink_if.v
wire [1:0] elink_clk_div; // From axi_elink_if of axi_elink_if.v
wire [3:0] elink_ctrlmode_inb; // From ewrapper_link_top of ewrapper_link_top.v
wire [3:0] elink_ctrlmode_outb; // From axi_elink_if of axi_elink_if.v
wire [31:0] elink_data_inb; // From ewrapper_link_top of ewrapper_link_top.v
wire [31:0] elink_data_outb; // From axi_elink_if of axi_elink_if.v
wire [1:0] elink_datamode_inb; // From ewrapper_link_top of ewrapper_link_top.v
wire [1:0] elink_datamode_outb; // From axi_elink_if of axi_elink_if.v
wire elink_disable; // From axi_elink_if of axi_elink_if.v
wire [31:0] elink_dstaddr_outb; // From axi_elink_if of axi_elink_if.v
wire elink_rd_wait_inb; // From ewrapper_link_top of ewrapper_link_top.v
wire elink_rd_wait_outb; // From axi_elink_if of axi_elink_if.v
wire [31:0] elink_srcaddr_inb; // From ewrapper_link_top of ewrapper_link_top.v
wire [31:0] elink_srcaddr_outb; // From axi_elink_if of axi_elink_if.v
wire elink_wr_wait_inb; // From ewrapper_link_top of ewrapper_link_top.v
wire elink_wr_wait_outb; // From axi_elink_if of axi_elink_if.v
wire elink_write_inb; // From ewrapper_link_top of ewrapper_link_top.v
wire elink_write_outb; // From axi_elink_if of axi_elink_if.v
wire emaxi_access_inb; // From axi_master of axi_master.v
wire emaxi_access_outb; // From axi_elink_if of axi_elink_if.v
wire [3:0] emaxi_ctrlmode_inb; // From axi_master of axi_master.v
wire [3:0] emaxi_ctrlmode_outb; // From axi_elink_if of axi_elink_if.v
wire [31:0] emaxi_data_inb; // From axi_master of axi_master.v
wire [31:0] emaxi_data_outb; // From axi_elink_if of axi_elink_if.v
wire [1:0] emaxi_datamode_inb; // From axi_master of axi_master.v
wire [1:0] emaxi_datamode_outb; // From axi_elink_if of axi_elink_if.v
wire [31:0] emaxi_dstaddr_inb; // From axi_master of axi_master.v
wire [31:0] emaxi_dstaddr_outb; // From axi_elink_if of axi_elink_if.v
wire emaxi_rd_wait_inb; // From axi_master of axi_master.v
wire [31:0] emaxi_srcaddr_inb; // From axi_master of axi_master.v
wire [31:0] emaxi_srcaddr_outb; // From axi_elink_if of axi_elink_if.v
wire emaxi_wr_wait_inb; // From axi_master of axi_master.v
wire emaxi_wr_wait_outb; // From axi_elink_if of axi_elink_if.v
wire emaxi_write_inb; // From axi_master of axi_master.v
wire emaxi_write_outb; // From axi_elink_if of axi_elink_if.v
wire esaxi_access_inb; // From axi_slave of axi_slave.v
wire esaxi_access_outb; // From axi_elink_if of axi_elink_if.v
wire [3:0] esaxi_ctrlmode_inb; // From axi_slave of axi_slave.v
wire [3:0] esaxi_ctrlmode_outb; // From axi_elink_if of axi_elink_if.v
wire [31:0] esaxi_data_inb; // From axi_slave of axi_slave.v
wire [31:0] esaxi_data_outb; // From axi_elink_if of axi_elink_if.v
wire [1:0] esaxi_datamode_inb; // From axi_slave of axi_slave.v
wire [1:0] esaxi_datamode_outb; // From axi_elink_if of axi_elink_if.v
wire [31:0] esaxi_dstaddr_inb; // From axi_slave of axi_slave.v
wire [31:0] esaxi_dstaddr_outb; // From axi_elink_if of axi_elink_if.v
wire esaxi_rd_wait_inb; // From axi_slave of axi_slave.v
wire esaxi_rd_wait_outb; // From axi_elink_if of axi_elink_if.v
wire [31:0] esaxi_srcaddr_inb; // From axi_slave of axi_slave.v
wire [31:0] esaxi_srcaddr_outb; // From axi_elink_if of axi_elink_if.v
wire esaxi_wr_wait_inb; // From axi_slave of axi_slave.v
wire esaxi_wr_wait_outb; // From axi_elink_if of axi_elink_if.v
wire esaxi_write_inb; // From axi_slave of axi_slave.v
wire esaxi_write_outb; // From axi_elink_if of axi_elink_if.v
// End of automatics
//#########
//# Regs
//#########
//#########
//# Wires
//#########
wire emaxi_reset;
wire esaxi_reset;
wire rx_eclk;
wire [31:0] elink_dstaddr_inb;
wire [31:0] elink_dstaddr_tmp;
wire ext_mem_access;
//#################
//# global signals
//#################
wire reset = ~resetn;
assign emaxi_reset = ~emaxi_aresetn;
assign esaxi_reset = ~esaxi_aresetn;
//##################################
//# AXI Slave Port Instantiation
//##################################
/*axi_slave AUTO_TEMPLATE(.eclk (rx_eclk),
.reset (esaxi_reset),
.aclk (esaxi_aclk),
.aw\(.*\) (esaxi_aw\1[]),
.w\(.*\) (esaxi_w\1[]),
.b\(.*\) (esaxi_b\1[]),
.ar\(.*\) (esaxi_ar\1[]),
.r\(.*\) (esaxi_r\1[]),
.emesh_\(.*\) (esaxi_\1[]),
);
*/
axi_slave axi_slave(/*AUTOINST*/
// Outputs
.csysack (csysack),
.cactive (cactive),
.awready (esaxi_awready), // Templated
.wready (esaxi_wready), // Templated
.bid (esaxi_bid[12-1:0]), // Templated
.bresp (esaxi_bresp[1:0]), // Templated
.bvalid (esaxi_bvalid), // Templated
.arready (esaxi_arready), // Templated
.rid (esaxi_rid[12-1:0]), // Templated
.rdata (esaxi_rdata[32-1:0]), // Templated
.rresp (esaxi_rresp[1:0]), // Templated
.rlast (esaxi_rlast), // Templated
.rvalid (esaxi_rvalid), // Templated
.emesh_access_inb(esaxi_access_inb), // Templated
.emesh_write_inb (esaxi_write_inb), // Templated
.emesh_datamode_inb(esaxi_datamode_inb[1:0]), // Templated
.emesh_ctrlmode_inb(esaxi_ctrlmode_inb[3:0]), // Templated
.emesh_dstaddr_inb(esaxi_dstaddr_inb[31:0]), // Templated
.emesh_srcaddr_inb(esaxi_srcaddr_inb[31:0]), // Templated
.emesh_data_inb (esaxi_data_inb[31:0]), // Templated
.emesh_wr_wait_inb(esaxi_wr_wait_inb), // Templated
.emesh_rd_wait_inb(esaxi_rd_wait_inb), // Templated
// Inputs
.aclk (esaxi_aclk), // Templated
.eclk (rx_eclk), // Templated
.reset (esaxi_reset), // Templated
.csysreq (csysreq),
.awid (esaxi_awid[12-1:0]), // Templated
.awaddr (esaxi_awaddr[32-1:0]), // Templated
.awlen (esaxi_awlen[3:0]), // Templated
.awsize (esaxi_awsize[2:0]), // Templated
.awburst (esaxi_awburst[1:0]), // Templated
.awlock (esaxi_awlock[1:0]), // Templated
.awcache (esaxi_awcache[3:0]), // Templated
.awprot (esaxi_awprot[2:0]), // Templated
.awvalid (esaxi_awvalid), // Templated
.wid (esaxi_wid[12-1:0]), // Templated
.wdata (esaxi_wdata[32-1:0]), // Templated
.wstrb (esaxi_wstrb[4-1:0]), // Templated
.wlast (esaxi_wlast), // Templated
.wvalid (esaxi_wvalid), // Templated
.bready (esaxi_bready), // Templated
.arid (esaxi_arid[12-1:0]), // Templated
.araddr (esaxi_araddr[32-1:0]), // Templated
.arlen (esaxi_arlen[3:0]), // Templated
.arsize (esaxi_arsize[2:0]), // Templated
.arburst (esaxi_arburst[1:0]), // Templated
.arlock (esaxi_arlock[1:0]), // Templated
.arcache (esaxi_arcache[3:0]), // Templated
.arprot (esaxi_arprot[2:0]), // Templated
.arvalid (esaxi_arvalid), // Templated
.rready (esaxi_rready), // Templated
.emesh_access_outb(esaxi_access_outb), // Templated
.emesh_write_outb(esaxi_write_outb), // Templated
.emesh_datamode_outb(esaxi_datamode_outb[1:0]), // Templated
.emesh_ctrlmode_outb(esaxi_ctrlmode_outb[3:0]), // Templated
.emesh_dstaddr_outb(esaxi_dstaddr_outb[31:0]), // Templated
.emesh_srcaddr_outb(esaxi_srcaddr_outb[31:0]), // Templated
.emesh_data_outb (esaxi_data_outb[31:0]), // Templated
.emesh_wr_wait_outb(esaxi_wr_wait_outb), // Templated
.emesh_rd_wait_outb(esaxi_rd_wait_outb), // Templated
.awqos (esaxi_awqos[3:0]), // Templated
.arqos (esaxi_arqos[3:0])); // Templated
//##################################
//# AXI Master Port Instantiation
//##################################
/*axi_master AUTO_TEMPLATE(.eclk (rx_eclk),
.reset (emaxi_reset),
.aclk (emaxi_aclk),
.aw\(.*\) (emaxi_aw\1[]),
.w\(.*\) (emaxi_w\1[]),
.b\(.*\) (emaxi_b\1[]),
.ar\(.*\) (emaxi_ar\1[]),
.r\(.*\) (emaxi_r\1[]),
.emesh_\(.*\) (emaxi_\1[]),
);
*/
axi_master axi_master(/*AUTOINST*/
// Outputs
.awid (emaxi_awid[6-1:0]), // Templated
.awaddr (emaxi_awaddr[32-1:0]), // Templated
.awlen (emaxi_awlen[3:0]), // Templated
.awsize (emaxi_awsize[2:0]), // Templated
.awburst (emaxi_awburst[1:0]), // Templated
.awlock (emaxi_awlock[1:0]), // Templated
.awcache (emaxi_awcache[3:0]), // Templated
.awprot (emaxi_awprot[2:0]), // Templated
.awvalid (emaxi_awvalid), // Templated
.wid (emaxi_wid[6-1:0]), // Templated
.wdata (emaxi_wdata[64-1:0]), // Templated
.wstrb (emaxi_wstrb[8-1:0]), // Templated
.wlast (emaxi_wlast), // Templated
.wvalid (emaxi_wvalid), // Templated
.bready (emaxi_bready), // Templated
.arid (emaxi_arid[6-1:0]), // Templated
.araddr (emaxi_araddr[32-1:0]), // Templated
.arlen (emaxi_arlen[3:0]), // Templated
.arsize (emaxi_arsize[2:0]), // Templated
.arburst (emaxi_arburst[1:0]), // Templated
.arlock (emaxi_arlock[1:0]), // Templated
.arcache (emaxi_arcache[3:0]), // Templated
.arprot (emaxi_arprot[2:0]), // Templated
.arvalid (emaxi_arvalid), // Templated
.rready (emaxi_rready), // Templated
.emesh_access_inb (emaxi_access_inb), // Templated
.emesh_write_inb (emaxi_write_inb), // Templated
.emesh_datamode_inb (emaxi_datamode_inb[1:0]), // Templated
.emesh_ctrlmode_inb (emaxi_ctrlmode_inb[3:0]), // Templated
.emesh_dstaddr_inb (emaxi_dstaddr_inb[31:0]), // Templated
.emesh_srcaddr_inb (emaxi_srcaddr_inb[31:0]), // Templated
.emesh_data_inb (emaxi_data_inb[31:0]), // Templated
.emesh_wr_wait_inb (emaxi_wr_wait_inb), // Templated
.emesh_rd_wait_inb (emaxi_rd_wait_inb), // Templated
.awqos (emaxi_awqos[3:0]), // Templated
.arqos (emaxi_arqos[3:0]), // Templated
// Inputs
.aclk (emaxi_aclk), // Templated
.eclk (rx_eclk), // Templated
.reset (emaxi_reset), // Templated
.awready (emaxi_awready), // Templated
.wready (emaxi_wready), // Templated
.bid (emaxi_bid[6-1:0]), // Templated
.bresp (emaxi_bresp[1:0]), // Templated
.bvalid (emaxi_bvalid), // Templated
.arready (emaxi_arready), // Templated
.rid (emaxi_rid[6-1:0]), // Templated
.rdata (emaxi_rdata[64-1:0]), // Templated
.rresp (emaxi_rresp[1:0]), // Templated
.rlast (emaxi_rlast), // Templated
.rvalid (emaxi_rvalid), // Templated
.emesh_access_outb (emaxi_access_outb), // Templated
.emesh_write_outb (emaxi_write_outb), // Templated
.emesh_datamode_outb (emaxi_datamode_outb[1:0]), // Templated
.emesh_ctrlmode_outb (emaxi_ctrlmode_outb[3:0]), // Templated
.emesh_dstaddr_outb (emaxi_dstaddr_outb[31:0]), // Templated
.emesh_srcaddr_outb (emaxi_srcaddr_outb[31:0]), // Templated
.emesh_data_outb (emaxi_data_outb[31:0]), // Templated
.emesh_wr_wait_outb (emaxi_wr_wait_outb)); // Templated
//#####################################
//# ELINK (CHIP Port) Instantiation
//#####################################
//# "manual remapping" of external memory address seen by the chips
assign ext_mem_access = (elink_dstaddr_tmp[31:28] == `VIRT_EXT_MEM) &
~(elink_dstaddr_tmp[31:20] == `AXI_COORD);
assign elink_dstaddr_inb[31:28] = ext_mem_access ? `PHYS_EXT_MEM :
elink_dstaddr_tmp[31:28];
assign elink_dstaddr_inb[27:0] = elink_dstaddr_tmp[27:0];
/*ewrapper_link_top AUTO_TEMPLATE(.emesh_clk_inb (rx_eclk),
.burst_en (1'b1),
.emesh_dstaddr_inb(elink_dstaddr_tmp[31:0]),
.emesh_\(.*\) (elink_\1[]),
);
*/
ewrapper_link_top ewrapper_link_top
(/*AUTOINST*/
// Outputs
.emesh_clk_inb (rx_eclk), // Templated
.emesh_access_inb (elink_access_inb), // Templated
.emesh_write_inb (elink_write_inb), // Templated
.emesh_datamode_inb (elink_datamode_inb[1:0]), // Templated
.emesh_ctrlmode_inb (elink_ctrlmode_inb[3:0]), // Templated
.emesh_dstaddr_inb (elink_dstaddr_tmp[31:0]), // Templated
.emesh_srcaddr_inb (elink_srcaddr_inb[31:0]), // Templated
.emesh_data_inb (elink_data_inb[31:0]), // Templated
.emesh_wr_wait_inb (elink_wr_wait_inb), // Templated
.emesh_rd_wait_inb (elink_rd_wait_inb), // Templated
.txo_data_p (tx_data_p[7:0]),
.txo_data_n (tx_data_n[7:0]),
.txo_frame_p (tx_frame_p),
.txo_frame_n (tx_frame_n),
.txo_lclk_p (tx_lclk_p),
.txo_lclk_n (tx_lclk_n),
.rxo_wr_wait_p (rx_wr_wait_p),
.rxo_wr_wait_n (rx_wr_wait_n),
.rxo_rd_wait_p (rx_rd_wait_p),
.rxo_rd_wait_n (rx_rd_wait_n),
.rxi_cclk_p (rx_cclk_p),
.rxi_cclk_n (rx_cclk_n),
// Inputs
.reset (reset),
.clkin_100 (clkin_100),
.elink_disable (elink_disable),
.elink_cclk_enb (elink_cclk_enb),
.elink_clk_div (elink_clk_div[1:0]),
.emesh_access_outb (elink_access_outb), // Templated
.emesh_write_outb (elink_write_outb), // Templated
.emesh_datamode_outb (elink_datamode_outb[1:0]), // Templated
.emesh_ctrlmode_outb (elink_ctrlmode_outb[3:0]), // Templated
.emesh_dstaddr_outb (elink_dstaddr_outb[31:0]), // Templated
.emesh_srcaddr_outb (elink_srcaddr_outb[31:0]), // Templated
.emesh_data_outb (elink_data_outb[31:0]), // Templated
.emesh_wr_wait_outb (elink_wr_wait_outb), // Templated
.emesh_rd_wait_outb (elink_rd_wait_outb), // Templated
.rxi_data_p (rx_data_p[7:0]),
.rxi_data_n (rx_data_n[7:0]),
.rxi_frame_p (rx_frame_p),
.rxi_frame_n (rx_frame_n),
.rxi_lclk_p (rx_lclk_p),
.rxi_lclk_n (rx_lclk_n),
.txi_wr_wait_p (tx_wr_wait_p),
.txi_wr_wait_n (tx_wr_wait_n),
.txi_rd_wait_p (tx_rd_wait_p),
.txi_rd_wait_n (tx_rd_wait_n),
.burst_en (1'b1)); // Templated
//####################################
//# AXI-ELINK Interface Instantiation
//####################################
/*axi_elink_if AUTO_TEMPLATE(.eclk (rx_eclk),
.aclk (esaxi_aclk),
);
*/
axi_elink_if axi_elink_if
(/*AUTOINST*/
// Outputs
.reset_chip (reset_chip),
.reset_fpga (reset_fpga),
.emaxi_access_outb (emaxi_access_outb),
.emaxi_write_outb (emaxi_write_outb),
.emaxi_datamode_outb (emaxi_datamode_outb[1:0]),
.emaxi_ctrlmode_outb (emaxi_ctrlmode_outb[3:0]),
.emaxi_dstaddr_outb (emaxi_dstaddr_outb[31:0]),
.emaxi_srcaddr_outb (emaxi_srcaddr_outb[31:0]),
.emaxi_data_outb (emaxi_data_outb[31:0]),
.emaxi_wr_wait_outb (emaxi_wr_wait_outb),
.esaxi_access_outb (esaxi_access_outb),
.esaxi_write_outb (esaxi_write_outb),
.esaxi_datamode_outb (esaxi_datamode_outb[1:0]),
.esaxi_ctrlmode_outb (esaxi_ctrlmode_outb[3:0]),
.esaxi_dstaddr_outb (esaxi_dstaddr_outb[31:0]),
.esaxi_srcaddr_outb (esaxi_srcaddr_outb[31:0]),
.esaxi_data_outb (esaxi_data_outb[31:0]),
.esaxi_wr_wait_outb (esaxi_wr_wait_outb),
.esaxi_rd_wait_outb (esaxi_rd_wait_outb),
.elink_access_outb (elink_access_outb),
.elink_write_outb (elink_write_outb),
.elink_datamode_outb (elink_datamode_outb[1:0]),
.elink_ctrlmode_outb (elink_ctrlmode_outb[3:0]),
.elink_dstaddr_outb (elink_dstaddr_outb[31:0]),
.elink_srcaddr_outb (elink_srcaddr_outb[31:0]),
.elink_data_outb (elink_data_outb[31:0]),
.elink_wr_wait_outb (elink_wr_wait_outb),
.elink_rd_wait_outb (elink_rd_wait_outb),
.elink_disable (elink_disable),
.elink_cclk_enb (elink_cclk_enb),
.elink_clk_div (elink_clk_div[1:0]),
// Inputs
.eclk (rx_eclk), // Templated
.aclk (esaxi_aclk), // Templated
.reset (reset),
.emaxi_access_inb (emaxi_access_inb),
.emaxi_write_inb (emaxi_write_inb),
.emaxi_datamode_inb (emaxi_datamode_inb[1:0]),
.emaxi_ctrlmode_inb (emaxi_ctrlmode_inb[3:0]),
.emaxi_dstaddr_inb (emaxi_dstaddr_inb[31:0]),
.emaxi_srcaddr_inb (emaxi_srcaddr_inb[31:0]),
.emaxi_data_inb (emaxi_data_inb[31:0]),
.emaxi_wr_wait_inb (emaxi_wr_wait_inb),
.emaxi_rd_wait_inb (emaxi_rd_wait_inb),
.esaxi_access_inb (esaxi_access_inb),
.esaxi_write_inb (esaxi_write_inb),
.esaxi_datamode_inb (esaxi_datamode_inb[1:0]),
.esaxi_ctrlmode_inb (esaxi_ctrlmode_inb[3:0]),
.esaxi_dstaddr_inb (esaxi_dstaddr_inb[31:0]),
.esaxi_srcaddr_inb (esaxi_srcaddr_inb[31:0]),
.esaxi_data_inb (esaxi_data_inb[31:0]),
.esaxi_wr_wait_inb (esaxi_wr_wait_inb),
.esaxi_rd_wait_inb (esaxi_rd_wait_inb),
.elink_access_inb (elink_access_inb),
.elink_write_inb (elink_write_inb),
.elink_datamode_inb (elink_datamode_inb[1:0]),
.elink_ctrlmode_inb (elink_ctrlmode_inb[3:0]),
.elink_dstaddr_inb (elink_dstaddr_inb[31:0]),
.elink_srcaddr_inb (elink_srcaddr_inb[31:0]),
.elink_data_inb (elink_data_inb[31:0]),
.elink_wr_wait_inb (elink_wr_wait_inb),
.elink_rd_wait_inb (elink_rd_wait_inb));
endmodule // elink_ip_top
// Local Variables:
// verilog-library-directories:("." "../elink" "../axi")
// End:

View File

@ -0,0 +1,272 @@
/*
File: ewrapper_io_rx_slow.v
This file is part of the Parallella Project .
Copyright (C) 2013 Adapteva, Inc.
Contributed by Roman Trogan <support@adapteva.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program (see the file COPYING). If not, see
<http://www.gnu.org/licenses/>.
*/
`include "fpga_constants.v"
module ewrapper_io_rx_slow (/*AUTOARG*/
// Outputs
CLK_DIV_OUT, DATA_IN_TO_DEVICE,
// Inputs
CLK_IN_P, CLK_IN_N, CLK_RESET, IO_RESET, DATA_IN_FROM_PINS_P,
DATA_IN_FROM_PINS_N, BITSLIP
);
//###########
//# INPUTS
//###########
input CLK_IN_P; // Differential clock from IOB
input CLK_IN_N;
input CLK_RESET;
input IO_RESET;
input [8:0] DATA_IN_FROM_PINS_P;
input [8:0] DATA_IN_FROM_PINS_N;
input BITSLIP;
//#############
//# OUTPUTS
//#############
output CLK_DIV_OUT; // Slow clock output
output [71:0] DATA_IN_TO_DEVICE;
//############
//# REGS
//############
reg [3:0] clk_edge;
reg rx_pedge_first;
reg [8:0] clk_even_reg;
reg [8:0] clk_odd_reg;
reg [8:0] clk0_even;
reg [8:0] clk1_even;
reg [8:0] clk2_even;
reg [8:0] clk3_even;
reg [8:0] clk0_odd;
reg [8:0] clk1_odd;
reg [8:0] clk2_odd;
reg [8:0] clk3_odd;
reg [71:0] rx_out_sync_pos;
reg rx_outclock_del_45;
reg rx_outclock_del_135;
reg [71:0] rx_out;
//############
//# WIRES
//############
wire reset;
wire rx_outclock;
wire rxi_lclk;
wire [71:0] rx_out_int;
wire [8:0] rx_in_t;
wire [8:0] rx_in;
wire [8:0] clk_even;
wire [8:0] clk_odd;
wire [8:0] iddr_q1;
wire [8:0] iddr_q2;
// Inversions for E16/E64 migration
`ifdef TARGET_E16
assign rx_in = rx_in_t;
assign clk_even = iddr_q1;
assign clk_odd = iddr_q2;
`define CLKEDGE_DDR "SAME_EDGE_PIPELINED"
`elsif TARGET_E64
assign rx_in = ~rx_in_t;
assign clk_even = iddr_q2;
assign clk_odd = iddr_q1;
`define CLKEDGE_DDR "SAME_EDGE"
`endif
/*AUTOINPUT*/
/*AUTOWIRE*/
assign reset = IO_RESET;
assign DATA_IN_TO_DEVICE[71:0] = rx_out[71:0];
assign CLK_DIV_OUT = rx_outclock;
//################################
//# Input Buffers Instantiation
//################################
IBUFDS
#(.DIFF_TERM ("TRUE"), // Differential termination
.IOSTANDARD (`IOSTD_ELINK))
ibufds_inst[0:8]
(.I (DATA_IN_FROM_PINS_P),
.IB (DATA_IN_FROM_PINS_N),
.O (rx_in_t));
//#####################
//# Clock Buffers
//#####################
IBUFGDS
#(.DIFF_TERM ("TRUE"), // Differential termination
.IOSTANDARD (`IOSTD_ELINK))
ibufds_clk_inst
(.I (CLK_IN_P),
.IB (CLK_IN_N),
.O (rxi_lclk));
// BUFR generates the slow clock
BUFR
#(.SIM_DEVICE("7SERIES"),
.BUFR_DIVIDE("4"))
clkout_buf_inst
(.O (rx_outclock),
.CE(1'b1),
.CLR(CLK_RESET),
.I (rxi_lclk));
//#################################
//# De-serialization Cycle Counter
//#################################
always @ (posedge rxi_lclk) begin
if(rx_pedge_first)
clk_edge <= 4'b1000;
else
clk_edge <= {clk_edge[2:0], clk_edge[3]};
end
//################################################################
//# Posedge Detection of the Slow Clock in the Fast Clock Domain
//################################################################
always @ (negedge rxi_lclk) begin
rx_outclock_del_45 <= rx_outclock;
rx_outclock_del_135 <= rx_outclock_del_45;
rx_pedge_first <= ~rx_outclock_del_45 & ~rx_outclock_del_135;
end
//#############################
//# De-serialization Output
//#############################
// Synchronizing the clocks (fast to slow)
always @ (posedge rxi_lclk or posedge reset)
if(reset)
rx_out_sync_pos <= 72'd0;
else
rx_out_sync_pos <= rx_out_int;
always @ (posedge rx_outclock or posedge reset)
if(reset)
rx_out <= 72'd0;
else
rx_out <= rx_out_sync_pos;
//#############################
//# IDDR instantiation
//#############################
IDDR #(
.DDR_CLK_EDGE (`CLKEDGE_DDR),
.SRTYPE ("ASYNC"))
iddr_inst[0:8] (
.Q1 (iddr_q1),
.Q2 (iddr_q2),
.C (rxi_lclk),
.CE (1'b1),
.D (rx_in),
.R (1'b0),
.S (1'b0));
//#############################
//# De-serialization Registers
//#############################
always @ (posedge rxi_lclk or posedge reset) begin
if(reset) begin
clk_even_reg <= 9'd0;
clk_odd_reg <= 9'd0;
clk0_even <= 9'd0;
clk0_odd <= 9'd0;
clk1_even <= 9'd0;
clk1_odd <= 9'd0;
clk2_even <= 9'd0;
clk2_odd <= 9'd0;
clk3_even <= 9'd0;
clk3_odd <= 9'd0;
end else begin
clk_even_reg <= clk_even;
clk_odd_reg <= clk_odd;
if(clk_edge[0]) begin
clk0_even <= clk_even_reg;
clk0_odd <= clk_odd_reg;
end
if(clk_edge[1]) begin
clk1_even <= clk_even_reg;
clk1_odd <= clk_odd_reg;
end
if(clk_edge[2]) begin
clk2_even <= clk_even_reg;
clk2_odd <= clk_odd_reg;
end
if(clk_edge[3]) begin
clk3_even <= clk_even_reg;
clk3_odd <= clk_odd_reg;
end
end // else: !if(reset)
end // always @ (posedge rxi_lclk or posedge reset)
//#####################################
//# De-serialization Data Construction
//#####################################
assign rx_out_int[71:64]={clk0_even[8],clk0_odd[8],clk1_even[8],clk1_odd[8],
clk2_even[8],clk2_odd[8],clk3_even[8],clk3_odd[8]};
assign rx_out_int[63:56]={clk0_even[7],clk0_odd[7],clk1_even[7],clk1_odd[7],
clk2_even[7],clk2_odd[7],clk3_even[7],clk3_odd[7]};
assign rx_out_int[55:48]={clk0_even[6],clk0_odd[6],clk1_even[6],clk1_odd[6],
clk2_even[6],clk2_odd[6],clk3_even[6],clk3_odd[6]};
assign rx_out_int[47:40]={clk0_even[5],clk0_odd[5],clk1_even[5],clk1_odd[5],
clk2_even[5],clk2_odd[5],clk3_even[5],clk3_odd[5]};
assign rx_out_int[39:32]={clk0_even[4],clk0_odd[4],clk1_even[4],clk1_odd[4],
clk2_even[4],clk2_odd[4],clk3_even[4],clk3_odd[4]};
assign rx_out_int[31:24]={clk0_even[3],clk0_odd[3],clk1_even[3],clk1_odd[3],
clk2_even[3],clk2_odd[3],clk3_even[3],clk3_odd[3]};
assign rx_out_int[23:16]={clk0_even[2],clk0_odd[2],clk1_even[2],clk1_odd[2],
clk2_even[2],clk2_odd[2],clk3_even[2],clk3_odd[2]};
assign rx_out_int[15:8] ={clk0_even[1],clk0_odd[1],clk1_even[1],clk1_odd[1],
clk2_even[1],clk2_odd[1],clk3_even[1],clk3_odd[1]};
assign rx_out_int[7:0] ={clk0_even[0],clk0_odd[0],clk1_even[0],clk1_odd[0],
clk2_even[0],clk2_odd[0],clk3_even[0],clk3_odd[0]};
endmodule // dv_io_rx

View File

@ -0,0 +1,249 @@
/*
File: ewrapper_io_tx_slow.v
This file is part of the Parallella Project .
Copyright (C) 2013 Adapteva, Inc.
Contributed by Roman Trogan <support@adapteva.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program (see the file COPYING). If not, see
<http://www.gnu.org/licenses/>.
*/
`include "fpga_constants.v"
module ewrapper_io_tx_slow
(/*AUTOARG*/
// Outputs
DATA_OUT_TO_PINS_P, DATA_OUT_TO_PINS_N, LCLK_OUT_TO_PINS_P,
LCLK_OUT_TO_PINS_N,
// Inputs
CLK_IN, CLK_IN_90, CLK_DIV_IN, CLK_RESET, IO_RESET, elink_disable,
DATA_OUT_FROM_DEVICE
);
//###########
//# INPUTS
//###########
input CLK_IN; // Fast clock input from PLL/MMCM
input CLK_IN_90; // Fast clock input with 90deg phase shift
input CLK_DIV_IN; // Slow clock input from PLL/MMCM
input CLK_RESET;
input IO_RESET;
input elink_disable;
input [71:0] DATA_OUT_FROM_DEVICE;
//#############
//# OUTPUTS
//#############
output [8:0] DATA_OUT_TO_PINS_P;
output [8:0] DATA_OUT_TO_PINS_N;
output LCLK_OUT_TO_PINS_P;
output LCLK_OUT_TO_PINS_N;
//############
//# REGS
//############
reg [1:0] clk_cnt;
reg tx_coreclock_del_45;
reg tx_coreclock_del_135;
reg [8:0] clk_even_reg;
reg [8:0] clk_odd_reg;
reg [71:0] tx_in_sync;
reg tx_pedge_first;
reg [3:0] cycle_sel;
//############
//# WIRES
//############
wire txo_lclk;
wire txo_lclk90;
wire tx_coreclock;
wire reset;
wire [8:0] clk_even;
wire [8:0] clk0_even;
wire [8:0] clk1_even;
wire [8:0] clk2_even;
wire [8:0] clk3_even;
wire [8:0] clk_odd;
wire [8:0] clk0_odd;
wire [8:0] clk1_odd;
wire [8:0] clk2_odd;
wire [8:0] clk3_odd;
wire [71:0] tx_in;
wire [8:0] tx_out;
wire tx_lclk_out;
wire [8:0] DATA_OUT_TO_PINS_P;
wire [8:0] DATA_OUT_TO_PINS_N;
wire LCLK_OUT_TO_PINS_P;
wire LCLK_OUT_TO_PINS_N;
// Inversions for E16/E64 migration
`ifdef TARGET_E16
wire elink_invert = 1'b0;
`elsif TARGET_E64
wire elink_invert = 1'b1;
`endif
/*AUTOINPUT*/
/*AUTOWIRE*/
assign reset = IO_RESET;
assign tx_in[71:0] = DATA_OUT_FROM_DEVICE[71:0];
assign txo_lclk = CLK_IN;
assign txo_lclk90 = CLK_IN_90;
assign tx_coreclock = CLK_DIV_IN;
//#################################################
//# Synchronize incoming data to fast clock domain
//#################################################
always @ (posedge txo_lclk)
if(tx_pedge_first)
tx_in_sync <= elink_invert ? ~tx_in : tx_in;
//################################
//# Output Buffers Instantiation
//################################
OBUFTDS #(.IOSTANDARD (`IOSTD_ELINK))
obufds_inst [8:0]
(.O (DATA_OUT_TO_PINS_P),
.OB (DATA_OUT_TO_PINS_N),
.I (tx_out),
.T ({1'b0, {8{elink_disable}}})); // Frame is always enabled
OBUFDS #(.IOSTANDARD (`IOSTD_ELINK))
obufds_lclk_inst
(.O (LCLK_OUT_TO_PINS_P),
.OB (LCLK_OUT_TO_PINS_N),
.I (tx_lclk_out));
//#############################
//# ODDR instantiation
//#############################
ODDR #(
.DDR_CLK_EDGE ("SAME_EDGE"),
.INIT (1'b0),
.SRTYPE ("ASYNC"))
oddr_inst [8:0]
(
.Q (tx_out),
.C (txo_lclk),
.CE (1'b1),
.D1 (clk_even_reg),
.D2 (clk_odd_reg),
.R (reset),
.S (1'b0));
ODDR #(
.DDR_CLK_EDGE ("SAME_EDGE"),
.INIT (1'b0),
.SRTYPE ("ASYNC"))
oddr_lclk_inst
(
.Q (tx_lclk_out),
.C (txo_lclk90),
.CE (1'b1),
.D1 (~elink_invert & ~elink_disable),
.D2 (elink_invert & ~elink_disable),
.R (CLK_RESET),
.S (1'b0));
//########################
//# Data Serialization
//########################
always @ (posedge txo_lclk) begin
clk_even_reg[8:0] <= clk_even[8:0];
clk_odd_reg[8:0] <= clk_odd[8:0];
end
mux4 #(18) mux4
(// Outputs
.out ({clk_even[8:0],clk_odd[8:0]}),
// Inputs
.in0 ({clk0_even[8:0],clk0_odd[8:0]}),
.sel0 (cycle_sel[0]),
.in1 ({clk1_even[8:0],clk1_odd[8:0]}),
.sel1 (cycle_sel[1]),
.in2 ({clk2_even[8:0],clk2_odd[8:0]}),
.sel2 (cycle_sel[2]),
.in3 ({clk3_even[8:0],clk3_odd[8:0]}),
.sel3 (cycle_sel[3]));
//#################################
//# Serialization Cycle Counter
//#################################
always @ (posedge txo_lclk) begin
tx_pedge_first <= tx_coreclock_del_45 & tx_coreclock_del_135;
cycle_sel[0] <= tx_pedge_first;
cycle_sel[3:1] <= cycle_sel[2:0];
end
//################################################################
//# Posedge Detection of the Slow Clock in the Fast Clock Domain
//################################################################
always @ (negedge txo_lclk) begin
tx_coreclock_del_45 <= tx_coreclock;
tx_coreclock_del_135 <= tx_coreclock_del_45;
end
//##################################
//# Data Alignment Channel-to-Byte
//##################################
assign clk0_even[8:0] ={tx_in_sync[71],tx_in_sync[63],tx_in_sync[55],
tx_in_sync[47],tx_in_sync[39],tx_in_sync[31],
tx_in_sync[23],tx_in_sync[15],tx_in_sync[7]};
assign clk0_odd[8:0] ={tx_in_sync[70],tx_in_sync[62],tx_in_sync[54],
tx_in_sync[46],tx_in_sync[38],tx_in_sync[30],
tx_in_sync[22],tx_in_sync[14],tx_in_sync[6]};
assign clk1_even[8:0] ={tx_in_sync[69],tx_in_sync[61],tx_in_sync[53],
tx_in_sync[45],tx_in_sync[37],tx_in_sync[29],
tx_in_sync[21],tx_in_sync[13],tx_in_sync[5]};
assign clk1_odd[8:0] ={tx_in_sync[68],tx_in_sync[60],tx_in_sync[52],
tx_in_sync[44],tx_in_sync[36],tx_in_sync[28],
tx_in_sync[20],tx_in_sync[12],tx_in_sync[4]};
assign clk2_even[8:0] ={tx_in_sync[67],tx_in_sync[59],tx_in_sync[51],
tx_in_sync[43],tx_in_sync[35],tx_in_sync[27],
tx_in_sync[19],tx_in_sync[11],tx_in_sync[3]};
assign clk2_odd[8:0] ={tx_in_sync[66],tx_in_sync[58],tx_in_sync[50],
tx_in_sync[42],tx_in_sync[34],tx_in_sync[26],
tx_in_sync[18],tx_in_sync[10],tx_in_sync[2]};
assign clk3_even[8:0] ={tx_in_sync[65],tx_in_sync[57],tx_in_sync[49],
tx_in_sync[41],tx_in_sync[33],tx_in_sync[25],
tx_in_sync[17],tx_in_sync[9], tx_in_sync[1]};
assign clk3_odd[8:0] ={tx_in_sync[64],tx_in_sync[56],tx_in_sync[48],
tx_in_sync[40],tx_in_sync[32],tx_in_sync[24],
tx_in_sync[16],tx_in_sync[8], tx_in_sync[0]};
endmodule // ewrapper_io_tx_slow

View File

@ -0,0 +1,198 @@
/*
File: ewrapper_link_receiver.v
This file is part of the Parallella FPGA Reference Design.
Copyright (C) 2013 Adapteva, Inc.
Contributed by Roman Trogan <support@adapteva.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program (see the file COPYING). If not, see
<http://www.gnu.org/licenses/>.
*/
module ewrapper_link_receiver (/*AUTOARG*/
// Outputs
rxo_wr_wait, rxo_rd_wait, emesh_clk_inb, emesh_access_inb,
emesh_write_inb, emesh_datamode_inb, emesh_ctrlmode_inb,
emesh_dstaddr_inb, emesh_srcaddr_inb, emesh_data_inb,
// Inputs
reset, rxi_data, rxi_lclk, rxi_frame, emesh_wr_wait_outb,
emesh_rd_wait_outb
);
//#########
//# INPUTS
//#########
input reset; //reset input
//# From the lvds-serdes
input [63:0] rxi_data; //Eight Parallel Byte words
input rxi_lclk; //receive clock (synchronized to the data)
input [7:0] rxi_frame; //Parallel frame signals representing
// 4 transmission clock cycles
//# From the emesh interface
input emesh_wr_wait_outb;
input emesh_rd_wait_outb;
//##########
//# OUTPUTS
//##########
//# To the transmitter
output rxo_wr_wait; //wait indicator
output rxo_rd_wait; //wait indicator
//# To the emesh interface
output emesh_clk_inb;
output emesh_access_inb;
output emesh_write_inb;
output [1:0] emesh_datamode_inb;
output [3:0] emesh_ctrlmode_inb;
output [31:0] emesh_dstaddr_inb;
output [31:0] emesh_srcaddr_inb;
output [31:0] emesh_data_inb;
/*AUTOINPUT*/
/*AUTOWIRE*/
//#########
//# Wires
//#########
wire emesh_wr_access_inb;
wire emesh_wr_write_inb;
wire [1:0] emesh_wr_datamode_inb;
wire [3:0] emesh_wr_ctrlmode_inb;
wire [31:0] emesh_wr_dstaddr_inb;
wire [31:0] emesh_wr_srcaddr_inb;
wire [31:0] emesh_wr_data_inb;
wire emesh_rd_access_inb;
wire emesh_rd_write_inb;
wire [1:0] emesh_rd_datamode_inb;
wire [3:0] emesh_rd_ctrlmode_inb;
wire [31:0] emesh_rd_dstaddr_inb;
wire [31:0] emesh_rd_srcaddr_inb;
wire [31:0] emesh_rd_data_inb;
wire select_write_tran;
wire wr_wait;
wire rd_wait;
wire emesh_access_tmp;
//###############
//# Emesh clock
//###############
assign emesh_clk_inb = rxi_lclk;
//######################################
//# Write-Read Transactions Arbitration
//# Write has a higher priority ALWAYS
//######################################
assign select_write_tran = emesh_wr_access_inb & ~emesh_wr_wait_outb;
assign emesh_access_inb = emesh_access_tmp & ~emesh_wr_wait_outb;
assign wr_wait = emesh_wr_wait_outb;
assign rd_wait = emesh_rd_access_inb & select_write_tran |
(emesh_wr_wait_outb | emesh_rd_wait_outb);
assign emesh_srcaddr_inb[31:0] =
select_write_tran ? emesh_wr_srcaddr_inb[31:0] :
emesh_rd_srcaddr_inb[31:0];
assign emesh_dstaddr_inb[31:0] =
select_write_tran ? emesh_wr_dstaddr_inb[31:0] :
emesh_rd_dstaddr_inb[31:0];
assign emesh_datamode_inb[1:0] =
select_write_tran ? emesh_wr_datamode_inb[1:0] :
emesh_rd_datamode_inb[1:0];
assign emesh_ctrlmode_inb[3:0] =
select_write_tran ? emesh_wr_ctrlmode_inb[3:0] :
emesh_rd_ctrlmode_inb[3:0];
assign emesh_data_inb[31:0] = select_write_tran ? emesh_wr_data_inb[31:0] :
emesh_rd_data_inb[31:0];
assign emesh_access_tmp = select_write_tran ? emesh_wr_access_inb :
emesh_rd_access_inb;
assign emesh_write_inb = select_write_tran ? emesh_wr_write_inb :
emesh_rd_write_inb;
//############################################
//# Write Transactions Receiver Instantiation
//############################################
/*ewrapper_link_rxi AUTO_TEMPLATE(
.rxi_rd (1'b0),
.emesh_wait_outb (wr_wait),
.rxo_wait (rxo_wr_wait),
.emesh_\(.*\) (emesh_wr_\1[]),
);
*/
ewrapper_link_rxi wr_rxi(/*AUTOINST*/
// Outputs
.rxo_wait (rxo_wr_wait), // Templated
.emesh_access_inb (emesh_wr_access_inb), // Templated
.emesh_write_inb (emesh_wr_write_inb), // Templated
.emesh_datamode_inb (emesh_wr_datamode_inb[1:0]), // Templated
.emesh_ctrlmode_inb (emesh_wr_ctrlmode_inb[3:0]), // Templated
.emesh_dstaddr_inb (emesh_wr_dstaddr_inb[31:0]), // Templated
.emesh_srcaddr_inb (emesh_wr_srcaddr_inb[31:0]), // Templated
.emesh_data_inb (emesh_wr_data_inb[31:0]), // Templated
// Inputs
.reset (reset),
.rxi_data (rxi_data[63:0]),
.rxi_lclk (rxi_lclk),
.rxi_frame (rxi_frame[7:0]),
.emesh_wait_outb (wr_wait), // Templated
.rxi_rd (1'b0)); // Templated
//############################################
//# Read Transactions Receiver Instantiation
//############################################
/*ewrapper_link_rxi AUTO_TEMPLATE(
.rxi_rd (1'b1),
.emesh_wait_outb (rd_wait),
.rxo_wait (rxo_rd_wait),
.emesh_\(.*\) (emesh_rd_\1[]),
);
*/
ewrapper_link_rxi rd_rxi(/*AUTOINST*/
// Outputs
.rxo_wait (rxo_rd_wait), // Templated
.emesh_access_inb (emesh_rd_access_inb), // Templated
.emesh_write_inb (emesh_rd_write_inb), // Templated
.emesh_datamode_inb (emesh_rd_datamode_inb[1:0]), // Templated
.emesh_ctrlmode_inb (emesh_rd_ctrlmode_inb[3:0]), // Templated
.emesh_dstaddr_inb (emesh_rd_dstaddr_inb[31:0]), // Templated
.emesh_srcaddr_inb (emesh_rd_srcaddr_inb[31:0]), // Templated
.emesh_data_inb (emesh_rd_data_inb[31:0]), // Templated
// Inputs
.reset (reset),
.rxi_data (rxi_data[63:0]),
.rxi_lclk (rxi_lclk),
.rxi_frame (rxi_frame[7:0]),
.emesh_wait_outb (rd_wait), // Templated
.rxi_rd (1'b1)); // Templated
endmodule // ewrapper_link_receiver

View File

@ -0,0 +1,624 @@
/*
File: ewrapper_link_rxi.v
This file is part of the Parallella FPGA Reference Design.
Copyright (C) 2013 Adapteva, Inc.
Contributed by Roman Trogan <support@adapteva.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program (see the file COPYING). If not, see
<http://www.gnu.org/licenses/>.
*/
module ewrapper_link_rxi (/*AUTOARG*/
// Outputs
rxo_wait, emesh_access_inb, emesh_write_inb, emesh_datamode_inb,
emesh_ctrlmode_inb, emesh_dstaddr_inb, emesh_srcaddr_inb,
emesh_data_inb,
// Inputs
reset, rxi_data, rxi_lclk, rxi_frame, emesh_wait_outb, rxi_rd
);
//#########
//# INPUTS
//#########
input reset; //reset input
//# From the lvds-serdes
input [63:0] rxi_data; //Eight Parallel Byte words
input rxi_lclk; //receive clock (synchronized to the data)
input [7:0] rxi_frame; //Parallel frame signals representing
// 4 transmission clock cycles
//# From the emesh interface
input emesh_wait_outb;
//# constant control (distinguish read and write instances)
input rxi_rd; //this is read transactions instance
//##########
//# OUTPUTS
//##########
//# To the transmitter
output rxo_wait; //wait indicator
//# To the emesh interface
output emesh_access_inb;
output emesh_write_inb;
output [1:0] emesh_datamode_inb;
output [3:0] emesh_ctrlmode_inb;
output [31:0] emesh_dstaddr_inb;
output [31:0] emesh_srcaddr_inb;
output [31:0] emesh_data_inb;
/*AUTOINPUT*/
/*AUTOWIRE*/
//#########
//# Regs
//#########
reg rxi_frame_last;
reg [7:0] rxi_data_last;
reg [3:0] frame_reg;
reg [3:0] frame_reg_del;
reg [7:0] first_byte0;
reg [3:0] first_ctrlmode;
reg [31:0] first_dstaddr;
reg [1:0] first_datamode;
reg first_write;
reg first_access;
reg [15:0] first_data;
reg [3:0] frame_redge_first_reg;
reg new_tran_reg;
reg [7:0] second_byte0;
reg [3:0] second_ctrlmode;
reg [31:0] second_dstaddr;
reg [1:0] second_datamode;
reg second_write;
reg second_access;
reg [31:0] second_data;
reg [31:0] second_srcaddr;
reg [3:0] frame_redge_first_reg1;
reg burst_byte6;
reg burst_byte0;
reg burst_byte2;
reg burst_byte4;
reg [63:0] data_long;
reg [63:0] data_long_reg;
reg [103:0] fifo_in;
reg fifo_wr;
reg [103:0] fifo_out_reg;
reg emesh_access_inb;
reg rxo_wait;
reg add_latency;
reg [31:0] ref_dstaddr;
//#########
//# Wires
//#########
wire rxi_frame_76;
wire rxi_frame_54;
wire rxi_frame_32;
wire rxi_frame_10;
wire rxi_add_latency;
wire rxi_frame_07;
wire rxi_frame_65;
wire rxi_frame_43;
wire rxi_frame_21;
wire rxi_remove_latency;
wire [7:0] rxi_frame_aligned;
wire [63:0] rxi_data_aligned;
wire [3:0] frame_redge_first_int;
wire [3:0] frame_redge_first;
wire [7:0] rxi_byte7;
wire [7:0] rxi_byte6;
wire [7:0] rxi_byte5;
wire [7:0] rxi_byte4;
wire [7:0] rxi_byte3;
wire [7:0] rxi_byte2;
wire [7:0] rxi_byte1;
wire [7:0] rxi_byte0;
wire [63:0] rxi_data_long;
wire [7:0] data_byte7;
wire [7:0] data_byte6;
wire [7:0] data_byte5;
wire [7:0] data_byte4;
wire [7:0] data_byte3;
wire [7:0] data_byte2;
wire [7:0] data_byte1;
wire [7:0] data_byte0;
wire [7:0] tran_byte0_int;
wire [3:0] tran_ctrlmode_int0;
wire [31:0] tran_dstaddr_int0;
wire [1:0] tran_datamode_int0;
wire tran_write_int0;
wire tran_access_int0;
wire new_tran;
wire [31:0] tran_dstaddr_int1;
wire [1:0] tran_datamode_int1;
wire tran_write_int1;
wire tran_access_int1;
wire [31:0] tran_data_int1;
wire [31:0] tran_srcaddr_int1;
wire [31:0] tran_srcaddr_int2;
wire burst_start_byte6;
wire burst_start_byte0;
wire burst_start_byte2;
wire burst_start_byte4;
wire burst_stop_byte6;
wire burst_stop_byte0;
wire burst_stop_byte2;
wire burst_stop_byte4;
wire [63:0] burst_data;
wire byte0_inc8;
wire [31:0] burst_dstaddr;
wire [3:0] tran_ctrlmode;
wire [31:0] tran_dstaddr;
wire [1:0] tran_datamode;
wire tran_write;
wire tran_access;
wire [31:0] tran_data;
wire [31:0] tran_srcaddr;
wire [103:0] assembled_tran;
wire tran_ready;
wire [107:0] fifo_out;
wire fifo_rd;
wire fifo_empty;
wire mine_tran;
wire frame_redge_first_or20_reg1;
//# "add/remove latency" detection
assign rxi_frame_76 = ~rxi_frame[7] & rxi_frame[6];
assign rxi_frame_54 = ~rxi_frame[5] & rxi_frame[4];
assign rxi_frame_32 = ~rxi_frame[3] & rxi_frame[2];
assign rxi_frame_10 = ~rxi_frame[1] & rxi_frame[0];
assign rxi_add_latency = rxi_frame_76 | rxi_frame_54 |
rxi_frame_32 | rxi_frame_10;
assign rxi_frame_07 = ~rxi_frame_last & rxi_frame[7];
assign rxi_frame_65 = ~rxi_frame[6] & rxi_frame[5];
assign rxi_frame_43 = ~rxi_frame[4] & rxi_frame[3];
assign rxi_frame_21 = ~rxi_frame[2] & rxi_frame[1];
assign rxi_remove_latency = rxi_frame_07 | rxi_frame_65 |
rxi_frame_43 | rxi_frame_21;
always @ (posedge rxi_lclk or posedge reset)
if(reset)
add_latency <= 1'b0;
else if(rxi_add_latency)
add_latency <= 1'b1;
else if(rxi_remove_latency)
add_latency <= 1'b0;
//# frame alignment
always @ (posedge rxi_lclk or posedge reset)
if(reset)
rxi_frame_last <= 1'b0;
else
rxi_frame_last <= rxi_frame[0];
assign rxi_frame_aligned[7:0] = (rxi_add_latency | add_latency) ?
{rxi_frame_last,rxi_frame[7:1]} : rxi_frame[7:0];
//# data alignment
//# we should interleave the received data:
assign rxi_byte0[7:0] ={rxi_data[63],rxi_data[55],rxi_data[47],rxi_data[39],
rxi_data[31],rxi_data[23],rxi_data[15],rxi_data[7]};
assign rxi_byte1[7:0] ={rxi_data[62],rxi_data[54],rxi_data[46],rxi_data[38],
rxi_data[30],rxi_data[22],rxi_data[14],rxi_data[6]};
assign rxi_byte2[7:0] ={rxi_data[61],rxi_data[53],rxi_data[45],rxi_data[37],
rxi_data[29],rxi_data[21],rxi_data[13],rxi_data[5]};
assign rxi_byte3[7:0] ={rxi_data[60],rxi_data[52],rxi_data[44],rxi_data[36],
rxi_data[28],rxi_data[20],rxi_data[12],rxi_data[4]};
assign rxi_byte4[7:0] ={rxi_data[59],rxi_data[51],rxi_data[43],rxi_data[35],
rxi_data[27],rxi_data[19],rxi_data[11],rxi_data[3]};
assign rxi_byte5[7:0] ={rxi_data[58],rxi_data[50],rxi_data[42],rxi_data[34],
rxi_data[26],rxi_data[18],rxi_data[10],rxi_data[2]};
assign rxi_byte6[7:0] ={rxi_data[57],rxi_data[49],rxi_data[41],rxi_data[33],
rxi_data[25],rxi_data[17],rxi_data[9], rxi_data[1]};
assign rxi_byte7[7:0] ={rxi_data[56],rxi_data[48],rxi_data[40],rxi_data[32],
rxi_data[24],rxi_data[16],rxi_data[8], rxi_data[0]};
assign rxi_data_long[63:0] = {rxi_byte0[7:0],rxi_byte1[7:0],
rxi_byte2[7:0],rxi_byte3[7:0],
rxi_byte4[7:0],rxi_byte5[7:0],
rxi_byte6[7:0],rxi_byte7[7:0]};
always @ (posedge rxi_lclk)
rxi_data_last[7:0] <= rxi_byte7[7:0];
assign rxi_data_aligned[63:0] = (rxi_add_latency | add_latency) ?
{rxi_data_last[7:0],rxi_data_long[63:8]} :
rxi_data_long[63:0];
//################################
//# Main "After Alignment" Logic
//################################
//# frame
always @ (posedge rxi_lclk or posedge reset)
if(reset)
begin
frame_reg[3:0] <= 4'b0000;
frame_reg_del[3:0] <= 4'b0000;
end
else
begin
frame_reg[3:0] <= {rxi_frame_aligned[7],rxi_frame_aligned[5],
rxi_frame_aligned[3],rxi_frame_aligned[1]};
frame_reg_del[3:0] <= frame_reg[3:0];
end
//# data
always @ (posedge rxi_lclk)
data_long[63:0] <= rxi_data_aligned[63:0];
assign data_byte7[7:0] = data_long[7:0];
assign data_byte6[7:0] = data_long[15:8];
assign data_byte5[7:0] = data_long[23:16];
assign data_byte4[7:0] = data_long[31:24];
assign data_byte3[7:0] = data_long[39:32];
assign data_byte2[7:0] = data_long[47:40];
assign data_byte1[7:0] = data_long[55:48];
assign data_byte0[7:0] = data_long[63:56];
//# frame rising edge detection
assign frame_redge_first_int[3] = frame_reg[3] & ~frame_reg_del[0];
assign frame_redge_first_int[2] = frame_reg[2] & ~frame_reg[3];
assign frame_redge_first_int[1] = frame_reg[1] & ~frame_reg[2];
assign frame_redge_first_int[0] = frame_reg[0] & ~frame_reg[1];
//# First Cycle of the Transaction
//# new transactions is detected when the type of transaction matches
//# type of the instance (read or write) during the rising edge of frame
assign mine_tran = ~(tran_byte0_int[7] ^ rxi_rd);
assign frame_redge_first[3:0] =frame_redge_first_int[3:0] & {(4){mine_tran}};
assign new_tran = |(frame_redge_first[3:0]);
assign tran_byte0_int[7:0] = frame_redge_first_int[3] ? data_byte0[7:0] :
frame_redge_first_int[2] ? data_byte2[7:0] :
frame_redge_first_int[1] ? data_byte4[7:0] :
data_byte6[7:0];
assign tran_ctrlmode_int0[3:0] = frame_redge_first[3] ? data_byte1[7:4] :
frame_redge_first[2] ? data_byte3[7:4] :
frame_redge_first[1] ? data_byte5[7:4] :
data_byte7[7:4];
assign tran_dstaddr_int0[31:28] = frame_redge_first[3] ? data_byte1[3:0] :
frame_redge_first[2] ? data_byte3[3:0] :
frame_redge_first[1] ? data_byte5[3:0] :
data_byte7[3:0];
assign tran_dstaddr_int0[27:20] = frame_redge_first[3] ? data_byte2[7:0] :
frame_redge_first[2] ? data_byte4[7:0] :
data_byte6[7:0];
assign tran_dstaddr_int0[19:12] = frame_redge_first[3] ? data_byte3[7:0] :
frame_redge_first[2] ? data_byte5[7:0] :
data_byte7[7:0];
assign tran_dstaddr_int0[11:4] = frame_redge_first[3] ? data_byte4[7:0] :
data_byte6[7:0];
assign tran_dstaddr_int0[3:0] = frame_redge_first[3] ? data_byte5[7:4] :
data_byte7[7:4];
assign tran_datamode_int0[1:0] = frame_redge_first[3] ? data_byte5[3:2] :
data_byte7[3:2];
assign tran_write_int0 = frame_redge_first[3] ? data_byte5[1] :
data_byte7[1];
assign tran_access_int0 = frame_redge_first[3] ? data_byte5[0] :
data_byte7[0];
always @ (posedge rxi_lclk)
if (new_tran)
begin
first_byte0[7:0] <= tran_byte0_int[7:0];
first_ctrlmode[3:0] <= tran_ctrlmode_int0[3:0];
first_dstaddr[31:0] <= tran_dstaddr_int0[31:0];
first_datamode[1:0] <= tran_datamode_int0[1:0];
first_write <= tran_write_int0;
first_access <= tran_access_int0;
first_data[15:0] <= {data_byte6[7:0],data_byte7[7:0]};
end
//# Second Cycle of the Transaction
always @ (posedge rxi_lclk or posedge reset)
if (reset)
begin
frame_redge_first_reg[3:0] <= 4'b0000;
new_tran_reg <= 1'b0;
end
else
begin
frame_redge_first_reg[3:0] <= frame_redge_first[3:0];
new_tran_reg <= new_tran;
end
assign tran_dstaddr_int1[31:28] = first_dstaddr[31:28];
assign tran_dstaddr_int1[27:12] =
frame_redge_first_reg[0] ? {data_byte0[7:0],data_byte1[7:0]} :
first_dstaddr[27:12];
assign tran_dstaddr_int1[11:4] = frame_redge_first_reg[1] ? data_byte0[7:0] :
frame_redge_first_reg[0] ? data_byte2[7:0] :
first_dstaddr[11:4];
assign tran_dstaddr_int1[3:0] = frame_redge_first_reg[1] ? data_byte1[7:4] :
frame_redge_first_reg[0] ? data_byte3[7:4] :
first_dstaddr[3:0];
assign tran_datamode_int1[1:0] = frame_redge_first_reg[1] ? data_byte1[3:2] :
frame_redge_first_reg[0] ? data_byte3[3:2] :
first_datamode[1:0];
assign tran_write_int1 = frame_redge_first_reg[1] ? data_byte1[1] :
frame_redge_first_reg[0] ? data_byte3[1] :
first_write;
assign tran_access_int1 = frame_redge_first_reg[1] ? data_byte1[0] :
frame_redge_first_reg[0] ? data_byte3[0] :
first_access;
assign tran_data_int1[31:24] = frame_redge_first_reg[2] ? data_byte0[7:0] :
frame_redge_first_reg[1] ? data_byte2[7:0] :
frame_redge_first_reg[0] ? data_byte4[7:0] :
first_data[15:8];
assign tran_data_int1[23:16] = frame_redge_first_reg[2] ? data_byte1[7:0] :
frame_redge_first_reg[1] ? data_byte3[7:0] :
frame_redge_first_reg[0] ? data_byte5[7:0] :
first_data[7:0];
assign tran_data_int1[15:8] = frame_redge_first_reg[3] ? data_byte0[7:0] :
frame_redge_first_reg[2] ? data_byte2[7:0] :
frame_redge_first_reg[1] ? data_byte4[7:0] :
data_byte6[7:0];
assign tran_data_int1[7:0] = frame_redge_first_reg[3] ? data_byte1[7:0] :
frame_redge_first_reg[2] ? data_byte3[7:0] :
frame_redge_first_reg[1] ? data_byte5[7:0] :
data_byte7[7:0];
assign tran_srcaddr_int1[31:24] = frame_redge_first_reg[3] ? data_byte2[7:0]:
frame_redge_first_reg[2] ? data_byte4[7:0]:
data_byte6[7:0];
assign tran_srcaddr_int1[23:16] = frame_redge_first_reg[3] ? data_byte3[7:0]:
frame_redge_first_reg[2] ? data_byte5[7:0]:
data_byte7[7:0];
assign tran_srcaddr_int1[15:8] = frame_redge_first_reg[3] ? data_byte4[7:0] :
data_byte6[7:0];
assign tran_srcaddr_int1[7:0] = frame_redge_first_reg[3] ? data_byte5[7:0] :
data_byte7[7:0];
always @ (posedge rxi_lclk)
if (new_tran_reg)
begin
second_byte0[7:0] <= first_byte0[7:0];
second_ctrlmode[3:0] <= first_ctrlmode[3:0];
second_dstaddr[31:0] <= tran_dstaddr_int1[31:0];
second_datamode[1:0] <= tran_datamode_int1[1:0];
second_write <= tran_write_int1;
second_access <= tran_access_int1;
second_data[31:0] <= tran_data_int1[31:0];
second_srcaddr[31:0] <= tran_srcaddr_int1[31:0];
end // if (new_tran_reg)
//# Third Cycle of the Transaction
always @ (posedge rxi_lclk or posedge reset)
if (reset)
frame_redge_first_reg1[3:0] <= 4'b0000;
else
frame_redge_first_reg1[3:0] <= frame_redge_first_reg[3:0];
assign tran_srcaddr_int2[31:16] =
frame_redge_first_reg1[0] ? {data_byte0[7:0],data_byte1[7:0]} :
second_srcaddr[31:16];
assign tran_srcaddr_int2[15:8] = frame_redge_first_reg1[1] ? data_byte0[7:0]:
frame_redge_first_reg1[0] ? data_byte2[7:0]:
second_srcaddr[15:8];
assign tran_srcaddr_int2[7:0] = frame_redge_first_reg1[1] ? data_byte1[7:0]:
frame_redge_first_reg1[0] ? data_byte3[7:0]:
second_srcaddr[7:0];
//############################################
//# Data Collection of the Burst Transactions
//############################################
assign burst_start_byte6 = frame_redge_first_reg[3] & frame_reg[0];
assign burst_start_byte0 = frame_redge_first_reg1[2] & frame_reg[3];
assign burst_start_byte2 = frame_redge_first_reg1[1] & frame_reg[2];
assign burst_start_byte4 = frame_redge_first_reg1[0] & frame_reg[1];
assign burst_stop_byte6 = ~frame_reg[0] & frame_reg_del[0];
assign burst_stop_byte0 = ~frame_reg[3] & frame_reg_del[3];
assign burst_stop_byte2 = ~frame_reg[2] & frame_reg_del[2];
assign burst_stop_byte4 = ~frame_reg[1] & frame_reg_del[1];
always @ (posedge rxi_lclk or posedge reset)
if (reset)
burst_byte6 <= 1'b0;
else if(burst_start_byte6)
burst_byte6 <= 1'b1;
else if(burst_stop_byte6)
burst_byte6 <= 1'b0;
always @ (posedge rxi_lclk or posedge reset)
if (reset)
burst_byte0 <= 1'b0;
else if(burst_start_byte0)
burst_byte0 <= 1'b1;
else if(burst_stop_byte0)
burst_byte0 <= 1'b0;
always @ (posedge rxi_lclk or posedge reset)
if (reset)
burst_byte2 <= 1'b0;
else if(burst_start_byte2)
burst_byte2 <= 1'b1;
else if(burst_stop_byte2)
burst_byte2 <= 1'b0;
always @ (posedge rxi_lclk or posedge reset)
if (reset)
burst_byte4 <= 1'b0;
else if(burst_start_byte4)
burst_byte4 <= 1'b1;
else if(burst_stop_byte4)
burst_byte4 <= 1'b0;
always @ (posedge rxi_lclk)
data_long_reg[63:0] <= data_long[63:0];
assign burst_data[63:0] =
burst_byte6 ? {data_long_reg[15:0],data_long[63:16]} :
burst_byte0 ? data_long_reg[63:0] :
burst_byte2 ? {data_long_reg[47:0],data_long[63:48]} :
{data_long_reg[31:0],data_long[63:32]};
//###############################################
//# Address Calculation of the Burst Transaction
//###############################################
always @ (posedge rxi_lclk)
if (tran_ready)
ref_dstaddr[31:0] <= tran_dstaddr[31:0];
assign byte0_inc8 = ~second_byte0[2];
assign burst_dstaddr[31:0] = ref_dstaddr[31:0] +
{{(28){1'b0}},byte0_inc8,3'b000};
//##########################################
//# Assembled Transaction to enter the FIFO
//##########################################
assign frame_redge_first_or20_reg1 = |(frame_redge_first_reg1[2:0]);
assign tran_ctrlmode[3:0] = frame_redge_first_reg[3] ? first_ctrlmode[3:0] :
second_ctrlmode[3:0];
assign tran_datamode[1:0] = frame_redge_first_reg[3] ? tran_datamode_int1[1:0]:
second_datamode[1:0];
assign tran_write = frame_redge_first_reg[3] ? tran_write_int1 :
second_write;
assign tran_access = frame_redge_first_reg[3] ? tran_access_int1 :
second_access;
assign tran_srcaddr[31:0] = frame_redge_first_reg[3] ? tran_srcaddr_int1[31:0]:
frame_redge_first_or20_reg1 ? tran_srcaddr_int2[31:0]:
burst_data[31:0];
assign tran_data[31:0] = frame_redge_first_reg[3] ? tran_data_int1[31:0]:
frame_redge_first_or20_reg1 ? second_data[31:0]:
burst_data[63:32];
assign tran_dstaddr[31:0] = frame_redge_first_reg[3] ? tran_dstaddr_int1[31:0]:
frame_redge_first_or20_reg1 ? second_dstaddr[31:0]:
burst_dstaddr[31:0];
assign assembled_tran[103:0] = {tran_srcaddr[31:0],
tran_data[31:0],
tran_dstaddr[31:0],
tran_ctrlmode[3:0],
tran_datamode[1:0],
tran_write,
tran_access};
assign tran_ready = frame_redge_first_reg[3] | frame_redge_first_or20_reg1 |
burst_byte6 | burst_byte0 | burst_byte2 | burst_byte4;
//# The transaction is latched before entering FIFO to prevent timing
//# issues
always @ (posedge rxi_lclk)
fifo_in[103:0] <= assembled_tran[103:0];
always @ (posedge rxi_lclk or posedge reset)
if (reset)
fifo_wr <= 1'b0;
else
fifo_wr <= tran_ready;
//# Wait logic
always @ (posedge rxi_lclk or posedge reset)
if (reset)
rxo_wait <= 1'b0;
else if (emesh_wait_outb)
rxo_wait <= 1'b1;
else if (fifo_empty)
rxo_wait <= 1'b0;
assign emesh_srcaddr_inb[31:0] = fifo_out_reg[103:72];
assign emesh_data_inb[31:0] = fifo_out_reg[71:40];
assign emesh_dstaddr_inb[31:0] = fifo_out_reg[39:8];
assign emesh_ctrlmode_inb[3:0] = fifo_out_reg[7:4];
assign emesh_datamode_inb[1:0] = fifo_out_reg[3:2];
assign emesh_write_inb = fifo_out_reg[1];
always @ (posedge rxi_lclk or posedge reset)
if (reset)
emesh_access_inb <= 1'b0;
else if (~emesh_wait_outb)
emesh_access_inb <= fifo_rd;
always @ (posedge rxi_lclk)
if (~emesh_wait_outb)
fifo_out_reg[103:0] <= fifo_out[103:0];
assign fifo_rd = ~(fifo_empty | emesh_wait_outb);
/*fifo AUTO_TEMPLATE(.rd_clk (rxi_lclk),
.wr_clk (rxi_lclk),
.wr_data (fifo_in[103:0]),
.rd_data (fifo_out[103:0]),
.rd_fifo_empty (fifo_empty),
.wr_fifo_full (),
.wr_write (fifo_wr),
.rd_read (fifo_rd),
);
*/
//# We have 32 entries of 104 bits each
fifo #(.DW(104), .AW(5)) fifo_rxi(/*AUTOINST*/
// Outputs
.rd_data (fifo_out[103:0]), // Templated
.rd_fifo_empty (fifo_empty), // Templated
.wr_fifo_full (), // Templated
// Inputs
.reset (reset),
.wr_clk (rxi_lclk), // Templated
.rd_clk (rxi_lclk), // Templated
.wr_write (fifo_wr), // Templated
.wr_data (fifo_in[103:0]), // Templated
.rd_read (fifo_rd)); // Templated
endmodule // ewrapper_link_rxi

View File

@ -0,0 +1,467 @@
/*
File: ewrapper_link_top.v
This file is part of the Parallella Project
Copyright (C) 2013 Adapteva, Inc.
Contributed by Roman Trogan <support@adapteva.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program (see the file COPYING). If not, see
<http://www.gnu.org/licenses/>.
*/
`include "fpga_constants.v"
module ewrapper_link_top (/*AUTOARG*/
// Outputs
emesh_clk_inb, emesh_access_inb, emesh_write_inb,
emesh_datamode_inb, emesh_ctrlmode_inb, emesh_dstaddr_inb,
emesh_srcaddr_inb, emesh_data_inb, emesh_wr_wait_inb,
emesh_rd_wait_inb, txo_data_p, txo_data_n, txo_frame_p,
txo_frame_n, txo_lclk_p, txo_lclk_n, rxo_wr_wait_p, rxo_wr_wait_n,
rxo_rd_wait_p, rxo_rd_wait_n, rxi_cclk_p, rxi_cclk_n,
// Inputs
reset, clkin_100, elink_disable, elink_cclk_enb, elink_clk_div,
emesh_access_outb, emesh_write_outb, emesh_datamode_outb,
emesh_ctrlmode_outb, emesh_dstaddr_outb, emesh_srcaddr_outb,
emesh_data_outb, emesh_wr_wait_outb, emesh_rd_wait_outb,
rxi_data_p, rxi_data_n, rxi_frame_p, rxi_frame_n, rxi_lclk_p,
rxi_lclk_n, txi_wr_wait_p, txi_wr_wait_n, txi_rd_wait_p,
txi_rd_wait_n, burst_en
);
//#############
//# INPUTS
//#############
input reset;
input clkin_100;
//# Controls
input elink_disable;
input elink_cclk_enb;
input [1:0] elink_clk_div;
//# From the emesh interface
input emesh_access_outb;
input emesh_write_outb;
input [1:0] emesh_datamode_outb;
input [3:0] emesh_ctrlmode_outb;
input [31:0] emesh_dstaddr_outb;
input [31:0] emesh_srcaddr_outb;
input [31:0] emesh_data_outb;
input emesh_wr_wait_outb;
input emesh_rd_wait_outb;
//# From the chip (hsmc port)
input [7:0] rxi_data_p;
input [7:0] rxi_data_n;
input rxi_frame_p;
input rxi_frame_n;
input rxi_lclk_p;
input rxi_lclk_n;
input txi_wr_wait_p;
input txi_wr_wait_n;
input txi_rd_wait_p;
input txi_rd_wait_n;
input burst_en; // Burst enable control
//###################
//# OUTPUTS
//###################
//# To the emesh interface
output emesh_clk_inb;
output emesh_access_inb;
output emesh_write_inb;
output [1:0] emesh_datamode_inb;
output [3:0] emesh_ctrlmode_inb;
output [31:0] emesh_dstaddr_inb;
output [31:0] emesh_srcaddr_inb;
output [31:0] emesh_data_inb;
output emesh_wr_wait_inb;
output emesh_rd_wait_inb;
//# To the chip (hsmc port)
output [7:0] txo_data_p;
output [7:0] txo_data_n;
output txo_frame_p;
output txo_frame_n;
output txo_lclk_p;
output txo_lclk_n;
output rxo_wr_wait_p;
output rxo_wr_wait_n;
output rxo_rd_wait_p;
output rxo_rd_wait_n;
output rxi_cclk_p;
output rxi_cclk_n;
/*AUTOINPUT*/
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire [71:0] tx_in; // From ctrl_tx of ewrapper_link_transmitter.v
// End of automatics
//############
//# REGS
//############
//############
//# WIRES
//############
wire [63:0] rxi_data_paral;
wire [7:0] rxi_frame_paral;
wire [8:0] rx_in_p;
wire [8:0] rx_in_n;
wire [71:0] rx_out;
wire rx_outclock;
wire [8:0] tx_out_p;
wire [8:0] tx_out_n;
wire rxi_cclk;
wire clk_fast_deg0;
wire clk_slow_deg0;
wire clk_fast_deg90;
wire rxo_wr_wait;
wire rxo_rd_wait;
wire txi_wr_wait;
wire txi_rd_wait;
// Inversions for E16/E64 migration
`ifdef TARGET_E16
wire elink_invert = 1'b0;
`elsif TARGET_E64
wire elink_invert = 1'b1;
`endif
//#######################
//# LVDS RECEIVER
//#######################
assign rxi_data_paral[63:0] = rx_out[63:0];
assign rxi_frame_paral[7:0] = rx_out[71:64];
assign rx_in_p[8:0] = {rxi_frame_p,rxi_data_p[7:0]};
assign rx_in_n[8:0] = {rxi_frame_n,rxi_data_n[7:0]};
ewrapper_link_receiver ctrl_rx
(.rxi_data (rxi_data_paral[63:0]),
.rxi_frame (rxi_frame_paral[7:0]),
.rxi_lclk (rx_outclock),
/*AUTOINST*/
// Outputs
.rxo_wr_wait (rxo_wr_wait),
.rxo_rd_wait (rxo_rd_wait),
.emesh_clk_inb (emesh_clk_inb),
.emesh_access_inb (emesh_access_inb),
.emesh_write_inb (emesh_write_inb),
.emesh_datamode_inb (emesh_datamode_inb[1:0]),
.emesh_ctrlmode_inb (emesh_ctrlmode_inb[3:0]),
.emesh_dstaddr_inb (emesh_dstaddr_inb[31:0]),
.emesh_srcaddr_inb (emesh_srcaddr_inb[31:0]),
.emesh_data_inb (emesh_data_inb[31:0]),
// Inputs
.reset (reset),
.emesh_wr_wait_outb (emesh_wr_wait_outb),
.emesh_rd_wait_outb (emesh_rd_wait_outb));
ewrapper_io_rx_slow io_rx
(// Outputs
.CLK_DIV_OUT (rx_outclock),
.DATA_IN_TO_DEVICE (rx_out[71:0]),
// Inputs
.CLK_IN_P (rxi_lclk_p),
.CLK_IN_N (rxi_lclk_n),
.CLK_RESET (reset),
.IO_RESET (reset),
.DATA_IN_FROM_PINS_P(rx_in_p[8:0]),
.DATA_IN_FROM_PINS_N(rx_in_n[8:0]),
.BITSLIP (1'b0));
// xilinx ISERDESE2 ip instantiation
// !!! Make sure that the DIFF_TERM attribute of IBUFDS and IBUFGDS
// !!! is set to TRUE inside ewrapper_io_rx.v
//ewrapper_io_rx io_rx(// Inputs
// .CLK_IN_P (rxi_lclk_p),
// .CLK_IN_N (rxi_lclk_n),
// .DATA_IN_FROM_PINS_P (rx_in_p[8:0]),
// .DATA_IN_FROM_PINS_N (rx_in_n[8:0]),
// .BITSLIP (1'b0),
// .CLK_RESET (reset),
// .IO_RESET (reset),
// // Outputs
// .DATA_IN_TO_DEVICE (rx_out[71:0]),
// .CLK_DIV_OUT (rx_outclock));
//#######################
//# LVDS TRANSMITTER
//#######################
assign txo_frame_p = tx_out_p[8];
assign txo_frame_n = tx_out_n[8];
assign txo_data_p[7:0] = tx_out_p[7:0];
assign txo_data_n[7:0] = tx_out_n[7:0];
ewrapper_link_transmitter ctrl_tx
(.txo_lclk (clk_slow_deg0),
/*AUTOINST*/
// Outputs
.emesh_wr_wait_inb (emesh_wr_wait_inb),
.emesh_rd_wait_inb (emesh_rd_wait_inb),
.tx_in (tx_in[71:0]),
// Inputs
.reset (reset),
.emesh_clk_inb (emesh_clk_inb),
.emesh_access_outb (emesh_access_outb),
.emesh_write_outb (emesh_write_outb),
.emesh_datamode_outb (emesh_datamode_outb[1:0]),
.emesh_ctrlmode_outb (emesh_ctrlmode_outb[3:0]),
.emesh_dstaddr_outb (emesh_dstaddr_outb[31:0]),
.emesh_srcaddr_outb (emesh_srcaddr_outb[31:0]),
.emesh_data_outb (emesh_data_outb[31:0]),
.txi_wr_wait (txi_wr_wait),
.txi_rd_wait (txi_rd_wait),
.burst_en (burst_en));
// xilinx MMCME2_ADV ip instantiation
io_clock_gen_600mhz io_clock_gen(// Inputs
.CLK_IN1 (clkin_100),
.RESET (reset),
// Outputs
.CLK_OUT1 (rxi_cclk),
.CLK_OUT2 (clk_fast_deg0),
.CLK_OUT3 (clk_slow_deg0),
.CLK_OUT4 (clk_fast_deg90),
.LOCKED ());
ewrapper_io_tx_slow io_tx(// Outputs
.DATA_OUT_TO_PINS_P(tx_out_p[8:0]),
.DATA_OUT_TO_PINS_N(tx_out_n[8:0]),
.LCLK_OUT_TO_PINS_P(txo_lclk_p),
.LCLK_OUT_TO_PINS_N(txo_lclk_n),
// Inputs
.CLK_IN (clk_fast_deg0),
.CLK_IN_90 (clk_fast_deg90),
.CLK_DIV_IN (clk_slow_deg0),
.CLK_RESET (reset),
.IO_RESET (reset),
.elink_disable (elink_disable),
.DATA_OUT_FROM_DEVICE(tx_in[71:0]));
// xilinx ISERDESE2 ip instantiation
//
// ewrapper_io_tx io_tx(// Inputs
// .CLK_IN (clk_fast_deg0),
// .CLK_DIV_IN (clk_slow_deg0),
// .DATA_OUT_FROM_DEVICE (tx_in[71:0]),
// .CLK_RESET (reset),
// .IO_RESET (reset),
// // Outputs
// .DATA_OUT_TO_PINS_P (tx_out_p[8:0]),
// .DATA_OUT_TO_PINS_N (tx_out_n[8:0]));
// io_clock_fwd io_clock_fwd(// Inputs
// .CLK_IN (clk_fast_deg45),
// .CLK_DIV_IN (clk_slow_deg45),
// .DATA_OUT_FROM_DEVICE (8'b01010101),
// .CLK_RESET (reset),
// .IO_RESET (reset),
// // Outputs
// .DATA_OUT_TO_PINS_P (txo_lclk_p),
// .DATA_OUT_TO_PINS_N (txo_lclk_n));
`ifdef FEATURE_CCLK_DIV
// Create adjustable (but fast) CCLK
wire rxi_cclk_out;
reg [8:1] cclk_pattern;
reg [1:0] clk_div_sync;
reg enb_sync;
always @ (posedge clk_slow_deg0) begin
clk_div_sync <= elink_clk_div;
enb_sync <= elink_cclk_enb;
if(enb_sync)
case(clk_div_sync)
2'b00: cclk_pattern <= 8'b10101010; // Divide by 1
2'b01: cclk_pattern <= 8'b11001100; // Divide by 2
2'b10: cclk_pattern <= 8'b11110000; // Divide by 4
default: cclk_pattern <= {8{~cclk_pattern[1]}}; // /8
endcase
else
cclk_pattern <= 8'b00000000;
end // always @ (posedge clk_slow_deg0)
OSERDESE2
#(
.DATA_RATE_OQ("DDR"), // DDR, SDR
.DATA_RATE_TQ("SDR"), // DDR, BUF, SDR
.DATA_WIDTH(8), // Parallel data width (2-8,10,14)
.INIT_OQ(1'b0), // Initial value of OQ output (1'b0,1'b1)
.INIT_TQ(1'b0), // Initial value of TQ output (1'b0,1'b1)
.SERDES_MODE("MASTER"), // MASTER, SLAVE
.SRVAL_OQ(1'b0), // OQ output value when SR is used (1'b0,1'b1)
.SRVAL_TQ(1'b0), // TQ output value when SR is used (1'b0,1'b1)
.TBYTE_CTL("FALSE"), // Enable tristate byte operation (FALSE, TRUE)
.TBYTE_SRC("FALSE"), // Tristate byte source (FALSE, TRUE)
.TRISTATE_WIDTH(1) // 3-state converter width (1,4)
) OSERDESE2_inst
(
.OFB(), // 1-bit output: Feedback path for data
.OQ(rxi_cclk_out), // 1-bit output: Data path output
.SHIFTOUT1(), // SHIFTOUTn: 1-bit (each): Data output expansion
.SHIFTOUT2(),
.TBYTEOUT(), // 1-bit output: Byte group tristate
.TFB(), // 1-bit output: 3-state control
.TQ(), // 1-bit output: 3-state control
.CLK(rxi_cclk), // 1-bit input: High speed clock
.CLKDIV(clk_slow_deg0), // 1-bit input: Divided clock
.D1(cclk_pattern[1]), // D1 - D8: Parallel data inputs (1-bit each)
.D2(cclk_pattern[2]),
.D3(cclk_pattern[3]),
.D4(cclk_pattern[4]),
.D5(cclk_pattern[5]),
.D6(cclk_pattern[6]),
.D7(cclk_pattern[7]),
.D8(cclk_pattern[8]),
.OCE(1'b1), // 1-bit input: Output data clock enable
.RST(reset), // 1-bit input: Reset
.SHIFTIN1(1'b0), // SHIFTINn: Data input expansion (1-bit each)
.SHIFTIN2(1'b0),
.T1(1'b0), // T1 - T4: Parallel 3-state inputs
.T2(1'b0),
.T3(1'b0),
.T4(1'b0),
.TBYTEIN(1'b0), // 1-bit input: Byte group tristate
.TCE(1'b0) // 1-bit input: 3-state clock enable
);
`else // Non-dividable CCLK
reg enb_sync;
always @ (posedge clk_slow_deg0)
enb_sync <= elink_cclk_enb;
// The following does not result in timing failures,
// but doesn't seem glitch-safe
assign rxi_cclk_out = rxi_cclk & enb_sync;
`endif
// xilinx OBUFDS instantiation
//
OBUFDS
#(.IOSTANDARD (`IOSTD_ELINK))
obufds_cclk_inst
(.O (rxi_cclk_p),
.OB (rxi_cclk_n),
.I (rxi_cclk_out));
OBUFDS
#(.IOSTANDARD (`IOSTD_ELINK))
rxo_wr_wait_inst
(.O (rxo_wr_wait_p),
.OB (rxo_wr_wait_n),
.I (rxo_wr_wait ^ elink_invert));
OBUFDS
#(.IOSTANDARD (`IOSTD_ELINK))
rxo_rd_wait_inst
(.O (rxo_rd_wait_p),
.OB (rxo_rd_wait_n),
.I (rxo_rd_wait ^ elink_invert));
// xilinx IBUFDS instantiation
wire [1:0] txi_wr_wait_buf;
IBUFDS_DIFF_OUT
#(.DIFF_TERM ("TRUE"), // Differential termination
.IOSTANDARD (`IOSTD_ELINK))
txi_wr_wait_inst
(.I (txi_wr_wait_p),
.IB (txi_wr_wait_n),
.O (txi_wr_wait_buf[0]),
.OB (txi_wr_wait_buf[1]));
assign txi_wr_wait = elink_invert ? txi_wr_wait_buf[1] : txi_wr_wait_buf[0];
// IBUFDS #(.DIFF_TERM ("TRUE"), // Differential termination
// .IOSTANDARD (`IOSTD_ELINK)) txo_rd_wait_inst (.I (txo_rd_wait_p),
// .IB (txo_rd_wait_n),
// .O (txo_rd_wait));
//No need for differential buffer
assign txi_rd_wait = txi_rd_wait_p ^ elink_invert;
//#################################
//# Chip Scope Instantiation
//#################################
`ifdef kCHIPSCOPE_EWRAPPER
wire [7:0] cs_ila2_TRIG3;
wire [7:0] cs_ila3_TRIG3;
wire [35:0] CONTROL0;
wire [35:0] CONTROL1;
wire [35:0] CONTROL2;
wire [35:0] CONTROL3;
assign cs_ila2_TRIG3[7:0] = {emesh_wr_wait_inb,
emesh_rd_wait_inb,
emesh_ctrlmode_outb[1:0],
emesh_datamode_outb[1:0],
emesh_write_outb,
emesh_access_outb};
assign cs_ila3_TRIG3[7:0] = {emesh_wr_wait_outb,
emesh_rd_wait_outb,
emesh_ctrlmode_inb[1:0],
emesh_datamode_inb[1:0],
emesh_write_inb,
emesh_access_inb};
cs_ila0 cs_ila0(.TRIG0 (tx_in[71:0]),
.CONTROL (CONTROL0[35:0]),
.CLK (clk_slow_deg0));
cs_ila0 cs_ila1(.TRIG0 (rx_out[71:0]),
.CONTROL (CONTROL1[35:0]),
.CLK (emesh_clk_inb));
cs_ila1 cs_ila2(.TRIG0 (emesh_dstaddr_outb[31:0]),
.TRIG1 (emesh_data_outb[31:0]),
.TRIG2 (emesh_srcaddr_outb[31:0]),
.TRIG3 (cs_ila2_TRIG3[7:0]),
.CONTROL (CONTROL2[35:0]),
.CLK (emesh_clk_inb));
cs_ila1 cs_ila3(.TRIG0 (emesh_dstaddr_inb[31:0]),
.TRIG1 (emesh_data_inb[31:0]),
.TRIG2 (emesh_srcaddr_inb[31:0]),
.TRIG3 (cs_ila3_TRIG3[7:0]),
.CONTROL (CONTROL3[35:0]),
.CLK (emesh_clk_inb));
cs_icon cs_icon(.CONTROL0 (CONTROL0[35:0]),
.CONTROL1 (CONTROL1[35:0]),
.CONTROL2 (CONTROL2[35:0]),
.CONTROL3 (CONTROL3[35:0]));
`endif // kCHIPSCOPE_EWRAPPER
endmodule // ewrapper_link_top

View File

@ -0,0 +1,232 @@
/*
File: ewrapper_link_transmitter.v
This file is part of the Parallella FPGA Reference Design.
Copyright (C) 2013 Adapteva, Inc.
Contributed by Roman Trogan <support@adapteva.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program (see the file COPYING). If not, see
<http://www.gnu.org/licenses/>.
*/
module ewrapper_link_transmitter(/*AUTOARG*/
// Outputs
emesh_wr_wait_inb, emesh_rd_wait_inb, tx_in,
// Inputs
reset, txo_lclk, emesh_clk_inb, emesh_access_outb,
emesh_write_outb, emesh_datamode_outb, emesh_ctrlmode_outb,
emesh_dstaddr_outb, emesh_srcaddr_outb, emesh_data_outb,
txi_wr_wait, txi_rd_wait, burst_en
);
//#########
//# INPUTS
//#########
input reset; //reset input
input txo_lclk; //transmitter clock
input emesh_clk_inb; // clock of the incoming emesh transaction
//# From the Emesh
input emesh_access_outb;
input emesh_write_outb;
input [1:0] emesh_datamode_outb;
input [3:0] emesh_ctrlmode_outb;
input [31:0] emesh_dstaddr_outb;
input [31:0] emesh_srcaddr_outb;
input [31:0] emesh_data_outb;
//# From the receiver
input txi_wr_wait; //wait indicator
input txi_rd_wait; //wait indicator
input burst_en; // Burst enable control
//##########
//# OUTPUTS
//##########
//# To the Emesh
output emesh_wr_wait_inb;
output emesh_rd_wait_inb;
//# To the lvds-serdes
output [71:0] tx_in;
/*AUTOINPUT*/
/*AUTOWIRE*/
//#########
//# Regs
//#########
reg wrfifo_rd_en;
//#########
//# Wires
//#########
wire [1:0] txi_wait;
wire [1:0] txi_wait_sync;
wire txi_wr_wait_sync;
wire txi_rd_wait_sync;
wire [103:0] fifo_in;
wire [103:0] fifo_out;
wire [107:0] wrfifo_out;
wire [107:0] rdfifo_out;
wire wrfifo_wait;
wire rdfifo_wait;
wire wrfifo_rd_int;
wire rdfifo_rd_int;
wire wrfifo_rd;
wire rdfifo_rd;
wire wrfifo_wr;
wire rdfifo_wr;
wire rdfifo_empty;
wire wrfifo_empty;
wire txo_emesh_wait;
wire txo_emesh_access;
wire txo_emesh_write;
wire [1:0] txo_emesh_datamode;
wire [3:0] txo_emesh_ctrlmode;
wire [31:0] txo_emesh_dstaddr;
wire [31:0] txo_emesh_srcaddr;
wire [31:0] txo_emesh_data;
//############################
//# txo_wait synchronization
//############################
assign txi_wait[1:0] = {txi_rd_wait,txi_wr_wait};
assign txi_wr_wait_sync = txi_wait_sync[0];
assign txi_rd_wait_sync = txi_wait_sync[1];
synchronizer #(.DW(2)) synchronizer(.out (txi_wait_sync[1:0]),
.in (txi_wait[1:0]),
.clk (txo_lclk),
.reset (reset));
//#####################################
//# lvds_link_txo instantiation
//#####################################
ewrapper_link_txo txo(/*AUTOINST*/
// Outputs
.txo_emesh_wait (txo_emesh_wait),
.tx_in (tx_in[71:0]),
// Inputs
.reset (reset),
.txo_lclk (txo_lclk),
.txo_emesh_access (txo_emesh_access),
.txo_emesh_write (txo_emesh_write),
.txo_emesh_datamode (txo_emesh_datamode[1:0]),
.txo_emesh_ctrlmode (txo_emesh_ctrlmode[3:0]),
.txo_emesh_dstaddr (txo_emesh_dstaddr[31:0]),
.txo_emesh_srcaddr (txo_emesh_srcaddr[31:0]),
.txo_emesh_data (txo_emesh_data[31:0]),
.burst_en (burst_en));
//#####################################
//# synchronization FIFOs (read/write)
//#####################################
//# FIFO writes
assign wrfifo_wr = emesh_access_outb & emesh_write_outb & ~emesh_wr_wait_inb;
assign rdfifo_wr = emesh_access_outb &~emesh_write_outb & ~emesh_rd_wait_inb;
//# FIFO reads
assign wrfifo_rd_int = ~(wrfifo_empty | txi_wr_wait_sync | txo_emesh_wait);
assign rdfifo_rd_int = ~(rdfifo_empty | txi_rd_wait_sync | txo_emesh_wait);
//# arbitration
always @ (posedge txo_lclk or posedge reset)
if(reset)
wrfifo_rd_en <= 1'b0;
else
wrfifo_rd_en <= ~wrfifo_rd_en;
assign wrfifo_rd = wrfifo_rd_int & ( wrfifo_rd_en | ~rdfifo_rd_int);
assign rdfifo_rd = rdfifo_rd_int & (~wrfifo_rd_en | ~wrfifo_rd_int);
//# FIFO input
assign fifo_in[103:0] = {emesh_srcaddr_outb[31:0],
emesh_data_outb[31:0],
emesh_dstaddr_outb[31:0],
emesh_ctrlmode_outb[3:0],
emesh_datamode_outb[1:0],
emesh_write_outb,
emesh_access_outb};
//# FIFO output
assign fifo_out[103:0] = wrfifo_rd ? wrfifo_out[103:0] : rdfifo_out[103:0];
assign txo_emesh_access = wrfifo_rd | rdfifo_rd;
assign txo_emesh_write = fifo_out[1];
assign txo_emesh_datamode[1:0] = fifo_out[3:2];
assign txo_emesh_ctrlmode[3:0] = fifo_out[7:4];
assign txo_emesh_dstaddr[31:0] = fifo_out[39:8];
assign txo_emesh_data[31:0] = fifo_out[71:40];
assign txo_emesh_srcaddr[31:0] = fifo_out[103:72];
/*fifo AUTO_TEMPLATE(.rd_clk (txo_lclk),
.wr_clk (emesh_clk_inb),
.wr_data (fifo_in[103:0]),
.rd_data (wrfifo_out[103:0]),
.rd_fifo_empty (wrfifo_empty),
.wr_fifo_full (emesh_wr_wait_inb),
.wr_write (wrfifo_wr),
.rd_read (wrfifo_rd),
);
*/
//# We have 4 entries of 104 bits each
fifo #(.DW(104), .AW(2)) wrfifo_txo(/*AUTOINST*/
// Outputs
.rd_data (wrfifo_out[103:0]), // Templated
.rd_fifo_empty (wrfifo_empty), // Templated
.wr_fifo_full (emesh_wr_wait_inb), // Templated
// Inputs
.reset (reset),
.wr_clk (emesh_clk_inb), // Templated
.rd_clk (txo_lclk), // Templated
.wr_write (wrfifo_wr), // Templated
.wr_data (fifo_in[103:0]), // Templated
.rd_read (wrfifo_rd)); // Templated
/*fifo AUTO_TEMPLATE(.rd_clk (txo_lclk),
.wr_clk (emesh_clk_inb),
.wr_data (fifo_in[103:0]),
.rd_data (rdfifo_out[103:0]),
.rd_fifo_empty (rdfifo_empty),
.wr_fifo_full (emesh_rd_wait_inb),
.wr_write (rdfifo_wr),
.rd_read (rdfifo_rd),
);
*/
//# We have 4 entries of 104 bits each
fifo #(.DW(104), .AW(2)) rdfifo_txo(/*AUTOINST*/
// Outputs
.rd_data (rdfifo_out[103:0]), // Templated
.rd_fifo_empty (rdfifo_empty), // Templated
.wr_fifo_full (emesh_rd_wait_inb), // Templated
// Inputs
.reset (reset),
.wr_clk (emesh_clk_inb), // Templated
.rd_clk (txo_lclk), // Templated
.wr_write (rdfifo_wr), // Templated
.wr_data (fifo_in[103:0]), // Templated
.rd_read (rdfifo_rd)); // Templated
endmodule // ewrapper_link_transmitter

View File

@ -0,0 +1,382 @@
/*
File: ewrapper_link_txo.v
This file is part of the Parallella Project
Copyright (C) 2013 Adapteva, Inc.
Contributed by Roman Trogan <support@adapteva.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program (see the file COPYING). If not, see
<http://www.gnu.org/licenses/>.
*/
module ewrapper_link_txo(/*AUTOARG*/
// Outputs
txo_emesh_wait, tx_in,
// Inputs
reset, txo_lclk, txo_emesh_access, txo_emesh_write,
txo_emesh_datamode, txo_emesh_ctrlmode, txo_emesh_dstaddr,
txo_emesh_srcaddr, txo_emesh_data, burst_en
);
//#########
//# INPUTS
//#########
input reset; //reset input
input txo_lclk; //transmitter clock
//# From the Emesh
input txo_emesh_access;
input txo_emesh_write;
input [1:0] txo_emesh_datamode;
input [3:0] txo_emesh_ctrlmode;
input [31:0] txo_emesh_dstaddr;
input [31:0] txo_emesh_srcaddr;
input [31:0] txo_emesh_data;
input burst_en; // Burst enable control
//##########
//# OUTPUTS
//##########
//# To the Emesh
output txo_emesh_wait;
//# To the lvds-serdes
// output [63:0] txo_data; //Eight Parallel Byte words
// output [7:0] txo_frame; //Parallel frame signals representing
// // 4 transmission clock cycles
output [71:0] tx_in;
/*AUTOINPUT*/
/*AUTOWIRE*/
//#########
//# Regs
//#########
reg shadow_access;
reg shadow_write;
reg [1:0] shadow_datamode;
reg [3:0] shadow_ctrlmode;
reg [31:0] shadow_dstaddr;
reg [31:0] shadow_srcaddr;
reg [31:0] shadow_data;
reg cycle1_access;
reg cycle1_write;
reg [1:0] cycle1_datamode;
reg [3:0] cycle1_ctrlmode;
reg [31:0] cycle1_dstaddr;
reg [31:0] cycle1_srcaddr;
reg [31:0] cycle1_data;
reg cycle2_access;
reg [31:0] cycle2_dstaddr;
reg [31:0] cycle2_srcaddr;
reg [31:0] cycle2_data;
reg cycle2_dbl;
reg [31:0] cycle2_dstaddr_inc8;
reg byte0_inc0;
reg txo_emesh_wait;
//reg [7:0] txo_frame;
//reg [63:0] txo_data;
reg [71:0] tx_in;
reg cycle1_frame_bit_del;
reg inc0_match_del;
//#########
//# Wires
//#########
wire emesh_access;
wire emesh_write;
wire [1:0] emesh_datamode;
wire [3:0] emesh_ctrlmode;
wire [31:0] emesh_dstaddr;
wire [31:0] emesh_srcaddr;
wire [31:0] emesh_data;
wire cycle1_dbl; // Cycle1 has a valid double write transaction
wire [31:0] cycle1_dstaddr_inc8;
wire inc8_match;
wire inc0_match;
wire burst_tran;
wire emesh_wait;
wire cycle1_frame_bit;
wire cycle2_frame_bit;
wire [7:0] cycle1_frame;
wire [7:0] cycle2_frame;
wire [7:0] txo_frame_int;
wire [7:0] tran_byte0;
wire [63:0] cycle1_data_long;
wire [63:0] cycle2_data_long;
wire [63:0] data_long;
wire [7:0] channel0;
wire [7:0] channel1;
wire [7:0] channel2;
wire [7:0] channel3;
wire [7:0] channel4;
wire [7:0] channel5;
wire [7:0] channel6;
wire [7:0] channel7;
// wire [8:0] channel0;
// wire [8:0] channel1;
// wire [8:0] channel2;
// wire [8:0] channel3;
// wire [8:0] channel4;
// wire [8:0] channel5;
// wire [8:0] channel6;
// wire [8:0] channel7;
// wire [63:0] txo_data_int;
wire [71:0] txo_data_int;
//##########################
//# Latch Emesh Transaction
//##########################
always @ (posedge txo_lclk or posedge reset)
if (reset)
shadow_access <= 1'b0;
else if(~txo_emesh_wait)
shadow_access <= txo_emesh_access;
always @ (posedge txo_lclk)
if (~txo_emesh_wait)
begin
shadow_write <= txo_emesh_write;
shadow_datamode[1:0] <= txo_emesh_datamode[1:0];
shadow_ctrlmode[3:0] <= txo_emesh_ctrlmode[3:0];
shadow_dstaddr[31:0] <= txo_emesh_dstaddr[31:0];
shadow_srcaddr[31:0] <= txo_emesh_srcaddr[31:0];
shadow_data[31:0] <= txo_emesh_data[31:0];
end
assign emesh_access = txo_emesh_wait ? shadow_access : txo_emesh_access;
assign emesh_write = txo_emesh_wait ? shadow_write : txo_emesh_write;
assign emesh_datamode[1:0] = txo_emesh_wait ? shadow_datamode[1:0] :
txo_emesh_datamode[1:0];
assign emesh_ctrlmode[3:0] = txo_emesh_wait ? shadow_ctrlmode[3:0] :
txo_emesh_ctrlmode[3:0];
assign emesh_dstaddr[31:0] = txo_emesh_wait ? shadow_dstaddr[31:0] :
txo_emesh_dstaddr[31:0];
assign emesh_srcaddr[31:0] = txo_emesh_wait ? shadow_srcaddr[31:0] :
txo_emesh_srcaddr[31:0];
assign emesh_data[31:0] = txo_emesh_wait ? shadow_data[31:0] :
txo_emesh_data[31:0];
//# Wait indication for emesh
assign emesh_wait = cycle1_access & cycle2_access & ~burst_tran;
always @ (posedge txo_lclk or posedge reset)
if (reset)
txo_emesh_wait <= 1'b0;
else
txo_emesh_wait <= emesh_wait;
//# First Cycle of the transaction to LVDS-SERDES
always @ (posedge txo_lclk or posedge reset)
if (reset)
cycle1_access <= 1'b0;
else if(~emesh_wait)
cycle1_access <= emesh_access;
always @ (posedge txo_lclk)
if (~emesh_wait)
begin
cycle1_write <= emesh_write;
cycle1_datamode[1:0] <= emesh_datamode[1:0];
cycle1_ctrlmode[3:0] <= emesh_ctrlmode[3:0];
cycle1_dstaddr[31:0] <= emesh_dstaddr[31:0];
cycle1_srcaddr[31:0] <= emesh_srcaddr[31:0];
cycle1_data[31:0] <= emesh_data[31:0];
end
//# Second Cycle of the transaction to LVDS-SERDES (never gets stalled)
always @ (posedge txo_lclk or posedge reset)
if (reset)
cycle2_access <= 1'b0;
else if(emesh_wait)
cycle2_access <= 1'b0;
else
cycle2_access <= cycle1_access;
always @ (posedge txo_lclk)
begin
cycle2_dstaddr[31:0] <= cycle1_dstaddr[31:0];
cycle2_srcaddr[31:0] <= cycle1_srcaddr[31:0];
cycle2_data[31:0] <= cycle1_data[31:0];
cycle2_dbl <= cycle1_dbl;
cycle2_dstaddr_inc8[31:0] <= cycle1_dstaddr_inc8[31:0];
end
always @ (posedge txo_lclk or posedge reset)
if(reset)
begin
cycle1_frame_bit_del <= 1'b0;
inc0_match_del <= 1'b0;
end
else
begin
cycle1_frame_bit_del <= cycle1_frame_bit;
inc0_match_del <= inc0_match;
end
//# keeping track of the address increment mode of burst transaction
always @ (posedge txo_lclk or posedge reset)
if(reset)
byte0_inc0 <= 1'b0;
else if(cycle1_frame_bit_del)
byte0_inc0 <= inc0_match_del;
//# transaction type + transaction address comparison
assign cycle1_dbl = cycle1_access & cycle1_write &
(&(cycle1_datamode[1:0])) & ~(|(cycle1_ctrlmode[3:0]));
assign cycle1_dstaddr_inc8[31:0] = cycle1_dstaddr[31:0] +
{{(28){1'b0}},4'b1000};
assign inc8_match = cycle1_dbl & cycle2_dbl &
(cycle1_dstaddr[31:0] == cycle2_dstaddr_inc8[31:0]);
assign inc0_match = cycle1_dbl & cycle2_dbl &
(cycle1_dstaddr[31:0] == cycle2_dstaddr[31:0]);
//# this is burst transaction
assign burst_tran = burst_en &
cycle1_dbl & cycle2_dbl &
((inc8_match & ~byte0_inc0) | // address match
(inc0_match & byte0_inc0));
assign tran_byte0[7:0] = {~cycle1_write,4'b0000,byte0_inc0,2'b00};
//###############################################
//# Actual Interface with LVDS-SERDES (easy :-) )
//###############################################
assign cycle1_frame_bit = cycle1_access & ~cycle2_access;
assign cycle2_frame_bit = cycle2_access;
assign cycle1_frame[7:0] = {2'b00,{(6){cycle1_frame_bit}}};
assign cycle2_frame[7:0] = {(8){cycle2_frame_bit}};
assign txo_frame_int[7:0] = cycle1_frame[7:0] | cycle2_frame[7:0];
assign cycle1_data_long[63:0] = {{(8){1'b0}},
{(8){1'b0}},
tran_byte0[7:0],
cycle1_ctrlmode[3:0],cycle1_dstaddr[31:28],
cycle1_dstaddr[27:20],
cycle1_dstaddr[19:12],
cycle1_dstaddr[11:4],
cycle1_dstaddr[3:0],cycle1_datamode[1:0],cycle1_write,cycle1_access};
assign cycle2_data_long[63:0] = {cycle2_data[31:0],cycle2_srcaddr[31:0]};
assign data_long[63:0] = cycle2_access ? cycle2_data_long[63:0] :
cycle1_data_long[63:0];
//# data per-channel arrangement
assign channel0[7:0] = {data_long[56],data_long[48],
data_long[40],data_long[32],
data_long[24],data_long[16],
data_long[8], data_long[0]
};
// assign channel0[8:0] = {txo_frame_int[0],data_long[7:0]};
assign channel1[7:0] = {data_long[57],data_long[49],
data_long[41],data_long[33],
data_long[25],data_long[17],
data_long[9], data_long[1]
};
// assign channel1[8:0] = {txo_frame_int[1],data_long[15:8]};
assign channel2[7:0] = {data_long[58],data_long[50],
data_long[42],data_long[34],
data_long[26],data_long[18],
data_long[10],data_long[2]
};
// assign channel2[8:0] = {txo_frame_int[2],data_long[23:16]};
assign channel3[7:0] = {data_long[59],data_long[51],
data_long[43],data_long[35],
data_long[27],data_long[19],
data_long[11],data_long[3]
};
// assign channel3[8:0] = {txo_frame_int[3],data_long[31:24]};
assign channel4[7:0] = {data_long[60],data_long[52],
data_long[44],data_long[36],
data_long[28],data_long[20],
data_long[12],data_long[4]
};
// assign channel4[8:0] = {txo_frame_int[4],data_long[39:32]};
assign channel5[7:0] = {data_long[61],data_long[53],
data_long[45],data_long[37],
data_long[29],data_long[21],
data_long[13],data_long[5]
};
// assign channel5[8:0] = {txo_frame_int[5],data_long[47:40]};
assign channel6[7:0] = {data_long[62],data_long[54],
data_long[46],data_long[38],
data_long[30],data_long[22],
data_long[14],data_long[6]
};
// assign channel6[8:0] = {txo_frame_int[6],data_long[55:48]};
assign channel7[7:0] = {data_long[63],data_long[55],
data_long[47],data_long[39],
data_long[31],data_long[23],
data_long[15],data_long[7]
};
// assign channel7[8:0] = {txo_frame_int[7],data_long[63:56]};
assign txo_data_int[71:0] =
{txo_frame_int[7:0],
channel7[7:0],channel6[7:0],channel5[7:0],channel4[7:0],
channel3[7:0],channel2[7:0],channel1[7:0],channel0[7:0]};
// assign txo_data_int[71:0] =
// {channel7[8:0],channel6[8:0],channel5[8:0],channel4[8:0],
// channel3[8:0],channel2[8:0],channel1[8:0],channel0[8:0]};
// always @ (posedge txo_lclk or posedge reset)
// if (reset)
// txo_frame[7:0] <= {(8){1'b0}};
// else
// txo_frame[7:0] <= txo_frame_int[7:0];
// always @ (posedge txo_lclk)
// txo_data[63:0] <= txo_data_int[63:0];
always @ (posedge txo_lclk or posedge reset)
if (reset)
tx_in[71:0] <= {(72){1'b0}};
else
tx_in[71:0] <= txo_data_int[71:0];
endmodule // ewrapper_link_txo

Some files were not shown because too many files have changed in this diff Show More