mirror of
https://github.com/aolofsson/oh.git
synced 2025-01-17 20:02:53 +08:00
More file organization
Adding some more utility functions
This commit is contained in:
parent
60182e52e3
commit
b151bc90e1
@ -1,71 +0,0 @@
|
||||
module axi_memif (/*AUTOARG*/
|
||||
// Outputs
|
||||
s_axi_awready, s_axi_wready, s_axi_bresp, s_axi_bvalid,
|
||||
s_axi_arready, s_axi_rdata, s_axi_rresp, s_axi_rvalid, mi_addr,
|
||||
mi_access, mi_write, mi_data_in,
|
||||
// Inputs
|
||||
s_axi_aclk, s_axi_aresetn, s_axi_awaddr, s_axi_awprot,
|
||||
s_axi_awvalid, s_axi_wdata, s_axi_wstrb, s_axi_wvalid,
|
||||
s_axi_bready, s_axi_araddr, s_axi_arprot, s_axi_arvalid,
|
||||
s_axi_rready, mi_data_out
|
||||
);
|
||||
|
||||
parameter AW = 32; //axi addr width
|
||||
parameter DW = 32; //axi data width
|
||||
parameter SW = DW/8;//==ADW/8
|
||||
parameter MAW = 6; //memory address width
|
||||
parameter MDW = 32; //memory data width
|
||||
|
||||
/*****************************/
|
||||
/*AXI SLAVE INTERFACE */
|
||||
/*****************************/
|
||||
|
||||
//Global signals
|
||||
input s_axi_aclk; //clock source for axi slave interfaces
|
||||
input s_axi_aresetn; //synchronous reset signal, active low
|
||||
|
||||
//Write address channel
|
||||
input [AW-1:0] s_axi_awaddr; //write address
|
||||
input [2:0] s_axi_awprot; //protection type
|
||||
input s_axi_awvalid; //write address valid
|
||||
output s_axi_awready; //write address ready
|
||||
|
||||
//Write data channel
|
||||
input [DW-1:0] s_axi_wdata; //write data
|
||||
input [SW-1:0] s_axi_wstrb; //write strobes
|
||||
input s_axi_wvalid; //write valid
|
||||
output s_axi_wready; //write channel ready
|
||||
|
||||
//Buffered write response channel
|
||||
input s_axi_bready; //write ready
|
||||
output [1:0] s_axi_bresp; //write response
|
||||
output s_axi_bvalid; //write response valid
|
||||
|
||||
//Read address channel
|
||||
input [AW-1:0] s_axi_araddr; //read address
|
||||
input [2:0] s_axi_arprot; //protection type
|
||||
input s_axi_arvalid; //read address valid
|
||||
output s_axi_arready; //read address ready
|
||||
|
||||
//Read data channel
|
||||
output [DW-1:0] s_axi_rdata; //read data
|
||||
output [1:0] s_axi_rresp; //read response
|
||||
output s_axi_rvalid; //read valid
|
||||
input s_axi_rready; //read ready
|
||||
|
||||
/*****************************/
|
||||
/*MEORY INTERFACE */
|
||||
/*****************************/
|
||||
output [MAW-1:0] mi_addr;
|
||||
output mi_access;
|
||||
output mi_write;
|
||||
output [MDW-1:0] mi_data_in;
|
||||
input [MDW-1:0] mi_data_out;
|
||||
|
||||
|
||||
//Dummy interface, need to instantiate IP!!!
|
||||
//this will lock up AXI bus
|
||||
|
||||
|
||||
endmodule // axi_memif
|
||||
|
49
common/hdl/mux2.v
Normal file
49
common/hdl/mux2.v
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
Copyright (C) 2013 Adapteva, Inc.
|
||||
Contributed by Andreas Olofsson <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 mux2(/*AUTOARG*/
|
||||
// Outputs
|
||||
out,
|
||||
// Inputs
|
||||
in0, in1, sel0, sel1
|
||||
);
|
||||
|
||||
parameter DW=99;
|
||||
|
||||
//data inputs
|
||||
input [DW-1:0] in0;
|
||||
input [DW-1:0] in1;
|
||||
|
||||
//select inputs
|
||||
input sel0;
|
||||
input sel1;
|
||||
|
||||
output [DW-1:0] out;
|
||||
|
||||
assign out[DW-1:0] = ({(DW){sel0}} & in0[DW-1:0] |
|
||||
{(DW){sel1}} & in1[DW-1:0]);
|
||||
|
||||
|
||||
//making sure that selects are really one hot
|
||||
always @*
|
||||
if((sel0+sel1>1) && ($time>0))
|
||||
$display("ERROR>>Arbitration failure in cell %m");
|
||||
|
||||
|
||||
endmodule // mux2
|
51
common/hdl/mux3.v
Normal file
51
common/hdl/mux3.v
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
Copyright (C) 2013 Adapteva, Inc.
|
||||
Contributed by Andreas Olofsson <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 mux3(/*AUTOARG*/
|
||||
// Outputs
|
||||
out,
|
||||
// Inputs
|
||||
in0, in1, in2, sel0, sel1, sel2
|
||||
);
|
||||
|
||||
parameter DW=99;
|
||||
|
||||
//data inputs
|
||||
input [DW-1:0] in0;
|
||||
input [DW-1:0] in1;
|
||||
input [DW-1:0] in2;
|
||||
|
||||
//select inputs
|
||||
input sel0;
|
||||
input sel1;
|
||||
input sel2;
|
||||
|
||||
output [DW-1:0] out;
|
||||
|
||||
|
||||
assign out[DW-1:0] = ({(DW){sel0}} & in0[DW-1:0] |
|
||||
{(DW){sel1}} & in1[DW-1:0] |
|
||||
{(DW){sel2}} & in2[DW-1:0]);
|
||||
|
||||
// synthesis translate_off
|
||||
always @*
|
||||
if((sel0+sel1+sel2>1) && ($time>0))
|
||||
$display("ERROR>>Arbitration failure in cell %m");
|
||||
// synthesis translate_on
|
||||
|
||||
endmodule // mux3
|
22
elink/hdl/axi_elink_master.v
Normal file
22
elink/hdl/axi_elink_master.v
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
Copyright (C) 2014 Adapteva, Inc.
|
||||
|
||||
Contributed by Andreas Olofsson <andreas@adapteva.com>
|
||||
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/>.
|
||||
*/
|
||||
|
||||
module axi_elink_master(/*AUTOARG*/);
|
||||
|
||||
endmodule // elink_axi_slave
|
||||
|
||||
|
22
elink/hdl/axi_elink_slave.v
Normal file
22
elink/hdl/axi_elink_slave.v
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
Copyright (C) 2014 Adapteva, Inc.
|
||||
|
||||
Contributed by Andreas Olofsson <andreas@adapteva.com>
|
||||
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/>.
|
||||
*/
|
||||
|
||||
module axi_elink_slave(/*AUTOARG*/);
|
||||
|
||||
endmodule // elink_axi_slave
|
||||
|
||||
|
436
elink/hdl/esys_regs.v
Normal file
436
elink/hdl/esys_regs.v
Normal file
@ -0,0 +1,436 @@
|
||||
`define REG_ESYSRESET 6'h00
|
||||
`define REG_ESYSCFGTX 6'h01
|
||||
`define REG_ESYSCFGRX 6'h02
|
||||
`define REG_ESYSCFGCLK 6'h03
|
||||
`define REG_ESYSCOREID 6'h04
|
||||
`define REG_ESYSVERSION 6'h05
|
||||
`define REG_ESYSDATAIN 6'h06
|
||||
`define REG_ESYSDATAOUT 6'h07
|
||||
`define REG_ESYSRXMON0 6'h08
|
||||
`define REG_ESYSRXMON1 6'h09
|
||||
`define REG_ESYSRXMON2 6'h0A
|
||||
`define REG_ESYSTXMON0 6'h0B
|
||||
`define REG_ESYSTXMON1 6'h0C
|
||||
`define REG_ESYSTXMON2 6'h0D
|
||||
`define REG_ESYSTXMO2 6'h0E
|
||||
`define REG_ESYSIRQSRC 6'h0F
|
||||
`define REG_ESYSIRQDATA 6'h10
|
||||
`define EVERSION 32'h00000000
|
||||
|
||||
/*
|
||||
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 in reset
|
||||
1 - elink NOT 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 - reserved
|
||||
11 - reserved
|
||||
[7:4] Transmit control mode for eMesh
|
||||
[9:8] 00 - No division, full speed
|
||||
01 - Divide by 2
|
||||
10 - Reserved
|
||||
11 - 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
|
||||
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_fram
|
||||
[9] rx_wait_rd
|
||||
[10] rx_wait_wr
|
||||
-------------------------------------------------------------
|
||||
ESYSRXMON0 ***Counts RX master write transactions***
|
||||
-------------------------------------------------------------
|
||||
ESYSRXMON1 ***Counts RX master read transactions***
|
||||
-------------------------------------------------------------
|
||||
ESYSRXMON2 ***Counts RX slave read response transactions***
|
||||
-------------------------------------------------------------
|
||||
ESYSTXMON0 ***Counts TX slave write transactions***
|
||||
-------------------------------------------------------------
|
||||
ESYSTXMON1 ***Counts TX slave read transactions***
|
||||
-------------------------------------------------------------
|
||||
ESYSTXMON2 ***Counts TX master read response transactions***
|
||||
-------------------------------------------------------------
|
||||
ESYSIRQSRC ***Current IRQ FIFO entry (12 bits)
|
||||
Read of entry will increment FIFO read pointer
|
||||
-------------------------------------------------------------
|
||||
ESYSIRQDATA ***Data associated with current IRQ FIFO entry
|
||||
32 bits (should be read before src)
|
||||
-------------------------------------------------------------
|
||||
|
||||
########################################################################
|
||||
*/
|
||||
module esys_regs (/*AUTOARG*/
|
||||
// Outputs
|
||||
data_out, esys_tx_enable, esys_tx_mmu_mode, esys_tx_gpio_mode,
|
||||
esys_tx_ctrl_mode, esys_tx_clkdiv, esys_rx_enable,
|
||||
esys_rx_mmu_mode, esys_rx_gpio_mode, esys_rx_loopback_mode,
|
||||
esys_cclk_div, esys_coreid, esys_dataout, esys_irqsrc_read,
|
||||
// Inputs
|
||||
param_coreid, clk, hw_reset, access, write, addr, data_in,
|
||||
erx_irq_fifo_src, erx_irq_fifo_data, erx_rdfifo_access,
|
||||
erx_rdfifo_wait, erx_wrfifo_access, erx_wrfifo_wait,
|
||||
erx_wbfifo_access, erx_wbfifo_wait, etx_rdfifo_access,
|
||||
etx_rdfifo_wait, etx_wrfifo_access, etx_wrfifo_wait,
|
||||
etx_wbfifo_access, etx_wbfifo_wait
|
||||
);
|
||||
//Register file parameters
|
||||
|
||||
/*
|
||||
#####################################################################
|
||||
COMPILE TIME PARAMETERS
|
||||
######################################################################
|
||||
*/
|
||||
parameter EMONW = 32; //elink monitor register width
|
||||
parameter EMAW = 12; //mmu table address width
|
||||
parameter EDW = 32; //Epiphany native data width
|
||||
parameter EAW = 32; //Epiphany native address width
|
||||
parameter EIDW = 12; //Elink ID (row,column coordinate)
|
||||
parameter RFAW = 5; //Number of registers=2^RFAW
|
||||
|
||||
|
||||
/*****************************/
|
||||
/*STATIC CONFIG SIGNALS */
|
||||
/*****************************/
|
||||
input [EIDW-1:0] param_coreid;
|
||||
|
||||
/*****************************/
|
||||
/*SIMPLE MEMORY INTERFACE */
|
||||
/*****************************/
|
||||
input clk;
|
||||
input hw_reset;
|
||||
input access;
|
||||
input write;
|
||||
input [RFAW-1:0] addr;
|
||||
input [31:0] data_in;
|
||||
output [31:0] data_out;
|
||||
|
||||
/*****************************/
|
||||
/*ELINK DATAPATH INPUTS */
|
||||
/*****************************/
|
||||
input [11:0] erx_irq_fifo_src;
|
||||
input [11:0] erx_irq_fifo_data;
|
||||
input erx_rdfifo_access;
|
||||
input erx_rdfifo_wait;
|
||||
input erx_wrfifo_access;
|
||||
input erx_wrfifo_wait;
|
||||
input erx_wbfifo_access;
|
||||
input erx_wbfifo_wait;
|
||||
input etx_rdfifo_access;
|
||||
input etx_rdfifo_wait;
|
||||
input etx_wrfifo_access;
|
||||
input etx_wrfifo_wait;
|
||||
input etx_wbfifo_access;
|
||||
input etx_wbfifo_wait;
|
||||
|
||||
/*****************************/
|
||||
/*ESYS CONTROL OUTPUTS */
|
||||
/*****************************/
|
||||
//tx
|
||||
output esys_tx_enable; //enable signal for TX
|
||||
output esys_tx_mmu_mode; //enables MMU on transnmit path
|
||||
output esys_tx_gpio_mode; //forces TX output pins to constants
|
||||
output [3:0] esys_tx_ctrl_mode; //value for emesh ctrlmode tag
|
||||
output [3:0] esys_tx_clkdiv; //transmit clock divider
|
||||
|
||||
//rx
|
||||
output esys_rx_enable; //enable signal for rx
|
||||
output esys_rx_mmu_mode; //enables MMU on rx path
|
||||
output esys_rx_gpio_mode; //forces rx wait pins to constants
|
||||
output esys_rx_loopback_mode; //loops back tx to rx receiver (after serdes)
|
||||
|
||||
//cclk
|
||||
output [3:0] esys_cclk_div; //cclk divider setting
|
||||
output [3:0] esys_cclk_pllcfg; //pll configuration
|
||||
|
||||
//coreid
|
||||
output [11:0] esys_coreid; //core-id of fpga elink
|
||||
|
||||
//gpio
|
||||
output [11:0] esys_dataout; //data for elink outputs {rd_wait,wr_wait,frame,data[7:0}
|
||||
|
||||
//irq
|
||||
output esys_irqsrc_read; //increments the irq fifo pointer
|
||||
|
||||
/*------------------------BODY CODE---------------------------------------*/
|
||||
|
||||
//registers
|
||||
reg [9:0] esys_cfgtx_reg;
|
||||
reg [4:0] esys_cfgrx_reg;
|
||||
reg [7:0] esys_cfgclk_reg;
|
||||
reg [11:0] esys_coreid_reg;
|
||||
wire [31:0] esys_version_reg; //fixed read only constant
|
||||
reg esys_reset_reg;
|
||||
reg [11:0] esys_datain_reg;
|
||||
reg [11:0] esys_dataout_reg;
|
||||
wire [11:0] esys_irqsrc_reg;
|
||||
wire [31:0] esys_irqdata_reg;
|
||||
reg [31:0] data_out;
|
||||
|
||||
//wires
|
||||
wire esys_read;
|
||||
wire esys_write;
|
||||
wire esys_reset_match;
|
||||
wire esys_cfgtx_match;
|
||||
wire esys_cfgrx_match;
|
||||
wire esys_cfgclk_match;
|
||||
wire esys_coreid_match;
|
||||
wire esys_version_match;
|
||||
wire esys_datain_match;
|
||||
wire esys_dataout_match;
|
||||
wire esys_rxmon0_match;
|
||||
wire esys_rxmon1_match;
|
||||
wire esys_rxmon2_match;
|
||||
wire esys_txmon0_match;
|
||||
wire esys_txmon1_match;
|
||||
wire esys_txmon2_match;
|
||||
wire esys_irqsrc_match;
|
||||
wire esys_irqdata_match;
|
||||
wire esys_regmux;
|
||||
wire [31:0] esys_reg_mux;
|
||||
|
||||
/*****************************/
|
||||
/*ADDRESS DECODE LOGIC */
|
||||
/*****************************/
|
||||
|
||||
//read/write decode
|
||||
assign esys_write = access & write;
|
||||
assign esys_read = access & ~write;
|
||||
|
||||
//address match signals
|
||||
assign esys_reset_match = addr[RFAW-1:0]==`REG_ESYSRESET;
|
||||
assign esys_cfgtx_match = addr[RFAW-1:0]==`REG_ESYSCFGTX;
|
||||
assign esys_cfgrx_match = addr[RFAW-1:0]==`REG_ESYSCFGRX;
|
||||
assign esys_cfgclk_match = addr[RFAW-1:0]==`REG_ESYSCFGCLK;
|
||||
assign esys_coreid_match = addr[RFAW-1:0]==`REG_ESYSCOREID;
|
||||
assign esys_version_match = addr[RFAW-1:0]==`REG_ESYSVERSION;
|
||||
assign esys_datain_match = addr[RFAW-1:0]==`REG_ESYSDATAIN;
|
||||
assign esys_dataout_match = addr[RFAW-1:0]==`REG_ESYSDATAOUT;
|
||||
assign esys_rxmon0_match = addr[RFAW-1:0]==`REG_ESYSRXMON0;
|
||||
assign esys_rxmon1_match = addr[RFAW-1:0]==`REG_ESYSRXMON1;
|
||||
assign esys_rxmon2_match = addr[RFAW-1:0]==`REG_ESYSRXMON2;
|
||||
assign esys_txmon0_match = addr[RFAW-1:0]==`REG_ESYSTXMON0;
|
||||
assign esys_txmon1_match = addr[RFAW-1:0]==`REG_ESYSTXMON1;
|
||||
assign esys_txmon2_match = addr[RFAW-1:0]==`REG_ESYSTXMON2;
|
||||
assign esys_irqsrc_match = addr[RFAW-1:0]==`REG_ESYSIRQSRC;
|
||||
assign esys_irqdata_match = addr[RFAW-1:0]==`REG_ESYSIRQDATA;
|
||||
|
||||
//Write enables
|
||||
assign esys_reset_write = esys_reset_match & esys_write;
|
||||
assign esys_cfgtx_write = esys_cfgtx_match & esys_write;
|
||||
assign esys_cfgrx_write = esys_cfgrx_match & esys_write;
|
||||
assign esys_cfgclk_write = esys_cfgclk_match & esys_write;
|
||||
assign esys_coreid_write = esys_coreid_match & esys_write;
|
||||
assign esys_version_write = esys_version_match & esys_write;
|
||||
assign esys_datain_write = esys_datain_match & esys_write;
|
||||
assign esys_dataout_write = esys_dataout_match & esys_write;
|
||||
assign esys_rxmon0_write = esys_rxmon0_match & esys_write;
|
||||
assign esys_rxmon1_write = esys_rxmon1_match & esys_write;
|
||||
assign esys_rxmon2_write = esys_rxmon2_match & esys_write;
|
||||
assign esys_txmon0_write = esys_rxmon0_match & esys_write;
|
||||
assign esys_txmon1_write = esys_rxmon1_match & esys_write;
|
||||
assign esys_txmon2_write = esys_rxmon2_match & esys_write;
|
||||
assign esys_irqsrc_write = esys_irqsrc_match & esys_write;
|
||||
assign esys_irqdata_write = esys_irqdata_match & esys_write;
|
||||
|
||||
//###########################
|
||||
//# ESYSCFGTX
|
||||
//###########################
|
||||
always @ (posedge clk)
|
||||
if(hw_reset)
|
||||
esys_cfgtx_reg[9:0] <= 10'b0;
|
||||
else if (esys_cfgtx_write)
|
||||
esys_cfgtx_reg[9:0] <= data_in[9:0];
|
||||
|
||||
assign esys_tx_enable = esys_cfgtx_reg[0];
|
||||
assign esys_tx_mmu_mode = esys_cfgtx_reg[1];
|
||||
assign esys_tx_gpio_mode = esys_cfgtx_reg[3:2]==2'b01;
|
||||
assign esys_tx_ctrl_mode[3:0] = esys_cfgtx_reg[7:4];
|
||||
assign esys_tx_clkdiv[3:0] = esys_cfgtx_reg[11:8];
|
||||
|
||||
//###########################
|
||||
//# ESYSCFGRX
|
||||
//###########################
|
||||
always @ (posedge clk)
|
||||
if(hw_reset)
|
||||
esys_cfgrx_reg[4:0] <= 5'b0;
|
||||
else if (esys_cfgrx_write)
|
||||
esys_cfgrx_reg[4:0] <= data_in[4:0];
|
||||
|
||||
assign esys_rx_enable = esys_cfgrx_reg[0];
|
||||
assign esys_tx_mmu_mode = esys_cfgrx_reg[1];
|
||||
assign esys_rx_gpio_mode = esys_cfgrx_reg[3:2]==2'b01;
|
||||
assign esys_rx_loopback_mode = esys_cfgrx_reg[3:2]==2'b10;
|
||||
assign esys_rx_monitor_mode = esys_cfgrx_reg[4];
|
||||
|
||||
//###########################
|
||||
//# ESYSCFGCLK
|
||||
//###########################
|
||||
always @ (posedge clk)
|
||||
if(hw_reset)
|
||||
esys_cfgclk_reg[7:0] <= 8'b0;
|
||||
else if (esys_cfgclk_write)
|
||||
esys_cfgclk_reg[7:0] <= data_in[7:0];
|
||||
|
||||
assign esys_cclk_div[3:0] = esys_cfgclk_reg[3:0];
|
||||
assign esys_cclk_pllcfg[3:0] = esys_cfgclk_reg[7:4];
|
||||
|
||||
//###########################
|
||||
//# ESYSCOREID
|
||||
//###########################
|
||||
always @ (posedge clk)
|
||||
if(hw_reset)
|
||||
esys_coreid_reg[EIDW-1:0] <= param_coreid[EIDW-1:0];
|
||||
else if (esys_coreid_write)
|
||||
esys_coreid_reg[EIDW-1:0] <= data_in[EIDW-1:0];
|
||||
|
||||
assign esys_coreid[EIDW-1:0] = esys_coreid_reg[EIDW-1:0];
|
||||
|
||||
//###########################
|
||||
//# ESYSVERSION
|
||||
//###########################
|
||||
assign esys_version_reg[31:0] = `EVERSION;
|
||||
|
||||
//###########################
|
||||
//# ESYSDATAIN
|
||||
//###########################
|
||||
always @ (posedge clk)
|
||||
if(hw_reset)
|
||||
esys_datain_reg[11:0] <= 12'b0;
|
||||
else if (esys_datain_write)
|
||||
esys_datain_reg[11:0] <= data_in[11:0];
|
||||
else
|
||||
esys_datain_reg[11:0] <= data_in[11:0];
|
||||
|
||||
//###########################
|
||||
//# ESYSDATAOUT
|
||||
//###########################
|
||||
always @ (posedge clk)
|
||||
if(hw_reset)
|
||||
esys_dataout_reg[11:0] <= 12'b0;
|
||||
else if (esys_dataout_write)
|
||||
esys_dataout_reg[11:0] <= data_in[11:0];
|
||||
|
||||
assign esys_dataout[11:0] = esys_dataout_reg[11:0];
|
||||
|
||||
//###########################
|
||||
//# ESYSRXMON0
|
||||
//###########################
|
||||
`ifdef USE_ESYS_MONITORS
|
||||
//create module
|
||||
//instantiate monitors, similar to timers
|
||||
//inputs
|
||||
`endif
|
||||
|
||||
//###########################
|
||||
//# ESYSIRQSRC
|
||||
//###########################
|
||||
assign esys_irqsrc_read = esys_irqsrc_match & access;
|
||||
assign esys_irqsrc_reg[11:0] = erx_irq_fifo_src[11:0];
|
||||
|
||||
//###########################
|
||||
//# ESYSIRQDATA
|
||||
//###########################
|
||||
assign esys_irqdata_reg[31:0] = erx_irq_fifo_data[31:0];
|
||||
|
||||
//###########################
|
||||
//# ESYSRESET
|
||||
//###########################
|
||||
always @ (posedge clk)
|
||||
if(hw_reset)
|
||||
esys_reset_reg <= 1'b0;
|
||||
else if (esys_reset_write)
|
||||
esys_reset_reg <= data_in[0];
|
||||
|
||||
assign esys_reset = esys_reset_reg;
|
||||
|
||||
//###############################
|
||||
//# DATA READBACK MUX
|
||||
//###############################
|
||||
|
||||
assign esys_reg_mux[31:0] = ({(32){esys_cfgtx_match}} & {18'b0,esys_cfgtx_reg[11:0]}) |
|
||||
({(32){esys_cfgrx_match}} & {18'b0,esys_cfgrx_reg[11:0]}) |
|
||||
({(32){esys_cfgclk_match}} & {24'b0,esys_cfgclk_reg[7:0]}) |
|
||||
({(32){esys_coreid_match}} & {18'b0,esys_coreid_reg[11:0]}) |
|
||||
({(32){esys_irqsrc_match}} & {18'b0,esys_irqsrc_reg[11:0]}) |
|
||||
({(32){esys_version_match}} & esys_version_reg[31:0]) |
|
||||
({(32){esys_datain_match}} & esys_datain_reg[31:0]) |
|
||||
({(32){esys_dataout_match}} & esys_dataout_reg[31:0]) |
|
||||
({(32){esys_rxmon0_match}} & esys_rxmon0_reg[31:0]) |
|
||||
({(32){esys_rxmon1_match}} & esys_rxmon1_reg[31:0]) |
|
||||
({(32){esys_rxmon2_match}} & esys_rxmon2_reg[31:0]) |
|
||||
({(32){esys_txmon0_match}} & esys_txmon0_reg[31:0]) |
|
||||
({(32){esys_txmon1_match}} & esys_txmon1_reg[31:0]) |
|
||||
({(32){esys_txmon2_match}} & esys_txmon2_reg[31:0]) |
|
||||
({(32){esys_irqdata_match}} & esys_irqdata_reg[31:0]);
|
||||
|
||||
//Pipelineing readback
|
||||
always @ (posedge clk)
|
||||
if(access)
|
||||
data_out[31:0] <= esys_reg_mux[31:0];
|
||||
|
||||
endmodule // para_config
|
||||
|
269
elink/hdl/ewrapper_io_rx_slow.v
Normal file
269
elink/hdl/ewrapper_io_rx_slow.v
Normal file
@ -0,0 +1,269 @@
|
||||
/*
|
||||
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/>.
|
||||
*/
|
||||
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
|
246
elink/hdl/ewrapper_io_tx_slow.v
Normal file
246
elink/hdl/ewrapper_io_tx_slow.v
Normal file
@ -0,0 +1,246 @@
|
||||
/*
|
||||
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/>.
|
||||
*/
|
||||
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
|
198
elink/hdl/ewrapper_link_receiver.v
Normal file
198
elink/hdl/ewrapper_link_receiver.v
Normal 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
|
624
elink/hdl/ewrapper_link_rxi.v
Normal file
624
elink/hdl/ewrapper_link_rxi.v
Normal 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
|
464
elink/hdl/ewrapper_link_top.v
Normal file
464
elink/hdl/ewrapper_link_top.v
Normal file
@ -0,0 +1,464 @@
|
||||
/*
|
||||
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/>.
|
||||
*/
|
||||
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
|
232
elink/hdl/ewrapper_link_transmitter.v
Normal file
232
elink/hdl/ewrapper_link_transmitter.v
Normal 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
|
382
elink/hdl/ewrapper_link_txo.v
Normal file
382
elink/hdl/ewrapper_link_txo.v
Normal 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
|
Loading…
x
Reference in New Issue
Block a user