mirror of
https://github.com/aolofsson/oh.git
synced 2025-01-17 20:02:53 +08:00
91f8e3db5a
- After finding the bug in the reference model and wasting countless hours going back and forth with FPGA timing optimization and bug tweaks, I realized that the design was fundementally broken. The decision to use two clock domains (high speed) and low speed was correct from the beginning. The FPGA is dreadfully slow, (you definitely don't want to do much logic at 300MHz...), but the handoff between tclk and tclk_div4 was too complicated. The puzzle of having to respond to wait quickly, covering the corner cases, and meeting timing was just too ugly. - The "new" design goes back to the method of using the high speed logic only for doing a "dumb" parallel to serial converter and preparing all the necessary signals in the low speed domain. - This feel A LOT cleaner and the it already passes basic tests with the chip reference and the loopback after less than 3 hours of redesign work! - The TX meets timing but there is still some work to do with wait pushback testing.
552 lines
19 KiB
Verilog
552 lines
19 KiB
Verilog
/*
|
|
########################################################################
|
|
Epiphany eLink AXI Master Module
|
|
########################################################################
|
|
|
|
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
|
|
|
|
*/
|
|
|
|
module emaxi(/*autoarg*/
|
|
// Outputs
|
|
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,
|
|
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,
|
|
// Inputs
|
|
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 M_IDW = 12;
|
|
parameter PW = 104;
|
|
parameter AW = 32;
|
|
parameter DW = 32;
|
|
|
|
//########################
|
|
//ELINK INTERFACE
|
|
//########################
|
|
|
|
|
|
//Write request from erx
|
|
input rxwr_access;
|
|
input [PW-1:0] rxwr_packet;
|
|
output rxwr_wait;
|
|
|
|
//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.
|
|
|
|
//Write address channel
|
|
output [M_IDW-1:0] m_axi_awid; // write address ID
|
|
output [31 : 0] m_axi_awaddr; // master interface write address
|
|
output [7 : 0] m_axi_awlen; // burst length.
|
|
output [2 : 0] m_axi_awsize; // burst size.
|
|
output [1 : 0] m_axi_awburst; // burst type.
|
|
output m_axi_awlock; // lock type
|
|
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
|
|
output [M_IDW-1:0] m_axi_wid;
|
|
output [63 : 0] m_axi_wdata; // master interface write data.
|
|
output [7 : 0] m_axi_wstrb; // byte write strobes
|
|
output m_axi_wlast; // last transfer in a write burst.
|
|
output m_axi_wvalid; // indicates data is ready to go
|
|
input m_axi_wready; // slave is ready for data
|
|
|
|
//Write response channel
|
|
input [M_IDW-1:0] m_axi_bid;
|
|
input [1 : 0] m_axi_bresp; // status of the write transaction.
|
|
input m_axi_bvalid; // channel is a valid write response
|
|
output m_axi_bready; // master can accept write response.
|
|
|
|
//Read address channel
|
|
output [M_IDW-1:0] m_axi_arid; // read address ID
|
|
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
|
|
output m_axi_arlock; // lock type
|
|
output [3 : 0] m_axi_arcache; // memory type
|
|
output [2 : 0] m_axi_arprot; // protection type
|
|
output [3 : 0] m_axi_arqos; // quality of service info
|
|
output m_axi_arvalid; // valid read address
|
|
input m_axi_arready; // slave is ready to accept an address
|
|
|
|
//Read data channel
|
|
input [M_IDW-1:0] m_axi_rid; // read data ID
|
|
input [63 : 0] m_axi_rdata; // master read data
|
|
input [1 : 0] m_axi_rresp; // status of the read transfer
|
|
input m_axi_rlast; // last transfer in a read burst
|
|
input m_axi_rvalid; // signaling the required read data
|
|
output m_axi_rready; // master can accept the readback data
|
|
|
|
|
|
//#########################################################################
|
|
//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 [63 : 0] m_axi_rdata_reg;
|
|
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_full;
|
|
wire [47:0] readinfo_out;
|
|
wire [47:0] readinfo_in;
|
|
|
|
wire awvalid_in;
|
|
|
|
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
|
|
.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
|
|
.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
|
|
.write_in (1'b1),
|
|
.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
|
|
//#########################################################################
|
|
|
|
//AW
|
|
assign m_axi_awid[M_IDW-1:0] = {(M_IDW){1'b0}};
|
|
assign m_axi_awburst[1:0] = 2'b01; //only increment burst supported
|
|
assign m_axi_awcache[3:0] = 4'b0000;//TODO: correct value??
|
|
assign m_axi_awprot[2:0] = 3'b000;
|
|
assign m_axi_awqos[3:0] = 4'b0000;
|
|
assign m_axi_awlock = 1'b0;
|
|
|
|
//AR
|
|
assign m_axi_arid[M_IDW-1:0] = {(M_IDW){1'b0}};
|
|
assign m_axi_arburst[1:0] = 2'b01; //only increment burst supported
|
|
assign m_axi_arcache[3:0] = 4'b0000;
|
|
assign m_axi_arprot[2:0] = 3'h0;
|
|
assign m_axi_arqos[3:0] = 4'h0;
|
|
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}};
|
|
|
|
//#########################################################################
|
|
//Write address channel
|
|
//#########################################################################
|
|
|
|
assign aw_go = m_axi_awvalid & m_axi_awready;
|
|
assign w_go = m_axi_wvalid & m_axi_wready;
|
|
assign rxwr_wait = awvalid_b | wvalid_b;
|
|
assign awvalid_in = rxwr_access & ~awvalid_b & ~wvalid_b;
|
|
|
|
// generate write-address signals
|
|
always @( posedge m_axi_aclk )
|
|
if(!m_axi_aresetn)
|
|
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;
|
|
awvalid_b <= 1'b0;
|
|
awaddr_b <= 'd0;
|
|
awlen_b[7:0] <= 'd0;
|
|
awsize_b[2:0] <= 'd0;
|
|
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
|
|
m_axi_awvalid <= awvalid_in;
|
|
m_axi_awaddr[31:0] <= rxwr_dstaddr[31:0];
|
|
m_axi_awlen[7:0] <= 8'b0;
|
|
m_axi_awsize[2:0] <= { 1'b0, rxwr_datamode[1:0]};
|
|
end
|
|
end
|
|
if( awvalid_in & m_axi_awvalid & ~aw_go )
|
|
awvalid_b <= 1'b1;
|
|
else if( aw_go )
|
|
awvalid_b <= 1'b0;
|
|
|
|
//Pipeline stage
|
|
if( awvalid_in )
|
|
begin
|
|
awaddr_b[31:0] <= rxwr_dstaddr[31:0];
|
|
awlen_b[7:0] <= 8'b0;
|
|
awsize_b[2:0] <= { 1'b0, rxwr_datamode[1:0] };
|
|
end
|
|
end // else: !if(~m_axi_aresetn)
|
|
|
|
//#########################################################################
|
|
//Write data alignment circuit
|
|
//#########################################################################
|
|
|
|
always @*
|
|
case( rxwr_datamode[1:0] )
|
|
2'b00: wdata_aligned[63:0] = { 8{rxwr_data[7:0]}};
|
|
2'b01: wdata_aligned[63:0] = { 4{rxwr_data[15:0]}};
|
|
2'b10: wdata_aligned[63:0] = { 2{rxwr_data[31:0]}};
|
|
default: wdata_aligned[63:0] = { rxwr_srcaddr[31:0], rxwr_data[31:0]};
|
|
endcase
|
|
|
|
always @*
|
|
begin
|
|
case(rxwr_datamode[1:0])
|
|
2'd0: // byte
|
|
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;
|
|
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
|
|
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(rxwr_dstaddr[2])
|
|
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 @ *
|
|
|
|
//#########################################################################
|
|
//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:bursts!!
|
|
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
|
|
m_axi_wvalid <= awvalid_in;
|
|
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( rxwr_access & m_axi_wvalid & ~w_go )
|
|
wvalid_b <= 1'b1;
|
|
else if( w_go )
|
|
wvalid_b <= 1'b0;
|
|
|
|
if( awvalid_in )
|
|
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 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,
|
|
rxrd_srcaddr[31:0],//40:9
|
|
rxrd_dstaddr[2:0], //8:6
|
|
rxrd_ctrlmode[3:0],//5:2
|
|
rxrd_datamode[1:0]
|
|
};
|
|
|
|
|
|
//Rest synchronization (for safety, assume incoming reset is async)
|
|
wire sync_nreset;
|
|
dsync dsync(.dout (sync_nreset),
|
|
.clk (m_axi_aclk),
|
|
.din (m_axi_aresetn)
|
|
);
|
|
|
|
//Synchronous FIFO for read transactions
|
|
|
|
//TODO: We don't have a way of testing this, since we don't have a model that will accept enough
|
|
//transactions (need an actual axi implementation that doesn't stall on every read)
|
|
//SOLUTION: Put in the bullet proof async fifo and hope...
|
|
|
|
|
|
wire [PW-1:0] packet_out;
|
|
wire fifo_prog_full;
|
|
|
|
defparam fifo.DW = 104;
|
|
defparam fifo.DEPTH = 32;
|
|
defparam fifo.WAIT = 0;
|
|
|
|
fifo_async fifo (.full (),
|
|
.prog_full (fifo_prog_full),
|
|
.dout (packet_out[PW-1:0]),
|
|
.empty (),
|
|
.valid (),
|
|
// Inputs
|
|
.rst (~sync_nreset),
|
|
.wr_clk (m_axi_aclk),
|
|
.rd_clk (m_axi_aclk),
|
|
.wr_en (fifo_wr_en),
|
|
.din ({56'b0,readinfo_in[47:0]}),
|
|
.rd_en (fifo_rd_en)
|
|
);
|
|
|
|
assign readinfo_out[47:0] = packet_out[47:0];
|
|
|
|
/*
|
|
|
|
fifo_sync
|
|
#(
|
|
// parameters
|
|
.AW (5),
|
|
.DW (48))
|
|
fifo_readinfo_i
|
|
(
|
|
// outputs
|
|
.rd_data (readinfo_out[47:0]),
|
|
.rd_empty (),
|
|
.wr_full (readinfo_full),
|
|
// inputs
|
|
.clk (m_axi_aclk),
|
|
.reset (~sync_nreset),
|
|
.wr_data (readinfo_in[47:0]),
|
|
.wr_en (m_axi_arvalid & m_axi_arready),
|
|
.rd_en (m_axi_rready & m_axi_rvalid)
|
|
);
|
|
*/
|
|
|
|
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
|
|
//###################################################################
|
|
|
|
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 & ~fifo_prog_full;
|
|
assign rxrd_wait = ~m_axi_arready | fifo_prog_full;
|
|
assign fifo_wr_en = m_axi_arvalid & m_axi_arready;
|
|
assign fifo_rd_en = m_axi_rvalid & ~txrr_wait;
|
|
|
|
//#################################################################
|
|
//Read response channel
|
|
//#################################################################
|
|
assign m_axi_rready = ~txrr_wait;
|
|
|
|
always @( posedge m_axi_aclk )
|
|
if ( ~m_axi_aresetn )
|
|
m_axi_rdata_reg <= 'b0;
|
|
else
|
|
m_axi_rdata_reg <= m_axi_rdata;
|
|
|
|
always @( posedge m_axi_aclk )
|
|
if( ~m_axi_aresetn )
|
|
begin
|
|
txrr_data[31:0] <= 32'b0;
|
|
txrr_srcaddr[31:0] <= 32'b0;
|
|
txrr_access_reg <= 1'b0;
|
|
txrr_access <= 1'b0;
|
|
end
|
|
else
|
|
begin
|
|
txrr_access_reg <= fifo_rd_en;
|
|
txrr_access <= txrr_access_reg;//added pipeline stage for data ???/
|
|
// 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: txrr_data[31:0] <= {24'b0,m_axi_rdata_reg[7:0]};
|
|
3'd1: txrr_data[31:0] <= {24'b0,m_axi_rdata_reg[15:8]};
|
|
3'd2: txrr_data[31:0] <= {24'b0,m_axi_rdata_reg[23:16]};
|
|
3'd3: txrr_data[31:0] <= {24'b0,m_axi_rdata_reg[31:24]};
|
|
3'd4: txrr_data[31:0] <= {24'b0,m_axi_rdata_reg[39:32]};
|
|
3'd5: txrr_data[31:0] <= {24'b0,m_axi_rdata_reg[47:40]};
|
|
3'd6: txrr_data[31:0] <= {24'b0,m_axi_rdata_reg[55:48]};
|
|
default: txrr_data[31:0] <= {24'b0,m_axi_rdata_reg[63:56]};
|
|
endcase
|
|
2'd1: // 16b hword
|
|
case( readinfo_out[8:7] )
|
|
2'd0: txrr_data[31:0] <= {16'b0,m_axi_rdata_reg[15:0]};
|
|
2'd1: txrr_data[31:0] <= {16'b0,m_axi_rdata_reg[31:16]};
|
|
2'd2: txrr_data[31:0] <= {16'b0,m_axi_rdata_reg[47:32]};
|
|
default: txrr_data[31:0] <= {16'b0,m_axi_rdata_reg[63:48]};
|
|
endcase
|
|
2'd2: // 32b word
|
|
if( readinfo_out[8] )
|
|
txrr_data[31:0] <= m_axi_rdata_reg[63:32];
|
|
else
|
|
txrr_data[31:0] <= m_axi_rdata_reg[31:0];
|
|
// 64b word already defined by defaults above
|
|
2'd3:
|
|
begin // 64b dword
|
|
txrr_data[31:0] <= m_axi_rdata_reg[31:0];
|
|
txrr_srcaddr[31:0] <= m_axi_rdata_reg[63:32];
|
|
end
|
|
endcase
|
|
end // else: !if( ~m_axi_aresetn )
|
|
|
|
endmodule // emaxi
|
|
// Local Variables:
|
|
// verilog-library-directories:("." "../../emesh/hdl" "../../memory/hdl" "../../common/hdl" )
|
|
// End:
|
|
|