1
0
mirror of https://github.com/aolofsson/oh.git synced 2025-01-30 02:32:53 +08:00
oh/c2c/hdl/ctx_protocol.v
2016-02-24 20:29:56 -05:00

100 lines
2.9 KiB
Verilog

//##########################################################################
//#
//# - DW is fixed per design
//# - size of packet being fed should be programmable
//# - data is transmitted LSB first!
//#
//#
//##########################################################################
module ctx_protocol (/*AUTOARG*/
// Outputs
fifo_wait, io_access, io_packet,
// Inputs
clk, nreset, datasize, fifo_access, fifo_packet, tx_wait
);
//#####################################################################
//# INTERFACE
//#####################################################################
//parameters
parameter PW = 104; // packet width (core)
parameter IOW = 16; // io packet width
localparam CW = $clog2(2*PW/IOW); // transfer count width
//clock and reset
input clk; // core clock
input nreset; // async active low reset
//config
input [CW-1:0] datasize; // dynamic width of input data
//wide input interface
input fifo_access; // data valid
input [PW-1:0] fifo_packet; // wide data
output fifo_wait; // wait pushback
//io interface (16 bits SDR)
output io_access; // access signal for io
output [2*IOW-1:0] io_packet; // data for IO
input tx_wait; // pushback (from io)
//regs
reg [2:0] ctx_state;
reg [PW-1:0] ctx_data;
reg [CW-1:0] ctx_count;
//##########################
//# STATE MACHINE
//##########################
`define CTX_IDLE 3'b000
`define CTX_BUSY 3'b001
assign start_transfer = (fifo_access & ~tx_wait);
always @ (posedge clk or negedge nreset)
if(!nreset)
ctx_state[2:0] <= `CTX_IDLE;
else
case (ctx_state[2:0])
`CTX_IDLE: ctx_state[2:0] <= start_transfer ? `CTX_BUSY : `CTX_IDLE;
`CTX_BUSY: ctx_state[2:0] <= transfer_done ? `CTX_IDLE : `CTX_BUSY;
default: ctx_state[2:0] <= 'b0;
endcase // case (ctx_state[2:0])
always @ (posedge clk)
if(ctx_state[2:0]==`CTX_BUSY)
ctx_count[CW-1:0] <= ctx_count[CW-1:0] - 1'b1;
else
ctx_count[CW-1:0] <= datasize[CW-1:0];
assign transfer_done = ~(|ctx_count[CW-1:0]) & (ctx_state[2:0]==`CTX_BUSY) ;
assign io_access = (ctx_state[2:0]==`CTX_BUSY);
//##########################
//# DATA SHIFT REGISTER
//##########################
always @ (posedge clk)
if(ctx_state[2:0]==`CTX_BUSY)
ctx_data[PW-1:0] <= {ctx_data[PW-2*IOW-1:0],{(2*IOW){1'b0}}};
else if(start_transfer)
ctx_data[PW-1:0] <= fifo_packet[PW-1:0];
assign io_packet[2*IOW-1:0] = ctx_data[PW-1:PW-2*IOW];
//##########################
//# WAIT SIGNAL
//##########################
assign fifo_wait = tx_wait |
(ctx_state[2:0]==`CTX_BUSY);
endmodule // ctx_protocol