From eb3051ea93185aa33793739a1645ff14bfdf1b8f Mon Sep 17 00:00:00 2001 From: Andreas Olofsson Date: Sat, 9 May 2015 08:56:51 -0400 Subject: [PATCH] Cleaning up logic to fit new access/packet interface (pre-debug) --- elink/hdl/emaxi.v | 394 ++++++++++++++++++++++++++-------------------- elink/hdl/esaxi.v | 357 +++++++++++++++++++---------------------- 2 files changed, 382 insertions(+), 369 deletions(-) diff --git a/elink/hdl/emaxi.v b/elink/hdl/emaxi.v index 095f21e..613b3b5 100644 --- a/elink/hdl/emaxi.v +++ b/elink/hdl/emaxi.v @@ -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 diff --git a/elink/hdl/esaxi.v b/elink/hdl/esaxi.v index 628780b..12e1325 100644 --- a/elink/hdl/esaxi.v +++ b/elink/hdl/esaxi.v @@ -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