Skip to content

Commit

Permalink
phy/xilinx_usp/s_axis_rq_adapt: Switch to 4DWs (to support 64-bit add…
Browse files Browse the repository at this point in the history
…ressing).
  • Loading branch information
enjoy-digital committed Nov 15, 2023
1 parent fff2287 commit 517e1ba
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 109 deletions.
164 changes: 56 additions & 108 deletions litepcie/phy/xilinx_usp/s_axis_rq_adapt_x8.v
Original file line number Diff line number Diff line change
Expand Up @@ -26,124 +26,72 @@ module s_axis_rq_adapt # (
output s_axis_rq_tvalid_a
);

wire s_axis_rq_tready_ff,
s_axis_rq_tvalid_ff,
s_axis_rq_tlast_ff;
wire [7:0] s_axis_rq_tkeep_or = {s_axis_rq_tkeep[28], s_axis_rq_tkeep[24], s_axis_rq_tkeep[20], s_axis_rq_tkeep[16],
s_axis_rq_tkeep[12], s_axis_rq_tkeep[8], s_axis_rq_tkeep[4], s_axis_rq_tkeep[0]};

wire [3:0] s_axis_rq_tuser_ff;
wire [7:0] s_axis_rq_tkeep_ff;
wire [255:0] s_axis_rq_tdata_ff;

