1
0
mirror of https://github.com/aolofsson/oh.git synced 2025-01-17 20:02:53 +08:00
oh/elink/hdl/etx_protocol.v
Andreas Olofsson d558bd5f99 Packet converter interface changes
-packet2emesh and emesh2packet had interface name changes
2015-12-17 12:51:22 -05:00

213 lines
6.3 KiB
Verilog

`include "elink_regmap.v"
/*
*
* This module converts the packet interface to a 64bit wide format
* suitable for sending out to a parallel to serial shift register.
* The frame signal is sent along together with the data making.
* The goal is to minimize the amount of logic done on the high speed
* domain.
*
*
*/
module etx_protocol (/*AUTOARG*/
// Outputs
etx_rd_wait, etx_wr_wait, tx_burst, tx_access, tx_data_slow,
tx_frame_slow,
// Inputs
nreset, clk, etx_access, etx_packet, tx_enable, burst_enable,
gpio_data, gpio_enable, tx_rd_wait, tx_wr_wait
);
parameter PW = 104;
parameter AW = 32;
parameter DW = 32;
parameter ID = 12'h000;
//Clock/reset
input nreset;
input clk;
//System side
input etx_access;
input [PW-1:0] etx_packet;
//Pushback signals
output etx_rd_wait;
output etx_wr_wait;
//Config interface
input tx_enable; //transmit enable
input burst_enable; //Enables bursting
input [8:0] gpio_data; //TODO
input gpio_enable; //TODO
output tx_burst; //for TXSTATUS
output tx_access; //for TXMON
//Interface to IO
output [63:0] tx_data_slow;
output [3:0] tx_frame_slow;
input tx_rd_wait;
input tx_wr_wait;
//################################################################
//# Local regs & wires
//################################################################
reg [2:0] tx_state;
reg [PW-1:0] tx_packet;
wire etx_write;
wire [1:0] etx_datamode;
wire [4:0] etx_ctrlmode;
wire [AW-1:0] etx_dstaddr;
wire [DW-1:0] etx_data;
wire tx_write;
wire [1:0] tx_datamode;
wire [4:0] tx_ctrlmode;
wire [AW-1:0] tx_dstaddr;
wire [DW-1:0] tx_data;
wire [AW-1:0] tx_srcaddr;
wire burst_match;
wire burst_type_match;
wire [31:0] burst_addr;
wire burst_addr_match;
wire burst_in;
wire adjust;
wire current_match;
wire next_match;
wire tx_burst_in;
//##############################################################
//# Packet Pipeline
//##############################################################
packet2emesh #(.AW(AW))
p2m0 (
.write_in (etx_write),
.datamode_in (etx_datamode[1:0]),
.ctrlmode_in (etx_ctrlmode[4:0]),
.dstaddr_in (etx_dstaddr[31:0]),
.data_in (),
.srcaddr_in (),
.packet_in (etx_packet[PW-1:0]));//input
//Hold transaction while waiting
always @ (posedge clk)
if(~etx_wait)
tx_packet[PW-1:0] <= etx_packet[PW-1:0];
//the IO pipeline flushes out
packet2emesh #(.AW(AW))
p2m1 (
.write_in (tx_write),
.datamode_in (tx_datamode[1:0]),
.ctrlmode_in (tx_ctrlmode[4:0]),
.dstaddr_in (tx_dstaddr[31:0]),
.data_in (tx_data[31:0]),
.srcaddr_in (tx_srcaddr[31:0]),
.packet_in (tx_packet[PW-1:0]));//input
//#############################
//# Burst Detection
//#############################
assign burst_addr_match = ((tx_dstaddr[31:0]+32'h8) == etx_dstaddr[31:0]);
assign current_match = tx_access &
tx_write &
(tx_datamode[1:0]==2'b11) &
(tx_ctrlmode[3:0]==4'b0000);
assign next_match = etx_access & //BUG: should be valid?
etx_write &
(etx_datamode[1:0]==2'b11) &
(etx_ctrlmode[3:0]==4'b0000);
assign tx_burst = burst_enable &
~tx_wait &
current_match &
next_match &
burst_addr_match;
reg tx_burst_reg;
always @ (posedge clk)
tx_burst_reg <=tx_burst;
//############################################################
//# TRANSMIT STATE MACHINE
//#############################################################
assign etx_valid = tx_enable &
etx_access &
~(etx_dstaddr[31:20]==ID) &
~tx_wait;
`define TX_IDLE 3'b000
`define TX_START 3'b001
`define TX_ACK 3'b010
`define TX_BURST 3'b011
`define TX_WAIT 3'b100
always @ (posedge clk)
if(!nreset)
tx_state[2:0] <= `TX_IDLE;
else
case (tx_state[2:0])
`TX_IDLE: tx_state[2:0] <= etx_valid ? `TX_START : `TX_IDLE;
`TX_START: tx_state[2:0] <= `TX_ACK;
`TX_ACK: tx_state[2:0] <= tx_burst ? `TX_BURST :
etx_valid ? `TX_START :
`TX_IDLE;
`TX_BURST: tx_state[2:0] <= tx_burst ? `TX_BURST : `TX_IDLE;
endcase // case (tx_state[2:0])
assign tx_ack_wait = (tx_state[1:0]==`TX_START);
assign tx_access = (tx_state[1:0]==`TX_START) |
(tx_state[1:0]==`TX_BURST);
//#######################################
//# Wait propagation circuit backwards
//########################################
wire [63:0] tx_cycle1;
wire [63:0] tx_cycle2;
assign tx_frame_slow[3:0] = (tx_state[1:0]==`TX_START) ? 4'b0111 :
(tx_state[1:0]!=`TX_IDLE) ? 4'b1111 :
4'b0000;
assign tx_cycle1[63:0] = {tx_dstaddr[11:0],tx_datamode[1:0],tx_write,tx_access, //47:32
tx_dstaddr[27:12], //31:16
~tx_write,5'b0,tx_burst_reg,1'b0, //8-15
tx_ctrlmode[3:0],tx_dstaddr[31:28], //0-7
16'b0 //garbage
};
assign tx_cycle2[63:0] = {tx_srcaddr[15:0], //48-63
tx_srcaddr[31:16], //32-47
tx_data[15:0], //16-31
tx_data[31:16] //0-15
};
assign tx_data_slow[63:0] = (tx_state[2:0]==`TX_START) ? tx_cycle1[63:0] :
tx_cycle2[63:0];
//#######################################
//# Wait propagation circuit backwards
//########################################
//immediate wait for state machine
assign tx_wait = tx_wr_wait | tx_rd_wait;
//wait for data
assign etx_wr_wait = (tx_wr_wait | tx_ack_wait );
assign etx_rd_wait = (tx_rd_wait | tx_ack_wait );
assign etx_wait = etx_wr_wait | etx_rd_wait;
endmodule // etx_protocol
// Local Variables:
// verilog-library-directories:("." "../../common/hdl")
// End: