| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 |
- hub_size = 6
- source = """
- `timescale 1 ns / 1 ps
- module axi_hub #
- (
- parameter integer CFG_DATA_WIDTH = 1024,
- parameter integer STS_DATA_WIDTH = 1024
- )
- (
- input wire aclk,
- input wire aresetn,
- input wire [11:0] s_axi_awid,
- input wire [31:0] s_axi_awaddr,
- input wire s_axi_awvalid,
- output wire s_axi_awready,
- input wire [3:0] s_axi_wstrb,
- input wire s_axi_wlast,
- input wire [31:0] s_axi_wdata,
- input wire s_axi_wvalid,
- output wire s_axi_wready,
- output wire [11:0] s_axi_bid,
- output wire s_axi_bvalid,
- input wire s_axi_bready,
- input wire [11:0] s_axi_arid,
- input wire [3:0] s_axi_arlen,
- input wire [31:0] s_axi_araddr,
- input wire s_axi_arvalid,
- output wire s_axi_arready,
- output wire [11:0] s_axi_rid,
- output wire s_axi_rlast,
- output wire [31:0] s_axi_rdata,
- output wire s_axi_rvalid,
- input wire s_axi_rready,
- output wire [CFG_DATA_WIDTH-1:0] cfg_data,
- input wire [STS_DATA_WIDTH-1:0] sts_data,
- {% for i in range(hub_size) -%}
- {% set index = "%02d" % i %}
- (* X_INTERFACE_INFO = "xilinx.com:interface:bram:1.0 b{{index}}_bram CLK" *)
- output wire b{{index}}_bram_clk,
- (* X_INTERFACE_INFO = "xilinx.com:interface:bram:1.0 b{{index}}_bram RST" *)
- output wire b{{index}}_bram_rst,
- (* X_INTERFACE_INFO = "xilinx.com:interface:bram:1.0 b{{index}}_bram EN" *)
- output wire b{{index}}_bram_en,
- (* X_INTERFACE_INFO = "xilinx.com:interface:bram:1.0 b{{index}}_bram WE" *)
- output wire [3:0] b{{index}}_bram_we,
- (* X_INTERFACE_INFO = "xilinx.com:interface:bram:1.0 b{{index}}_bram ADDR" *)
- output wire [21:0] b{{index}}_bram_addr,
- (* X_INTERFACE_INFO = "xilinx.com:interface:bram:1.0 b{{index}}_bram DIN" *)
- output wire [31:0] b{{index}}_bram_wdata,
- (* X_INTERFACE_INFO = "xilinx.com:interface:bram:1.0 b{{index}}_bram DOUT" *)
- input wire [31:0] b{{index}}_bram_rdata,
- input wire [31:0] s{{index}}_axis_tdata,
- input wire s{{index}}_axis_tvalid,
- output wire s{{index}}_axis_tready,
- output wire [31:0] m{{index}}_axis_tdata,
- output wire m{{index}}_axis_tvalid,
- input wire m{{index}}_axis_tready{% if not loop.last %},{% endif %}
- {% endfor -%}
- );
- localparam integer HUB_SIZE = {{hub_size}};
- localparam integer MUX_SIZE = HUB_SIZE + 2;
- localparam integer CFG_SIZE = CFG_DATA_WIDTH / 32;
- localparam integer CFG_WIDTH = CFG_SIZE > 1 ? $clog2(CFG_SIZE) : 1;
- localparam integer STS_SIZE = STS_DATA_WIDTH / 32;
- localparam integer STS_WIDTH = STS_SIZE > 1 ? $clog2(STS_SIZE) : 1;
- reg [3:0] int_awcntr_reg = 4'd0;
- reg [3:0] int_arcntr_reg = 4'd0;
- wire int_awvalid_wire, int_awready_wire;
- wire int_wvalid_wire, int_wready_wire;
- wire int_bvalid_wire, int_bready_wire;
- wire int_arvalid_wire, int_arready_wire;
- wire int_rvalid_wire, int_rready_wire;
- wire [11:0] int_awid_wire;
- wire [31:0] int_awaddr_wire;
- wire [3:0] int_wstrb_wire;
- wire int_wlast_wire;
- wire [31:0] int_wdata_wire;
- wire [11:0] int_arid_wire;
- wire [3:0] int_arlen_wire;
- wire [31:0] int_araddr_wire;
- wire [11:0] int_rid_wire;
- wire int_rlast_wire;
- wire [31:0] int_rdata_wire [MUX_SIZE-1:0];
- wire [31:0] int_sdata_wire [HUB_SIZE-1:0];
- wire [31:0] int_mdata_wire [HUB_SIZE-1:0];
- wire [HUB_SIZE-1:0] int_svalid_wire, int_sready_wire;
- wire [HUB_SIZE-1:0] int_mvalid_wire, int_mready_wire;
- wire [31:0] int_bdata_wire [HUB_SIZE-1:0];
- wire [21:0] int_waddr_wire;
- wire [21:0] int_raddr_wire;
- wire [31:0] int_cfg_mux [CFG_SIZE-1:0];
- wire [31:0] int_sts_mux [STS_SIZE-1:0];
- wire [31:0] int_rdata_mux [MUX_SIZE-1:0];
- wire [MUX_SIZE-1:0] int_wsel_wire, int_rsel_wire;
- wire [HUB_SIZE-1:0] int_bsel_wire;
- wire [CFG_SIZE-1:0] int_ce_wire;
- wire int_we_wire, int_re_wire;
- genvar j, k;
- assign int_awready_wire = int_bready_wire & int_wvalid_wire & int_wlast_wire;
- assign int_wready_wire = int_bready_wire & int_awvalid_wire;
- assign int_bvalid_wire = int_awvalid_wire & int_wvalid_wire & int_wlast_wire;
- assign int_arready_wire = int_rready_wire & int_rlast_wire;
- assign int_rvalid_wire = int_arvalid_wire;
- assign int_rlast_wire = int_arcntr_reg == int_arlen_wire;
- assign int_we_wire = int_bready_wire & int_awvalid_wire & int_wvalid_wire;
- assign int_re_wire = int_rready_wire & int_arvalid_wire;
- assign int_waddr_wire = int_awaddr_wire[23:2] + int_awcntr_reg;
- assign int_raddr_wire = int_araddr_wire[23:2] + int_arcntr_reg;
- assign int_rdata_wire[0] = int_rdata_mux[int_araddr_wire[27:24]];
- assign int_rdata_mux[0] = int_cfg_mux[int_raddr_wire[CFG_WIDTH-1:0]];
- assign int_rdata_mux[1] = int_sts_mux[int_raddr_wire[STS_WIDTH-1:0]];
- generate
- for(j = 0; j < HUB_SIZE; j = j + 1)
- begin : MUXES
- assign int_rdata_mux[j+2] = int_svalid_wire[j] ? int_sdata_wire[j] : 32'd0;
- assign int_rdata_wire[j+2] = int_bsel_wire[j] ? int_bdata_wire[j] : 32'd0;
- assign int_mdata_wire[j] = int_wdata_wire;
- assign int_mvalid_wire[j] = int_wsel_wire[j+2];
- assign int_sready_wire[j] = int_rsel_wire[j+2];
- end
- endgenerate
- generate
- for(j = 0; j < MUX_SIZE; j = j + 1)
- begin : SELECTS
- assign int_wsel_wire[j] = int_we_wire & (int_awaddr_wire[27:24] == j);
- assign int_rsel_wire[j] = int_re_wire & (int_araddr_wire[27:24] == j);
- end
- endgenerate
- generate
- for(j = 0; j < CFG_SIZE; j = j + 1)
- begin : CFG_WORDS
- assign int_cfg_mux[j] = cfg_data[j*32+31:j*32];
- assign int_ce_wire[j] = int_wsel_wire[0] & (int_waddr_wire[CFG_WIDTH-1:0] == j);
- for(k = 0; k < 32; k = k + 1)
- begin : CFG_BITS
- FDRE #(
- .INIT(1'b0)
- ) FDRE_inst (
- .CE(int_ce_wire[j] & int_wstrb_wire[k/8]),
- .C(aclk),
- .R(~aresetn),
- .D(int_wdata_wire[k]),
- .Q(cfg_data[j*32 + k])
- );
- end
- end
- endgenerate
- generate
- for(j = 0; j < STS_SIZE; j = j + 1)
- begin : STS_WORDS
- assign int_sts_mux[j] = sts_data[j*32+31:j*32];
- end
- endgenerate
- always @(posedge aclk)
- begin
- if(~aresetn | (int_awvalid_wire & int_awready_wire))
- begin
- int_awcntr_reg <= 4'd0;
- end
- else if(~int_wlast_wire & int_we_wire)
- begin
- int_awcntr_reg <= int_awcntr_reg + 1'b1;
- end
- if(~aresetn | (int_arvalid_wire & int_arready_wire))
- begin
- int_arcntr_reg <= 4'd0;
- end
- else if(~int_rlast_wire & int_re_wire)
- begin
- int_arcntr_reg <= int_arcntr_reg + 1'b1;
- end
- end
- inout_buffer #(
- .DATA_WIDTH(44)
- ) buf_0 (
- .aclk(aclk), .aresetn(aresetn),
- .in_data({s_axi_awid, s_axi_awaddr}),
- .in_valid(s_axi_awvalid), .in_ready(s_axi_awready),
- .out_data({int_awid_wire, int_awaddr_wire}),
- .out_valid(int_awvalid_wire), .out_ready(int_awready_wire)
- );
- inout_buffer #(
- .DATA_WIDTH(37)
- ) buf_1 (
- .aclk(aclk), .aresetn(aresetn),
- .in_data({s_axi_wstrb, s_axi_wlast, s_axi_wdata}),
- .in_valid(s_axi_wvalid), .in_ready(s_axi_wready),
- .out_data({int_wstrb_wire, int_wlast_wire, int_wdata_wire}),
- .out_valid(int_wvalid_wire), .out_ready(int_wready_wire)
- );
- output_buffer #(
- .DATA_WIDTH(12)
- ) buf_2 (
- .aclk(aclk), .aresetn(aresetn),
- .in_data(int_awid_wire), .in_valid(int_bvalid_wire), .in_ready(int_bready_wire),
- .out_data(s_axi_bid), .out_valid(s_axi_bvalid), .out_ready(s_axi_bready)
- );
- inout_buffer #(
- .DATA_WIDTH(48)
- ) buf_3 (
- .aclk(aclk), .aresetn(aresetn),
- .in_data({s_axi_arid, s_axi_arlen, s_axi_araddr}),
- .in_valid(s_axi_arvalid), .in_ready(s_axi_arready),
- .out_data({int_arid_wire, int_arlen_wire, int_araddr_wire}),
- .out_valid(int_arvalid_wire), .out_ready(int_arready_wire)
- );
- output_buffer #(
- .DATA_WIDTH(HUB_SIZE + 45)
- ) buf_4 (
- .aclk(aclk), .aresetn(aresetn),
- .in_data({int_rsel_wire[MUX_SIZE-1:2] & ~int_svalid_wire, int_arid_wire, int_rlast_wire, int_rdata_wire[0]}),
- .in_valid(int_rvalid_wire), .in_ready(int_rready_wire),
- .out_data({int_bsel_wire, s_axi_rid, s_axi_rlast, int_rdata_wire[1]}),
- .out_valid(s_axi_rvalid), .out_ready(s_axi_rready)
- );
- assign s_axi_rdata = {{s_axi_rdata(hub_size)}};
- {% for i in range(hub_size) -%}
- {% set index = "%02d" % i %}
- assign int_bdata_wire[{{i}}] = b{{index}}_bram_rdata;
- assign b{{index}}_bram_clk = aclk;
- assign b{{index}}_bram_rst = ~aresetn;
- assign b{{index}}_bram_en = int_rsel_wire[{{i+2}}] | int_wsel_wire[{{i+2}}];
- assign b{{index}}_bram_we = int_wsel_wire[{{i+2}}] ? int_wstrb_wire : 4'd0;
- assign b{{index}}_bram_addr = int_we_wire ? int_waddr_wire : int_raddr_wire;
- assign b{{index}}_bram_wdata = int_wdata_wire;
- assign int_sdata_wire[{{i}}] = s{{index}}_axis_tdata;
- assign int_svalid_wire[{{i}}] = s{{index}}_axis_tvalid;
- assign s{{index}}_axis_tready = int_sready_wire[{{i}}];
- inout_buffer #(
- .DATA_WIDTH(32)
- ) mbuf_{{i}} (
- .aclk(aclk), .aresetn(aresetn),
- .in_data(int_mdata_wire[{{i}}]), .in_valid(int_mvalid_wire[{{i}}]), .in_ready(int_mready_wire[{{i}}]),
- .out_data(m{{index}}_axis_tdata), .out_valid(m{{index}}_axis_tvalid), .out_ready(m{{index}}_axis_tready)
- );
- {% endfor %}
- endmodule
- """
- import jinja2
- def s_axi_rdata(n):
- return " | ".join(map(lambda i: "int_rdata_wire[%d]" % i, range(1, n + 2)))
- print(jinja2.Template(source).render(hub_size=hub_size, s_axi_rdata=s_axi_rdata))
|