axis_iff #(.DAT_B(256+8+4)) s_axis_rq_iff
(
.clk (user_clk),
.rst (user_reset),

.i_vld (s_axis_rq_tvalid),
.o_rdy (s_axis_rq_tready),
.i_sop (1'b0),
.i_eop (s_axis_rq_tlast),
.i_dat ({s_axis_rq_tuser, s_axis_rq_tkeep_or, s_axis_rq_tdata}),

.o_vld (s_axis_rq_tvalid_ff),
.i_rdy (s_axis_rq_tready_ff),
.o_sop (),
.o_eop (s_axis_rq_tlast_ff),
.o_dat ({s_axis_rq_tuser_ff, s_axis_rq_tkeep_ff, s_axis_rq_tdata_ff})
);


reg [1:0] s_axis_rq_cnt; //0-2
always @(posedge user_clk)
if (user_reset) s_axis_rq_cnt <= 2'd0;
else if (s_axis_rq_tvalid_ff && s_axis_rq_tready_ff)
begin
if (s_axis_rq_tlast_ff) s_axis_rq_cnt <= 2'd0;
else if (!s_axis_rq_cnt[1]) s_axis_rq_cnt <= s_axis_rq_cnt + 1;
end

wire s_axis_rq_tfirst = (s_axis_rq_cnt == 0) && (!s_axis_rq_tlast_lat);
wire s_axis_rq_tsecond = s_axis_rq_cnt == 1;

//processing for tlast: generate new last in case write & last num of dword = 5 + i*8
wire s_axis_rq_read = (s_axis_rq_tdata_ff[31:30] == 2'b0); //Read request
wire s_axis_rq_write = !s_axis_rq_read;
reg s_axis_rq_tlast_dly_en;
reg s_axis_rq_tlast_lat;
reg s_axis_rq_tfirst;
always @(posedge user_clk)
if (user_reset) s_axis_rq_tlast_dly_en <= 1'd0;
else if (s_axis_rq_tvalid_ff && s_axis_rq_tfirst && s_axis_rq_write) s_axis_rq_tlast_dly_en <= (s_axis_rq_tdata_ff[2:0] == 3'b101);

always @(posedge user_clk)
if (user_reset) s_axis_rq_tlast_lat <= 1'd0;
else if (s_axis_rq_tlast_lat && s_axis_rq_tready_a) s_axis_rq_tlast_lat <= 1'd0;
else if (s_axis_rq_tvalid_ff && s_axis_rq_tlast_ff && s_axis_rq_tready_a)
begin
if (s_axis_rq_tfirst) s_axis_rq_tlast_lat <= s_axis_rq_write ? (s_axis_rq_dwlen == 11'd5) : 1'b0; //write 5 dwords
else s_axis_rq_tlast_lat <= s_axis_rq_tlast_dly_en;
if (user_reset) begin
s_axis_rq_tfirst <= 1'd1;
end
else if (s_axis_rq_tvalid && s_axis_rq_tready) begin
s_axis_rq_tfirst <= 1'd0;
if (s_axis_rq_tlast) begin
s_axis_rq_tfirst <= 1'd1;
end
end

assign s_axis_rq_tlast_a = s_axis_rq_tfirst ? (s_axis_rq_read | (s_axis_rq_dwlen < 11'd5)) :
s_axis_rq_tlast_dly_en ? s_axis_rq_tlast_lat : s_axis_rq_tlast_ff;

//Generate ready for TLP
assign s_axis_rq_tready_ff = s_axis_rq_tready_a && (!s_axis_rq_tlast_lat);
assign s_axis_rq_tvalid_a = s_axis_rq_tvalid_ff | s_axis_rq_tlast_lat;

wire [10:0] s_axis_rq_dwlen = {1'b0, s_axis_rq_tdata_ff[9:0]};
wire [3:0] s_axis_rq_reqtype = {s_axis_rq_tdata_ff[31:30], s_axis_rq_tdata_ff[28:24]} == 7'b0000000 ? 4'b0000 : //Mem read Request
{s_axis_rq_tdata_ff[31:30], s_axis_rq_tdata_ff[28:24]} == 7'b0000001 ? 4'b0111 : //Mem Read request-locked
{s_axis_rq_tdata_ff[31:30], s_axis_rq_tdata_ff[28:24]} == 7'b0100000 ? 4'b0001 : //Mem write request
s_axis_rq_tdata_ff[31:24] == 8'b00000010 ? 4'b0010 : //I/O Read request
s_axis_rq_tdata_ff[31:24] == 8'b01000010 ? 4'b0011 : //I/O Write request
s_axis_rq_tdata_ff[31:24] == 8'b00000100 ? 4'b1000 : //Cfg Read Type 0
s_axis_rq_tdata_ff[31:24] == 8'b01000100 ? 4'b1010 : //Cfg Write Type 0
s_axis_rq_tdata_ff[31:24] == 8'b00000101 ? 4'b1001 : //Cfg Read Type 1
s_axis_rq_tdata_ff[31:24] == 8'b01000101 ? 4'b1011 : //Cfg Write Type 1
4'b1111;
wire s_axis_rq_poisoning = s_axis_rq_tdata_ff[14] | s_axis_rq_tuser_ff[1]; //EP must be 0 for request
wire [15:0] s_axis_rq_requesterid = s_axis_rq_tdata_ff[63:48];
wire [7:0] s_axis_rq_tag = s_axis_rq_tdata_ff[47:40];
wire [15:0] s_axis_rq_completerid = 16'b0; //applicable only to Configuration requests and messages routed by ID
wire s_axis_rq_requester_en = 1'b0; //Must be 0 for Endpoint
wire [2:0] s_axis_rq_tc = s_axis_rq_tdata_ff[22:20];
wire [2:0] s_axis_rq_attr = {1'b0, s_axis_rq_tdata_ff[13:12]};
wire s_axis_rq_ecrc = s_axis_rq_tdata_ff[15] | s_axis_rq_tuser_ff[0]; //TLP Digest

wire [63:0] s_axis_rq_tdata_header = {s_axis_rq_ecrc,
s_axis_rq_attr,
s_axis_rq_tc,
s_axis_rq_requester_en,
s_axis_rq_completerid,
s_axis_rq_tag,
s_axis_rq_requesterid,
s_axis_rq_poisoning, s_axis_rq_reqtype, s_axis_rq_dwlen};

wire [3:0] s_axis_rq_firstbe = s_axis_rq_tdata_ff[35:32];
wire [3:0] s_axis_rq_lastbe = s_axis_rq_tdata_ff[39:36];
reg [3:0] s_axis_rq_firstbe_l;
reg [3:0] s_axis_rq_lastbe_l;
assign s_axis_rq_tlast_a = s_axis_rq_tlast;
assign s_axis_rq_tready = s_axis_rq_tready_a;
assign s_axis_rq_tvalid_a = s_axis_rq_tvalid;

wire [10:0] s_axis_rq_dwlen = {1'b0, s_axis_rq_tdata[9:0]};
wire [3:0] s_axis_rq_reqtype =
{s_axis_rq_tdata[31:30], s_axis_rq_tdata[28:24]} == 7'b0000000 ? 4'b0000 : // Mem Read request.
{s_axis_rq_tdata[31:30], s_axis_rq_tdata[28:24]} == 7'b0000001 ? 4'b0111 : // Mem Read request-locked
{s_axis_rq_tdata[31:30], s_axis_rq_tdata[28:24]} == 7'b0100000 ? 4'b0001 : // Mem Write request.
s_axis_rq_tdata[31:24] == 8'b00000010 ? 4'b0010 : // I/O Read request.
s_axis_rq_tdata[31:24] == 8'b01000010 ? 4'b0011 : // I/O Write request.
s_axis_rq_tdata[31:24] == 8'b00000100 ? 4'b1000 : // Cfg Read Type 0.
s_axis_rq_tdata[31:24] == 8'b01000100 ? 4'b1010 : // Cfg Write Type 0.
s_axis_rq_tdata[31:24] == 8'b00000101 ? 4'b1001 : // Cfg Read Type 1.
s_axis_rq_tdata[31:24] == 8'b01000101 ? 4'b1011 : // Cfg Write Type 1.
4'b1111;

wire s_axis_rq_poisoning = s_axis_rq_tdata[14] | s_axis_rq_tuser[1]; // EP must be 0 for request.
wire [15:0] s_axis_rq_requesterid = s_axis_rq_tdata[63:48];
wire [7:0] s_axis_rq_tag = s_axis_rq_tdata[47:40];
wire [15:0] s_axis_rq_completerid = 16'b0; // Applicable only to Configuration requests and messages routed by ID.
wire s_axis_rq_requester_en = 1'b0; // Must be 0 for Endpoint.
wire [2:0] s_axis_rq_tc = s_axis_rq_tdata[22:20];
wire [2:0] s_axis_rq_attr = {1'b0, s_axis_rq_tdata[13:12]};
wire s_axis_rq_ecrc = s_axis_rq_tdata[15] | s_axis_rq_tuser[0]; //TLP Digest

wire [63:0] s_axis_rq_tdata_header = {
s_axis_rq_ecrc,
s_axis_rq_attr,
s_axis_rq_tc,
s_axis_rq_requester_en,
s_axis_rq_completerid,
s_axis_rq_tag,
s_axis_rq_requesterid,
s_axis_rq_poisoning, s_axis_rq_reqtype, s_axis_rq_dwlen
};

wire [3:0] s_axis_rq_firstbe = s_axis_rq_tdata[35:32];
wire [3:0] s_axis_rq_lastbe = s_axis_rq_tdata[39:36];
reg [3:0] s_axis_rq_firstbe_l;
reg [3:0] s_axis_rq_lastbe_l;

always @(posedge user_clk)
begin
if (s_axis_rq_tvalid_ff && s_axis_rq_tfirst)
if (s_axis_rq_tvalid && s_axis_rq_tfirst)
begin
s_axis_rq_firstbe_l <= s_axis_rq_firstbe;
s_axis_rq_lastbe_l <= s_axis_rq_lastbe;
s_axis_rq_lastbe_l <= s_axis_rq_lastbe;
end
end

reg [31:0] s_axis_rq_tdata_l;
always @(posedge user_clk)
if (s_axis_rq_tvalid_ff && s_axis_rq_tready_ff)
s_axis_rq_tdata_l <= s_axis_rq_tdata_ff[255:224];

assign s_axis_rq_tdata_a = s_axis_rq_tfirst ? {s_axis_rq_tdata_ff[223:96], s_axis_rq_tdata_header, 32'b0, s_axis_rq_tdata_ff[95:64]} :
{s_axis_rq_tdata_ff[223:0], s_axis_rq_tdata_l[31:0]};
assign s_axis_rq_tkeep_a = s_axis_rq_tlast_lat ? 8'h1 : {s_axis_rq_tkeep_ff[6:0], 1'b1};
assign s_axis_rq_tuser_a[59:8] = {32'b0, 4'b0, 1'b0, 8'b0, 2'b0, 1'b0, s_axis_rq_tuser_ff[3], 3'b0};
assign s_axis_rq_tuser_a[7:0] = {s_axis_rq_lastbe, s_axis_rq_firstbe};
assign s_axis_rq_tdata_a = s_axis_rq_tfirst ? {s_axis_rq_tdata[255:127], s_axis_rq_tdata_header, s_axis_rq_tdata[95:64], s_axis_rq_tdata[127:96]} : s_axis_rq_tdata;
assign s_axis_rq_tkeep_a = s_axis_rq_tfirst ? 8'b11111111 : s_axis_rq_tkeep;
assign s_axis_rq_tuser_a[59:8] = {32'b0, 4'b0, 1'b0, 8'b0, 2'b0, 1'b0, s_axis_rq_tuser[3], 3'b0};
assign s_axis_rq_tuser_a[7:0] = s_axis_rq_tfirst ? {s_axis_rq_lastbe, s_axis_rq_firstbe} : {s_axis_rq_lastbe_l, s_axis_rq_firstbe_l};

endmodule
4 changes: 3 additions & 1 deletion litepcie/tlp/packetizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -803,9 +803,11 @@ def __init__(self, data_width, endianness, address_width=32, capabilities=["REQU
tlp_req.address.eq(req_sink.adr),
]
if address_width == 64:
# On Ultrascale(+), force to 64-bit (for 4DWs format).
force_64b = (LiteXContext.platform.device[:4] in ["xcku", "xcvu"]) and (data_width in [256])
self.comb += [
# Use WR64/RD64 only when 64-bit Address's MSB != 0, else use WR32/RD32.
If(req_sink.adr[32:] != 0,
If((req_sink.adr[32:] != 0) | force_64b,
# Address's MSB on DW2, LSB on DW3 with 64-bit addressing: Requires swap due to
# Packetizer's behavior.
tlp_req.address[:32].eq(req_sink.adr[32:]),
Expand Down

0 comments on commit 517e1ba

Please sign in to comment.