// --------------------------------------------------------------------
|
//////////////////////////////////////////////////////////////////////
|
//
|
//// ////
|
// --------------------------------------------------------------------
|
//// Copyright (C) 2015 Authors and OPENCORES.ORG ////
|
|
//// ////
|
|
//// This source file may be used and distributed without ////
|
|
//// restriction provided that this copyright statement is not ////
|
|
//// removed from the file and that any derivative work contains ////
|
|
//// the original copyright notice and the associated disclaimer. ////
|
|
//// ////
|
|
//// This source file is free software; you can redistribute it ////
|
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
|
//// Public License as published by the Free Software Foundation; ////
|
|
//// either version 2.1 of the License, or (at your option) any ////
|
|
//// later version. ////
|
|
//// ////
|
|
//// This source is distributed in the hope that it will be ////
|
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
|
//// details. ////
|
|
//// ////
|
|
//// You should have received a copy of the GNU Lesser General ////
|
|
//// Public License along with this source; if not, download it ////
|
|
//// from http://www.opencores.org/lgpl.shtml ////
|
|
//// ////
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
interface
|
interface
|
tb_channel_link_rx_if
|
tb_channel_link_rx_if
|
(
|
(
|
input [3:0] p,
|
input [3:0] p,
|
input [3:0] n,
|
input [3:0] n,
|
input [4:0] invert_mux,
|
input [4:0] invert_mux,
|
input reset,
|
input reset,
|
input clk_p,
|
input clk_p,
|
input clk_n
|
input clk_n
|
);
|
);
|
|
|
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
//
|
//
|
timeunit 1ps / 1ps;
|
timeunit 1ps / 1ps;
|
time clk_period = 0;
|
time clk_period = 0;
|
time clk_7x_period = 0;
|
time clk_7x_period = 0;
|
time strobe_delay = 0;
|
time strobe_delay = 0;
|
|
|
|
|
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
//
|
//
|
int bit_index;
|
int bit_index;
|
logic clk_7x;
|
logic clk_7x;
|
wire tx_clk = invert_mux[4] ? ~clk_p : clk_p;
|
wire tx_clk = invert_mux[4] ? ~clk_p : clk_p;
|
|
|
|
|
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
//
|
//
|
default clocking cb @(posedge tx_clk);
|
default clocking cb @(posedge tx_clk);
|
input p;
|
input p;
|
input n;
|
input n;
|
input reset;
|
input reset;
|
endclocking
|
endclocking
|
|
|
|
|
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
//
|
//
|
localparam B = 7;
|
localparam B = 7;
|
|
|
|
|
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
//
|
//
|
task
|
task
|
generate_clocks
|
generate_clocks
|
(
|
(
|
time clk_7x_period,
|
time clk_7x_period,
|
time strobe_delay
|
time strobe_delay
|
);
|
);
|
|
|
bit_index = 5;
|
bit_index = 5;
|
|
|
forever
|
forever
|
@(cb)
|
@(cb)
|
begin
|
begin
|
|
|
#strobe_delay;
|
#strobe_delay;
|
clk_7x <= 1;
|
clk_7x <= 1;
|
|
|
generate_clk_7x_fork : fork
|
generate_clk_7x_fork : fork
|
begin
|
begin
|
repeat((B * 2) - 1)
|
repeat((B * 2) - 1)
|
begin
|
begin
|
#(clk_7x_period / 2);
|
#(clk_7x_period / 2);
|
clk_7x <= ~clk_7x;
|
clk_7x <= ~clk_7x;
|
|
|
if(clk_7x == 1)
|
if(clk_7x == 1)
|
if(bit_index == 6)
|
if(bit_index == 6)
|
bit_index = 0;
|
bit_index = 0;
|
else
|
else
|
bit_index++;
|
bit_index++;
|
|
|
end
|
end
|
end
|
end
|
join_none
|
join_none
|
|
|
end
|
end
|
|
|
endtask: generate_clocks
|
endtask: generate_clocks
|
|
|
|
|
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
//
|
//
|
logic [6:0] rx_in [4];
|
logic [6:0] rx_in [4];
|
|
|
always @(posedge clk_7x)
|
always @(posedge clk_7x)
|
begin
|
begin
|
rx_in[3][bit_index] <= invert_mux[3] ? ~p[3] : p[3];
|
rx_in[3][bit_index] <= invert_mux[3] ? ~p[3] : p[3];
|
rx_in[2][bit_index] <= invert_mux[2] ? ~p[2] : p[2];
|
rx_in[2][bit_index] <= invert_mux[2] ? ~p[2] : p[2];
|
rx_in[1][bit_index] <= invert_mux[1] ? ~p[1] : p[1];
|
rx_in[1][bit_index] <= invert_mux[1] ? ~p[1] : p[1];
|
rx_in[0][bit_index] <= invert_mux[0] ? ~p[0] : p[0];
|
rx_in[0][bit_index] <= invert_mux[0] ? ~p[0] : p[0];
|
end
|
end
|
|
|
|
|
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
//
|
//
|
logic [27:0] rx_data;
|
logic [27:0] rx_data;
|
|
|
always @(posedge clk_7x)
|
always @(posedge clk_7x)
|
if(bit_index == 6)
|
if(bit_index == 6)
|
begin
|
begin
|
// 6 5 4 3 2 1 0
|
// 6 5 4 3 2 1 0
|
{rx_data[27], rx_data[ 5], rx_data[10], rx_data[11], rx_data[16], rx_data[17], rx_data[23]} <= {invert_mux[3] ? ~p[3] : p[3], rx_in[3][5:0]};
|
{rx_data[27], rx_data[ 5], rx_data[10], rx_data[11], rx_data[16], rx_data[17], rx_data[23]} <= {invert_mux[3] ? ~p[3] : p[3], rx_in[3][5:0]};
|
{rx_data[19], rx_data[20], rx_data[21], rx_data[22], rx_data[24], rx_data[25], rx_data[26]} <= {invert_mux[2] ? ~p[2] : p[2], rx_in[2][5:0]};
|
{rx_data[19], rx_data[20], rx_data[21], rx_data[22], rx_data[24], rx_data[25], rx_data[26]} <= {invert_mux[2] ? ~p[2] : p[2], rx_in[2][5:0]};
|
{rx_data[ 8], rx_data[ 9], rx_data[12], rx_data[13], rx_data[14], rx_data[15], rx_data[18]} <= {invert_mux[1] ? ~p[1] : p[1], rx_in[1][5:0]};
|
{rx_data[ 8], rx_data[ 9], rx_data[12], rx_data[13], rx_data[14], rx_data[15], rx_data[18]} <= {invert_mux[1] ? ~p[1] : p[1], rx_in[1][5:0]};
|
{rx_data[ 0], rx_data[ 1], rx_data[ 2], rx_data[ 3], rx_data[ 4], rx_data[ 6], rx_data[ 7]} <= {invert_mux[0] ? ~p[0] : p[0], rx_in[0][5:0]};
|
{rx_data[ 0], rx_data[ 1], rx_data[ 2], rx_data[ 3], rx_data[ 4], rx_data[ 6], rx_data[ 7]} <= {invert_mux[0] ? ~p[0] : p[0], rx_in[0][5:0]};
|
end
|
end
|
|
|
|
|
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
//
|
//
|
wire dval = rx_data[26];
|
wire dval = rx_data[26];
|
wire fval = rx_data[25];
|
wire fval = rx_data[25];
|
wire lval = rx_data[24];
|
wire lval = rx_data[24];
|
wire spare = rx_data[23];
|
wire spare = rx_data[23];
|
wire [7:0] port_a_d_g = {rx_data[5], rx_data[27], rx_data[6], rx_data[4:0]};
|
wire [7:0] port_a_d_g = {rx_data[5], rx_data[27], rx_data[6], rx_data[4:0]};
|
wire [7:0] port_b_e_h = {rx_data[11], rx_data[10], rx_data[14:12], rx_data[9:7]};
|
wire [7:0] port_b_e_h = {rx_data[11], rx_data[10], rx_data[14:12], rx_data[9:7]};
|
wire [7:0] port_c_f = {rx_data[17:16], rx_data[22:18], rx_data[15]};
|
wire [7:0] port_c_f = {rx_data[17:16], rx_data[22:18], rx_data[15]};
|
|
|
|
|
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
//
|
//
|
task
|
task
|
init_clocks;
|
init_clocks;
|
|
|
time clk_rise_t;
|
time clk_rise_t;
|
|
|
@(cb iff ~reset);
|
@(cb iff ~reset);
|
clk_rise_t = $time;
|
clk_rise_t = $time;
|
|
|
@(cb iff ~reset);
|
@(cb iff ~reset);
|
clk_period = $time - clk_rise_t;
|
clk_period = $time - clk_rise_t;
|
clk_7x_period = clk_period / B;
|
clk_7x_period = clk_period / B;
|
strobe_delay = clk_7x_period / 2;
|
strobe_delay = clk_7x_period / 2;
|
|
|
$display("^^^ %16.t | %m | clk_period = %t, ", $time, clk_period);
|
$display("^^^ %16.t | %m | clk_period = %t, ", $time, clk_period);
|
$display("^^^ %16.t | %m | clk_7x_period = %t", $time, clk_7x_period);
|
$display("^^^ %16.t | %m | clk_7x_period = %t", $time, clk_7x_period);
|
$display("^^^ %16.t | %m | strobe_delay = %t", $time, strobe_delay);
|
$display("^^^ %16.t | %m | strobe_delay = %t", $time, strobe_delay);
|
|
|
generate_clocks_fork : fork
|
generate_clocks_fork : fork
|
generate_clocks(clk_7x_period, strobe_delay);
|
generate_clocks(clk_7x_period, strobe_delay);
|
join_none
|
join_none
|
|
|
endtask: init_clocks
|
endtask: init_clocks
|
|
|
|
|
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
//
|
//
|
initial
|
initial
|
begin
|
begin
|
|
|
wait(~reset);
|
wait(~reset);
|
#500ns;
|
#500ns;
|
|
|
init_clocks();
|
init_clocks();
|
end
|
end
|
|
|
|
|
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
//
|
//
|
|
|
endinterface
|
endinterface
|
|
|
|
|