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