1
0
mirror of https://github.com/aolofsson/oh.git synced 2025-01-17 20:02:53 +08:00

An unverified clean top level elink design module

This commit is contained in:
aolofsson 2014-12-14 17:25:46 -05:00
parent 4f51cc342d
commit c9a70e5f6b
3 changed files with 1266 additions and 0 deletions

357
elink/hdl/ecfg.v Normal file
View File

@ -0,0 +1,357 @@
/*
Copyright (C) 2013 Adapteva, Inc.
Contributed by Andreas Olofsson <andreas@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/>.
*/
/*
########################################################################
EPIPHANY CONFIGURATION REGISTER
########################################################################
-------------------------------------------------------------
ESYSRESET ***Elink reset***
[0] 0 - elink active
1 - elink in reset
-------------------------------------------------------------
ESYSCFGTX ***Elink transmitter configuration***
[0] 0 - link TX disable
1 - link TX enable
[1] 0 - normal pass through transaction mode
1 - mmu mode
[3:2] 00 - normal mode
01 - gpio mode
10 - auto-increment 64-bit address/data pairs
11 - reserved
[7:4] Transmit control mode for eMesh
[11:8] 0000 - No division, full speed
0001 - Divide by 2
Others - Reserved
-------------------------------------------------------------
ESYSCFGRX ***Elink receiver configuration***
[0] 0 - link RX disable
1 - link RX enable
[1] 0 - normal transaction mode
1 - mmu mode
[3:2] 00 - normal mode
01 - GPIO mode (drive rd wait pins from registers)
10 - loopback mode (loops TX-->RX)
11 - reserved
[4] 0 - set monitor to count traffic
1 - set monitor to count congestion
-------------------------------------------------------------
ESYSCFGCLK ***Epiphany clock frequency setting***
[3:0] Output divider
0000 - Clock turned off
0001 - CLKIN/64
0010 - CLKIN/32
0011 - CLKIN/16
0100 - CLKIN/8
0101 - CLKIN/4
0110 - CLKIN/2
0111 - CLKIN/1 (full speed)
1XXX - RESERVED
[7:4] PLL settings (TBD)
-------------------------------------------------------------
ESYSCOREID ***CORE ID***
[5:0] Column ID-->default at powerup/reset
[11:6] Row ID
-------------------------------------------------------------
ESYSVERSION ***Version number (read only)***
[7:0] Revision #, incremented in each change (match git?)
[15:8] Type (features included in FPGA load, same board)
[23:16] Board platform #
[31:24] Generation # (needed??)
-------------------------------------------------------------
ESYSDATAIN ***Data on elink input pins
[7:0] rx_data[7:0]
[8] tx_frame
[9] tx_wait_rd
[10] tx_wait_wr
-------------------------------------------------------------
ESYSDATAOUT ***Data on eLink output pins
[7:0] tx_data[7:0]
[8] tx_frame
[9] rx_wait_rd
[10] rx_wait_wr
-------------------------------------------------------------
ESYSDEBUG ***Various debug signals from elink
[31:0] (design specific, generic inferface for now)
included:
-all wait signals, (4)
-fifo fulls,
-fifo emptys
-axi access, ready signals for master/slave
-frame signals (in and out)
########################################################################
*/
// These are WORD addresses (bits 11:2)
`define E_REG_SYSRESET 10'h010
`define E_REG_SYSCFGTX 10'h011
`define E_REG_SYSCFGRX 10'h012
`define E_REG_SYSCFGCLK 10'h013
`define E_REG_SYSCOREID 10'h014
`define E_REG_SYSVERSION 10'h015
`define E_REG_SYSDATAIN 10'h016
`define E_REG_SYSDATAOUT 10'h017
`define E_REG_SYSDEBUG 10'h018
module ecfg (/*AUTOARG*/
// Outputs
mi_dout, ecfg_reset, ecfg_tx_enable, ecfg_tx_mmu_mode,
ecfg_tx_gpio_mode, ecfg_tx_tp_mode, ecfg_tx_ctrl_mode,
ecfg_tx_clkdiv, ecfg_rx_enable, ecfg_rx_mmu_mode,
ecfg_rx_gpio_mode, ecfg_cclk_en, ecfg_cclk_div, ecfg_cclk_pllcfg,
ecfg_coreid, ecfg_dataout,
// Inputs
mi_clk, mi_en, mi_we, mi_addr, mi_din, hw_reset, ecfg_datain,
ecfg_debug_signals
);
//Register file parameters
/*
#####################################################################
COMPILE TIME PARAMETERS
######################################################################
*/
parameter COREID = 12'h808;
parameter VERSION = 32'h00_00_00_00; // FPGA (gen:plat:type:rev)
parameter IDW = 12; // Elink ID (row,column coordinate)
parameter RFAW = 12; // Register file address width
// NB: The BRAM interface seems to provide BYTE addresses!
/******************************/
/*HARDWARE RESET (POR/BUTTON) */
/******************************/
input hw_reset;
/*****************************/
/*SIMPLE MEMORY INTERFACE */
/*****************************/
input mi_clk;
input mi_en;
input mi_we; //Single we, must write full words!
input [RFAW-1:0] mi_addr;
input [31:0] mi_din;
output [31:0] mi_dout;
/*****************************/
/*ELINK CONTROL SIGNALS */
/*****************************/
//RESET
output ecfg_reset;
//tx
output ecfg_tx_enable; //enable signal for TX
output ecfg_tx_mmu_mode; //enables MMU on transmit path
output ecfg_tx_gpio_mode; //forces TX output pins to constants
output ecfg_tx_tp_mode; //auto-generates TX transactions
output [3:0] ecfg_tx_ctrl_mode; //value for emesh ctrlmode tag
output [3:0] ecfg_tx_clkdiv; //transmit clock divider
//rx
output ecfg_rx_enable; //enable signal for rx
output ecfg_rx_mmu_mode; //enables MMU on rx path
output ecfg_rx_gpio_mode; //forces rx wait pins to constants
//cclk
output ecfg_cclk_en; //cclk enable
output [3:0] ecfg_cclk_div; //cclk divider setting
output [3:0] ecfg_cclk_pllcfg; //pll configuration
//coreid
output [11:0] ecfg_coreid; //core-id of fpga elink
//gpio
input [10:0] ecfg_datain; // data from elink inputs
output [10:0] ecfg_dataout; //data for elink outputs {rd_wait,wr_wait,frame,data[7:0]}
//debug
input [31:0] ecfg_debug_signals;//various signals for debugging the elink hardware
/*------------------------BODY CODE---------------------------------------*/
//registers
reg [11:0] ecfg_cfgtx_reg;
reg [4:0] ecfg_cfgrx_reg;
reg [7:0] ecfg_cfgclk_reg;
reg [11:0] ecfg_coreid_reg;
reg ecfg_reset_reg;
reg [11:0] ecfg_datain_reg;
reg [11:0] ecfg_dataout_reg;
reg [31:0] mi_dout;
//wires
wire ecfg_read;
wire ecfg_write;
wire ecfg_reset_match;
wire ecfg_cfgtx_match;
wire ecfg_cfgrx_match;
wire ecfg_cfgclk_match;
wire ecfg_coreid_match;
wire ecfg_datain_match;
wire ecfg_dataout_match;
wire ecfg_match;
wire ecfg_regmux;
wire [31:0] ecfg_reg_mux;
wire ecfg_cfgtx_write;
wire ecfg_cfgrx_write;
wire ecfg_cfgclk_write;
wire ecfg_coreid_write;
wire ecfg_dataout_write;
wire ecfg_rx_monitor_mode;
wire ecfg_reset_write;
/*****************************/
/*ADDRESS DECODE LOGIC */
/*****************************/
//read/write decode
assign ecfg_write = mi_en & mi_we;
assign ecfg_read = mi_en & ~mi_we;
//address match signals
assign ecfg_reset_match = mi_addr[RFAW-1:2]==`E_REG_SYSRESET;
assign ecfg_cfgtx_match = mi_addr[RFAW-1:2]==`E_REG_SYSCFGTX;
assign ecfg_cfgrx_match = mi_addr[RFAW-1:2]==`E_REG_SYSCFGRX;
assign ecfg_cfgclk_match = mi_addr[RFAW-1:2]==`E_REG_SYSCFGCLK;
assign ecfg_coreid_match = mi_addr[RFAW-1:2]==`E_REG_SYSCOREID;
assign ecfg_version_match = mi_addr[RFAW-1:2]==`E_REG_SYSVERSION;
assign ecfg_datain_match = mi_addr[RFAW-1:2]==`E_REG_SYSDATAIN;
assign ecfg_dataout_match = mi_addr[RFAW-1:2]==`E_REG_SYSDATAOUT;
assign ecfg_match = ecfg_reset_match |
ecfg_cfgtx_match |
ecfg_cfgrx_match |
ecfg_cfgclk_match |
ecfg_coreid_match |
ecfg_version_match |
ecfg_datain_match |
ecfg_dataout_match;
//Write enables
assign ecfg_reset_write = ecfg_reset_match & ecfg_write;
assign ecfg_cfgtx_write = ecfg_cfgtx_match & ecfg_write;
assign ecfg_cfgrx_write = ecfg_cfgrx_match & ecfg_write;
assign ecfg_cfgclk_write = ecfg_cfgclk_match & ecfg_write;
assign ecfg_coreid_write = ecfg_coreid_match & ecfg_write;
assign ecfg_dataout_write = ecfg_dataout_match & ecfg_write;
//###########################
//# ESYSCFGTX
//###########################
always @ (posedge mi_clk)
if(hw_reset)
ecfg_cfgtx_reg[11:0] <= 12'b0;
else if (ecfg_cfgtx_write)
ecfg_cfgtx_reg[11:0] <= mi_din[11:0];
assign ecfg_tx_enable = ecfg_cfgtx_reg[0];
assign ecfg_tx_mmu_mode = ecfg_cfgtx_reg[1];
assign ecfg_tx_gpio_mode = ecfg_cfgtx_reg[3:2]==2'b01;
assign ecfg_tx_tp_mode = ecfg_cfgtx_reg[3:2]==2'b10;
assign ecfg_tx_ctrl_mode[3:0] = ecfg_cfgtx_reg[7:4];
assign ecfg_tx_clkdiv[3:0] = ecfg_cfgtx_reg[11:8];
//###########################
//# ESYSCFGRX
//###########################
always @ (posedge mi_clk)
if(hw_reset)
ecfg_cfgrx_reg[4:0] <= 5'b0;
else if (ecfg_cfgrx_write)
ecfg_cfgrx_reg[4:0] <= mi_din[4:0];
assign ecfg_rx_enable = ecfg_cfgrx_reg[0];
assign ecfg_rx_mmu_mode = ecfg_cfgrx_reg[1];
assign ecfg_rx_gpio_mode = ecfg_cfgrx_reg[3:2]==2'b01;
assign ecfg_rx_loopback_mode = ecfg_cfgrx_reg[3:2]==2'b10;
assign ecfg_rx_monitor_mode = ecfg_cfgrx_reg[4];
//###########################
//# ESYSCFGCLK
//###########################
always @ (posedge mi_clk)
if(hw_reset)
ecfg_cfgclk_reg[7:0] <= 8'b0;
else if (ecfg_cfgclk_write)
ecfg_cfgclk_reg[7:0] <= mi_din[7:0];
assign ecfg_cclk_en = ~(ecfg_cfgclk_reg[3:0]==4'b0000);
assign ecfg_cclk_div[3:0] = ecfg_cfgclk_reg[3:0];
assign ecfg_cclk_pllcfg[3:0] = ecfg_cfgclk_reg[7:4];
//###########################
//# ESYSCOREID
//###########################
always @ (posedge mi_clk)
if(hw_reset)
ecfg_coreid_reg[IDW-1:0] <= PARAM_COREID;
else if (ecfg_coreid_write)
ecfg_coreid_reg[IDW-1:0] <= mi_din[IDW-1:0];
assign ecfg_coreid[IDW-1:0] = ecfg_coreid_reg[IDW-1:0];
//###########################
//# ESYSDATAIN
//###########################
always @ (posedge mi_clk)
ecfg_datain_reg <= ecfg_datain;
//###########################
//# ESYSDATAOUT
//###########################
always @ (posedge mi_clk)
if(hw_reset)
ecfg_dataout_reg <= 'd0;
else if (ecfg_dataout_write)
ecfg_dataout_reg <= mi_din[10:0];
assign ecfg_dataout[10:0] = ecfg_dataout_reg[10:0];
//###########################
//# ESYSRESET
//###########################
always @ (posedge mi_clk)
if(hw_reset)
ecfg_reset_reg <= 1'b0;
else if (ecfg_reset_write)
ecfg_reset_reg <= mi_din[0];
assign ecfg_reset = ecfg_reset_reg | hw_reset;
//###############################
//# DATA READBACK MUX
//###############################
//Pipelineing readback
always @ (posedge mi_clk)
if(ecfg_read)
case(mi_addr[RFAW-1:2])
`E_REG_SYSRESET: mi_dout[31:0] <= {31'b0, ecfg_reset_reg};
`E_REG_SYSCFGTX: mi_dout[31:0] <= {20'b0, ecfg_cfgtx_reg[11:0]};
`E_REG_SYSCFGRX: mi_dout[31:0] <= {27'b0, ecfg_cfgrx_reg[4:0]};
`E_REG_SYSCFGCLK: mi_dout[31:0] <= {24'b0, ecfg_cfgclk_reg[7:0]};
`E_REG_SYSCOREID: mi_dout[31:0] <= {{(32-IDW){1'b0}}, ecfg_coreid_reg[IDW-1:0]};
`E_REG_SYSVERSION: mi_dout[31:0] <= VERSION;
`E_REG_SYSDATAIN: mi_dout[31:0] <= {20'b0, ecfg_datain_reg[11:0]};
`E_REG_SYSDATAOUT: mi_dout[31:0] <= {20'b0, ecfg_dataout_reg[11:0]};
`E_REG_SYSDEBUG: mi_dout[31:0] <= ecfg_debug_signals[31:0];
default: mi_dout[31:0] <= 32'd0;
endcase
endmodule // e_cfg

255
elink/hdl/eclock.v Normal file
View File

@ -0,0 +1,255 @@
/*
Copyright (C) 2014 Adapteva, Inc.
Contributed 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/>.
*/
/*###########################################################################
# Function: Generates clocks for eLink module:
# clk_n/p - Epiphany Core Clock, Differential, must be connected
# directly to IO pins.
#
# txlclk_p - Parallel data clock, at bit rate / 8
#
# txlclk_s - Serial DDR data clock, at bit rate / 2
#
# txlclk_out - DDR "Clock" clock, to generate LCLK output
# At bit rate / 2, 90deg shifted from lclk_s
#
# Inputs:
# ecfg_cclk_en - Enable the CCLK output
# ecfg_cclk_div - CCLK divider
# ecfg_cclk_pllcfg - PLL configuration (not implemented)
#
# Notes: Uses Xilinx macros throughout
#
############################################################################
*/
`timescale 1ns/1ps
module eclock (/*AUTOARG*/
// Outputs
cclk_p, cclk_n, txlclk_s, txlclk_out, txlclk_p,
// Inputs
clkin, reset, ecfg_cclk_en, ecfg_cclk_div, ecfg_cclk_pllcfg
);
// Parameters must be set as follows:
// PFD input frequency = 1/CLKIN1_PERIOD / DIVCLK_DIVIDE (10-450MHz)
// VCO frequency = PFD input frequency * CLKFBOUT_MULT (800-1600MHz)
// Output frequency = VCO frequency / CLKOUTn_DIVIDE
parameter CLKIN_PERIOD = 10.000; // ns -> 100MHz
parameter CLKIN_DIVIDE = 1;
parameter VCO_MULT = 12; // VCO = 1200MHz
parameter CCLK_DIVIDE = 2; // CCLK = 600MHz (at /1 setting)
parameter LCLK_DIVIDE = 4; // LCLK = 300MHz (600MB/s eLink, 75MW/s parallel)
parameter FEATURE_CCLK_DIV = 1'b1;
parameter IOSTD_ELINK = "LVDS_25";
// input clock & reset
input clkin;
input reset;
// From configuration register
input ecfg_cclk_en; //cclk enable
input [3:0] ecfg_cclk_div; //cclk divider setting
input [3:0] ecfg_cclk_pllcfg; //pll configuration TODO: ??
//epiphany clock
output cclk_p, cclk_n;
//clocks for elink transmitter
output txlclk_s;
output txlclk_out;
output txlclk_p;
// Wires
wire cclk_src;
wire cclk_base;
wire cclk_p_src;
wire cclk_p;
wire cclk;
wire lclk_s_src;
wire lclk_out_src;
wire lclk_p_src;
wire clkfb;
// PLL Primitive
PLLE2_BASE
#(
.BANDWIDTH("OPTIMIZED"), // OPTIMIZED, HIGH, LOW
.CLKFBOUT_MULT(VCO_MULT), // Multiply value for all CLKOUT, (2-64)
.CLKFBOUT_PHASE(0.0), // Phase offset in degrees of CLKFB, (-360.000-360.000).
.CLKIN1_PERIOD(CLKIN_PERIOD),// Input clock period in ns to ps resolution (i.e. 33.333 is 30 MHz).
// CLKOUT0_DIVIDE - CLKOUT5_DIVIDE: Divide amount for each CLKOUT (1-128)
.CLKOUT0_DIVIDE(CCLK_DIVIDE),
.CLKOUT1_DIVIDE(LCLK_DIVIDE),
.CLKOUT2_DIVIDE(LCLK_DIVIDE),
.CLKOUT3_DIVIDE(LCLK_DIVIDE * 4),
.CLKOUT4_DIVIDE(CCLK_DIVIDE * 4),
.CLKOUT5_DIVIDE(128),
// CLKOUT0_DUTY_CYCLE - CLKOUT5_DUTY_CYCLE: Duty cycle for each CLKOUT (0.001-0.999).
.CLKOUT0_DUTY_CYCLE(0.5),
.CLKOUT1_DUTY_CYCLE(0.5),
.CLKOUT2_DUTY_CYCLE(0.5),
.CLKOUT3_DUTY_CYCLE(0.5),
.CLKOUT4_DUTY_CYCLE(0.5),
.CLKOUT5_DUTY_CYCLE(0.5),
// CLKOUT0_PHASE - CLKOUT5_PHASE: Phase offset for each CLKOUT (-360.000-360.000).
.CLKOUT0_PHASE(0.0),
.CLKOUT1_PHASE(0.0),
.CLKOUT2_PHASE(90.0),
.CLKOUT3_PHASE(0.0),
.CLKOUT4_PHASE(0.0),
.CLKOUT5_PHASE(0.0),
.DIVCLK_DIVIDE(CLKIN_DIVIDE),// Master division value, (1-56)
.REF_JITTER1(0.01), // Reference input jitter in UI, (0.000-0.999).
.STARTUP_WAIT("FALSE") // Delay DONE until PLL Locks, ("TRUE"/"FALSE")
) eclk_pll
(
// Clock Outputs: 1-bit (each) output: User configurable clock outputs
.CLKOUT0(cclk_src), // 1-bit output: CLKOUT0
.CLKOUT1(lclk_s_src), // 1-bit output: CLKOUT1
.CLKOUT2(lclk_out_src), // 1-bit output: CLKOUT2
.CLKOUT3(lclk_p_src), // 1-bit output: CLKOUT3
.CLKOUT4(cclk_p_src), // 1-bit output: CLKOUT4
.CLKOUT5(), // 1-bit output: CLKOUT5
// Feedback Clocks: 1-bit (each) output: Clock feedback ports
.CLKFBOUT(clkfb), // 1-bit output: Feedback clock
.LOCKED(), // 1-bit output: LOCK
.CLKIN1(clkin), // 1-bit input: Input clock
// Control Ports: 1-bit (each) inpu: PLL control ports
.PWRDWN(1'b0), // 1-bit input: Power-down
.RST(1'b0), // 1-bit input: Reset
// Feedback Clocks: 1-bit (each) input: Clock feedback ports
.CLKFBIN(clkfb) // 1-bit input: Feedback clock
);
// Output buffering
BUFG cclk_buf
(.O (cclk_base),
.I (cclk_src));
BUFG cclk_p_buf
(.O (cclk_p),
.I (cclk_p_src));
BUFG lclk_s_buf
(.O (txlclk_s),
.I (lclk_s_src));
BUFG lclk_out_buf
(.O (txlclk_out),
.I (lclk_out_src));
BUFG lclk_p_buf
(.O (txlclk_p),
.I (lclk_p_src));
generate
if( FEATURE_CCLK_DIV ) begin : gen_cclk_div
// Create adjustable (but fast) CCLK
wire rxi_cclk_out;
reg [8:1] cclk_pattern;
reg [3:0] clk_div_sync;
reg enb_sync;
always @ (posedge cclk_p) begin // Might need x-clock TIG here
clk_div_sync <= ecfg_cclk_div;
enb_sync <= ecfg_cclk_en;
if(enb_sync)
case(clk_div_sync)
4'h0: cclk_pattern <= 8'd0; // Clock OFF
4'h7: cclk_pattern <= 8'b10101010; // Divide by 1
4'h6: cclk_pattern <= 8'b11001100; // Divide by 2
4'h5: cclk_pattern <= 8'b11110000; // Divide by 4
default: cclk_pattern <= {8{~cclk_pattern[1]}}; // /8
endcase
else
cclk_pattern <= 8'b00000000;
end // always @ (posedge lclk_p)
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(cclk), // 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(cclk_base), // 1-bit input: High speed clock
.CLKDIV(cclk_p), // 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
);
end else begin : gen_fixed_cclk // Non-dividable CCLK
reg enb_sync;
always @ (posedge cclk_p)
enb_sync <= ecfg_cclk_en;
// The following does not result in timing failures,
// but doesn't seem glitch-safe
assign cclk = cclk_base & enb_sync;
end
endgenerate
// xilinx OBUFDS instantiation
//
OBUFDS
#(.IOSTANDARD (IOSTD_ELINK))
obufds_cclk_inst
(.O (cclk_p),
.OB (cclk_n),
.I (cclk));
endmodule // eclock

654
elink/hdl/elink.v Normal file
View File

@ -0,0 +1,654 @@
/*
Copyright (C) 2014 Adapteva, Inc.
Contributed by Fred Huettig <fred@adapteva.com>
Contributed by Andreas Olofsson <andreas@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 e_link(/*AUTOARG*/
// Outputs
rowid, colid, reset_n, cclk_p, cclk_n, rx_wr_wait_p, rx_wr_wait_n,
rx_rd_wait_p, rx_rd_wait_n, tx_lclk_p, tx_lclk_n, tx_frame_p,
tx_frame_n, tx_data_p, tx_data_n, embox_not_empty, embox_full,
m_axi_araddr, m_axi_arburst, m_axi_arcache, m_axi_arid,
m_axi_arlen, m_axi_arlock, m_axi_arprot, m_axi_arqos, m_axi_arsize,
m_axi_arvalid, m_axi_awaddr, m_axi_awburst, m_axi_awcache,
m_axi_awid, m_axi_awlen, m_axi_awlock, m_axi_awprot, m_axi_awqos,
m_axi_awsize, m_axi_awvalid, m_axi_bready, m_axi_rready,
m_axi_wdata, m_axi_wlast, m_axi_wstrb, m_axi_wvalid, s_axi_arready,
s_axi_awready, s_axi_bid, s_axi_bresp, s_axi_bvalid, s_axi_rdata,
s_axi_rid, s_axi_rlast, s_axi_rresp, s_axi_rvalid, s_axi_wready,
s_axicfg_arready, s_axicfg_awready, s_axicfg_bresp,
s_axicfg_bvalid, s_axicfg_rdata, s_axicfg_rresp, s_axicfg_rvalid,
s_axicfg_wready,
// Inputs
hw_reset, clkin, rx_lclk_p, rx_lclk_n, rx_frame_p, rx_frame_n,
rx_data_p, rx_data_n, tx_wr_wait_p, tx_wr_wait_n, tx_rd_wait_p,
tx_rd_wait_n, m_axi_aclk, m_axi_aresetn, m_axi_arready,
m_axi_awready, m_axi_bid, m_axi_bresp, m_axi_bvalid, m_axi_rdata,
m_axi_rid, m_axi_rlast, m_axi_rresp, m_axi_rvalid, m_axi_wready,
s_axi_aclk, s_axi_aresetn, s_axi_araddr, s_axi_arburst,
s_axi_arcache, s_axi_arid, s_axi_arlen, s_axi_arlock, s_axi_arprot,
s_axi_arqos, s_axi_arregion, s_axi_arsize, s_axi_arvalid,
s_axi_awaddr, s_axi_awburst, s_axi_awcache, s_axi_awid,
s_axi_awlen, s_axi_awlock, s_axi_awprot, s_axi_awqos,
s_axi_awregion, s_axi_awsize, s_axi_awvalid, s_axi_bready,
s_axi_rready, s_axi_wdata, s_axi_wlast, s_axi_wstrb, s_axi_wvalid,
s_axicfg_araddr, s_axicfg_arprot, s_axicfg_arvalid,
s_axicfg_awaddr, s_axicfg_awprot, s_axicfg_awvalid,
s_axicfg_bready, s_axicfg_rready, s_axicfg_wdata, s_axicfg_wstrb,
s_axicfg_wvalid
);
parameter COREID = `CFG_COREID;
/****************************/
/*BASIC SIGNALS */
/****************************/
input hw_reset; //active high asynchronous hardware reset
input clkin; //primary clock input
/*****************************/
/*EPIPHANY BASIC INTERFACE */
/*****************************/
output [3:0] rowid; //row id to drive out to Epiphany
output [3:0] colid; //col id to drive out to Epiphany
output reset_n; //reset signal for Epiphany (active low)
output cclk_p; //high speed core clock (1GHz) to Epiphany
output cclk_n;
/*****************************/
/*ELINK INTERFACE (I/O PINS) */
/*****************************/
//Receiver
input rx_lclk_p; //linkh speed clock input (up to 500MHz)
input rx_lclk_n;
input rx_frame_p; //transaction frame signal
input rx_frame_n;
input [7:0] rx_data_p; //receive data (dual data rate)
input [7:0] rx_data_n;
output rx_wr_wait_p; //outgoing pushback on write transactions
output rx_wr_wait_n;
output rx_rd_wait_p; //outgoing pushback on read transactions
output rx_rd_wait_n;
//Transmitter
output tx_lclk_p; //hlink clock output (up to 500MHz)
output tx_lclk_n;
output tx_frame_p; //transaction frame signal
output tx_frame_n;
output [7:0] tx_data_p; //transmit data (dual data rate)
output [7:0] tx_data_n;
input tx_wr_wait_p; //incoming pushback on write transactions
input tx_wr_wait_n;
input tx_rd_wait_p; //incoming pushback on read transactions
input tx_rd_wait_n;
/*****************************/
/*MAILBOX */
/*****************************/
output embox_not_empty;
output embox_full;
/*****************************/
/*AXI master interface */
/*****************************/
//Clock and reset
input m_axi_aclk;
input m_axi_aresetn;
//Read address channel
output [31:0] m_axi_araddr; //read address
output [1:0] m_axi_arburst; //burst type
output [3:0] m_axi_arcache; //memory type
output [0:0] m_axi_arid; //address ID
output [7:0] m_axi_arlen; //burst length (number of data transfers)
output [0:0] m_axi_arlock; //lock type (atomic characteristics)
output [2:0] m_axi_arprot; //protection type
output [3:0] m_axi_arqos; //quality of service (setting?)
input m_axi_arready; //read ready
output [2:0] m_axi_arsize; //burst size (the size of each transfer)
output m_axi_arvalid; //write address valid
//Write address channel
output [31:0] m_axi_awaddr;
output [1:0] m_axi_awburst;
output [3:0] m_axi_awcache;
output [0:0] m_axi_awid;
output [7:0] m_axi_awlen;
output [0:0] m_axi_awlock;
output [2:0] m_axi_awprot;
output [3:0] m_axi_awqos;
input m_axi_awready;
output [2:0] m_axi_awsize;
output m_axi_awvalid;
//Buffered write response channel
input [0:0] m_axi_bid; //response tag
output m_axi_bready;
input [1:0] m_axi_bresp;
input m_axi_bvalid;
//Read channel
input [63:0] m_axi_rdata;
input [0:0] m_axi_rid; //read id tag
input m_axi_rlast; //indicates last transfer of a burst
output m_axi_rready; //read ready signal
input [1:0] m_axi_rresp;
input m_axi_rvalid;
//Write channel
output [63:0] m_axi_wdata;
output m_axi_wlast; //indicates last transfer of a burs
input m_axi_wready; //response ready
output [7:0] m_axi_wstrb;
output m_axi_wvalid;
/*****************************/
/*AXI slave interface */
/*****************************/
//Clock and reset
input s_axi_aclk;
input s_axi_aresetn;
//Read address channel
input [29:0] s_axi_araddr;
input [1:0] s_axi_arburst;
input [3:0] s_axi_arcache;
input [11:0] s_axi_arid;
input [7:0] s_axi_arlen;
input [0:0] s_axi_arlock;
input [2:0] s_axi_arprot;
input [3:0] s_axi_arqos;
output s_axi_arready;
input [3:0] s_axi_arregion;
input [2:0] s_axi_arsize;
input s_axi_arvalid;
//Write address channel
input [29:0] s_axi_awaddr;
input [1:0] s_axi_awburst;
input [3:0] s_axi_awcache;
input [11:0] s_axi_awid;
input [7:0] s_axi_awlen;
input [0:0] s_axi_awlock;
input [2:0] s_axi_awprot;
input [3:0] s_axi_awqos;
output s_axi_awready;
input [3:0] s_axi_awregion;
input [2:0] s_axi_awsize;
input s_axi_awvalid;
//Buffered write response channel
output [11:0] s_axi_bid;
input s_axi_bready;
output [1:0] s_axi_bresp;
output s_axi_bvalid;
//Read channel
output [31:0] s_axi_rdata;
output [11:0] s_axi_rid;
output s_axi_rlast;
input s_axi_rready;
output [1:0] s_axi_rresp;
output s_axi_rvalid;
//Write channel
input [31:0] s_axi_wdata;
input s_axi_wlast;
output s_axi_wready;
input [3:0] s_axi_wstrb;
input s_axi_wvalid;
/*****************************/
/*AXI config slave interface */
/*****************************/
//read address channel
input [12:0] s_axicfg_araddr;
input [2:0] s_axicfg_arprot;
output s_axicfg_arready;
input s_axicfg_arvalid;
//write address channel
input [12:0] s_axicfg_awaddr;
input [2:0] s_axicfg_awprot;
output s_axicfg_awready;
input s_axicfg_awvalid;
//buffered read response channel
input s_axicfg_bready;
output [1:0] s_axicfg_bresp;
output s_axicfg_bvalid;
//read channel
output [31:0] s_axicfg_rdata;
input s_axicfg_rready;
output [1:0] s_axicfg_rresp;
output s_axicfg_rvalid;
//write channel
input [31:0] s_axicfg_wdata;
output s_axicfg_wready;
input [3:0] s_axicfg_wstrb;
input s_axicfg_wvalid;
//wires
wire [31:0] mi_rd_data;
wire [31:0] mi_dout_ecfg;
wire [31:0] mi_dout_embox;
wire [31:0] mi_dout_rx;
wire [31:0] mi_dout_tx;
/*AUTOINPUT*/
/*AUTOOUTPUT*/
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire [3:0] ecfg_cclk_div; // From ecfg of ecfg.v
wire ecfg_cclk_en; // From ecfg of ecfg.v
wire [3:0] ecfg_cclk_pllcfg; // From ecfg of ecfg.v
wire [11:0] ecfg_coreid; // From ecfg of ecfg.v
wire [8:0] ecfg_datain; // From erx of erx.v
wire [10:0] ecfg_dataout; // From ecfg of ecfg.v
wire [15:0] ecfg_rx_debug_signals; // From erx of erx.v
wire ecfg_rx_enable; // From ecfg of ecfg.v
wire ecfg_rx_gpio_mode; // From ecfg of ecfg.v
wire ecfg_rx_mmu_mode; // From ecfg of ecfg.v
wire [3:0] ecfg_tx_clkdiv; // From ecfg of ecfg.v
wire [3:0] ecfg_tx_ctrl_mode; // From ecfg of ecfg.v
wire [15:0] ecfg_tx_debug_signals; // From etx of etx.v
wire ecfg_tx_enable; // From ecfg of ecfg.v
wire ecfg_tx_gpio_mode; // From ecfg of ecfg.v
wire ecfg_tx_mmu_mode; // From ecfg of ecfg.v
wire ecfg_tx_tp_mode; // From ecfg of ecfg.v
wire emaxi_emrq_empty; // From erx of erx.v
wire [102:0] emaxi_emrq_rd_data; // From erx of erx.v
wire emaxi_emrq_rd_en; // From emaxi of emaxi.v
wire emaxi_emrr_full; // From etx of etx.v
wire emaxi_emrr_prog_full; // From etx of etx.v
wire [102:0] emaxi_emrr_wr_data; // From emaxi of emaxi.v
wire emaxi_emrr_wr_en; // From emaxi of emaxi.v
wire emaxi_emwr_empty; // From erx of erx.v
wire [102:0] emaxi_emwr_rd_data; // From erx of erx.v
wire emaxi_emwr_rd_en; // From emaxi of emaxi.v
wire esaxi_emrq_full; // From etx of etx.v
wire esaxi_emrq_prog_full; // From etx of etx.v
wire [102:0] esaxi_emrq_wr_data; // From esaxi of esaxi.v
wire esaxi_emrq_wr_en; // From esaxi of esaxi.v
wire esaxi_emrr_empty; // From erx of erx.v
wire [102:0] esaxi_emrr_rd_data; // From erx of erx.v
wire esaxi_emrr_rd_en; // From esaxi of esaxi.v
wire esaxi_emwr_full; // From etx of etx.v
wire esaxi_emwr_prog_full; // From etx of etx.v
wire [102:0] esaxi_emwr_wr_data; // From esaxi of esaxi.v
wire esaxi_emwr_wr_en; // From esaxi of esaxi.v
wire [RFAW-1:0] mi_addr; // From esaxilite of esaxilite.v
wire mi_clk; // From esaxilite of esaxilite.v
wire [31:0] mi_din; // From esaxilite of esaxilite.v
wire mi_en; // From esaxilite of esaxilite.v
wire mi_we; // From esaxilite of esaxilite.v
wire reset; // From ecfg of ecfg.v
wire txlclk_out; // From eclock of eclock.v
wire txlclk_p; // From eclock of eclock.v
wire txlclk_s; // From eclock of eclock.v
// End of automatics
/***********************************************************/
/*AXI MASTER */
/***********************************************************/
/*emaxi AUTO_TEMPLATE (
// Outputs
.m00_\(.*\) (m_\1[]),
.em\(.*\) (emaxi_em\1[]),
);
*/
emaxi emaxi(/*AUTOINST*/
// Outputs
.emwr_rd_en (emaxi_emwr_rd_en), // Templated
.emrq_rd_en (emaxi_emrq_rd_en), // Templated
.emrr_wr_data (emaxi_emrr_wr_data[102:0]), // Templated
.emrr_wr_en (emaxi_emrr_wr_en), // Templated
.m00_axi_awid (m_axi_awid[0:0]), // Templated
.m00_axi_awaddr (m_axi_awaddr[31:0]), // Templated
.m00_axi_awlen (m_axi_awlen[7:0]), // Templated
.m00_axi_awsize (m_axi_awsize[2:0]), // Templated
.m00_axi_awburst (m_axi_awburst[1:0]), // Templated
.m00_axi_awlock (m_axi_awlock), // Templated
.m00_axi_awcache (m_axi_awcache[3:0]), // Templated
.m00_axi_awprot (m_axi_awprot[2:0]), // Templated
.m00_axi_awqos (m_axi_awqos[3:0]), // Templated
.m00_axi_awvalid (m_axi_awvalid), // Templated
.m00_axi_wdata (m_axi_wdata[31:0]), // Templated
.m00_axi_wstrb (m_axi_wstrb[3:0]), // Templated
.m00_axi_wlast (m_axi_wlast), // Templated
.m00_axi_wvalid (m_axi_wvalid), // Templated
.m00_axi_bready (m_axi_bready), // Templated
.m00_axi_arid (m_axi_arid[0:0]), // Templated
.m00_axi_araddr (m_axi_araddr[31:0]), // Templated
.m00_axi_arlen (m_axi_arlen[7:0]), // Templated
.m00_axi_arsize (m_axi_arsize[2:0]), // Templated
.m00_axi_arburst (m_axi_arburst[1:0]), // Templated
.m00_axi_arlock (m_axi_arlock), // Templated
.m00_axi_arcache (m_axi_arcache[3:0]), // Templated
.m00_axi_arprot (m_axi_arprot[2:0]), // Templated
.m00_axi_arqos (m_axi_arqos[3:0]), // Templated
.m00_axi_arvalid (m_axi_arvalid), // Templated
.m00_axi_rready (m_axi_rready), // Templated
// Inputs
.emwr_rd_data (emaxi_emwr_rd_data[102:0]), // Templated
.emwr_empty (emaxi_emwr_empty), // Templated
.emrq_rd_data (emaxi_emrq_rd_data[102:0]), // Templated
.emrq_empty (emaxi_emrq_empty), // Templated
.emrr_full (emaxi_emrr_full), // Templated
.emrr_prog_full (emaxi_emrr_prog_full), // Templated
.m00_axi_aclk (m_axi_aclk), // Templated
.m00_axi_aresetn (m_axi_aresetn), // Templated
.m00_axi_awready (m_axi_awready), // Templated
.m00_axi_wready (m_axi_wready), // Templated
.m00_axi_bid (m_axi_bid[0:0]), // Templated
.m00_axi_bresp (m_axi_bresp[1:0]), // Templated
.m00_axi_bvalid (m_axi_bvalid), // Templated
.m00_axi_arready (m_axi_arready), // Templated
.m00_axi_rid (m_axi_rid[0:0]), // Templated
.m00_axi_rdata (m_axi_rdata[31:0]), // Templated
.m00_axi_rresp (m_axi_rresp[1:0]), // Templated
.m00_axi_rlast (m_axi_rlast), // Templated
.m00_axi_rvalid (m_axi_rvalid)); // Templated
/***********************************************************/
/*AXI SLAVE */
/***********************************************************/
/*esaxi AUTO_TEMPLATE (
// Outputs
.s00_\(.*\) (s_\1[]),
.em\(.*\) (esaxi_em\1[]),
);
*/
esaxi esaxi(/*AUTOINST*/
// Outputs
.emwr_wr_data (esaxi_emwr_wr_data[102:0]), // Templated
.emwr_wr_en (esaxi_emwr_wr_en), // Templated
.emrq_wr_data (esaxi_emrq_wr_data[102:0]), // Templated
.emrq_wr_en (esaxi_emrq_wr_en), // Templated
.emrr_rd_en (esaxi_emrr_rd_en), // Templated
.s00_axi_awready (s_axi_awready), // Templated
.s00_axi_wready (s_axi_wready), // Templated
.s00_axi_bid (s_axi_bid[0:0]), // Templated
.s00_axi_bresp (s_axi_bresp[1:0]), // Templated
.s00_axi_bvalid (s_axi_bvalid), // Templated
.s00_axi_arready (s_axi_arready), // Templated
.s00_axi_rid (s_axi_rid[0:0]), // Templated
.s00_axi_rdata (s_axi_rdata[31:0]), // Templated
.s00_axi_rresp (s_axi_rresp[1:0]), // Templated
.s00_axi_rlast (s_axi_rlast), // Templated
.s00_axi_rvalid (s_axi_rvalid), // Templated
// Inputs
.emwr_full (esaxi_emwr_full), // Templated
.emwr_prog_full (esaxi_emwr_prog_full), // Templated
.emrq_full (esaxi_emrq_full), // Templated
.emrq_prog_full (esaxi_emrq_prog_full), // Templated
.emrr_rd_data (esaxi_emrr_rd_data[102:0]), // Templated
.emrr_empty (esaxi_emrr_empty), // Templated
.ecfg_tx_ctrl_mode (ecfg_tx_ctrl_mode[3:0]),
.ecfg_coreid (ecfg_coreid[11:0]),
.s00_axi_aclk (s_axi_aclk), // Templated
.s00_axi_aresetn (s_axi_aresetn), // Templated
.s00_axi_awid (s_axi_awid[0:0]), // Templated
.s00_axi_awaddr (s_axi_awaddr[29:0]), // Templated
.s00_axi_awlen (s_axi_awlen[7:0]), // Templated
.s00_axi_awsize (s_axi_awsize[2:0]), // Templated
.s00_axi_awburst (s_axi_awburst[1:0]), // Templated
.s00_axi_awlock (s_axi_awlock), // Templated
.s00_axi_awcache (s_axi_awcache[3:0]), // Templated
.s00_axi_awprot (s_axi_awprot[2:0]), // Templated
.s00_axi_awqos (s_axi_awqos[3:0]), // Templated
.s00_axi_awregion (s_axi_awregion[3:0]), // Templated
.s00_axi_awvalid (s_axi_awvalid), // Templated
.s00_axi_wdata (s_axi_wdata[31:0]), // Templated
.s00_axi_wstrb (s_axi_wstrb[3:0]), // Templated
.s00_axi_wlast (s_axi_wlast), // Templated
.s00_axi_wvalid (s_axi_wvalid), // Templated
.s00_axi_bready (s_axi_bready), // Templated
.s00_axi_arid (s_axi_arid[0:0]), // Templated
.s00_axi_araddr (s_axi_araddr[29:0]), // Templated
.s00_axi_arlen (s_axi_arlen[7:0]), // Templated
.s00_axi_arsize (s_axi_arsize[2:0]), // Templated
.s00_axi_arburst (s_axi_arburst[1:0]), // Templated
.s00_axi_arlock (s_axi_arlock), // Templated
.s00_axi_arcache (s_axi_arcache[3:0]), // Templated
.s00_axi_arprot (s_axi_arprot[2:0]), // Templated
.s00_axi_arqos (s_axi_arqos[3:0]), // Templated
.s00_axi_arregion (s_axi_arregion[3:0]), // Templated
.s00_axi_arvalid (s_axi_arvalid), // Templated
.s00_axi_rready (s_axi_rready)); // Templated
/***********************************************************/
/*AXI CONFIGURATION SLAVE (LITE) */
/***********************************************************/
esaxilite esaxilite(
/*AUTOINST*/
// Outputs
.s_axicfg_arready(s_axicfg_arready),
.s_axicfg_awready(s_axicfg_awready),
.s_axicfg_bresp (s_axicfg_bresp[1:0]),
.s_axicfg_bvalid(s_axicfg_bvalid),
.s_axicfg_rdata (s_axicfg_rdata[31:0]),
.s_axicfg_rresp (s_axicfg_rresp[1:0]),
.s_axicfg_rvalid(s_axicfg_rvalid),
.s_axicfg_wready(s_axicfg_wready),
.mi_clk (mi_clk),
.mi_en (mi_en),
.mi_we (mi_we),
.mi_addr (mi_addr[RFAW-1:0]),
.mi_din (mi_din[31:0]),
// Inputs
.s_axicfg_araddr(s_axicfg_araddr[15:0]),
.s_axicfg_arprot(s_axicfg_arprot[2:0]),
.s_axicfg_arvalid(s_axicfg_arvalid),
.s_axicfg_awaddr(s_axicfg_awaddr[15:0]),
.s_axicfg_awprot(s_axicfg_awprot[2:0]),
.s_axicfg_awvalid(s_axicfg_awvalid),
.s_axicfg_bready(s_axicfg_bready),
.s_axicfg_rready(s_axicfg_rready),
.s_axicfg_wdata (s_axicfg_wdata[31:0]),
.s_axicfg_wstrb (s_axicfg_wstrb[3:0]),
.s_axicfg_wvalid(s_axicfg_wvalid),
.mi_rd_data (mi_rd_data[31:0]));
/***********************************************************/
/*ELINK CLOCK GENERATOR */
/***********************************************************/
eclock eclock(/*AUTOINST*/
// Outputs
.cclk_p (cclk_p),
.cclk_n (cclk_n),
.txlclk_s (txlclk_s),
.txlclk_out (txlclk_out),
.txlclk_p (txlclk_p),
// Inputs
.clkin (clkin),
.reset (reset),
.ecfg_cclk_en (ecfg_cclk_en),
.ecfg_cclk_div (ecfg_cclk_div[3:0]),
.ecfg_cclk_pllcfg (ecfg_cclk_pllcfg[3:0]));
/***********************************************************/
/*RECEIVER */
/***********************************************************/
erx erx(.mi_dout (mi_dout_rx[DW-1:0]),
/*AUTOINST*/
// Outputs
.ecfg_rx_debug_signals (ecfg_rx_debug_signals[15:0]),
.ecfg_datain (ecfg_datain[8:0]),
.emaxi_emwr_empty (emaxi_emwr_empty),
.emaxi_emwr_rd_data (emaxi_emwr_rd_data[102:0]),
.emaxi_emrq_empty (emaxi_emrq_empty),
.emaxi_emrq_rd_data (emaxi_emrq_rd_data[102:0]),
.esaxi_emrr_empty (esaxi_emrr_empty),
.esaxi_emrr_rd_data (esaxi_emrr_rd_data[102:0]),
.rx_wr_wait_p (rx_wr_wait_p),
.rx_wr_wait_n (rx_wr_wait_n),
.rx_rd_wait_p (rx_rd_wait_p),
.rx_rd_wait_n (rx_rd_wait_n),
// Inputs
.reset (reset),
.s_axi_aclk (s_axi_aclk),
.m_axi_aclk (m_axi_aclk),
.ecfg_rx_enable (ecfg_rx_enable),
.ecfg_rx_mmu_mode (ecfg_rx_mmu_mode),
.ecfg_rx_gpio_mode (ecfg_rx_gpio_mode),
.ecfg_dataout (ecfg_dataout[10:0]),
.emaxi_emwr_rd_en (emaxi_emwr_rd_en),
.emaxi_emrq_rd_en (emaxi_emrq_rd_en),
.esaxi_emrr_rd_en (esaxi_emrr_rd_en),
.rx_lclk_p (rx_lclk_p),
.rx_lclk_n (rx_lclk_n),
.rx_frame_p (rx_frame_p),
.rx_frame_n (rx_frame_n),
.rx_data_p (rx_data_p[7:0]),
.rx_data_n (rx_data_n[7:0]),
.mi_clk (mi_clk),
.mi_en (mi_en),
.mi_we (mi_we),
.mi_addr (mi_addr[RFAW-1:0]),
.mi_din (mi_din[31:0]));
/***********************************************************/
/*TRANSMITTER */
/***********************************************************/
etx etx(.mi_dout (mi_dout_tx[DW-1:0]),
/*AUTOINST*/
// Outputs
.ecfg_tx_debug_signals (ecfg_tx_debug_signals[15:0]),
.esaxi_emrq_full (esaxi_emrq_full),
.esaxi_emrq_prog_full (esaxi_emrq_prog_full),
.esaxi_emwr_full (esaxi_emwr_full),
.esaxi_emwr_prog_full (esaxi_emwr_prog_full),
.emaxi_emrr_full (emaxi_emrr_full),
.emaxi_emrr_prog_full (emaxi_emrr_prog_full),
.tx_lclk_p (tx_lclk_p),
.tx_lclk_n (tx_lclk_n),
.tx_frame_p (tx_frame_p),
.tx_frame_n (tx_frame_n),
.tx_data_p (tx_data_p[7:0]),
.tx_data_n (tx_data_n[7:0]),
// Inputs
.reset (reset),
.txlclk_out (txlclk_out),
.txlclk_p (txlclk_p),
.txlclk_s (txlclk_s),
.s_axi_aclk (s_axi_aclk),
.m_axi_aclk (m_axi_aclk),
.ecfg_tx_clkdiv (ecfg_tx_clkdiv[3:0]),
.ecfg_tx_enable (ecfg_tx_enable),
.ecfg_tx_gpio_mode (ecfg_tx_gpio_mode),
.ecfg_tx_mmu_mode (ecfg_tx_mmu_mode),
.ecfg_dataout (ecfg_dataout[10:0]),
.ecfg_tx_tp_mode (ecfg_tx_tp_mode),
.esaxi_emrq_wr_en (esaxi_emrq_wr_en),
.esaxi_emrq_wr_data (esaxi_emrq_wr_data[102:0]),
.esaxi_emwr_wr_en (esaxi_emwr_wr_en),
.esaxi_emwr_wr_data (esaxi_emwr_wr_data[102:0]),
.emaxi_emrr_wr_en (emaxi_emrr_wr_en),
.emaxi_emrr_wr_data (emaxi_emrr_wr_data[102:0]),
.tx_wr_wait_p (tx_wr_wait_p),
.tx_wr_wait_n (tx_wr_wait_n),
.tx_rd_wait_p (tx_rd_wait_p),
.tx_rd_wait_n (tx_rd_wait_n));
/***********************************************************/
/*ELINK CONFIGURATION REGISTERES */
/***********************************************************/
/*ecfg AUTO_TEMPLATE (
// Outputs
.ecfg_reset (reset),
.ecfg_debug_signals ({embox_full, embox_not_empty, ecfg_rx_debug_signals[13:0],ecfg_tx_debug_signals[15:0]}),
);
*/
ecfg ecfg(.mi_dout (mi_dout_ecfg[DW-1:0]),
/*AUTOINST*/
// Outputs
.ecfg_reset (reset), // Templated
.ecfg_tx_enable (ecfg_tx_enable),
.ecfg_tx_mmu_mode (ecfg_tx_mmu_mode),
.ecfg_tx_gpio_mode (ecfg_tx_gpio_mode),
.ecfg_tx_tp_mode (ecfg_tx_tp_mode),
.ecfg_tx_ctrl_mode (ecfg_tx_ctrl_mode[3:0]),
.ecfg_tx_clkdiv (ecfg_tx_clkdiv[3:0]),
.ecfg_rx_enable (ecfg_rx_enable),
.ecfg_rx_mmu_mode (ecfg_rx_mmu_mode),
.ecfg_rx_gpio_mode (ecfg_rx_gpio_mode),
.ecfg_cclk_en (ecfg_cclk_en),
.ecfg_cclk_div (ecfg_cclk_div[3:0]),
.ecfg_cclk_pllcfg (ecfg_cclk_pllcfg[3:0]),
.ecfg_coreid (ecfg_coreid[11:0]),
.ecfg_dataout (ecfg_dataout[10:0]),
// Inputs
.hw_reset (hw_reset),
.mi_clk (mi_clk),
.mi_en (mi_en),
.mi_we (mi_we),
.mi_addr (mi_addr[RFAW-1:0]),
.mi_din (mi_din[31:0]),
.ecfg_datain (ecfg_datain[10:0]),
.ecfg_debug_signals ({embox_full, embox_not_empty, ecfg_rx_debug_signals[13:0],ecfg_tx_debug_signals[15:0]})); // Templated
/***********************************************************/
/*GENERAL PURPOSE MAILBOX */
/***********************************************************/
embox embox(.clk (mi_clk),
.mi_dout (mi_dout_embox[DW-1:0]),
/*AUTOINST*/
// Outputs
.embox_full (embox_full),
.embox_not_empty (embox_not_empty),
// Inputs
.reset (reset),
.mi_en (mi_en),
.mi_we (mi_we),
.mi_addr (mi_addr[RFAW-1:0]),
.mi_din (mi_din[DW-1:0]));
/***********************************************************/
/*AXI-LITE READBACK */
/***********************************************************/
//TODO: fix decode logic
assign mi_rd_data[31:0] = (mi_addr[15:14]==2'b00) ? mi_dout_ecfg[31:0] :
(mi_addr[15:14]==2'b01) ? mi_dout_embox[31:0] :
(mi_addr[15:14]==2'b10) ? mi_dout_rx[31:0] :
mi_dout_tx[31:0] ;
endmodule // elink
// Local Variables:
// verilog-library-directories:("." "../../embox/hdl" "../../erx/hdl" "../../etx/hdl" "../../emaxi/hdl" "../../esaxi/hdl" "../../esaxilite/hdl" )
// End: