1
0
mirror of https://github.com/aolofsson/oh.git synced 2025-01-17 20:02:53 +08:00
oh/mio/hdl/mtx_fifo.v
2020-01-28 18:12:57 -05:00

141 lines
5.1 KiB
Verilog

//#############################################################################
//# Purpose: MIO Transmit FIFO #
//#############################################################################
//# Author: Andreas Olofsson #
//# License: MIT (see LICENSE file in OH! repository) #
//#############################################################################
module mtx_fifo # ( parameter PW = 136, // packet width
parameter AW = 64, // address width
parameter FIFO_DEPTH = 16, // fifo depth
parameter TARGET = "GENERIC" // fifo target
)
(// reset, clk, cfg
input clk, // main core clock
input io_clk, // clock for tx logic
input nreset, // async active low reset
input tx_en,// transmit enable
input emode,// emesh transaction mode
// Data from mesh
input access_in, // fifo data valid
input [PW-1:0] packet_in, // fifo packet
output wait_out, // wait pushback for fifo
// Data for IO logic
output [63:0] io_packet, // packet for IO
output [7:0] io_valid, // byte valids for IO
input io_wait // pushback from IO
);
//local wires
reg [1:0] emesh_cycle;
reg [191:0] packet_buffer;
wire fifo_access_out;
wire [71:0] fifo_packet_out;
wire fifo_access_in;
wire [71:0] fifo_packet_in;
wire [63:0] data_wide;
wire [7:0] valid;
wire emesh_wait;
wire [63:0] fifo_data_in;
wire fifo_wait;
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire [4:0] ctrlmode_in; // From p2e of packet2emesh.v
wire [AW-1:0] data_in; // From p2e of packet2emesh.v
wire [1:0] datamode_in; // From p2e of packet2emesh.v
wire [AW-1:0] dstaddr_in; // From p2e of packet2emesh.v
wire [AW-1:0] srcaddr_in; // From p2e of packet2emesh.v
wire write_in; // From p2e of packet2emesh.v
// End of automatics
//######################
//# FIFO INPUT LOGIC
//######################
packet2emesh #(.AW(AW),
.PW(PW))
p2e (.packet_in (packet_in[PW-1:0]),
/*AUTOINST*/
// Outputs
.write_in (write_in),
.datamode_in (datamode_in[1:0]),
.ctrlmode_in (ctrlmode_in[4:0]),
.dstaddr_in (dstaddr_in[AW-1:0]),
.srcaddr_in (srcaddr_in[AW-1:0]),
.data_in (data_in[AW-1:0]));
// create 64 bit data vector (related to packet packing)
assign data_wide[63:0] = {srcaddr_in[31:0],data_in[31:0]};
// create a dummy wide packet to avoid warnings
always @ (posedge clk)
if(~wait_out & access_in)
packet_buffer[191:0] <= packet_in[PW-1:0];
// Emesh write pipeline (note! fifo_wait means half full!)
always @ (posedge clk or negedge nreset)
if(!nreset)
emesh_cycle[1:0] <= 'b0;
else if(emesh_cycle[0] && (AW==64)) // 2nd stall for 64bit
emesh_cycle[1:0] <= 2'b10;
else if(emode & access_in & ~fifo_wait) // 1 stall for emesh
emesh_cycle[1:0] <= 2'b01;
else
emesh_cycle[1:0] <= 2'b00;
// valid bits depending on type of transaction
assign valid[7:0] = (emesh_cycle[0] && (AW==32)) ? 8'h3F : //48 bits
(emesh_cycle[1] && (AW==64)) ? 8'h03 : //16 bits
(~emode & datamode_in[1:0]==2'b00) ? 8'h01 : //double
(~emode & datamode_in[1:0]==2'b01) ? 8'h03 : //word
(~emode & datamode_in[1:0]==2'b10) ? 8'h0F : //short
8'hFF; //default
// folding data for fifo
assign fifo_data_in[63:0] = ~emode ? data_wide[63:0] :
emesh_cycle[0] ? packet_buffer[127:64] :
emesh_cycle[1] ? packet_buffer[191:128] :
packet_in[63:0];
assign fifo_packet_in[71:0] = {fifo_data_in[63:0], valid[7:0]};
// fifo access
assign fifo_access_in = access_in | (|emesh_cycle[1:0]);
// pushback wait while emesh transaction is active or while fifo is half-full
assign wait_out = fifo_wait | (|emesh_cycle[1:0]);
//########################################################
//# FIFO
//#######################################################
oh_fifo_cdc #(.TARGET(TARGET),
.DW(72),
.DEPTH(FIFO_DEPTH))
fifo (.clk_in (clk),
.clk_out (io_clk),
.wait_in (io_wait),
.prog_full (),
.full (),
.empty (),
.wait_out (fifo_wait),
.access_in (fifo_access_in),
.packet_in (fifo_packet_in[71:0]),
.access_out (fifo_access_out),
.packet_out (fifo_packet_out[71:0]),
.nreset (nreset));
//########################################################
//# FIFO OUTPUT LOGIC
//#######################################################
assign io_valid[7:0] = {{(8){fifo_access_out}} & fifo_packet_out[7:0]};
assign io_packet[63:0] = fifo_packet_out[71:8];
endmodule // mtx
// Local Variables:
// verilog-library-directories:("." "../../common/hdl" "../../emesh/hdl")
// End: