blob: ee07d5ed3adf56fefb39bebcd76aeac5381ae4f1 [file] [log] [blame]
`include "distributor.v"
`include "arbiter.v"
module wb_xbar #(
parameter NM = 2,
parameter NS = 4,
parameter AW = 32,
parameter DW = 32
) (
input wb_clk_i,
input wb_rst_i,
// Masters interface
input [NM-1:0] wbm_cyc_i,
input [NM-1:0] wbm_stb_i,
input [NM-1:0] wbm_we_i,
input [(NM*(DW/8))-1:0] wbm_sel_i,
input [(NM*AW)-1:0] wbm_adr_i,
input [(NM*DW)-1:0] wbm_dat_i,
output [NM-1:0] wbm_ack_o,
output [NM-1:0] wbm_err_o,
output [(NM*DW)-1:0] wbm_dat_o,
// Slaves interfaces
input [NS-1:0] wbs_ack_i,
input [(NS*DW)-1:0] wbs_dat_i,
output [NS-1:0] wbs_cyc_o,
output [NS-1:0] wbs_stb_o,
output [NS-1:0] wbs_we_o,
output [(NS*(DW/8))-1:0] wbs_sel_o,
output [(NS*AW)-1:0] wbs_adr_o,
output [(NS*DW)-1:0] wbs_dat_o
);
parameter ADR_MASK = {
{8'hFF, {24{1'b0}}},
{8'hFF, {24{1'b0}}},
{8'hFF, {24{1'b0}}},
{8'hFF, {24{1'b0}}}
};
parameter SLAVE_ADR = {
{8'hB0, {24{1'b0}}},
{8'hA0, {24{1'b0}}},
{8'h90, {24{1'b0}}},
{8'h80, {24{1'b0}}}
};
localparam SEL = DW / 8;
wire [(NM*NS)-1:0] distributor_cyc_o;
wire [(NM*NS)-1:0] distributor_stb_o;
wire [(NM*NS)-1:0] distributor_we_o;
wire [(NM*NS*SEL)-1:0] distributor_sel_o;
wire [(NM*NS*AW)-1:0] distributor_adr_o;
wire [(NM*NS*DW)-1:0] distributor_dat_o;
wire [(NM*NS)-1:0] distributor_ack_i;
wire [(NM*NS)-1:0] distributor_err_i;
wire [(NM*NS)-1:0] distributor_rty_i;
wire [(NM*NS*DW)-1:0] distributor_dat_i;
//Arbiter busses:
wire [(NM*NS)-1:0] arbiter_cyc_i;
wire [(NM*NS)-1:0] arbiter_stb_i;
wire [(NM*NS)-1:0] arbiter_we_i;
wire [(NM*NS*SEL)-1:0] arbiter_sel_i;
wire [(NM*NS*AW)-1:0] arbiter_adr_i;
wire [(NM*NS*DW)-1:0] arbiter_dat_i;
wire [(NM*NS)-1:0] arbiter_ack_o;
wire [(NM*NS)-1:0] arbiter_err_o;
wire [(NM*NS*DW)-1:0] arbiter_dat_o;
//Instantiate distributors
generate
genvar i;
for (i=0; i<NM; i=i+1)
begin
distributor #(
.NS(NS),
.AW(AW),
.DW(DW),
.SLAVE_ADR(SLAVE_ADR),
.ADR_MASK(ADR_MASK)
) distributor (
.wb_clk_i(wb_clk_i),
.wb_rst_i(wb_rst_i),
.wbm_cyc_i(wbm_cyc_i[i]),
.wbm_stb_i(wbm_stb_i[i]),
.wbm_we_i(wbm_we_i[i]),
.wbm_sel_i(wbm_sel_i[(SEL*(i+1))-1:(SEL*i)]),
.wbm_adr_i(wbm_adr_i[(AW*(i+1))-1:(AW*i)]),
.wbm_dat_i(wbm_dat_i[(DW*(i+1))-1:(DW*i)]),
.wbm_ack_o(wbm_ack_o[i]),
.wbm_dat_o(wbm_dat_o[(DW*(i+1))-1:(DW*i)]),
// Slave interfaces
.wbs_cyc_o (distributor_cyc_o[(NS*(i+1))-1:NS*i]),
.wbs_stb_o (distributor_stb_o[(NS*(i+1))-1:NS*i]),
.wbs_we_o (distributor_we_o [(NS*(i+1))-1:NS*i]),
.wbs_sel_o (distributor_sel_o[(NS*SEL*(i+1))-1:NS*SEL*i]),
.wbs_adr_o (distributor_adr_o[(NS*AW*(i+1))-1:NS*AW*i]),
.wbs_dat_o (distributor_dat_o[(NS*DW*(i+1))-1:NS*DW*i]),
.wbs_ack_i (distributor_ack_i[(NS*(i+1))-1:NS*i]),
.wbs_dat_i (distributor_dat_i[(NS*DW*(i+1))-1:NS*DW*i])
);
end
endgenerate
//Instantiate arbiters
generate
genvar j;
for (j=0; j<NS; j=j+1)
begin
wb_arbiter #(
.NM(NM),
.AW(AW),
.DW(DW)
) arbiter (
.wb_clk_i(wb_clk_i),
.wb_rst_i(wb_rst_i),
// Masters Interface
.wbm_cyc_i (arbiter_cyc_i[(NM*(j+1))-1:NM*j]),
.wbm_stb_i (arbiter_stb_i[(NM*(j+1))-1:NM*j]),
.wbm_we_i (arbiter_we_i [(NM*(j+1))-1:NM*j]),
.wbm_sel_i (arbiter_sel_i[(NM*SEL*(j+1))-1:NM*SEL*j]),
.wbm_adr_i (arbiter_adr_i[(NM*AW*(j+1))-1:NM*AW*j]),
.wbm_dat_i (arbiter_dat_i[(NM*DW*(j+1))-1:NM*DW*j]),
.wbm_ack_o (arbiter_ack_o[(NM*(j+1))-1:NM*j]),
.wbm_dat_o (arbiter_dat_o[(NM*DW*(j+1))-1:NM*DW*j]),
// Slave interfaces
.wbs_cyc_o (wbs_cyc_o[j]),
.wbs_stb_o (wbs_stb_o[j]),
.wbs_we_o (wbs_we_o[j]),
.wbs_sel_o (wbs_sel_o[(SEL*(j+1))-1:(SEL*j)]),
.wbs_adr_o (wbs_adr_o[(AW*(j+1))-1:(AW*j)]),
.wbs_dat_o (wbs_dat_o[(DW*(j+1))-1:(DW*j)]),
.wbs_ack_i (wbs_ack_i[j]),
.wbs_dat_i (wbs_dat_i[(DW*(j+1))-1:(DW*j)])
);
end
endgenerate
//Crossbar connections
generate
genvar k, l, m, indx;
for (k=0; k<NM; k=k+1)
for (l=0; l<NS; l=l+1)
begin
assign arbiter_cyc_i[(NM*l)+k] = distributor_cyc_o[(NS*k)+l];
assign arbiter_stb_i[(NM*l)+k] = distributor_stb_o[(NS*k)+l];
assign arbiter_we_i [(NM*l)+k] = distributor_we_o [(NS*k)+l];
assign arbiter_sel_i[(((NM*l)+k)*SEL)+(SEL-1):((NM*l)+k)*SEL] =
distributor_sel_o[(((NS*k)+l)*SEL)+(SEL-1):((NS*k)+l)*SEL];
assign arbiter_adr_i[(((NM*l)+k)*AW)+(AW-1) : ((NM*l)+k)*AW] =
distributor_adr_o[(((NS*k)+l)*AW)+(AW-1) : ((NS*k)+l)*AW];
assign arbiter_dat_i[(((NM*l)+k)*AW)+(AW-1) : ((NM*l)+k)*AW] =
distributor_dat_o[(((NS*k)+l)*AW)+(AW-1) : ((NS*k)+l)*AW];
assign distributor_dat_i[(((NS*k)+l)*DW)+(DW-1) : ((NS*k)+l)*DW] =
arbiter_dat_o[(((NM*l)+k)*DW)+(DW-1) : ((NM*l)+k)*DW];
assign distributor_ack_i[(NS*k)+l] = arbiter_ack_o[(NM*l)+k];
end
endgenerate
endmodule