1// 2// Copyright 2020 Ettus Research, a National Instruments Brand 3// 4// SPDX-License-Identifier: LGPL-3.0-or-later 5// 6// Description: 7// System Verilog wrapper for axis_width_conv that accepts a AxiStreamIfc 8// with slave_user/master_user interface. This block requires that the 9// bottom bits of user contain the number of bytes in the last word. 10// 11// If TKEEP - tkeep contains byte_enables 12// If USER_TRAILING_BYTES - tuser contains byte_enables 13// Else everything is a full word 14// 15// Parameters: 16// PIPELINE - Add pipelining for timing. 17// SYNC_CLKS - Input and output clock are the same. 18// I_USER_TRAILING_BYTES - input byte_enable is set by user 19// O_USER_TRAILING_BYTES - output byte_enable is set in user 20// 21 22module axi4s_width_conv #( 23 PIPELINE = "NONE", 24 bit I_USER_TRAILING_BYTES = 0, 25 bit O_USER_TRAILING_BYTES = 0, 26 bit SYNC_CLKS = 1 27) ( 28 interface i, // AxiStreamIf or AxiStreamPacketIf 29 interface o // AxiStreamIf or AxiStreamPacketIf 30); 31 32 localparam IWIDTH =i.DATA_WIDTH; 33 localparam OWIDTH =o.DATA_WIDTH; 34 35 `include "axi4s.vh" 36 // Parameter Checks 37 initial begin 38 if(i.TKEEP) begin 39 assert (!I_USER_TRAILING_BYTES) else 40 $fatal("I_USER_TRAILING_BYTE set at the same time as TKEEP"); 41 assert (!i.TUSER) else 42 $fatal("i.TUSER set- This module does not pass user"); 43 end else if(I_USER_TRAILING_BYTES) begin 44 assert (i.USER_WIDTH >= i.TRAILING_WIDTH ) else 45 $fatal("i.USER_WIDTH does not match TRAILING_WIDTH"); 46 end else begin 47 assert (!i.TUSER) else 48 $fatal("This module does not pass generic user_data"); 49 end 50 51 if(o.TKEEP) begin 52 assert (!O_USER_TRAILING_BYTES) else 53 $fatal("O_USER_TRAILING_BYTE set at the same time as TKEEP"); 54 assert (!o.TUSER) else 55 $fatal("O.TUSER set- This module does not pass user"); 56 end else if(O_USER_TRAILING_BYTES) begin 57 assert (o.USER_WIDTH >= o.TRAILING_WIDTH) else 58 $fatal("o.USER_WIDTH does not match TRAILING_WIDTH"); 59 end else begin 60 assert (!o.TUSER) else 61 $fatal("This module does not pass generic user_data"); 62 end 63 64 assert (i.TLAST == 1) else 65 $fatal("i.TLAST not present"); 66 assert (o.TLAST == 1) else 67 $fatal("o.TLAST not present"); 68 end 69 70 AxiStreamPacketIf #(.DATA_WIDTH(i.DATA_WIDTH),.USER_WIDTH(i.USER_WIDTH), 71 .TDATA(i.TDATA),.TKEEP(i.TKEEP),.TUSER(i.TUSER),.TLAST(i.TLAST), 72 .MAX_PACKET_BYTES(i.MAX_PACKET_BYTES)) 73 s0(i.clk,i.rst); 74 AxiStreamPacketIf #(.DATA_WIDTH(o.DATA_WIDTH),.USER_WIDTH(o.USER_WIDTH), 75 .TDATA(o.TDATA),.TKEEP(o.TKEEP),.TUSER(o.TUSER),.TLAST(o.TLAST), 76 .MAX_PACKET_BYTES(o.MAX_PACKET_BYTES)) 77 s1(o.clk,o.rst); 78 79 // move from AxiStreamIfc to AxiStreamPacketIf 80 always_comb begin 81 `AXI4S_ASSIGN(s0,i) 82 end 83 // move from AxiStreamPacketIf to AxiStreamIfc 84 always_comb begin 85 `AXI4S_ASSIGN(o,s1) 86 end 87 88 logic [IWIDTH/8-1:0] s0_tkeep; 89 90 if (s0.TKEEP) begin 91 always_comb s0_tkeep = s0.tkeep; 92 end else if (I_USER_TRAILING_BYTES) begin 93 always_comb s0_tkeep = s0.get_trailing_bytes(); 94 end else begin 95 always_comb s0_tkeep = '1; 96 end 97 98 logic [OWIDTH/8-1:0] s1_tkeep; 99 logic [15:0] s1_bytes; 100 101 if (s1.TKEEP) begin 102 always_comb s1.tkeep = s1_tkeep; 103 always_comb s1.tuser = 'X; 104 end else if (O_USER_TRAILING_BYTES) begin 105 always_comb s1.tkeep = 'X; 106 always_comb begin : assign_s1_tuser 107 s1.tuser = 0; 108 // MODELSIM_BUG - deleting the s1_bytes assignment causes modelsim failures. 109 s1_bytes = s1.keep2trailing(s1_tkeep); 110 s1.set_trailing_bytes(s1_tkeep); 111 end 112 end else begin 113 always_comb s1.tkeep = 'X; 114 always_comb s1.tuser = 'X; 115 end 116 117 logic s0_ready, s1_valid, s1_last; 118 logic [s1.DATA_WIDTH-1:0] s1_data; 119 always_comb s0.tready = s0_ready; 120 always_comb s1.tvalid = s1_valid; 121 always_comb s1.tlast = s1_last; 122 always_comb s1.tdata = s1_data; 123 124 axis_width_conv #( 125 .IN_WORDS(IWIDTH/8), .OUT_WORDS(OWIDTH/8), 126 .SYNC_CLKS(SYNC_CLKS), .PIPELINE(PIPELINE) 127 ) axis_width_conv ( 128 .s_axis_aclk(s0.clk), .s_axis_rst(s0.rst), 129 .s_axis_tdata(s0.tdata), .s_axis_tkeep(s0_tkeep), .s_axis_tlast(s0.tlast), 130 .s_axis_tvalid(s0.tvalid), .s_axis_tready(s0_ready), 131 132 .m_axis_aclk(s1.clk), .m_axis_rst(s1.rst), 133 .m_axis_tdata(s1_data), .m_axis_tkeep(s1_tkeep), .m_axis_tlast(s1_last), 134 .m_axis_tvalid(s1_valid), .m_axis_tready(s1.tready) 135 ); 136 137endmodule : axi4s_width_conv 138