mirror of
https://github.com/aolofsson/oh.git
synced 2025-01-30 02:32:53 +08:00
Cleaning up logic to fit new access/packet interface
(pre-debug)
This commit is contained in:
parent
ab26378a99
commit
eb3051ea93
@ -6,8 +6,7 @@
|
||||
|
||||
module emaxi(/*autoarg*/
|
||||
// Outputs
|
||||
emwr_rd_en, emrq_rd_en, emrr_access, emrr_write, emrr_datamode,
|
||||
emrr_ctrlmode, emrr_dstaddr, emrr_data, emrr_srcaddr, m_axi_awid,
|
||||
rxwr_wait, rxrd_wait, txrr_access, txrr_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,
|
||||
@ -15,52 +14,41 @@ module emaxi(/*autoarg*/
|
||||
m_axi_arsize, m_axi_arburst, m_axi_arlock, m_axi_arcache,
|
||||
m_axi_arprot, m_axi_arqos, m_axi_arvalid, m_axi_rready,
|
||||
// Inputs
|
||||
emwr_access, emwr_write, emwr_datamode, emwr_ctrlmode,
|
||||
emwr_dstaddr, emwr_data, emwr_srcaddr, emrq_access, emrq_write,
|
||||
emrq_datamode, emrq_ctrlmode, emrq_dstaddr, emrq_data,
|
||||
emrq_srcaddr, emrr_progfull, 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
|
||||
rxwr_access, rxwr_packet, rxrd_access, rxrd_packet, txrr_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
|
||||
);
|
||||
|
||||
parameter IDW = 12;
|
||||
|
||||
// fifo read-master port, writes from rx
|
||||
input emwr_access;
|
||||
input emwr_write;
|
||||
input [1:0] emwr_datamode;
|
||||
input [3:0] emwr_ctrlmode;
|
||||
input [31:0] emwr_dstaddr;
|
||||
input [31:0] emwr_data;
|
||||
input [31:0] emwr_srcaddr;
|
||||
output emwr_rd_en; //read ptr update for fifo
|
||||
parameter IDW = 12;
|
||||
parameter PW = 104;
|
||||
parameter AW = 32;
|
||||
parameter DW = 32;
|
||||
|
||||
//########################
|
||||
//ELINK INTERFACE
|
||||
//########################
|
||||
|
||||
|
||||
// fifo read-master port; read requests from rx
|
||||
input emrq_access;
|
||||
input emrq_write;
|
||||
input [1:0] emrq_datamode;
|
||||
input [3:0] emrq_ctrlmode;
|
||||
input [31:0] emrq_dstaddr;
|
||||
input [31:0] emrq_data;
|
||||
input [31:0] emrq_srcaddr;
|
||||
output emrq_rd_en; //read ptr update for fifo
|
||||
//Write request from erx
|
||||
input rxwr_access;
|
||||
input [PW-1:0] rxwr_packet;
|
||||
output rxwr_wait;
|
||||
|
||||
// fifo write-master port; read responses for etx
|
||||
output emrr_access;
|
||||
output emrr_write;
|
||||
output [1:0] emrr_datamode;
|
||||
output [3:0] emrr_ctrlmode;
|
||||
output [31:0] emrr_dstaddr;
|
||||
output [31:0] emrr_data;
|
||||
output [31:0] emrr_srcaddr;
|
||||
input emrr_progfull;
|
||||
|
||||
/*****************************/
|
||||
/*axi */
|
||||
/*****************************/
|
||||
//Read request from erx
|
||||
input rxrd_access;
|
||||
input [PW-1:0] rxrd_packet;
|
||||
output rxrd_wait;
|
||||
|
||||
//Read respoonse for etx
|
||||
output txrr_access;
|
||||
output [PW-1:0] txrr_packet;
|
||||
input txrr_wait;
|
||||
|
||||
//########################
|
||||
//AXI MASTER INTERFACE
|
||||
//########################
|
||||
|
||||
input m_axi_aclk; // global clock signal.
|
||||
input m_axi_aresetn; // global reset singal.
|
||||
|
||||
@ -112,58 +100,125 @@ module emaxi(/*autoarg*/
|
||||
input m_axi_rvalid; // signaling the required read data
|
||||
output m_axi_rready; // master can accept the readback data
|
||||
|
||||
//registers
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
reg emrr_access;
|
||||
reg emrr_access_reg;
|
||||
reg [31:0] emrr_data;
|
||||
reg [31:0] emrr_srcaddr;
|
||||
//#########################################################################
|
||||
//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;
|
||||
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;
|
||||
|
||||
reg txrr_access;
|
||||
reg txrr_access_reg;
|
||||
reg [31:0] txrr_data;
|
||||
reg [31:0] txrr_srcaddr;
|
||||
|
||||
//wires
|
||||
wire aw_go;
|
||||
wire w_go;
|
||||
wire readinfo_wren;
|
||||
wire readinfo_rden;
|
||||
wire readinfo_full;
|
||||
wire [47:0] readinfo_out;
|
||||
wire [47:0] readinfo_in;
|
||||
wire aw_go;
|
||||
wire w_go;
|
||||
wire readinfo_wren;
|
||||
wire readinfo_rden;
|
||||
wire readinfo_full;
|
||||
wire [47:0] readinfo_out;
|
||||
wire [47:0] readinfo_in;
|
||||
|
||||
//i/o connections. write address (aw)
|
||||
assign m_axi_awburst[1:0] = 2'b01;
|
||||
|
||||
wire [1:0] rxwr_datamode;
|
||||
wire [AW-1:0] rxwr_dstaddr;
|
||||
wire [DW-1:0] rxwr_data;
|
||||
wire [AW-1:0] rxwr_srcaddr;
|
||||
|
||||
wire [1:0] rxrd_datamode;
|
||||
wire [3:0] rxrd_ctrlmode;
|
||||
wire [AW-1:0] rxrd_dstaddr;
|
||||
wire [AW-1:0] rxrd_srcaddr;
|
||||
|
||||
wire [1:0] txrr_datamode;
|
||||
wire [3:0] txrr_ctrlmode;
|
||||
wire [31:0] txrr_dstaddr;
|
||||
|
||||
//#########################################################################
|
||||
//EMESH 2 PACKET CONVERSION
|
||||
//#########################################################################
|
||||
|
||||
//RXWR
|
||||
packet2emesh p2e_rxwr (
|
||||
// Outputs
|
||||
.access_out (),
|
||||
.write_out (),
|
||||
.datamode_out (rxwr_datamode[1:0]),
|
||||
.ctrlmode_out (),
|
||||
.dstaddr_out (rxwr_dstaddr[AW-1:0]),
|
||||
.data_out (rxwr_data[DW-1:0]),
|
||||
.srcaddr_out (rxwr_srcaddr[AW-1:0]),
|
||||
// Inputs
|
||||
.packet_in (rxwr_packet[PW-1:0])
|
||||
);
|
||||
|
||||
//RXRD
|
||||
packet2emesh p2e_rxrd (
|
||||
// Outputs
|
||||
.access_out (),
|
||||
.write_out (),
|
||||
.datamode_out (rxrd_datamode[1:0]),
|
||||
.ctrlmode_out (rxrd_ctrlmode[3:0]),
|
||||
.dstaddr_out (rxrd_dstaddr[AW-1:0]),
|
||||
.data_out (),
|
||||
.srcaddr_out (rxrd_srcaddr[AW-1:0]),
|
||||
// Inputs
|
||||
.packet_in (rxrd_packet[PW-1:0])
|
||||
);
|
||||
|
||||
//TXRR
|
||||
emesh2packet e2p (
|
||||
// Outputs
|
||||
.packet_out (txrr_packet[PW-1:0]),
|
||||
// Inputs
|
||||
.access_in (txrr_access),
|
||||
.write_in (txrr_write),
|
||||
.datamode_in (txrr_datamode[1:0]),
|
||||
.ctrlmode_in (txrr_ctrlmode[3:0]),
|
||||
.dstaddr_in (txrr_dstaddr[AW-1:0]),
|
||||
.data_in (txrr_data[DW-1:0]),
|
||||
.srcaddr_in (txrr_srcaddr[AW-1:0])
|
||||
);
|
||||
|
||||
//#########################################################################
|
||||
//AXI unimplemented constants
|
||||
//#########################################################################
|
||||
|
||||
assign m_axi_awburst[1:0] = 2'b01; //TODO???
|
||||
assign m_axi_awcache[3:0] = 4'b0010;//TODO??update value to 4'b0011 if coherent accesses to be used via the zynq acp port
|
||||
assign m_axi_awprot[2:0] = 3'h0;
|
||||
assign m_axi_awqos[3:0] = 4'h0;
|
||||
assign m_axi_bready = 1'b1; //TODO? axi_bready, why constant
|
||||
|
||||
assign m_axi_arburst[1:0] = 2'b01;
|
||||
assign m_axi_arburst[1:0] = 2'b01;//TODO???
|
||||
assign m_axi_arcache[3:0] = 4'b0010;
|
||||
assign m_axi_arprot[2:0] = 3'h0;
|
||||
assign m_axi_arqos[3:0] = 4'h0;
|
||||
|
||||
//--------------------
|
||||
//write address channel
|
||||
//--------------------
|
||||
//#########################################################################
|
||||
//Write address channel
|
||||
//#########################################################################
|
||||
|
||||
assign aw_go = m_axi_awvalid & m_axi_awready;
|
||||
assign w_go = m_axi_wvalid & m_axi_wready;
|
||||
assign emwr_rd_en = ( emwr_access & ~awvalid_b & ~wvalid_b);
|
||||
assign w_go = m_axi_wvalid & m_axi_wready;
|
||||
assign rxwr_wait = awvalid_b | wvalid_b;
|
||||
|
||||
// generate write-address signals
|
||||
always @( posedge m_axi_aclk )
|
||||
@ -173,10 +228,7 @@ module emaxi(/*autoarg*/
|
||||
m_axi_awaddr[31:0] <= 32'd0;
|
||||
m_axi_awlen[7:0] <= 8'd0;
|
||||
m_axi_awsize[2:0] <= 3'd0;
|
||||
awvalid_b <= 1'b0;
|
||||
awaddr_b[31:0] <= 32'd0;
|
||||
awlen_b[7:0] <= 8'd0;
|
||||
awsize_b[2:0] <= 3'd0;
|
||||
|
||||
end
|
||||
else
|
||||
begin
|
||||
@ -191,47 +243,43 @@ module emaxi(/*autoarg*/
|
||||
end
|
||||
else
|
||||
begin
|
||||
m_axi_awvalid <= emwr_rd_en;
|
||||
m_axi_awaddr[31:0] <= emwr_dstaddr[31:0];
|
||||
m_axi_awvalid <= rxwr_access;
|
||||
m_axi_awaddr[31:0] <= rxwr_dstaddr[31:0];
|
||||
m_axi_awlen[7:0] <= 8'b0;
|
||||
m_axi_awsize[2:0] <= { 1'b0, emwr_datamode[1:0]};
|
||||
m_axi_awsize[2:0] <= { 1'b0, rxwr_datamode[1:0]};
|
||||
end
|
||||
end
|
||||
if( emwr_rd_en & m_axi_awvalid & ~aw_go )
|
||||
if( rxwr_access & m_axi_awvalid & ~aw_go )
|
||||
awvalid_b <= 1'b1;
|
||||
else if( aw_go )
|
||||
awvalid_b <= 1'b0;
|
||||
|
||||
//Pipeline stage
|
||||
if( emwr_rd_en )
|
||||
if( rxwr_access )
|
||||
begin
|
||||
awaddr_b[31:0] <= emwr_dstaddr[31:0];
|
||||
awaddr_b[31:0] <= rxwr_dstaddr[31:0];
|
||||
awlen_b[7:0] <= 8'b0;
|
||||
awsize_b[2:0] <= { 1'b0, emwr_datamode[1:0] };
|
||||
awsize_b[2:0] <= { 1'b0, rxwr_datamode[1:0] };
|
||||
end
|
||||
end // else: !if(~m_axi_aresetn)
|
||||
|
||||
|
||||
|
||||
//--------------------
|
||||
//write alignment circuit
|
||||
//--------------------
|
||||
|
||||
//#########################################################################
|
||||
//Write data alignment circuit
|
||||
//#########################################################################
|
||||
|
||||
always @*
|
||||
case( emwr_datamode[1:0] )
|
||||
2'd0: wdata_aligned[63:0] = { 8{emwr_data[7:0]}};
|
||||
2'd1: wdata_aligned[63:0] = { 4{emwr_data[15:0]}};
|
||||
2'd2: wdata_aligned[63:0] = { 2{emwr_data[31:0]}};
|
||||
default: wdata_aligned[63:0] = { emwr_srcaddr[31:0], emwr_data[31:0]};
|
||||
case( rxwr_datamode[1:0] )
|
||||
2'd0: wdata_aligned[63:0] = { 8{rxwr_data[7:0]}};
|
||||
2'd1: wdata_aligned[63:0] = { 4{rxwr_data[15:0]}};
|
||||
2'd2: wdata_aligned[63:0] = { 2{rxwr_data[31:0]}};
|
||||
default: wdata_aligned[63:0] = { rxwr_srcaddr[31:0], rxwr_data[31:0]};
|
||||
endcase
|
||||
|
||||
//TODO: Simplify logic below!!!!!
|
||||
//Should include separate fields for address/data/datamode!!!!
|
||||
always @*
|
||||
begin
|
||||
case(emwr_datamode[1:0])
|
||||
case(rxwr_datamode[1:0])
|
||||
2'd0: // byte
|
||||
case(emwr_dstaddr[2:0])
|
||||
case(rxwr_dstaddr[2:0])
|
||||
3'd0: wstrb_aligned[7:0] = 8'h01;
|
||||
3'd1: wstrb_aligned[7:0] = 8'h02;
|
||||
3'd2: wstrb_aligned[7:0] = 8'h04;
|
||||
@ -242,14 +290,14 @@ module emaxi(/*autoarg*/
|
||||
default: wstrb_aligned[7:0] = 8'h80;
|
||||
endcase
|
||||
2'd1: // 16b hword
|
||||
case(emwr_dstaddr[2:1])
|
||||
case(rxwr_dstaddr[2:1])
|
||||
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
|
||||
if(emwr_dstaddr[2])
|
||||
if(rxwr_dstaddr[2])
|
||||
wstrb_aligned[7:0] = 8'hf0;
|
||||
else
|
||||
wstrb_aligned[7:0] = 8'h0f;
|
||||
@ -257,15 +305,18 @@ module emaxi(/*autoarg*/
|
||||
wstrb_aligned[7:0] = 8'hff;
|
||||
endcase // case (emwr_datamode[1:0])
|
||||
end // always @ *
|
||||
|
||||
// generate the write-data signals
|
||||
|
||||
//#########################################################################
|
||||
//Write data channel
|
||||
//#########################################################################
|
||||
|
||||
always @ (posedge m_axi_aclk )
|
||||
if(~m_axi_aresetn)
|
||||
begin
|
||||
m_axi_wvalid <= 1'b0;
|
||||
m_axi_wdata[63:0] <= 64'b0;
|
||||
m_axi_wstrb[7:0] <= 8'b0;
|
||||
m_axi_wlast <= 1'b1; // todo: no bursts for now?
|
||||
m_axi_wlast <= 1'b1; // TODO: no bursts for now?
|
||||
wvalid_b <= 1'b0;
|
||||
wdata_b[63:0] <= 64'b0;
|
||||
wstrb_b[7:0] <= 8'b0;
|
||||
@ -282,40 +333,38 @@ module emaxi(/*autoarg*/
|
||||
end
|
||||
else
|
||||
begin
|
||||
m_axi_wvalid <= emwr_rd_en;//todo
|
||||
m_axi_wvalid <= rxwr_access;
|
||||
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 )
|
||||
|
||||
if( emwr_rd_en & m_axi_wvalid & ~w_go )
|
||||
if( rxwr_access & m_axi_wvalid & ~w_go )
|
||||
wvalid_b <= 1'b1;
|
||||
else if( w_go )
|
||||
wvalid_b <= 1'b0;
|
||||
|
||||
if( emwr_rd_en )
|
||||
if( rxwr_access )
|
||||
begin
|
||||
wdata_b[63:0] <= wdata_aligned[63:0];
|
||||
wstrb_b[7:0] <= wstrb_aligned[7:0];
|
||||
end
|
||||
end // else: !if(~m_axi_aresetn)
|
||||
|
||||
//----------------------------
|
||||
// read handler
|
||||
// elink read requests generate a transaction on the ar channel,
|
||||
// buffer the src info to generate an elink write when the
|
||||
// read data comes back.
|
||||
//----------------------------
|
||||
|
||||
//TODO: Can we improve this??
|
||||
//#########################################################################
|
||||
//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
|
||||
|
||||
assign readinfo_in[47:0] =
|
||||
{
|
||||
7'b0,
|
||||
emrq_srcaddr[31:0],//40:9
|
||||
emrq_dstaddr[2:0], //8:6
|
||||
emrq_ctrlmode[3:0], //5:2
|
||||
emrq_datamode[1:0]
|
||||
rxrd_srcaddr[31:0],//40:9
|
||||
rxrd_dstaddr[2:0], //8:6
|
||||
rxrd_ctrlmode[3:0], //5:2
|
||||
rxrd_datamode[1:0]
|
||||
};
|
||||
|
||||
fifo_sync
|
||||
@ -333,82 +382,87 @@ module emaxi(/*autoarg*/
|
||||
.clk (m_axi_aclk),
|
||||
.reset (~m_axi_aresetn),
|
||||
.wr_data (readinfo_in[47:0]),
|
||||
.wr_en (emrq_rd_en),
|
||||
.rd_en (readinfo_rden));
|
||||
.wr_en (rxrd_access & ~readinfo_full),
|
||||
.rd_en (~txrr_wait & m_axi_rvalid)
|
||||
);
|
||||
|
||||
assign emrr_datamode[1:0] = readinfo_out[1:0];
|
||||
assign emrr_ctrlmode[3:0] = readinfo_out[5:2];
|
||||
assign emrr_dstaddr[31:0] = readinfo_out[40:9];
|
||||
|
||||
//----------------------------
|
||||
// read address channel
|
||||
//----------------------------
|
||||
|
||||
|
||||
assign m_axi_araddr[31:0] = emrq_dstaddr[31:0];
|
||||
assign m_axi_arsize[2:0] = {1'b0, emrq_datamode[1:0]};
|
||||
assign m_axi_arlen[7:0] = 8'd0;
|
||||
assign m_axi_arvalid = emrq_access & ~readinfo_full;
|
||||
assign emrq_rd_en = m_axi_arvalid & m_axi_arready;
|
||||
assign txrr_datamode[1:0] = readinfo_out[1:0];
|
||||
assign txrr_ctrlmode[3:0] = readinfo_out[5:2];
|
||||
assign txrr_dstaddr[31:0] = readinfo_out[40:9];
|
||||
|
||||
//#########################################################################
|
||||
//Read address channel
|
||||
//#########################################################################
|
||||
|
||||
//--------------------------------
|
||||
// read data (and response) channel
|
||||
//--------------------------------
|
||||
assign m_axi_araddr[31:0] = rxrd_dstaddr[31:0];
|
||||
assign m_axi_arsize[2:0] = {1'b0, rxrd_datamode[1:0]};
|
||||
assign m_axi_arlen[7:0] = 8'd0;
|
||||
assign m_axi_arvalid = rxrd_access & ~readinfo_full;
|
||||
assign rxrd_wait = ~(m_axi_arvalid & m_axi_arready);
|
||||
|
||||
assign m_axi_rready = ~emrr_progfull;
|
||||
assign readinfo_rden = ~emrr_progfull & m_axi_rvalid;
|
||||
//#########################################################################
|
||||
//Read response channel
|
||||
//#########################################################################
|
||||
|
||||
assign m_axi_rready = ~txrr_wait;
|
||||
assign readinfo_rden = ~txrr_wait & m_axi_rvalid;
|
||||
|
||||
assign emrr_write = 1'b1;
|
||||
assign txrr_write = 1'b1;
|
||||
|
||||
always @( posedge m_axi_aclk )
|
||||
if( ~m_axi_aresetn )
|
||||
begin
|
||||
emrr_data[31:0] <= 32'b0;
|
||||
emrr_srcaddr[31:0] <= 32'b0;
|
||||
emrr_access_reg <= 1'b0;
|
||||
emrr_access <= 1'b0;
|
||||
txrr_data[31:0] <= 32'b0;
|
||||
txrr_srcaddr[31:0] <= 32'b0;
|
||||
txrr_access_reg <= 1'b0;
|
||||
txrr_access <= 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
emrr_access_reg <= m_axi_rready & m_axi_rvalid;
|
||||
emrr_access <= emrr_access_reg;//added pipeline stage for data
|
||||
emrr_srcaddr[31:0] <= m_axi_rdata[63:32];
|
||||
txrr_access_reg <= m_axi_rready & m_axi_rvalid;
|
||||
txrr_access <= txrr_access_reg;//added pipeline stage for data
|
||||
txrr_srcaddr[31:0] <= m_axi_rdata[63:32];
|
||||
// steer read data according to size & host address lsbs
|
||||
//all data needs to be right aligned
|
||||
//(this is due to the Epiphany right aligning all words)
|
||||
case(readinfo_out[1:0])//datamode
|
||||
2'd0: // byte read
|
||||
case(readinfo_out[8:6])
|
||||
3'd0: emrr_data[7:0] <= m_axi_rdata[7:0];
|
||||
3'd1: emrr_data[7:0] <= m_axi_rdata[15:8];
|
||||
3'd2: emrr_data[7:0] <= m_axi_rdata[23:16];
|
||||
3'd3: emrr_data[7:0] <= m_axi_rdata[31:24];
|
||||
3'd4: emrr_data[7:0] <= m_axi_rdata[39:32];
|
||||
3'd5: emrr_data[7:0] <= m_axi_rdata[47:40];
|
||||
3'd6: emrr_data[7:0] <= m_axi_rdata[55:48];
|
||||
default: emrr_data[7:0] <= m_axi_rdata[63:56];
|
||||
3'd0: txrr_data[7:0] <= m_axi_rdata[7:0];
|
||||
3'd1: txrr_data[7:0] <= m_axi_rdata[15:8];
|
||||
3'd2: txrr_data[7:0] <= m_axi_rdata[23:16];
|
||||
3'd3: txrr_data[7:0] <= m_axi_rdata[31:24];
|
||||
3'd4: txrr_data[7:0] <= m_axi_rdata[39:32];
|
||||
3'd5: txrr_data[7:0] <= m_axi_rdata[47:40];
|
||||
3'd6: txrr_data[7:0] <= m_axi_rdata[55:48];
|
||||
default: txrr_data[7:0] <= m_axi_rdata[63:56];
|
||||
endcase
|
||||
2'd1: // 16b hword
|
||||
case( readinfo_out[8:7] )
|
||||
2'd0: emrr_data[15:0] <= m_axi_rdata[15:0];
|
||||
2'd1: emrr_data[15:0] <= m_axi_rdata[31:16];
|
||||
2'd2: emrr_data[15:0] <= m_axi_rdata[47:32];
|
||||
default: emrr_data[15:0] <= m_axi_rdata[63:48];
|
||||
2'd0: txrr_data[15:0] <= m_axi_rdata[15:0];
|
||||
2'd1: txrr_data[15:0] <= m_axi_rdata[31:16];
|
||||
2'd2: txrr_data[15:0] <= m_axi_rdata[47:32];
|
||||
default: txrr_data[15:0] <= m_axi_rdata[63:48];
|
||||
endcase
|
||||
2'd2: // 32b word
|
||||
if( readinfo_out[8] )
|
||||
emrr_data[31:0] <= m_axi_rdata[63:32];
|
||||
txrr_data[31:0] <= m_axi_rdata[63:32];
|
||||
else
|
||||
emrr_data[31:0] <= m_axi_rdata[31:0];
|
||||
txrr_data[31:0] <= m_axi_rdata[31:0];
|
||||
// 64b word already defined by defaults above
|
||||
2'd3: begin // 64b dword
|
||||
emrr_data[31:0] <= m_axi_rdata[31:0];
|
||||
|
||||
txrr_data[31:0] <= m_axi_rdata[31:0];
|
||||
end
|
||||
endcase
|
||||
end // else: !if( ~m_axi_aresetn )
|
||||
|
||||
endmodule
|
||||
endmodule // emaxi
|
||||
// Local Variables:
|
||||
// verilog-library-directories:("." "../../emesh/hdl" "../../memory/hdl")
|
||||
// End:
|
||||
|
||||
/*
|
||||
copyright (c) 2014 adapteva, inc.
|
||||
contributed by fred huettig <fred@adapteva.com>
|
||||
|
@ -1,86 +1,48 @@
|
||||
module esaxi (/*autoarg*/
|
||||
// Outputs
|
||||
emwr_access, emwr_write, emwr_datamode, emwr_ctrlmode,
|
||||
emwr_dstaddr, emwr_data, emwr_srcaddr, emrq_access, emrq_write,
|
||||
emrq_datamode, emrq_ctrlmode, emrq_dstaddr, emrq_data,
|
||||
emrq_srcaddr, emrr_rd_en, mi_clk, mi_rx_emmu_sel, mi_tx_emmu_sel,
|
||||
mi_ecfg_sel, mi_embox_sel, mi_we, mi_addr, mi_din, s_axi_arready,
|
||||
s_axi_awready, s_axi_bid, s_axi_bresp, s_axi_bvalid, s_axi_rid,
|
||||
s_axi_rdata, s_axi_rlast, s_axi_rresp, s_axi_rvalid, s_axi_wready,
|
||||
txwr_access, txwr_packet, txrd_access, txrd_packet, rxrr_wait,
|
||||
s_axi_arready, s_axi_awready, s_axi_bid, s_axi_bresp, s_axi_bvalid,
|
||||
s_axi_rid, s_axi_rdata, s_axi_rlast, s_axi_rresp, s_axi_rvalid,
|
||||
s_axi_wready,
|
||||
// Inputs
|
||||
emwr_progfull, emrq_progfull, emrr_data, emrr_access, mi_ecfg_dout,
|
||||
mi_tx_emmu_dout, mi_rx_emmu_dout, mi_embox_dout, ecfg_tx_ctrlmode,
|
||||
ecfg_coreid, ecfg_timeout_enable, s_axi_aclk, s_axi_aresetn,
|
||||
s_axi_arid, s_axi_araddr, s_axi_arburst, s_axi_arcache,
|
||||
s_axi_arlock, s_axi_arlen, s_axi_arprot, s_axi_arqos, s_axi_arsize,
|
||||
s_axi_arvalid, s_axi_awid, s_axi_awaddr, s_axi_awburst,
|
||||
s_axi_awcache, s_axi_awlock, s_axi_awlen, s_axi_awprot,
|
||||
s_axi_awqos, s_axi_awsize, s_axi_awvalid, s_axi_bready,
|
||||
s_axi_rready, s_axi_wid, s_axi_wdata, s_axi_wlast, s_axi_wstrb,
|
||||
s_axi_wvalid
|
||||
txwr_wait, txrd_wait, rxrr_access, rxrr_packet, s_axi_aclk,
|
||||
s_axi_aresetn, s_axi_arid, s_axi_araddr, s_axi_arburst,
|
||||
s_axi_arcache, s_axi_arlock, s_axi_arlen, s_axi_arprot,
|
||||
s_axi_arqos, s_axi_arsize, s_axi_arvalid, s_axi_awid, s_axi_awaddr,
|
||||
s_axi_awburst, s_axi_awcache, s_axi_awlock, s_axi_awlen,
|
||||
s_axi_awprot, s_axi_awqos, s_axi_awsize, s_axi_awvalid,
|
||||
s_axi_bready, s_axi_rready, s_axi_wid, s_axi_wdata, s_axi_wlast,
|
||||
s_axi_wstrb, s_axi_wvalid
|
||||
);
|
||||
|
||||
parameter [11:0] c_read_tag_addr = 12'h810;//emesh srcaddr tag
|
||||
parameter integer c_s_axi_addr_width = 30; //address width
|
||||
parameter [11:0] ELINKID = 12'h810;
|
||||
|
||||
parameter [11:0] ID = 12'h810;
|
||||
parameter IDW = 12;
|
||||
parameter PW = 104;
|
||||
parameter [15:0] RETURN_ADDR = {ID,4'hE};
|
||||
parameter AW = 32;
|
||||
parameter DW = 32;
|
||||
|
||||
/*****************************/
|
||||
/*Write request for TX fifo */
|
||||
/*****************************/
|
||||
output emwr_access;
|
||||
output emwr_write;
|
||||
output [1:0] emwr_datamode;
|
||||
output [3:0] emwr_ctrlmode;
|
||||
output [31:0] emwr_dstaddr;
|
||||
output [31:0] emwr_data;
|
||||
output [31:0] emwr_srcaddr;
|
||||
input emwr_progfull;
|
||||
output txwr_access;
|
||||
output [PW-1:0] txwr_packet;
|
||||
input txwr_wait;
|
||||
|
||||
/*****************************/
|
||||
/*Read request for TX fifo */
|
||||
/*****************************/
|
||||
output emrq_access;
|
||||
output emrq_write;
|
||||
output [1:0] emrq_datamode;
|
||||
output [3:0] emrq_ctrlmode;
|
||||
output [31:0] emrq_dstaddr;
|
||||
output [31:0] emrq_data;
|
||||
output [31:0] emrq_srcaddr;
|
||||
input emrq_progfull; //TODO? used for?
|
||||
output txrd_access;
|
||||
output [PW-1:0] txrd_packet;
|
||||
input txrd_wait;
|
||||
|
||||
/*****************************/
|
||||
/*Read response from RX fifo */
|
||||
/*****************************/
|
||||
//Only data needed
|
||||
input [31:0] emrr_data;
|
||||
input emrr_access;
|
||||
output emrr_rd_en; //update read fifo
|
||||
|
||||
|
||||
/*****************************/
|
||||
/*Register RD/WR Interface */
|
||||
/*****************************/
|
||||
output mi_clk;
|
||||
output mi_rx_emmu_sel;
|
||||
output mi_tx_emmu_sel;
|
||||
output mi_ecfg_sel;
|
||||
output mi_embox_sel;
|
||||
output mi_we;
|
||||
output [19:0] mi_addr;
|
||||
output [31:0] mi_din;
|
||||
input [31:0] mi_ecfg_dout;
|
||||
input [31:0] mi_tx_emmu_dout;
|
||||
input [31:0] mi_rx_emmu_dout;
|
||||
input [31:0] mi_embox_dout;
|
||||
|
||||
/*****************************/
|
||||
/*Config Settings */
|
||||
/*****************************/
|
||||
input [3:0] ecfg_tx_ctrlmode;
|
||||
input [11:0] ecfg_coreid;
|
||||
input ecfg_timeout_enable;
|
||||
|
||||
input rxrr_access;
|
||||
input [PW-1:0] rxrr_packet;
|
||||
output rxrr_wait;
|
||||
|
||||
/*****************************/
|
||||
/*AXI slave interface */
|
||||
/*****************************/
|
||||
@ -135,19 +97,17 @@ module esaxi (/*autoarg*/
|
||||
input [3:0] s_axi_wstrb;
|
||||
input s_axi_wvalid;
|
||||
output s_axi_wready;
|
||||
|
||||
/*-------------------------BODY----------------------------------*/
|
||||
|
||||
//###################################################
|
||||
//#WIRE/REG DECLARATIONS
|
||||
//###################################################
|
||||
|
||||
reg s_axi_awready;
|
||||
reg s_axi_wready;
|
||||
reg s_axi_bvalid;
|
||||
reg [1:0] s_axi_bresp;
|
||||
reg s_axi_arready;
|
||||
|
||||
reg [31:0] emwr_data_reg;
|
||||
reg [31:0] emwr_dstaddr_reg;
|
||||
reg [3:0] emwr_ctrlmode_reg;
|
||||
reg [1:0] emwr_datamode_reg;
|
||||
|
||||
reg [31:0] axi_awaddr; // 32b for epiphany addr
|
||||
reg [1:0] axi_awburst;
|
||||
reg [2:0] axi_awsize;
|
||||
@ -167,47 +127,75 @@ module esaxi (/*autoarg*/
|
||||
reg write_active;
|
||||
reg b_wait; // waiting to issue write response (unlikely?)
|
||||
|
||||
reg emwr_access_all;
|
||||
reg [3:0] emwr_ctrlmode;
|
||||
reg [1:0] emwr_datamode;
|
||||
reg [31:0] emwr_dstaddr;
|
||||
reg [31:0] emwr_data;
|
||||
reg [31:0] emwr_srcaddr; //upper 32 bits in case 64 bit writes are supported
|
||||
reg txwr_access;
|
||||
reg [1:0] txwr_datamode;
|
||||
reg [31:0] txwr_dstaddr;
|
||||
reg [31:0] txwr_data;
|
||||
|
||||
reg emrq_access_all;
|
||||
reg [3:0] emrq_ctrlmode;
|
||||
reg [1:0] emrq_datamode;
|
||||
reg [31:0] emrq_dstaddr;
|
||||
reg [31:0] emrq_srcaddr; //upper 32 bits in case 64 bit writes are supported
|
||||
reg [31:0] txwr_data_reg;
|
||||
reg [31:0] txwr_dstaddr_reg;
|
||||
reg [1:0] txwr_datamode_reg;
|
||||
|
||||
reg pre_wr_en; // delay for data alignment
|
||||
reg txrd_access;
|
||||
reg [1:0] txrd_datamode;
|
||||
reg [31:0] txrd_dstaddr;
|
||||
reg [31:0] txrd_srcaddr; //read reaspne address
|
||||
|
||||
reg pre_wr_en; // delay for data alignment
|
||||
|
||||
reg ractive_reg; // need leading edge of active for 1st req
|
||||
reg rnext;
|
||||
|
||||
reg mi_rx_emmu_reg;
|
||||
reg mi_tx_emmu_reg;
|
||||
reg mi_ecfg_reg;
|
||||
reg mi_embox_reg;
|
||||
reg mi_rd_reg;
|
||||
|
||||
wire last_wr_beat;
|
||||
wire last_rd_beat;
|
||||
wire mi_wr;
|
||||
wire mi_rd;
|
||||
wire mi_we;
|
||||
wire mi_en;
|
||||
wire [31:0] mi_dout;
|
||||
wire mi_sel;
|
||||
wire [31:0] emrr_mux_data;
|
||||
|
||||
wire [31:0] rxrr_mux_data;
|
||||
wire [DW-1:0] rxrr_data;
|
||||
|
||||
//local parameter for addressing 32 bit / 64 bit c_s_axi_data_width
|
||||
//addr_lsb is used for addressing 32/64 bit registers/memories
|
||||
//addr_lsb = 2 for 32 bits (n downto 2)
|
||||
//addr_lsb = 3 for 64 bits (n downto 3)
|
||||
//TODO? Do we really need this?
|
||||
localparam integer addr_lsb = 2;
|
||||
wire [11:0] elinkid=ELINKID;
|
||||
//###################################################
|
||||
//#PACKET TO MESH
|
||||
//###################################################
|
||||
|
||||
//TXWR
|
||||
emesh2packet e2p_txwr (
|
||||
// Outputs
|
||||
.packet_out (txwr_packet[PW-1:0]),
|
||||
// Inputs
|
||||
.access_in (txwr_access),
|
||||
.write_in (1'b1),
|
||||
.datamode_in (txwr_datamode[1:0]),
|
||||
.ctrlmode_in (4'b0),
|
||||
.dstaddr_in (txwr_dstaddr[AW-1:0]),
|
||||
.data_in (txwr_data[DW-1:0]),
|
||||
.srcaddr_in (32'b0)//only 32b slave write supported
|
||||
);
|
||||
|
||||
//TXRD
|
||||
emesh2packet e2p_txrd (
|
||||
// Outputs
|
||||
.packet_out (txrd_packet[PW-1:0]),
|
||||
// Inputs
|
||||
.access_in (txrd_access),
|
||||
.write_in (txrd_write),
|
||||
.datamode_in (txrd_datamode[1:0]),
|
||||
.ctrlmode_in (4'b0),
|
||||
.dstaddr_in (txrd_dstaddr[AW-1:0]),
|
||||
.data_in (32'b0),
|
||||
.srcaddr_in (txrd_srcaddr[AW-1:0])
|
||||
);
|
||||
//RXRR
|
||||
packet2emesh p2e_rxrr (
|
||||
// Outputs
|
||||
.access_out (),
|
||||
.write_out (),
|
||||
.datamode_out (),
|
||||
.ctrlmode_out (),
|
||||
.dstaddr_out (),
|
||||
.data_out (rxrr_data[DW-1:0]),
|
||||
.srcaddr_out (),
|
||||
// Inputs
|
||||
.packet_in (rxrr_packet[PW-1:0])
|
||||
);
|
||||
|
||||
//###################################################
|
||||
//#WRITE ADDRESS CHANNEL
|
||||
@ -243,7 +231,6 @@ module esaxi (/*autoarg*/
|
||||
end // else: !if(~s_axi_aresetn)
|
||||
end // always @ (posedge s_axi_aclk )
|
||||
|
||||
|
||||
// capture address & other aw info, update address during cycle
|
||||
always @( posedge s_axi_aclk )
|
||||
if (~s_axi_aresetn)
|
||||
@ -260,23 +247,20 @@ module esaxi (/*autoarg*/
|
||||
axi_awaddr[31:0] <= s_axi_awaddr[31:0];
|
||||
axi_awsize <= s_axi_awsize; // 0=byte, 1=16b, 2=32b
|
||||
axi_awburst <= s_axi_awburst; // type, 0=fixed, 1=incr, 2=wrap
|
||||
|
||||
end
|
||||
else if( s_axi_wvalid & s_axi_wready )
|
||||
if( axi_awburst == 2'b01 )
|
||||
begin //incremental burst
|
||||
// the write address for all the beats in the transaction are increments by the data width.
|
||||
// note: this should be based on awsize instead to support narrow bursts, i think.
|
||||
//TODO: BUG!!
|
||||
axi_awaddr[31:addr_lsb] <= axi_awaddr[31:addr_lsb] + 30'd1;
|
||||
//awaddr alignedto data width
|
||||
axi_awaddr[addr_lsb-1:0] <= {addr_lsb{1'b0}};
|
||||
end // both fixed & wrapping types are treated as fixed, no update.
|
||||
begin //incremental burst
|
||||
// the write address for all the beats in the transaction are increments by the data width.
|
||||
// note: this should be based on awsize instead to support narrow bursts, i think.
|
||||
axi_awaddr[31:2] <= axi_awaddr[31:2] + 30'd1;
|
||||
//awaddr alignedto data width
|
||||
axi_awaddr[1:0] <= 2'b0;
|
||||
end // both fixed & wrapping types are treated as fixed, no update.
|
||||
end // else: !if(~s_axi_aresetn)
|
||||
|
||||
|
||||
//###################################################
|
||||
//#WRITE CHANNEL
|
||||
//#WRITE RESPONSE CHANNEL
|
||||
//###################################################
|
||||
always @ (posedge s_axi_aclk)
|
||||
if(~s_axi_aresetn)
|
||||
@ -286,13 +270,9 @@ module esaxi (/*autoarg*/
|
||||
if( last_wr_beat )
|
||||
s_axi_wready <= 1'b0;
|
||||
else if( write_active )
|
||||
s_axi_wready <= ~emwr_progfull;
|
||||
s_axi_wready <= ~txwr_wait;
|
||||
end
|
||||
|
||||
// implement write response logic generation
|
||||
// the write response and response valid signals are asserted by the slave
|
||||
// at the end of each transaction, burst or single.
|
||||
|
||||
always @( posedge s_axi_aclk )
|
||||
if (~s_axi_aresetn)
|
||||
begin
|
||||
@ -305,7 +285,7 @@ module esaxi (/*autoarg*/
|
||||
if( last_wr_beat )
|
||||
begin
|
||||
s_axi_bvalid <= 1'b1;
|
||||
s_axi_bresp[1:0] <= 2'b0; // 'okay' response
|
||||
s_axi_bresp[1:0] <= 2'b0; // 'okay' response
|
||||
b_wait <= ~s_axi_bready; // note: assumes bready will not drop without valid?
|
||||
end
|
||||
else if (s_axi_bready & s_axi_bvalid)
|
||||
@ -315,13 +295,11 @@ module esaxi (/*autoarg*/
|
||||
end
|
||||
end // else: !if( s_axi_aresetn == 1'b0 )
|
||||
|
||||
|
||||
|
||||
//###################################################
|
||||
//#READ REQUEST CHANNEL
|
||||
//###################################################
|
||||
|
||||
assign last_rd_beat = s_axi_rvalid & s_axi_rlast & s_axi_rready;
|
||||
assign last_rd_beat = s_axi_rvalid & s_axi_rlast & s_axi_rready;
|
||||
|
||||
always @( posedge s_axi_aclk )
|
||||
if (~s_axi_aresetn)
|
||||
@ -358,9 +336,8 @@ module esaxi (/*autoarg*/
|
||||
else
|
||||
begin
|
||||
if( s_axi_arready & s_axi_arvalid )
|
||||
begin
|
||||
//NOTE: upper 2 bits get chopped by Zynq
|
||||
axi_araddr[31:0] <= s_axi_araddr[31:0]; //transfer start address
|
||||
begin
|
||||
axi_araddr[31:0] <= s_axi_araddr[31:0]; //NOTE: upper 2 bits get chopped by Zynq
|
||||
axi_arlen <= s_axi_arlen;
|
||||
axi_arburst <= s_axi_arburst;
|
||||
axi_arsize <= s_axi_arsize;
|
||||
@ -376,9 +353,9 @@ module esaxi (/*autoarg*/
|
||||
begin //incremental burst
|
||||
// the read address for all the beats in the transaction are increments by awsize
|
||||
// note: this should be based on awsize instead to support narrow bursts, i think?
|
||||
axi_araddr[c_s_axi_addr_width - 1:addr_lsb] <= axi_araddr[c_s_axi_addr_width - 1:addr_lsb] + 1;
|
||||
axi_araddr[31:2] <= axi_araddr[31:2] + 1;
|
||||
//araddr aligned to 4 byte boundary
|
||||
axi_araddr[addr_lsb-1:0] <= {addr_lsb{1'b0}};
|
||||
axi_araddr[1:0] <= 2'b0;
|
||||
//for awsize = 4 bytes (010)
|
||||
end
|
||||
end // if ( s_axi_rvalid & s_axi_rready)
|
||||
@ -386,119 +363,103 @@ module esaxi (/*autoarg*/
|
||||
|
||||
|
||||
//###################################################
|
||||
//#WRITE DATA
|
||||
//#WRITE REQUEST
|
||||
//###################################################
|
||||
assign emwr_write = 1'b1;
|
||||
assign txwr_write = 1'b1;
|
||||
|
||||
always @( posedge s_axi_aclk )
|
||||
if (~s_axi_aresetn)
|
||||
begin
|
||||
emwr_data_reg[31:0] <= 32'd0;
|
||||
emwr_dstaddr_reg[31:0] <= 32'd0;
|
||||
emwr_ctrlmode_reg[3:0] <= 4'd0;
|
||||
emwr_datamode_reg[1:0] <= 2'd0;
|
||||
emwr_access_all <= 1'b0;
|
||||
txwr_data_reg[31:0] <= 32'd0;
|
||||
txwr_dstaddr_reg[31:0] <= 32'd0;
|
||||
txwr_datamode_reg[1:0] <= 2'd0;
|
||||
txwr_access <= 1'b0;
|
||||
pre_wr_en <= 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
pre_wr_en <= s_axi_wready & s_axi_wvalid;
|
||||
emwr_access_all <= pre_wr_en;
|
||||
emwr_ctrlmode_reg[3:0] <= ecfg_tx_ctrlmode[3:0];//static
|
||||
emwr_datamode_reg[1:0] <= axi_awsize[1:0];
|
||||
emwr_dstaddr_reg[31:2] <= axi_awaddr[31:2]; //set lsbs of address based on write strobes
|
||||
txwr_access <= pre_wr_en;
|
||||
txwr_datamode_reg[1:0] <= axi_awsize[1:0];
|
||||
txwr_dstaddr_reg[31:2] <= axi_awaddr[31:2]; //set lsbs of address based on write strobes
|
||||
if(s_axi_wstrb[0] | (axi_awsize[1:0]==2'b10))
|
||||
begin
|
||||
emwr_data_reg[31:0] <= s_axi_wdata[31:0];
|
||||
emwr_dstaddr_reg[1:0] <= 2'd0;
|
||||
txwr_data_reg[31:0] <= s_axi_wdata[31:0];
|
||||
txwr_dstaddr_reg[1:0] <= 2'd0;
|
||||
end
|
||||
else if(s_axi_wstrb[1])
|
||||
begin
|
||||
emwr_data_reg[31:0] <= {8'd0, s_axi_wdata[31:8]};
|
||||
emwr_dstaddr_reg[1:0] <= 2'd1;
|
||||
txwr_data_reg[31:0] <= {8'd0, s_axi_wdata[31:8]};
|
||||
txwr_dstaddr_reg[1:0] <= 2'd1;
|
||||
end
|
||||
else if(s_axi_wstrb[2])
|
||||
begin
|
||||
emwr_data_reg[31:0] <= {16'd0, s_axi_wdata[31:16]};
|
||||
emwr_dstaddr_reg[1:0] <= 2'd2;
|
||||
txwr_data_reg[31:0] <= {16'd0, s_axi_wdata[31:16]};
|
||||
txwr_dstaddr_reg[1:0] <= 2'd2;
|
||||
end
|
||||
else
|
||||
begin
|
||||
emwr_data_reg[31:0] <= {24'd0, s_axi_wdata[31:24]};
|
||||
emwr_dstaddr_reg[1:0] <= 2'd3;
|
||||
txwr_data_reg[31:0] <= {24'd0, s_axi_wdata[31:24]};
|
||||
txwr_dstaddr_reg[1:0] <= 2'd3;
|
||||
end
|
||||
end // else: !if(~s_axi_aresetn)
|
||||
|
||||
//Pipeline stage
|
||||
always @( posedge s_axi_aclk )
|
||||
//Pipeline stage!
|
||||
always @( posedge s_axi_aclk )
|
||||
if (~s_axi_aresetn)
|
||||
begin
|
||||
emwr_srcaddr[31:0] <= 32'd0;
|
||||
emwr_data[31:0] <= 32'd0;
|
||||
emwr_dstaddr[31:0] <= 32'd0;
|
||||
emwr_ctrlmode[3:0] <= 4'd0;
|
||||
emwr_datamode[1:0] <= 2'd0;
|
||||
txwr_data[31:0] <= 32'd0;
|
||||
txwr_dstaddr[31:0] <= 32'd0;
|
||||
txwr_datamode[1:0] <= 2'd0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
emwr_srcaddr[31:0] <= 32'b0;
|
||||
emwr_data[31:0] <= emwr_data_reg[31:0];
|
||||
emwr_dstaddr[31:0] <= emwr_dstaddr_reg[31:0];
|
||||
emwr_ctrlmode[3:0] <= emwr_ctrlmode_reg[3:0];
|
||||
emwr_datamode[1:0] <= emwr_datamode_reg[1:0];
|
||||
txwr_data[31:0] <= txwr_data_reg[31:0];
|
||||
txwr_dstaddr[31:0] <= txwr_dstaddr_reg[31:0];
|
||||
txwr_datamode[1:0] <= txwr_datamode_reg[1:0];
|
||||
end // else: !if(~s_axi_aresetn)
|
||||
|
||||
assign emwr_access=emwr_access_all & ~(emwr_dstaddr[31:20]==elinkid[11:0]);
|
||||
|
||||
|
||||
//###################################################
|
||||
//#READ REQUEST (DATA CHANNEL)
|
||||
//###################################################
|
||||
// ------------------------------------------
|
||||
// -- read data handler
|
||||
// -- reads are performed by sending a read
|
||||
// -- request out the tx port and waiting for
|
||||
// -- data to come back through the rx port.
|
||||
// -- data to come back through the rx read response port.
|
||||
// --
|
||||
// -- because elink reads are not generally
|
||||
// -- returned in order, we will only allow
|
||||
// -- one at a time. that's ok because reads
|
||||
// -- are to be avoided for speed anyway.
|
||||
// ------------------------------------------
|
||||
|
||||
// since we're only sending one req at a time we can ignore the fifo flags
|
||||
// always read response data immediately
|
||||
assign emrr_rd_en = emrr_access & ~mi_rd_reg; //TODO: Verify this assumption!!!
|
||||
// -- one at a time.
|
||||
|
||||
assign emrq_write = 1'b0;
|
||||
assign emrq_data[31:0] = 32'b0;
|
||||
assign txrd_write = 1'b0;
|
||||
|
||||
always @( posedge s_axi_aclk )
|
||||
if (~s_axi_aresetn)
|
||||
begin
|
||||
emrq_access_all <= 1'b0;
|
||||
emrq_datamode[1:0] <= 2'd0;
|
||||
emrq_ctrlmode[3:0] <= 4'd0;
|
||||
emrq_dstaddr[31:0] <= 32'd0;
|
||||
emrq_srcaddr[31:0] <= 32'd0;
|
||||
txrd_access <= 1'b0;
|
||||
txrd_datamode[1:0] <= 2'd0;
|
||||
txrd_dstaddr[31:0] <= 32'd0;
|
||||
txrd_srcaddr[31:0] <= 32'd0;
|
||||
ractive_reg <= 1'b0;
|
||||
rnext <= 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
ractive_reg <= read_active; //read request state machone
|
||||
rnext <= s_axi_rvalid & s_axi_rready & ~s_axi_rlast;
|
||||
emrq_access_all <= ( ~ractive_reg & read_active ) | rnext;
|
||||
emrq_datamode[1:0] <= axi_arsize[1:0];
|
||||
emrq_ctrlmode[3:0] <= ecfg_tx_ctrlmode;
|
||||
emrq_dstaddr[31:0] <= axi_araddr[31:0];
|
||||
emrq_srcaddr[31:0] <= {c_read_tag_addr[11:0], 20'd0};//TODO? What can we do with lower 32 bits?
|
||||
ractive_reg <= read_active;
|
||||
rnext <= s_axi_rvalid & s_axi_rready & ~s_axi_rlast;
|
||||
txrd_access <= ( ~ractive_reg & read_active ) | rnext;
|
||||
txrd_datamode[1:0] <= axi_arsize[1:0];
|
||||
txrd_dstaddr[31:0] <= axi_araddr[31:0];
|
||||
txrd_srcaddr[31:0] <= {RETURN_ADDR, 16'd0};
|
||||
//TODO: use arid+srcaddr for out of order ?
|
||||
end
|
||||
|
||||
///Only letting through proper read requests
|
||||
assign emrq_access=emrq_access_all & ~(emrq_dstaddr[31:20]==elinkid[11:0]);
|
||||
|
||||
//###################################################
|
||||
//#READ RESPONSE (DATA CHANNEL)
|
||||
//###################################################
|
||||
//Read response AXI state machine
|
||||
//Only one outstanding read
|
||||
|
||||
assign rxrr_wait = 1'b0;
|
||||
|
||||
always @( posedge s_axi_aclk )
|
||||
if (~s_axi_aresetn)
|
||||
begin
|
||||
@ -508,21 +469,19 @@ module esaxi (/*autoarg*/
|
||||
end
|
||||
else
|
||||
begin
|
||||
if( emrr_access | mi_rd_reg )
|
||||
if( rxrr_access )
|
||||
begin
|
||||
s_axi_rvalid <= 1'b1;
|
||||
s_axi_rresp <= 2'd0;
|
||||
case( axi_arsize[1:0] )
|
||||
2'b00: s_axi_rdata[31:0] <= {4{emrr_mux_data[7:0]}}; //8-bit
|
||||
2'b01: s_axi_rdata[31:0] <= {2{emrr_mux_data[15:0]}}; //16-bit
|
||||
default: s_axi_rdata[31:0] <= emrr_mux_data[31:0]; //32-bit
|
||||
2'b00: s_axi_rdata[31:0] <= {4{rxrr_data[7:0]}}; //8-bit
|
||||
2'b01: s_axi_rdata[31:0] <= {2{rxrr_data[15:0]}}; //16-bit
|
||||
default: s_axi_rdata[31:0] <= rxrr_data[31:0]; //32-bit
|
||||
endcase // case ( axi_arsize[1:0] )
|
||||
end
|
||||
else if( s_axi_rready )
|
||||
s_axi_rvalid <= 1'b0;
|
||||
end // else: !if( s_axi_aresetn == 1'b0 )
|
||||
|
||||
|
||||
|
||||
endmodule // esaxi
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user