Skip to content

Commit c091f7e

Browse files
committed
Add switch wrapper generator
1 parent b4cebd8 commit c091f7e

File tree

1 file changed

+201
-0
lines changed

1 file changed

+201
-0
lines changed

rtl/axis_switch_wrap.py

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
#!/usr/bin/env python
2+
"""
3+
Generates an AXI Stream switch wrapper with the specified number of ports
4+
"""
5+
6+
from __future__ import print_function
7+
8+
import argparse
9+
import math
10+
from jinja2 import Template
11+
12+
def main():
13+
parser = argparse.ArgumentParser(description=__doc__.strip())
14+
parser.add_argument('-p', '--ports', type=int, default=[4], nargs='+', help="number of ports")
15+
parser.add_argument('-n', '--name', type=str, help="module name")
16+
parser.add_argument('-o', '--output', type=str, help="output file name")
17+
18+
args = parser.parse_args()
19+
20+
try:
21+
generate(**args.__dict__)
22+
except IOError as ex:
23+
print(ex)
24+
exit(1)
25+
26+
def generate(ports=4, name=None, output=None):
27+
if type(ports) is int:
28+
m = n = ports
29+
elif len(ports) == 1:
30+
m = n = ports[0]
31+
else:
32+
m, n = ports
33+
34+
if name is None:
35+
name = "axis_switch_wrap_{0}x{1}".format(m, n)
36+
37+
if output is None:
38+
output = name + ".v"
39+
40+
print("Opening file '{0}'...".format(output))
41+
42+
output_file = open(output, 'w')
43+
44+
print("Generating {0}x{1} port AXI stream switch wrapper {2}...".format(m, n, name))
45+
46+
cm = int(math.ceil(math.log(m, 2)))
47+
cn = int(math.ceil(math.log(n, 2)))
48+
49+
t = Template(u"""/*
50+
51+
Copyright (c) 2018 Alex Forencich
52+
53+
Permission is hereby granted, free of charge, to any person obtaining a copy
54+
of this software and associated documentation files (the "Software"), to deal
55+
in the Software without restriction, including without limitation the rights
56+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
57+
copies of the Software, and to permit persons to whom the Software is
58+
furnished to do so, subject to the following conditions:
59+
60+
The above copyright notice and this permission notice shall be included in
61+
all copies or substantial portions of the Software.
62+
63+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
64+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
65+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
66+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
67+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
68+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
69+
THE SOFTWARE.
70+
71+
*/
72+
73+
// Language: Verilog 2001
74+
75+
`timescale 1ns / 1ps
76+
77+
/*
78+
* AXI4-Stream {{m}}x{{n}} switch (wrapper)
79+
*/
80+
module {{name}} #
81+
(
82+
parameter DATA_WIDTH = 8,
83+
parameter KEEP_ENABLE = (DATA_WIDTH>8),
84+
parameter KEEP_WIDTH = (DATA_WIDTH/8),
85+
parameter ID_ENABLE = 0,
86+
parameter ID_WIDTH = 8,
87+
parameter DEST_WIDTH = {{cm}},
88+
parameter USER_ENABLE = 1,
89+
parameter USER_WIDTH = 1,
90+
{%- for p in range(n) %}
91+
parameter M{{'%02d'%p}}_BASE = {{p}},
92+
parameter M{{'%02d'%p}}_TOP = {{p}},
93+
parameter M{{'%02d'%p}}_CONNECT = {{m}}'b{% for p in range(m) %}1{% endfor %},
94+
{%- endfor %}
95+
parameter S_REG_TYPE = 0,
96+
parameter M_REG_TYPE = 2,
97+
// arbitration type: "PRIORITY" or "ROUND_ROBIN"
98+
parameter ARB_TYPE = "ROUND_ROBIN",
99+
// LSB priority: "LOW", "HIGH"
100+
parameter LSB_PRIORITY = "HIGH"
101+
)
102+
(
103+
input wire clk,
104+
input wire rst,
105+
106+
/*
107+
* AXI Stream inputs
108+
*/
109+
{%- for p in range(m) %}
110+
input wire [DATA_WIDTH-1:0] s{{'%02d'%p}}_axis_tdata,
111+
input wire [KEEP_WIDTH-1:0] s{{'%02d'%p}}_axis_tkeep,
112+
input wire s{{'%02d'%p}}_axis_tvalid,
113+
output wire s{{'%02d'%p}}_axis_tready,
114+
input wire s{{'%02d'%p}}_axis_tlast,
115+
input wire [ID_WIDTH-1:0] s{{'%02d'%p}}_axis_tid,
116+
input wire [DEST_WIDTH-1:0] s{{'%02d'%p}}_axis_tdest,
117+
input wire [USER_WIDTH-1:0] s{{'%02d'%p}}_axis_tuser,
118+
{% endfor %}
119+
/*
120+
* AXI Stream outputs
121+
*/
122+
{%- for p in range(n) %}
123+
output wire [DATA_WIDTH-1:0] m{{'%02d'%p}}_axis_tdata,
124+
output wire [KEEP_WIDTH-1:0] m{{'%02d'%p}}_axis_tkeep,
125+
output wire m{{'%02d'%p}}_axis_tvalid,
126+
input wire m{{'%02d'%p}}_axis_tready,
127+
output wire m{{'%02d'%p}}_axis_tlast,
128+
output wire [ID_WIDTH-1:0] m{{'%02d'%p}}_axis_tid,
129+
output wire [DEST_WIDTH-1:0] m{{'%02d'%p}}_axis_tdest,
130+
output wire [USER_WIDTH-1:0] m{{'%02d'%p}}_axis_tuser{% if not loop.last %},{% endif %}
131+
{% endfor -%}
132+
);
133+
134+
// parameter sizing helpers
135+
function [31:0] w_32(input [31:0] val);
136+
w_32 = val;
137+
endfunction
138+
139+
function [S_COUNT-1:0] w_s(input [S_COUNT-1:0] val);
140+
w_s = val;
141+
endfunction
142+
143+
axis_switch #(
144+
.S_COUNT({{m}}),
145+
.M_COUNT({{n}}),
146+
.DATA_WIDTH(DATA_WIDTH),
147+
.KEEP_ENABLE(KEEP_ENABLE),
148+
.KEEP_WIDTH(KEEP_WIDTH),
149+
.ID_ENABLE(ID_ENABLE),
150+
.ID_WIDTH(ID_WIDTH),
151+
.DEST_WIDTH(DEST_WIDTH),
152+
.USER_ENABLE(USER_ENABLE),
153+
.USER_WIDTH(USER_WIDTH),
154+
.M_BASE({ {% for p in range(n-1,-1,-1) %}w_32(M{{'%02d'%p}}_BASE){% if not loop.last %}, {% endif %}{% endfor %} }),
155+
.M_TOP({ {% for p in range(n-1,-1,-1) %}w_32(M{{'%02d'%p}}_TOP){% if not loop.last %}, {% endif %}{% endfor %} }),
156+
.M_CONNECT({ {% for p in range(n-1,-1,-1) %}w_s(M{{'%02d'%p}}_CONNECT){% if not loop.last %}, {% endif %}{% endfor %} }),
157+
.S_REG_TYPE(S_REG_TYPE),
158+
.M_REG_TYPE(M_REG_TYPE),
159+
.ARB_TYPE(ARB_TYPE),
160+
.LSB_PRIORITY(LSB_PRIORITY)
161+
)
162+
axis_switch_inst (
163+
.clk(clk),
164+
.rst(rst),
165+
// AXI inputs
166+
.s_axis_tdata({ {% for p in range(m-1,-1,-1) %}s{{'%02d'%p}}_axis_tdata{% if not loop.last %}, {% endif %}{% endfor %} }),
167+
.s_axis_tkeep({ {% for p in range(m-1,-1,-1) %}s{{'%02d'%p}}_axis_tkeep{% if not loop.last %}, {% endif %}{% endfor %} }),
168+
.s_axis_tvalid({ {% for p in range(m-1,-1,-1) %}s{{'%02d'%p}}_axis_tvalid{% if not loop.last %}, {% endif %}{% endfor %} }),
169+
.s_axis_tready({ {% for p in range(m-1,-1,-1) %}s{{'%02d'%p}}_axis_tready{% if not loop.last %}, {% endif %}{% endfor %} }),
170+
.s_axis_tlast({ {% for p in range(m-1,-1,-1) %}s{{'%02d'%p}}_axis_tlast{% if not loop.last %}, {% endif %}{% endfor %} }),
171+
.s_axis_tid({ {% for p in range(m-1,-1,-1) %}s{{'%02d'%p}}_axis_tid{% if not loop.last %}, {% endif %}{% endfor %} }),
172+
.s_axis_tdest({ {% for p in range(m-1,-1,-1) %}s{{'%02d'%p}}_axis_tdest{% if not loop.last %}, {% endif %}{% endfor %} }),
173+
.s_axis_tuser({ {% for p in range(m-1,-1,-1) %}s{{'%02d'%p}}_axis_tuser{% if not loop.last %}, {% endif %}{% endfor %} }),
174+
// AXI outputs
175+
.m_axis_tdata({ {% for p in range(n-1,-1,-1) %}m{{'%02d'%p}}_axis_tdata{% if not loop.last %}, {% endif %}{% endfor %} }),
176+
.m_axis_tkeep({ {% for p in range(n-1,-1,-1) %}m{{'%02d'%p}}_axis_tkeep{% if not loop.last %}, {% endif %}{% endfor %} }),
177+
.m_axis_tvalid({ {% for p in range(n-1,-1,-1) %}m{{'%02d'%p}}_axis_tvalid{% if not loop.last %}, {% endif %}{% endfor %} }),
178+
.m_axis_tready({ {% for p in range(n-1,-1,-1) %}m{{'%02d'%p}}_axis_tready{% if not loop.last %}, {% endif %}{% endfor %} }),
179+
.m_axis_tlast({ {% for p in range(n-1,-1,-1) %}m{{'%02d'%p}}_axis_tlast{% if not loop.last %}, {% endif %}{% endfor %} }),
180+
.m_axis_tid({ {% for p in range(n-1,-1,-1) %}m{{'%02d'%p}}_axis_tid{% if not loop.last %}, {% endif %}{% endfor %} }),
181+
.m_axis_tdest({ {% for p in range(n-1,-1,-1) %}m{{'%02d'%p}}_axis_tdest{% if not loop.last %}, {% endif %}{% endfor %} }),
182+
.m_axis_tuser({ {% for p in range(n-1,-1,-1) %}m{{'%02d'%p}}_axis_tuser{% if not loop.last %}, {% endif %}{% endfor %} })
183+
);
184+
185+
endmodule
186+
187+
""")
188+
189+
output_file.write(t.render(
190+
m=m,
191+
n=n,
192+
cm=cm,
193+
cn=cn,
194+
name=name
195+
))
196+
197+
print("Done")
198+
199+
if __name__ == "__main__":
200+
main()
201+

0 commit comments

Comments
 (0)