2016-02-24 20:29:56 -05:00
|
|
|
//#######################################################
|
|
|
|
//# Target specific IO logic (fast, timing sensitive)
|
|
|
|
//#######################################################
|
2016-02-26 22:51:35 -05:00
|
|
|
module mtx_io (/*AUTOARG*/
|
2016-02-24 20:29:56 -05:00
|
|
|
// Outputs
|
2016-03-20 22:37:50 -04:00
|
|
|
tx_packet, tx_access, io_wait,
|
2016-02-24 20:29:56 -05:00
|
|
|
// Inputs
|
2016-03-20 22:37:50 -04:00
|
|
|
nreset, clk, ddr_mode, tx_wait, io_access, io_packet
|
2016-02-24 20:29:56 -05:00
|
|
|
);
|
|
|
|
|
|
|
|
//#####################################################################
|
|
|
|
//# INTERFACE
|
|
|
|
//#####################################################################
|
|
|
|
|
|
|
|
//parameters
|
2016-03-20 22:37:50 -04:00
|
|
|
parameter N = 16;
|
2016-02-24 20:29:56 -05:00
|
|
|
|
2016-03-20 22:37:50 -04:00
|
|
|
//reset, clk, cfg
|
|
|
|
input nreset; // async active low reset
|
|
|
|
input clk; // clock from divider
|
|
|
|
input ddr_mode; // send data as ddr
|
|
|
|
|
2016-02-24 20:29:56 -05:00
|
|
|
//IO interface
|
2016-03-20 22:37:50 -04:00
|
|
|
output [N-1:0] tx_packet; // data for IO
|
|
|
|
output tx_access; // access signal for IO
|
|
|
|
input tx_wait; // IO wait signals
|
2016-02-24 20:29:56 -05:00
|
|
|
|
2016-03-20 22:37:50 -04:00
|
|
|
//Core side
|
|
|
|
input io_access; // valid packet
|
|
|
|
input [2*N-1:0] io_packet; // packet
|
|
|
|
output io_wait; // pushback to serializer in sdr mode
|
|
|
|
|
2016-02-24 20:29:56 -05:00
|
|
|
//regs
|
2016-03-20 22:37:50 -04:00
|
|
|
reg tx_access;
|
|
|
|
wire [N-1:0] tx_packet_ddr;
|
|
|
|
reg [N-1:0] tx_packet_sdr;
|
|
|
|
reg byte0_sel;
|
2016-02-24 20:29:56 -05:00
|
|
|
|
|
|
|
//########################################
|
|
|
|
//# RESET
|
|
|
|
//########################################
|
|
|
|
|
2016-03-20 22:37:50 -04:00
|
|
|
//synchronize reset to io_clk
|
2016-02-24 20:29:56 -05:00
|
|
|
oh_rsync oh_rsync(.nrst_out (io_nreset),
|
|
|
|
.clk (clk),
|
|
|
|
.nrst_in (nreset));
|
|
|
|
|
|
|
|
//########################################
|
|
|
|
//# ACCESS (SDR)
|
|
|
|
//########################################
|
|
|
|
|
|
|
|
always @ (posedge clk or negedge io_nreset)
|
|
|
|
if(!io_nreset)
|
|
|
|
tx_access <= 1'b0;
|
2016-03-20 22:37:50 -04:00
|
|
|
else
|
2016-02-24 20:29:56 -05:00
|
|
|
tx_access <= io_access;
|
2016-03-20 22:37:50 -04:00
|
|
|
|
2016-02-24 20:29:56 -05:00
|
|
|
//########################################
|
2016-03-20 22:37:50 -04:00
|
|
|
//# SDR DATA SELECTOR
|
2016-02-24 20:29:56 -05:00
|
|
|
//########################################
|
|
|
|
|
2016-03-20 22:37:50 -04:00
|
|
|
// sampling data for sdr
|
|
|
|
always @ (posedge clk)
|
|
|
|
if(io_access)
|
|
|
|
tx_packet_sdr[N-1:0] <= byte0_sel ? io_packet[N-1:0] :
|
|
|
|
io_packet[2*N-1:N];
|
|
|
|
|
|
|
|
//select 2nd byte (stall on this signal)
|
|
|
|
always @ (posedge clk)
|
|
|
|
if(~io_access)
|
|
|
|
byte0_sel <= 1'b0;
|
|
|
|
else if (~ddr_mode)
|
|
|
|
byte0_sel <= io_access ^ byte0_sel;
|
|
|
|
|
|
|
|
// TODO: add synchronizer?!
|
|
|
|
assign io_wait = tx_wait | byte0_sel;
|
|
|
|
|
|
|
|
//########################################
|
|
|
|
//# DATA SAMPLING (DDR/SDR)
|
|
|
|
//########################################
|
|
|
|
|
|
|
|
oh_oddr#(.DW(N))
|
|
|
|
data_oddr (.out (tx_packet_ddr[N-1:0]),
|
2016-02-24 20:29:56 -05:00
|
|
|
.clk (clk),
|
2016-03-20 22:37:50 -04:00
|
|
|
.ce (io_access),
|
|
|
|
.din1 (io_packet[N-1:0]),
|
|
|
|
.din2 (io_packet[2*N-1:N])
|
2016-02-24 20:29:56 -05:00
|
|
|
);
|
2016-03-20 22:37:50 -04:00
|
|
|
|
|
|
|
//select between ddr/sdr data
|
|
|
|
assign tx_packet[N-1:0] = ddr_mode ? tx_packet_ddr[N-1:0] :
|
|
|
|
tx_packet_sdr[N-1:0];
|
|
|
|
|
2016-02-26 22:51:35 -05:00
|
|
|
endmodule // mtx_io
|
2016-02-24 20:29:56 -05:00
|
|
|
// Local Variables:
|
|
|
|
// verilog-library-directories:("." "../../common/hdl")
|
|
|
|
// End:
|
|
|
|
|
|
|
|
|
|
|
|
|