2015-04-13 23:35:21 -04:00
|
|
|
/*
|
|
|
|
########################################################################
|
|
|
|
Epiphany eLink AXI Master Module
|
2015-04-18 17:35:22 -04:00
|
|
|
########################################################################
|
2015-05-19 22:08:41 -04:00
|
|
|
|
|
|
|
NOTES:
|
|
|
|
--write channels: write address, write data, write response
|
|
|
|
--read channels: read address, read data channel
|
|
|
|
--'valid' source signal used to show valid address,data,control is available
|
|
|
|
--'ready' destination ready signal indicates readyness to accept information
|
|
|
|
--'last' signal indicates the transfer of final data item
|
|
|
|
--read and write have separate address channels
|
|
|
|
--read data channel carries read data from slave to master
|
|
|
|
--write channel includes a byte lane strobe signal for every eight data bits
|
|
|
|
--there is no acknowledge on write, treated as buffered
|
|
|
|
--channels are unidirectional
|
|
|
|
--valid is asserted uncondotionally
|
|
|
|
--ready occurs cycle after valid
|
|
|
|
--there can be no combinatorial path between input and output of interface
|
|
|
|
--destination is permitted to wait for valud before asserting READY
|
|
|
|
--source is not allowed to wait for READY to assert VALID
|
|
|
|
--AWVALID must remain asserted until the rising clock edge after slave asserts AWREADY??
|
|
|
|
--The default state of AWREADY can be either HIGH or LOW. This specification recommends a default state of HIGH.
|
|
|
|
--During a write burst, the master can assert the WVALID signal only when it drives valid write data.
|
|
|
|
--The default state of WREADY can be HIGH, but only if the slave can always accept write data in a single cycle.
|
|
|
|
--The master must assert the WLAST signal while it is driving the final write transfer in the burst.
|
|
|
|
|
|
|
|
--_aw=write address channel
|
|
|
|
--_ar=read address channel
|
|
|
|
--_r=read data channel
|
|
|
|
--_w=write data channel
|
|
|
|
--_b=write response channel
|
|
|
|
|
|
|
|
*/
|
2014-12-14 22:22:49 -05:00
|
|
|
|
2015-04-13 23:35:21 -04:00
|
|
|
module emaxi(/*autoarg*/
|
|
|
|
// Outputs
|
2016-01-19 13:25:19 -05:00
|
|
|
wr_wait, rd_wait, rr_access, rr_packet, m_axi_awid, m_axi_awaddr,
|
|
|
|
m_axi_awlen, m_axi_awsize, m_axi_awburst, m_axi_awlock,
|
|
|
|
m_axi_awcache, m_axi_awprot, m_axi_awqos, m_axi_awvalid, m_axi_wid,
|
|
|
|
m_axi_wdata, m_axi_wstrb, m_axi_wlast, m_axi_wvalid, m_axi_bready,
|
|
|
|
m_axi_arid, m_axi_araddr, m_axi_arlen, m_axi_arsize, m_axi_arburst,
|
|
|
|
m_axi_arlock, m_axi_arcache, m_axi_arprot, m_axi_arqos,
|
|
|
|
m_axi_arvalid, m_axi_rready,
|
2015-04-13 23:35:21 -04:00
|
|
|
// Inputs
|
2016-01-19 13:25:19 -05:00
|
|
|
wr_access, wr_packet, rd_access, rd_packet, rr_wait, m_axi_aclk,
|
|
|
|
m_axi_aresetn, m_axi_awready, m_axi_wready, m_axi_bid, m_axi_bresp,
|
|
|
|
m_axi_bvalid, m_axi_arready, m_axi_rid, m_axi_rdata, m_axi_rresp,
|
|
|
|
m_axi_rlast, m_axi_rvalid
|
2015-04-13 23:35:21 -04:00
|
|
|
);
|
|
|
|
|
2015-10-07 14:46:12 -04:00
|
|
|
parameter M_IDW = 12;
|
2015-05-09 08:56:51 -04:00
|
|
|
parameter PW = 104;
|
|
|
|
parameter AW = 32;
|
|
|
|
parameter DW = 32;
|
|
|
|
|
|
|
|
//########################
|
2015-11-30 13:45:49 -05:00
|
|
|
//EMESH INTERFACE
|
2015-05-09 08:56:51 -04:00
|
|
|
//########################
|
2015-04-13 23:35:21 -04:00
|
|
|
|
2015-11-30 13:45:49 -05:00
|
|
|
//Write request
|
2016-01-19 13:25:19 -05:00
|
|
|
input wr_access;
|
|
|
|
input [PW-1:0] wr_packet;
|
|
|
|
output wr_wait;
|
2015-04-13 23:35:21 -04:00
|
|
|
|
2015-11-30 13:45:49 -05:00
|
|
|
//Read request
|
2016-01-19 13:25:19 -05:00
|
|
|
input rd_access;
|
|
|
|
input [PW-1:0] rd_packet;
|
|
|
|
output rd_wait;
|
2015-04-13 23:35:21 -04:00
|
|
|
|
2015-11-30 13:45:49 -05:00
|
|
|
//Read response
|
2016-01-19 13:25:19 -05:00
|
|
|
output rr_access;
|
|
|
|
output [PW-1:0] rr_packet;
|
|
|
|
input rr_wait;
|
2015-05-09 08:56:51 -04:00
|
|
|
|
|
|
|
//########################
|
|
|
|
//AXI MASTER INTERFACE
|
|
|
|
//########################
|
|
|
|
|
2015-04-13 23:35:21 -04:00
|
|
|
input m_axi_aclk; // global clock signal.
|
2015-04-18 17:35:22 -04:00
|
|
|
input m_axi_aresetn; // global reset singal.
|
|
|
|
|
|
|
|
//Write address channel
|
2015-11-03 19:49:38 -05:00
|
|
|
output [M_IDW-1:0] m_axi_awid; // write address ID
|
2015-04-13 23:35:21 -04:00
|
|
|
output [31 : 0] m_axi_awaddr; // master interface write address
|
2015-04-18 17:35:22 -04:00
|
|
|
output [7 : 0] m_axi_awlen; // burst length.
|
|
|
|
output [2 : 0] m_axi_awsize; // burst size.
|
|
|
|
output [1 : 0] m_axi_awburst; // burst type.
|
2015-11-09 16:09:12 -05:00
|
|
|
output m_axi_awlock; // lock type
|
2015-04-18 17:35:22 -04:00
|
|
|
output [3 : 0] m_axi_awcache; // memory type.
|
|
|
|
output [2 : 0] m_axi_awprot; // protection type.
|
|
|
|
output [3 : 0] m_axi_awqos; // quality of service
|
|
|
|
output m_axi_awvalid; // write address valid
|
|
|
|
input m_axi_awready; // write address ready
|
|
|
|
|
|
|
|
//Write data channel
|
2015-11-09 16:09:12 -05:00
|
|
|
output [M_IDW-1:0] m_axi_wid;
|
2015-04-13 23:35:21 -04:00
|
|
|
output [63 : 0] m_axi_wdata; // master interface write data.
|
2015-04-18 17:35:22 -04:00
|
|
|
output [7 : 0] m_axi_wstrb; // byte write strobes
|
2015-11-24 01:12:07 -05:00
|
|
|
output m_axi_wlast; // last transfer in a write burst.
|
2015-04-18 17:35:22 -04:00
|
|
|
output m_axi_wvalid; // indicates data is ready to go
|
2015-11-24 01:12:07 -05:00
|
|
|
input m_axi_wready; // slave is ready for data
|
2015-04-18 17:35:22 -04:00
|
|
|
|
|
|
|
//Write response channel
|
2015-11-24 01:12:07 -05:00
|
|
|
input [M_IDW-1:0] m_axi_bid;
|
2015-04-18 17:35:22 -04:00
|
|
|
input [1 : 0] m_axi_bresp; // status of the write transaction.
|
2015-11-24 01:12:07 -05:00
|
|
|
input m_axi_bvalid; // channel is a valid write response
|
2015-04-18 17:35:22 -04:00
|
|
|
output m_axi_bready; // master can accept write response.
|
|
|
|
|
|
|
|
//Read address channel
|
2015-11-09 16:09:12 -05:00
|
|
|
output [M_IDW-1:0] m_axi_arid; // read address ID
|
2015-04-18 17:35:22 -04:00
|
|
|
output [31 : 0] m_axi_araddr; // initial address of a read burst
|
|
|
|
output [7 : 0] m_axi_arlen; // burst length
|
|
|
|
output [2 : 0] m_axi_arsize; // burst size
|
|
|
|
output [1 : 0] m_axi_arburst; // burst type
|
2015-11-24 01:12:07 -05:00
|
|
|
output m_axi_arlock; // lock type
|
2015-04-13 23:35:21 -04:00
|
|
|
output [3 : 0] m_axi_arcache; // memory type
|
|
|
|
output [2 : 0] m_axi_arprot; // protection type
|
2015-11-24 01:12:07 -05:00
|
|
|
output [3 : 0] m_axi_arqos; // quality of service info
|
|
|
|
output m_axi_arvalid; // valid read address
|
2015-04-18 17:35:22 -04:00
|
|
|
input m_axi_arready; // slave is ready to accept an address
|
|
|
|
|
|
|
|
//Read data channel
|
2015-11-24 01:12:07 -05:00
|
|
|
input [M_IDW-1:0] m_axi_rid; // read data ID
|
2015-04-13 23:35:21 -04:00
|
|
|
input [63 : 0] m_axi_rdata; // master read data
|
2015-04-18 17:35:22 -04:00
|
|
|
input [1 : 0] m_axi_rresp; // status of the read transfer
|
2015-11-24 01:12:07 -05:00
|
|
|
input m_axi_rlast; // last transfer in a read burst
|
2015-04-18 17:35:22 -04:00
|
|
|
input m_axi_rvalid; // signaling the required read data
|
|
|
|
output m_axi_rready; // master can accept the readback data
|
2015-03-24 15:12:53 -04:00
|
|
|
|
2015-05-09 08:56:51 -04:00
|
|
|
|
|
|
|
//#########################################################################
|
|
|
|
//REGISTER/WIRE DECLARATIONS
|
|
|
|
//#########################################################################
|
|
|
|
reg [31 : 0] m_axi_awaddr;
|
|
|
|
reg [7:0] m_axi_awlen;
|
|
|
|
reg [2:0] m_axi_awsize;
|
|
|
|
reg m_axi_awvalid;
|
|
|
|
reg [63 : 0] m_axi_wdata;
|
2015-11-25 21:57:25 -05:00
|
|
|
reg [63 : 0] m_axi_rdata_reg;
|
2015-05-09 08:56:51 -04:00
|
|
|
reg [7 : 0] m_axi_wstrb;
|
|
|
|
reg m_axi_wlast;
|
|
|
|
reg m_axi_wvalid;
|
|
|
|
reg awvalid_b;
|
|
|
|
reg [31:0] awaddr_b;
|
|
|
|
reg [2:0] awsize_b;
|
|
|
|
reg [7:0] awlen_b;
|
|
|
|
reg wvalid_b;
|
|
|
|
reg [63:0] wdata_b;
|
|
|
|
reg [7:0] wstrb_b;
|
|
|
|
reg [63 : 0] wdata_aligned;
|
|
|
|
reg [7 : 0] wstrb_aligned;
|
2015-04-13 23:35:21 -04:00
|
|
|
|
2016-01-19 13:25:19 -05:00
|
|
|
reg rr_access;
|
|
|
|
reg [31:0] rr_data;
|
|
|
|
reg [31:0] rr_srcaddr;
|
|
|
|
reg [3:0] rr_datamode;
|
|
|
|
reg [3:0] rr_ctrlmode;
|
|
|
|
reg [31:0] rr_dstaddr;
|
2015-11-25 23:50:29 -05:00
|
|
|
reg [63:0] m_axi_rdata_fifo;
|
2016-01-19 13:25:19 -05:00
|
|
|
reg rr_access_fifo;
|
2015-11-25 23:50:29 -05:00
|
|
|
|
2015-04-13 23:35:21 -04:00
|
|
|
|
|
|
|
//wires
|
2015-05-09 08:56:51 -04:00
|
|
|
wire aw_go;
|
|
|
|
wire w_go;
|
|
|
|
wire readinfo_wren;
|
|
|
|
wire readinfo_full;
|
2015-11-25 23:50:29 -05:00
|
|
|
wire [40:0] readinfo_out;
|
|
|
|
wire [40:0] readinfo_in;
|
2015-05-19 22:08:41 -04:00
|
|
|
wire awvalid_in;
|
|
|
|
|
2016-01-19 13:25:19 -05:00
|
|
|
wire [1:0] wr_datamode;
|
|
|
|
wire [AW-1:0] wr_dstaddr;
|
|
|
|
wire [DW-1:0] wr_data;
|
|
|
|
wire [AW-1:0] wr_srcaddr;
|
|
|
|
|
|
|
|
wire [1:0] rd_datamode;
|
|
|
|
wire [4:0] rd_ctrlmode;
|
|
|
|
wire [AW-1:0] rd_dstaddr;
|
|
|
|
wire [AW-1:0] rd_srcaddr;
|
|
|
|
|
|
|
|
wire [1:0] rr_datamode_fifo;
|
|
|
|
wire [3:0] rr_ctrlmode_fifo;
|
|
|
|
wire [31:0] rr_dstaddr_fifo;
|
|
|
|
wire [2:0] rr_alignaddr_fifo;
|
2015-11-25 23:50:29 -05:00
|
|
|
wire [103:0] packet_out;
|
|
|
|
wire fifo_prog_full;
|
|
|
|
wire fifo_full;
|
|
|
|
wire fifo_rd_en;
|
|
|
|
wire fifo_wr_en;
|
|
|
|
|
2015-05-09 08:56:51 -04:00
|
|
|
//#########################################################################
|
|
|
|
//EMESH 2 PACKET CONVERSION
|
|
|
|
//#########################################################################
|
|
|
|
|
|
|
|
//RXWR
|
|
|
|
packet2emesh p2e_rxwr (
|
|
|
|
// Outputs
|
2016-01-14 21:21:55 +01:00
|
|
|
.write_in (),
|
2016-01-19 13:25:19 -05:00
|
|
|
.datamode_in (wr_datamode[1:0]),
|
2016-01-14 21:21:55 +01:00
|
|
|
.ctrlmode_in (),
|
2016-01-19 13:25:19 -05:00
|
|
|
.dstaddr_in (wr_dstaddr[AW-1:0]),
|
|
|
|
.data_in (wr_data[DW-1:0]),
|
|
|
|
.srcaddr_in (wr_srcaddr[AW-1:0]),
|
2015-05-09 08:56:51 -04:00
|
|
|
// Inputs
|
2016-01-19 13:25:19 -05:00
|
|
|
.packet_in (wr_packet[PW-1:0])
|
2015-05-09 08:56:51 -04:00
|
|
|
);
|
|
|
|
|
|
|
|
//RXRD
|
|
|
|
packet2emesh p2e_rxrd (
|
|
|
|
// Outputs
|
2016-01-14 21:21:55 +01:00
|
|
|
.write_in (),
|
2016-01-19 13:25:19 -05:00
|
|
|
.datamode_in (rd_datamode[1:0]),
|
|
|
|
.ctrlmode_in (rd_ctrlmode[4:0]),
|
|
|
|
.dstaddr_in (rd_dstaddr[AW-1:0]),
|
2016-01-14 21:21:55 +01:00
|
|
|
.data_in (),
|
2016-01-19 13:25:19 -05:00
|
|
|
.srcaddr_in (rd_srcaddr[AW-1:0]),
|
2015-05-09 08:56:51 -04:00
|
|
|
// Inputs
|
2016-01-19 13:25:19 -05:00
|
|
|
.packet_in (rd_packet[PW-1:0])
|
2015-05-09 08:56:51 -04:00
|
|
|
);
|
|
|
|
|
2016-01-19 13:25:19 -05:00
|
|
|
//RR
|
2015-05-09 08:56:51 -04:00
|
|
|
emesh2packet e2p (
|
|
|
|
// Outputs
|
2016-01-19 13:25:19 -05:00
|
|
|
.packet_out (rr_packet[PW-1:0]),
|
2015-05-09 08:56:51 -04:00
|
|
|
// Inputs
|
2016-01-14 21:21:55 +01:00
|
|
|
.write_out (1'b1),
|
2016-01-19 13:25:19 -05:00
|
|
|
.datamode_out (rr_datamode[1:0]),
|
|
|
|
.ctrlmode_out ({1'b0,rr_ctrlmode[3:0]}),
|
|
|
|
.dstaddr_out (rr_dstaddr[AW-1:0]),
|
|
|
|
.data_out (rr_data[DW-1:0]),
|
|
|
|
.srcaddr_out (rr_srcaddr[AW-1:0])
|
2015-05-09 08:56:51 -04:00
|
|
|
);
|
|
|
|
|
|
|
|
//#########################################################################
|
|
|
|
//AXI unimplemented constants
|
|
|
|
//#########################################################################
|
|
|
|
|
2015-11-09 16:09:12 -05:00
|
|
|
//AW
|
|
|
|
assign m_axi_awid[M_IDW-1:0] = {(M_IDW){1'b0}};
|
2015-05-19 22:08:41 -04:00
|
|
|
assign m_axi_awburst[1:0] = 2'b01; //only increment burst supported
|
2015-11-25 21:57:25 -05:00
|
|
|
assign m_axi_awcache[3:0] = 4'b0000; //TODO: should this be 0000 or 0010???
|
2015-05-19 22:08:41 -04:00
|
|
|
assign m_axi_awprot[2:0] = 3'b000;
|
|
|
|
assign m_axi_awqos[3:0] = 4'b0000;
|
2015-11-09 16:09:12 -05:00
|
|
|
assign m_axi_awlock = 1'b0;
|
2015-05-19 22:08:41 -04:00
|
|
|
|
2015-11-09 16:09:12 -05:00
|
|
|
//AR
|
|
|
|
assign m_axi_arid[M_IDW-1:0] = {(M_IDW){1'b0}};
|
2015-05-19 22:08:41 -04:00
|
|
|
assign m_axi_arburst[1:0] = 2'b01; //only increment burst supported
|
|
|
|
assign m_axi_arcache[3:0] = 4'b0000;
|
2015-04-13 23:35:21 -04:00
|
|
|
assign m_axi_arprot[2:0] = 3'h0;
|
|
|
|
assign m_axi_arqos[3:0] = 4'h0;
|
2015-11-09 16:09:12 -05:00
|
|
|
assign m_axi_arlock = 1'b0;
|
|
|
|
|
|
|
|
//B
|
|
|
|
assign m_axi_bready = 1'b1;//TODO: tie to wait signal????
|
|
|
|
|
|
|
|
//W
|
|
|
|
assign m_axi_wid[M_IDW-1:0] = {(M_IDW){1'b0}};
|
2015-04-13 23:35:21 -04:00
|
|
|
|
2015-05-09 08:56:51 -04:00
|
|
|
//#########################################################################
|
|
|
|
//Write address channel
|
|
|
|
//#########################################################################
|
|
|
|
|
2015-04-13 23:35:21 -04:00
|
|
|
assign aw_go = m_axi_awvalid & m_axi_awready;
|
2015-05-09 08:56:51 -04:00
|
|
|
assign w_go = m_axi_wvalid & m_axi_wready;
|
2016-01-19 13:25:19 -05:00
|
|
|
assign wr_wait = awvalid_b | wvalid_b;
|
|
|
|
assign awvalid_in = wr_access & ~awvalid_b & ~wvalid_b;
|
2015-05-19 22:08:41 -04:00
|
|
|
|
2015-04-13 23:35:21 -04:00
|
|
|
// generate write-address signals
|
|
|
|
always @( posedge m_axi_aclk )
|
2015-11-03 19:49:38 -05:00
|
|
|
if(!m_axi_aresetn)
|
2015-04-13 23:35:21 -04:00
|
|
|
begin
|
|
|
|
m_axi_awvalid <= 1'b0;
|
|
|
|
m_axi_awaddr[31:0] <= 32'd0;
|
|
|
|
m_axi_awlen[7:0] <= 8'd0;
|
|
|
|
m_axi_awsize[2:0] <= 3'd0;
|
2015-05-19 22:08:41 -04:00
|
|
|
awvalid_b <= 1'b0;
|
|
|
|
awaddr_b <= 'd0;
|
|
|
|
awlen_b[7:0] <= 'd0;
|
|
|
|
awsize_b[2:0] <= 'd0;
|
2015-04-13 23:35:21 -04:00
|
|
|
end
|
|
|
|
else
|
|
|
|
begin
|
|
|
|
if( ~m_axi_awvalid | aw_go )
|
|
|
|
begin
|
|
|
|
if( awvalid_b )
|
|
|
|
begin
|
|
|
|
m_axi_awvalid <= 1'b1;
|
|
|
|
m_axi_awaddr[31:0] <= awaddr_b[31:0];
|
|
|
|
m_axi_awlen[7:0] <= awlen_b[7:0];
|
|
|
|
m_axi_awsize[2:0] <= awsize_b[2:0];
|
|
|
|
end
|
|
|
|
else
|
|
|
|
begin
|
2015-05-19 22:08:41 -04:00
|
|
|
m_axi_awvalid <= awvalid_in;
|
2016-01-19 13:25:19 -05:00
|
|
|
m_axi_awaddr[31:0] <= wr_dstaddr[31:0];
|
2015-04-13 23:35:21 -04:00
|
|
|
m_axi_awlen[7:0] <= 8'b0;
|
2016-01-19 13:25:19 -05:00
|
|
|
m_axi_awsize[2:0] <= { 1'b0, wr_datamode[1:0]};
|
2015-04-13 23:35:21 -04:00
|
|
|
end
|
|
|
|
end
|
2015-05-19 22:08:41 -04:00
|
|
|
if( awvalid_in & m_axi_awvalid & ~aw_go )
|
2015-04-13 23:35:21 -04:00
|
|
|
awvalid_b <= 1'b1;
|
|
|
|
else if( aw_go )
|
|
|
|
awvalid_b <= 1'b0;
|
|
|
|
|
|
|
|
//Pipeline stage
|
2015-05-19 22:08:41 -04:00
|
|
|
if( awvalid_in )
|
2015-04-13 23:35:21 -04:00
|
|
|
begin
|
2016-01-19 13:25:19 -05:00
|
|
|
awaddr_b[31:0] <= wr_dstaddr[31:0];
|
2015-04-13 23:35:21 -04:00
|
|
|
awlen_b[7:0] <= 8'b0;
|
2016-01-19 13:25:19 -05:00
|
|
|
awsize_b[2:0] <= { 1'b0, wr_datamode[1:0] };
|
2015-04-13 23:35:21 -04:00
|
|
|
end
|
|
|
|
end // else: !if(~m_axi_aresetn)
|
2015-05-09 08:56:51 -04:00
|
|
|
|
|
|
|
//#########################################################################
|
|
|
|
//Write data alignment circuit
|
|
|
|
//#########################################################################
|
2015-04-13 23:35:21 -04:00
|
|
|
|
|
|
|
always @*
|
2016-01-19 13:25:19 -05:00
|
|
|
case( wr_datamode[1:0] )
|
|
|
|
2'b00: wdata_aligned[63:0] = { 8{wr_data[7:0]}};
|
|
|
|
2'b01: wdata_aligned[63:0] = { 4{wr_data[15:0]}};
|
|
|
|
2'b10: wdata_aligned[63:0] = { 2{wr_data[31:0]}};
|
|
|
|
default: wdata_aligned[63:0] = { wr_srcaddr[31:0], wr_data[31:0]};
|
2015-04-13 23:35:21 -04:00
|
|
|
endcase
|
|
|
|
|
|
|
|
always @*
|
|
|
|
begin
|
2016-01-19 13:25:19 -05:00
|
|
|
case(wr_datamode[1:0])
|
2015-04-13 23:35:21 -04:00
|
|
|
2'd0: // byte
|
2016-01-19 13:25:19 -05:00
|
|
|
case(wr_dstaddr[2:0])
|
2015-04-13 23:35:21 -04:00
|
|
|
3'd0: wstrb_aligned[7:0] = 8'h01;
|
|
|
|
3'd1: wstrb_aligned[7:0] = 8'h02;
|
|
|
|
3'd2: wstrb_aligned[7:0] = 8'h04;
|
|
|
|
3'd3: wstrb_aligned[7:0] = 8'h08;
|
|
|
|
3'd4: wstrb_aligned[7:0] = 8'h10;
|
|
|
|
3'd5: wstrb_aligned[7:0] = 8'h20;
|
|
|
|
3'd6: wstrb_aligned[7:0] = 8'h40;
|
|
|
|
default: wstrb_aligned[7:0] = 8'h80;
|
|
|
|
endcase
|
|
|
|
2'd1: // 16b hword
|
2016-01-19 13:25:19 -05:00
|
|
|
case(wr_dstaddr[2:1])
|
2015-04-13 23:35:21 -04:00
|
|
|
2'd0: wstrb_aligned[7:0] = 8'h03;
|
|
|
|
2'd1: wstrb_aligned[7:0] = 8'h0c;
|
|
|
|
2'd2: wstrb_aligned[7:0] = 8'h30;
|
|
|
|
default: wstrb_aligned[7:0] = 8'hc0;
|
|
|
|
endcase
|
|
|
|
2'd2: // 32b word
|
2016-01-19 13:25:19 -05:00
|
|
|
if(wr_dstaddr[2])
|
2015-04-13 23:35:21 -04:00
|
|
|
wstrb_aligned[7:0] = 8'hf0;
|
|
|
|
else
|
|
|
|
wstrb_aligned[7:0] = 8'h0f;
|
|
|
|
2'd3:
|
|
|
|
wstrb_aligned[7:0] = 8'hff;
|
|
|
|
endcase // case (emwr_datamode[1:0])
|
|
|
|
end // always @ *
|
2015-05-09 08:56:51 -04:00
|
|
|
|
|
|
|
//#########################################################################
|
|
|
|
//Write data channel
|
|
|
|
//#########################################################################
|
|
|
|
|
2015-04-13 23:35:21 -04:00
|
|
|
always @ (posedge m_axi_aclk )
|
|
|
|
if(~m_axi_aresetn)
|
|
|
|
begin
|
|
|
|
m_axi_wvalid <= 1'b0;
|
2015-04-14 14:00:23 -04:00
|
|
|
m_axi_wdata[63:0] <= 64'b0;
|
2015-04-13 23:35:21 -04:00
|
|
|
m_axi_wstrb[7:0] <= 8'b0;
|
2015-05-19 22:08:41 -04:00
|
|
|
m_axi_wlast <= 1'b1; // TODO:bursts!!
|
2015-04-13 23:35:21 -04:00
|
|
|
wvalid_b <= 1'b0;
|
|
|
|
wdata_b[63:0] <= 64'b0;
|
|
|
|
wstrb_b[7:0] <= 8'b0;
|
|
|
|
end
|
|
|
|
else
|
|
|
|
begin
|
|
|
|
if( ~m_axi_wvalid | w_go )
|
|
|
|
begin
|
|
|
|
if( wvalid_b )
|
|
|
|
begin
|
|
|
|
m_axi_wvalid <= 1'b1;
|
|
|
|
m_axi_wdata[63:0] <= wdata_b[63:0];
|
|
|
|
m_axi_wstrb[7:0] <= wstrb_b[7:0];
|
|
|
|
end
|
|
|
|
else
|
|
|
|
begin
|
2015-05-19 22:08:41 -04:00
|
|
|
m_axi_wvalid <= awvalid_in;
|
2015-04-13 23:35:21 -04:00
|
|
|
m_axi_wdata[63:0] <= wdata_aligned[63:0];
|
|
|
|
m_axi_wstrb[7:0] <= wstrb_aligned[7:0];
|
|
|
|
end
|
|
|
|
end // if ( ~axi_wvalid | w_go )
|
|
|
|
|
2016-01-19 13:25:19 -05:00
|
|
|
if( wr_access & m_axi_wvalid & ~w_go )
|
2015-04-13 23:35:21 -04:00
|
|
|
wvalid_b <= 1'b1;
|
|
|
|
else if( w_go )
|
|
|
|
wvalid_b <= 1'b0;
|
|
|
|
|
2015-05-19 22:08:41 -04:00
|
|
|
if( awvalid_in )
|
2015-04-13 23:35:21 -04:00
|
|
|
begin
|
|
|
|
wdata_b[63:0] <= wdata_aligned[63:0];
|
|
|
|
wstrb_b[7:0] <= wstrb_aligned[7:0];
|
|
|
|
end
|
|
|
|
end // else: !if(~m_axi_aresetn)
|
|
|
|
|
2015-11-25 23:50:29 -05:00
|
|
|
|
2015-05-09 08:56:51 -04:00
|
|
|
//#########################################################################
|
|
|
|
//Read request channel
|
|
|
|
//#########################################################################
|
|
|
|
//1. read request comes in on ar channel
|
|
|
|
//2. use src address to match with writes coming back
|
|
|
|
//3. Assumes in order returns
|
2015-04-20 23:07:13 -04:00
|
|
|
|
2016-01-19 13:25:19 -05:00
|
|
|
assign readinfo_in[40:0] = {rd_srcaddr[31:0],//40:9
|
|
|
|
rd_dstaddr[2:0], //8:6
|
|
|
|
rd_ctrlmode[3:0],//5:2
|
|
|
|
rd_datamode[1:0] //1:0
|
2015-11-25 23:50:29 -05:00
|
|
|
};
|
2015-04-13 23:35:21 -04:00
|
|
|
|
2015-11-09 13:23:40 -05:00
|
|
|
|
2015-11-24 01:12:07 -05:00
|
|
|
//Rest synchronization (for safety, assume incoming reset is async)
|
2015-11-09 13:23:40 -05:00
|
|
|
wire sync_nreset;
|
2015-12-04 03:12:07 -05:00
|
|
|
oh_dsync dsync(.dout (sync_nreset),
|
2015-11-09 13:23:40 -05:00
|
|
|
.clk (m_axi_aclk),
|
|
|
|
.din (m_axi_aresetn)
|
|
|
|
);
|
|
|
|
|
2015-11-25 23:50:29 -05:00
|
|
|
//Synchronous FIFO for read transactions
|
|
|
|
|
2016-01-19 13:25:19 -05:00
|
|
|
oh_fifo_sync #(.DW(104),
|
|
|
|
.DEPTH(32))
|
2015-11-25 23:50:29 -05:00
|
|
|
fifo_async (.full (fifo_full),
|
|
|
|
.prog_full (fifo_prog_full),
|
|
|
|
.dout (packet_out[103:0]),
|
|
|
|
.empty (),
|
|
|
|
// Inputs
|
2016-01-19 13:25:19 -05:00
|
|
|
.nreset (sync_nreset),
|
|
|
|
.clk (m_axi_aclk),
|
2015-11-25 23:50:29 -05:00
|
|
|
.wr_en (fifo_wr_en),
|
|
|
|
.din ({63'b0,readinfo_in[40:0]}),
|
|
|
|
.rd_en (fifo_rd_en)
|
|
|
|
);
|
|
|
|
|
2016-01-19 13:25:19 -05:00
|
|
|
assign rr_datamode_fifo[1:0] = packet_out[1:0];
|
|
|
|
assign rr_ctrlmode_fifo[3:0] = packet_out[5:2];
|
|
|
|
assign rr_alignaddr_fifo[2:0] = packet_out[8:6];
|
|
|
|
assign rr_dstaddr_fifo[31:0] = packet_out[40:9];
|
2015-11-25 23:50:29 -05:00
|
|
|
|
2015-11-24 01:12:07 -05:00
|
|
|
//###################################################################
|
2015-05-09 08:56:51 -04:00
|
|
|
//Read address channel
|
2015-11-24 01:12:07 -05:00
|
|
|
//###################################################################
|
2015-04-13 23:35:21 -04:00
|
|
|
|
2016-01-19 13:25:19 -05:00
|
|
|
assign m_axi_araddr[31:0] = rd_dstaddr[31:0];
|
|
|
|
assign m_axi_arsize[2:0] = {1'b0, rd_datamode[1:0]};
|
2015-11-24 01:12:07 -05:00
|
|
|
assign m_axi_arlen[7:0] = 8'd0;
|
2016-01-19 13:25:19 -05:00
|
|
|
assign m_axi_arvalid = rd_access & ~fifo_prog_full; //BUG& ~rr_wait & ~fifo_prog_full; //remove
|
2015-11-25 21:57:25 -05:00
|
|
|
assign fifo_wr_en = m_axi_arvalid & m_axi_arready ;
|
2016-01-19 13:25:19 -05:00
|
|
|
assign rd_wait = ~m_axi_arready | fifo_prog_full;//BUG| rr_wait
|
|
|
|
assign fifo_rd_en = m_axi_rvalid & m_axi_rready;//BUG & ~rr_wait
|
2015-11-24 01:12:07 -05:00
|
|
|
|
|
|
|
//#################################################################
|
2015-05-09 08:56:51 -04:00
|
|
|
//Read response channel
|
2015-11-24 01:12:07 -05:00
|
|
|
//#################################################################
|
2016-01-19 13:25:19 -05:00
|
|
|
assign m_axi_rready = ~rr_wait; //BUG!: 1'b1
|
2015-11-25 21:57:25 -05:00
|
|
|
|
|
|
|
//Pipeline axi transaction to account for FIFO read latency
|
2015-11-25 23:50:29 -05:00
|
|
|
always @ (posedge m_axi_aclk)
|
2015-11-25 21:57:25 -05:00
|
|
|
if(!m_axi_aresetn)
|
2015-04-13 23:35:21 -04:00
|
|
|
begin
|
2016-01-19 13:25:19 -05:00
|
|
|
rr_access_fifo <= 1'b0;
|
|
|
|
rr_access <= 1'b0;
|
2015-11-25 21:57:25 -05:00
|
|
|
end
|
|
|
|
else
|
|
|
|
begin
|
2016-01-19 13:25:19 -05:00
|
|
|
rr_access_fifo <= fifo_rd_en;
|
|
|
|
rr_access <= rr_access_fifo;
|
2015-11-25 21:57:25 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
//Alignment Mux (one cycle)
|
2015-11-25 23:50:29 -05:00
|
|
|
always @ (posedge m_axi_aclk)
|
|
|
|
begin
|
|
|
|
m_axi_rdata_fifo[63:0] <= m_axi_rdata[63:0];
|
2016-01-20 17:23:09 -05:00
|
|
|
rr_datamode[1:0] <= rr_datamode_fifo[1:0];
|
|
|
|
rr_ctrlmode[3:0] <= rr_ctrlmode_fifo[3:0];
|
|
|
|
rr_dstaddr[31:0] <= rr_dstaddr_fifo[31:0];
|
2015-11-25 23:50:29 -05:00
|
|
|
//all data needs to be right aligned
|
|
|
|
//(this is due to the Epiphany right aligning all words)
|
2016-01-19 13:25:19 -05:00
|
|
|
case(rr_datamode_fifo[1:0])//datamode
|
2015-11-25 23:50:29 -05:00
|
|
|
2'd0: // byte read
|
2016-01-19 13:25:19 -05:00
|
|
|
case(rr_alignaddr_fifo[2:0])
|
|
|
|
3'd0: rr_data[31:0] <= {24'b0,m_axi_rdata_fifo[7:0]};
|
|
|
|
3'd1: rr_data[31:0] <= {24'b0,m_axi_rdata_fifo[15:8]};
|
|
|
|
3'd2: rr_data[31:0] <= {24'b0,m_axi_rdata_fifo[23:16]};
|
|
|
|
3'd3: rr_data[31:0] <= {24'b0,m_axi_rdata_fifo[31:24]};
|
|
|
|
3'd4: rr_data[31:0] <= {24'b0,m_axi_rdata_fifo[39:32]};
|
|
|
|
3'd5: rr_data[31:0] <= {24'b0,m_axi_rdata_fifo[47:40]};
|
|
|
|
3'd6: rr_data[31:0] <= {24'b0,m_axi_rdata_fifo[55:48]};
|
|
|
|
3'd7: rr_data[31:0] <= {24'b0,m_axi_rdata_fifo[63:56]};
|
|
|
|
default: rr_data[31:0] <= {24'b0,m_axi_rdata_fifo[7:0]};
|
2015-11-25 23:50:29 -05:00
|
|
|
endcase
|
|
|
|
2'd1: // 16b hword
|
2016-01-19 13:25:19 -05:00
|
|
|
case(rr_alignaddr_fifo[2:1])
|
|
|
|
2'd0: rr_data[31:0] <= {16'b0,m_axi_rdata_fifo[15:0]};
|
|
|
|
2'd1: rr_data[31:0] <= {16'b0,m_axi_rdata_fifo[31:16]};
|
|
|
|
2'd2: rr_data[31:0] <= {16'b0,m_axi_rdata_fifo[47:32]};
|
|
|
|
2'd3: rr_data[31:0] <= {16'b0,m_axi_rdata_fifo[63:48]};
|
|
|
|
default: rr_data[31:0] <= {16'b0,m_axi_rdata_fifo[15:0]};
|
2015-11-25 23:50:29 -05:00
|
|
|
endcase
|
|
|
|
2'd2: // 32b word
|
|
|
|
begin
|
2016-01-19 13:25:19 -05:00
|
|
|
if(rr_alignaddr_fifo[2])
|
|
|
|
rr_data[31:0] <= m_axi_rdata_fifo[63:32];
|
2015-11-25 23:50:29 -05:00
|
|
|
else
|
2016-01-19 13:25:19 -05:00
|
|
|
rr_data[31:0] <= m_axi_rdata_fifo[31:0];
|
2015-11-25 23:50:29 -05:00
|
|
|
end
|
|
|
|
// 64b word already defined by defaults above
|
|
|
|
2'd3:
|
|
|
|
begin // 64b dword
|
2016-01-19 13:25:19 -05:00
|
|
|
rr_data[31:0] <= m_axi_rdata_fifo[31:0];
|
|
|
|
rr_srcaddr[31:0] <= m_axi_rdata_fifo[63:32];
|
2015-11-25 23:50:29 -05:00
|
|
|
end
|
|
|
|
endcase
|
|
|
|
end // always @ (posedge m_axi_aclk1 )
|
2015-04-13 23:35:21 -04:00
|
|
|
|
2015-05-09 08:56:51 -04:00
|
|
|
endmodule // emaxi
|
|
|
|
// Local Variables:
|
2015-11-09 13:23:40 -05:00
|
|
|
// verilog-library-directories:("." "../../emesh/hdl" "../../memory/hdl" "../../common/hdl" )
|
2015-05-09 08:56:51 -04:00
|
|
|
// End:
|
|
|
|
|