blob: 4631887f36eb5ffa5fb692ddb259b7f9e89a0312 [file] [log] [blame]
//-----------------------------------------------------------------------------
// @file wb_interconnect.vhd
//
// @brief Convey wishbone signals to corresponding module.
//
// @details 1 masters and 4 slaves share bus Wishbone connection
// M0 - WB_PORT
// S0 - SRAM
// S1 - UART
// S2 - TRNG
// S3 - SPI
//
// @author Sukru Uzun <sukru.uzun@procenne.com>
// @date 10.03.2022
//
// @todo add other modules
// @warning be careful about chip select
//
// @project https://github.com/Procenne-Digital-Design/secure-memory.git
//
// @revision :
// 0.1 - 10 March 2022, Sukru Uzun
// initial version
//-----------------------------------------------------------------------------
module wb_interconnect
(
`ifdef USE_POWER_PINS
input logic vccd1, // User area 1 1.8V supply
input logic vssd1, // User area 1 digital ground
`endif
input logic clk_i,
input logic rst_n,
// Master 0 Interface
input logic [31:0] m0_wb_dat_i,
input logic [31:0] m0_wb_adr_i,
input logic [3:0] m0_wb_sel_i,
input logic m0_wb_we_i,
input logic m0_wb_cyc_i,
input logic m0_wb_stb_i,
output logic [31:0] m0_wb_dat_o,
output logic m0_wb_ack_o,
output logic m0_wb_err_o,
// Slave 0 Interface
input logic [31:0] s0_wb_dat_i,
input logic s0_wb_ack_i,
output logic [31:0] s0_wb_dat_o,
output logic [7:0] s0_wb_adr_o,
output logic [3:0] s0_wb_sel_o,
output logic s0_wb_we_o,
output logic s0_wb_cyc_o,
output logic s0_wb_stb_o,
// Slave 1 Interface
input logic [31:0] s1_wb_dat_i,
input logic s1_wb_ack_i,
output logic [31:0] s1_wb_dat_o,
output logic [10:0] s1_wb_adr_o,
output logic [3:0] s1_wb_sel_o,
output logic s1_wb_we_o,
output logic s1_wb_cyc_o,
output logic s1_wb_stb_o,
// Slave 2 Interface
input logic [31:0] s2_wb_dat_i,
input logic s2_wb_ack_i,
output logic [31:0] s2_wb_dat_o,
output logic [10:0] s2_wb_adr_o,
output logic [3:0] s2_wb_sel_o,
output logic s2_wb_we_o,
output logic s2_wb_cyc_o,
output logic s2_wb_stb_o,
// Slave 3 Interface
input logic [31:0] s3_wb_dat_i,
input logic s3_wb_ack_i,
output logic [31:0] s3_wb_dat_o,
output logic [10:0] s3_wb_adr_o,
output logic [3:0] s3_wb_sel_o,
output logic s3_wb_we_o,
output logic s3_wb_cyc_o,
output logic s3_wb_stb_o
);
// WishBone Wr Interface
typedef struct packed {
logic [31:0] wb_dat;
logic [31:0] wb_adr;
logic [3:0] wb_sel;
logic wb_we;
logic wb_cyc;
logic wb_stb;
logic [1:0] wb_tid; // target id
} type_wb_wr_intf;
// WishBone Rd Interface
typedef struct packed {
logic [31:0] wb_dat;
logic wb_ack;
logic wb_err;
} type_wb_rd_intf;
// Master Write Interface
type_wb_wr_intf m0_wb_wr;
// Master Read Interface
type_wb_rd_intf m0_wb_rd;
// Slave Write Interface
type_wb_wr_intf s0_wb_wr;
type_wb_wr_intf s1_wb_wr;
type_wb_wr_intf s2_wb_wr;
type_wb_wr_intf s3_wb_wr;
// Slave Read Interface
type_wb_rd_intf s0_wb_rd;
type_wb_rd_intf s1_wb_rd;
type_wb_rd_intf s2_wb_rd;
type_wb_rd_intf s3_wb_rd;
type_wb_wr_intf s_bus_wr; // Multiplexed Master I/F
type_wb_rd_intf s_bus_rd; // Multiplexed Slave I/F
//-------------------------------------------------------------------
// EXTERNAL MEMORY MAP
// 0x0000_0000 to 0x0000_0FFF - SRAM
// 0x0000_1000 to 0x0000_1FFF - UART
// 0x0000_2000 to 0x0000_2FFF - TRNG
// 0x0000_3000 to 0x0000_3FFF - SPI
// ------------------------------------------------------------------
wire [1:0] m0_wb_tid_i = m0_wb_adr_i[13:12];
//----------------------------------------
// Master Mapping
// ---------------------------------------
assign m0_wb_wr.wb_dat = m0_wb_dat_i;
assign m0_wb_wr.wb_adr = {m0_wb_adr_i[31:2],2'b00};
assign m0_wb_wr.wb_sel = m0_wb_sel_i;
assign m0_wb_wr.wb_we = m0_wb_we_i;
assign m0_wb_wr.wb_cyc = m0_wb_cyc_i;
assign m0_wb_wr.wb_stb = m0_wb_stb_i;
assign m0_wb_wr.wb_tid = m0_wb_tid_i;
assign m0_wb_dat_o = m0_wb_rd.wb_dat;
assign m0_wb_ack_o = m0_wb_rd.wb_ack;
assign m0_wb_err_o = m0_wb_rd.wb_err;
//----------------------------------------
// Slave Mapping
// -------------------------------------
// 2KB SRAM
assign s0_wb_dat_o = s0_wb_wr.wb_dat;
assign s0_wb_adr_o = s0_wb_wr.wb_adr[8:0];
assign s0_wb_sel_o = s0_wb_wr.wb_sel;
assign s0_wb_we_o = s0_wb_wr.wb_we;
assign s0_wb_cyc_o = s0_wb_wr.wb_cyc;
assign s0_wb_stb_o = s0_wb_wr.wb_stb;
assign s0_wb_rd.wb_dat = s0_wb_dat_i;
assign s0_wb_rd.wb_ack = s0_wb_ack_i;
assign s0_wb_rd.wb_err = 1'b0;
// UART
assign s1_wb_dat_o = s1_wb_wr.wb_dat;
assign s1_wb_adr_o = s1_wb_wr.wb_adr[10:0];
assign s1_wb_sel_o = s1_wb_wr.wb_sel;
assign s1_wb_we_o = s1_wb_wr.wb_we;
assign s1_wb_cyc_o = s1_wb_wr.wb_cyc;
assign s1_wb_stb_o = s1_wb_wr.wb_stb;
assign s1_wb_rd.wb_dat = s1_wb_dat_i;
assign s1_wb_rd.wb_ack = s1_wb_ack_i;
assign s1_wb_rd.wb_err = 1'b0;
// TRNG
assign s2_wb_dat_o = s2_wb_wr.wb_dat;
assign s2_wb_adr_o = s2_wb_wr.wb_adr[10:0];
assign s2_wb_sel_o = s2_wb_wr.wb_sel;
assign s2_wb_we_o = s2_wb_wr.wb_we;
assign s2_wb_cyc_o = s2_wb_wr.wb_cyc;
assign s2_wb_stb_o = s2_wb_wr.wb_stb;
assign s2_wb_rd.wb_dat = s2_wb_dat_i;
assign s2_wb_rd.wb_ack = s2_wb_ack_i;
assign s2_wb_rd.wb_err = 1'b0;
// SPI
assign s3_wb_dat_o = s3_wb_wr.wb_dat;
assign s3_wb_adr_o = s3_wb_wr.wb_adr[10:0];
assign s3_wb_sel_o = s3_wb_wr.wb_sel;
assign s3_wb_we_o = s3_wb_wr.wb_we;
assign s3_wb_cyc_o = s3_wb_wr.wb_cyc;
assign s3_wb_stb_o = s3_wb_wr.wb_stb;
assign s3_wb_rd.wb_dat = s3_wb_dat_i;
assign s3_wb_rd.wb_ack = s3_wb_ack_i;
assign s3_wb_rd.wb_err = 1'b0;
// Generate Multiplexed Slave Interface based on target Id
wire [3:0] s_wb_tid = s_bus_wr.wb_tid; // to fix iverilog warning
always_comb begin
case(s_wb_tid)
2'b00: s_bus_rd = s0_wb_rd;
2'b01: s_bus_rd = s1_wb_rd;
2'b10: s_bus_rd = s2_wb_rd;
2'b11: s_bus_rd = s3_wb_rd;
endcase
end
// Connect Master => Slave
assign s0_wb_wr = (s_wb_tid == 2'b00) ? s_bus_wr : 2'b00;
assign s1_wb_wr = (s_wb_tid == 2'b01) ? s_bus_wr : 2'b00;
assign s2_wb_wr = (s_wb_tid == 2'b10) ? s_bus_wr : 2'b00;
assign s3_wb_wr = (s_wb_tid == 2'b11) ? s_bus_wr : 2'b00;
// Stagging FF to break write and read timing path
wb_stagging u_m_wb_stage(
.clk_i (clk_i),
.rst_n (rst_n),
// WishBone Input master I/P
.m_wb_dat_i (m0_wb_wr.wb_dat),
.m_wb_adr_i (m0_wb_wr.wb_adr),
.m_wb_sel_i (m0_wb_wr.wb_sel),
.m_wb_we_i (m0_wb_wr.wb_we ),
.m_wb_cyc_i (m0_wb_wr.wb_cyc),
.m_wb_stb_i (m0_wb_wr.wb_stb),
.m_wb_tid_i (m0_wb_wr.wb_tid),
.m_wb_dat_o (m0_wb_rd.wb_dat),
.m_wb_ack_o (m0_wb_rd.wb_ack),
.m_wb_err_o (m0_wb_rd.wb_err),
// Slave Interface
.s_wb_dat_i (s_bus_rd.wb_dat),
.s_wb_ack_i (s_bus_rd.wb_ack),
.s_wb_err_i (s_bus_rd.wb_err),
.s_wb_dat_o (s_bus_wr.wb_dat),
.s_wb_adr_o (s_bus_wr.wb_adr),
.s_wb_sel_o (s_bus_wr.wb_sel),
.s_wb_we_o (s_bus_wr.wb_we ),
.s_wb_cyc_o (s_bus_wr.wb_cyc),
.s_wb_stb_o (s_bus_wr.wb_stb),
.s_wb_tid_o (s_bus_wr.wb_tid)
);
endmodule