OpenCores
URL https://opencores.org/ocsvn/amber/amber/trunk

Subversion Repositories amber

[/] [amber/] [trunk/] [hw/] [vlog/] [system/] [wishbone_arbiter.v] - Rev 2

Go to most recent revision | Compare with Previous | Blame | View Log

//////////////////////////////////////////////////////////////////
//                                                              //
//  Wishbone Arbiter                                            //
//                                                              //
//  This file is part of the Amber project                      //
//  http://www.opencores.org/project,amber                      //
//                                                              //
//  Description                                                 //
//  Arbitrates between two wishbone masters and 13 wishbone     //
//  slave modules. The ethernet MAC wishbone master is given    //
//  priority over the Amber core.                               //
//                                                              //
//  Author(s):                                                  //
//      - Conor Santifort, csantifort.amber@gmail.com           //
//                                                              //
//////////////////////////////////////////////////////////////////
//                                                              //
// Copyright (C) 2010 Authors and OPENCORES.ORG                 //
//                                                              //
// This source file may be used and distributed without         //
// restriction provided that this copyright statement is not    //
// removed from the file and that any derivative work contains  //
// the original copyright notice and the associated disclaimer. //
//                                                              //
// This source file is free software; you can redistribute it   //
// and/or modify it under the terms of the GNU Lesser General   //
// Public License as published by the Free Software Foundation; //
// either version 2.1 of the License, or (at your option) any   //
// later version.                                               //
//                                                              //
// This source is distributed in the hope that it will be       //
// useful, but WITHOUT ANY WARRANTY; without even the implied   //
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
// PURPOSE.  See the GNU Lesser General Public License for more //
// details.                                                     //
//                                                              //
// You should have received a copy of the GNU Lesser General    //
// Public License along with this source; if not, download it   //
// from http://www.opencores.org/lgpl.shtml                     //
//                                                              //
//////////////////////////////////////////////////////////////////
 
 
module wishbone_arbiter (
input                   i_wb_clk,     // WISHBONE clock
 
// WISHBONE master 0 - Amber
input       [31:0]      i_m0_wb_adr,
input       [3:0]       i_m0_wb_sel,
input                   i_m0_wb_we,
output      [31:0]      o_m0_wb_dat,
input       [31:0]      i_m0_wb_dat,
input                   i_m0_wb_cyc,
input                   i_m0_wb_stb,
output                  o_m0_wb_ack,
output                  o_m0_wb_err,
 
 
// WISHBONE master 1 - Ethmac
input       [31:0]      i_m1_wb_adr,
input       [3:0]       i_m1_wb_sel,
input                   i_m1_wb_we,
output      [31:0]      o_m1_wb_dat,
input       [31:0]      i_m1_wb_dat,
input                   i_m1_wb_cyc,
input                   i_m1_wb_stb,
output                  o_m1_wb_ack,
output                  o_m1_wb_err,
 
 
// WISHBONE slave 0 - Ethmac
output      [31:0]      o_s0_wb_adr,
output      [3:0]       o_s0_wb_sel,
output                  o_s0_wb_we,
input       [31:0]      i_s0_wb_dat,
output      [31:0]      o_s0_wb_dat,
output                  o_s0_wb_cyc,
output                  o_s0_wb_stb,
input                   i_s0_wb_ack,
input                   i_s0_wb_err,
 
 
// WISHBONE slave 1 - Boot Memory
output      [31:0]      o_s1_wb_adr,
output      [3:0]       o_s1_wb_sel,
output                  o_s1_wb_we,
input       [31:0]      i_s1_wb_dat,
output      [31:0]      o_s1_wb_dat,
output                  o_s1_wb_cyc,
output                  o_s1_wb_stb,
input                   i_s1_wb_ack,
input                   i_s1_wb_err,
 
 
// WISHBONE slave 2 - Main Memory
output      [31:0]      o_s2_wb_adr,
output      [3:0]       o_s2_wb_sel,
output                  o_s2_wb_we,
input       [31:0]      i_s2_wb_dat,
output      [31:0]      o_s2_wb_dat,
output                  o_s2_wb_cyc,
output                  o_s2_wb_stb,
input                   i_s2_wb_ack,
input                   i_s2_wb_err,
 
 
// WISHBONE slave 3 - UART 0
output      [31:0]      o_s3_wb_adr,
output      [3:0]       o_s3_wb_sel,
output                  o_s3_wb_we,
input       [31:0]      i_s3_wb_dat,
output      [31:0]      o_s3_wb_dat,
output                  o_s3_wb_cyc,
output                  o_s3_wb_stb,
input                   i_s3_wb_ack,
input                   i_s3_wb_err,
 
 
// WISHBONE slave 4 - UART 1
output      [31:0]      o_s4_wb_adr,
output      [3:0]       o_s4_wb_sel,
output                  o_s4_wb_we,
input       [31:0]      i_s4_wb_dat,
output      [31:0]      o_s4_wb_dat,
output                  o_s4_wb_cyc,
output                  o_s4_wb_stb,
input                   i_s4_wb_ack,
input                   i_s4_wb_err,
 
 
// WISHBONE slave 5 - Test Module
output      [31:0]      o_s5_wb_adr,
output      [3:0]       o_s5_wb_sel,
output                  o_s5_wb_we,
input       [31:0]      i_s5_wb_dat,
output      [31:0]      o_s5_wb_dat,
output                  o_s5_wb_cyc,
output                  o_s5_wb_stb,
input                   i_s5_wb_ack,
input                   i_s5_wb_err,
 
 
// WISHBONE slave 6 - Timer Module
output      [31:0]      o_s6_wb_adr,
output      [3:0]       o_s6_wb_sel,
output                  o_s6_wb_we,
input       [31:0]      i_s6_wb_dat,
output      [31:0]      o_s6_wb_dat,
output                  o_s6_wb_cyc,
output                  o_s6_wb_stb,
input                   i_s6_wb_ack,
input                   i_s6_wb_err,
 
 
 // WISHBONE slave 7 - Interrupt Controller
output      [31:0]      o_s7_wb_adr,
output      [3:0]       o_s7_wb_sel,
output                  o_s7_wb_we,
input       [31:0]      i_s7_wb_dat,
output      [31:0]      o_s7_wb_dat,
output                  o_s7_wb_cyc,
output                  o_s7_wb_stb,
input                   i_s7_wb_ack,
input                   i_s7_wb_err
);
 
`include "memory_configuration.v"
reg         m0_wb_cyc_r = 'd0;
reg         m1_wb_cyc_r = 'd0;
wire        m0_in_cycle;
wire        m1_in_cycle;
wire        current_master;
reg         current_master_r = 'd0;
wire        next_master;
wire        select_master;
wire [3:0]  current_slave;
 
wire [31:0] master_adr;
wire [3:0]  master_sel;
wire        master_we;
wire [31:0] master_wdat;
wire        master_cyc;
wire        master_stb;
wire [31:0] master_rdat;
wire        master_ack;
wire        master_err;
 
// Arbitrate between m0 and m1. Ethmac (m0) always gets priority
assign next_master    = i_m0_wb_cyc ? 1'd0 : 1'd1;
 
// Use cyc signal for arbitration so block accesses are not split up
assign m0_in_cycle    = m0_wb_cyc_r && i_m0_wb_cyc;
assign m1_in_cycle    = m1_wb_cyc_r && i_m1_wb_cyc;
 
// only select a new bus master when the current bus master
// de-asserts the cyc signal
assign select_master  = current_master_r ? !m1_in_cycle : !m0_in_cycle;
assign current_master = select_master ? next_master : current_master_r;
 
 
always @( posedge i_wb_clk )
    begin
    current_master_r    <= current_master;
    m0_wb_cyc_r         <= i_m0_wb_cyc;
    m1_wb_cyc_r         <= i_m1_wb_cyc;
    end
 
 
// Arbitrate between slaves
assign current_slave = in_ethmac   ( master_adr ) ? 4'd0  :  // Ethmac
                       in_boot_mem ( master_adr ) ? 4'd1  :  // Boot memory
                       in_main_mem ( master_adr ) ? 4'd2  :  // Main memory
                       in_uart0    ( master_adr ) ? 4'd3  :  // UART 0
                       in_uart1    ( master_adr ) ? 4'd4  :  // UART 1
                       in_test     ( master_adr ) ? 4'd5  :  // Test Module
                       in_tm       ( master_adr ) ? 4'd6  :  // Timer Module
                       in_ic       ( master_adr ) ? 4'd7  :  // Interrupt Controller
                                                    4'd2  ;  // default to main memory
 
 
assign master_adr   = current_master ? i_m1_wb_adr : i_m0_wb_adr ;
// Switch endianess of ethmac Master
assign master_sel   = current_master ? i_m1_wb_sel : {i_m0_wb_sel[0], i_m0_wb_sel[1], 
                                                      i_m0_wb_sel[2], i_m0_wb_sel[3]};
assign master_wdat  = current_master ? i_m1_wb_dat : {i_m0_wb_dat[7:0],  i_m0_wb_dat[15:8],
                                                      i_m0_wb_dat[23:16],i_m0_wb_dat[31:24]} ;
assign master_we    = current_master ? i_m1_wb_we  : i_m0_wb_we  ;
assign master_cyc   = current_master ? i_m1_wb_cyc : i_m0_wb_cyc ;
assign master_stb   = current_master ? i_m1_wb_stb : i_m0_wb_stb ;
 
 
// Ethmac Slave outputs
assign o_s0_wb_adr  = master_adr;
assign o_s0_wb_dat  = master_wdat;
assign o_s0_wb_sel  = master_sel;
assign o_s0_wb_we   = current_slave == 4'd0 ? master_we  : 1'd0;
assign o_s0_wb_cyc  = current_slave == 4'd0 ? master_cyc : 1'd0;
assign o_s0_wb_stb  = current_slave == 4'd0 ? master_stb : 1'd0;
 
// Boot Memory outputs
assign o_s1_wb_adr  = master_adr;
assign o_s1_wb_dat  = master_wdat;
assign o_s1_wb_sel  = master_sel;
assign o_s1_wb_we   = current_slave == 4'd1 ? master_we  : 1'd0;
assign o_s1_wb_cyc  = current_slave == 4'd1 ? master_cyc : 1'd0;
assign o_s1_wb_stb  = current_slave == 4'd1 ? master_stb : 1'd0;
 
// Main Memory Outputs
assign o_s2_wb_adr  = master_adr;
assign o_s2_wb_dat  = master_wdat;
assign o_s2_wb_sel  = master_sel;
assign o_s2_wb_we   = current_slave == 4'd2 ? master_we  : 1'd0;
assign o_s2_wb_cyc  = current_slave == 4'd2 ? master_cyc : 1'd0;
assign o_s2_wb_stb  = current_slave == 4'd2 ? master_stb : 1'd0;
 
// UART0 Outputs
assign o_s3_wb_adr  = master_adr;
assign o_s3_wb_dat  = master_wdat;
assign o_s3_wb_sel  = master_sel;
assign o_s3_wb_we   = current_slave == 4'd3 ? master_we  : 1'd0;
assign o_s3_wb_cyc  = current_slave == 4'd3 ? master_cyc : 1'd0;
assign o_s3_wb_stb  = current_slave == 4'd3 ? master_stb : 1'd0;
 
// UART1 Outputs
assign o_s4_wb_adr  = master_adr;
assign o_s4_wb_dat  = master_wdat;
assign o_s4_wb_sel  = master_sel;
assign o_s4_wb_we   = current_slave == 4'd4 ? master_we  : 1'd0;
assign o_s4_wb_cyc  = current_slave == 4'd4 ? master_cyc : 1'd0;
assign o_s4_wb_stb  = current_slave == 4'd4 ? master_stb : 1'd0;
 
// Test Module Outputs
assign o_s5_wb_adr  = master_adr;
assign o_s5_wb_dat  = master_wdat;
assign o_s5_wb_sel  = master_sel;
assign o_s5_wb_we   = current_slave == 5'd5 ? master_we  : 1'd0;
assign o_s5_wb_cyc  = current_slave == 5'd5 ? master_cyc : 1'd0;
assign o_s5_wb_stb  = current_slave == 5'd5 ? master_stb : 1'd0;
 
// Timers Outputs
assign o_s6_wb_adr  = master_adr;
assign o_s6_wb_dat  = master_wdat;
assign o_s6_wb_sel  = master_sel;
assign o_s6_wb_we   = current_slave == 6'd6 ? master_we  : 1'd0;
assign o_s6_wb_cyc  = current_slave == 6'd6 ? master_cyc : 1'd0;
assign o_s6_wb_stb  = current_slave == 6'd6 ? master_stb : 1'd0;
 
// Interrupt Controller
assign o_s7_wb_adr  = master_adr;
assign o_s7_wb_dat  = master_wdat;
assign o_s7_wb_sel  = master_sel;
assign o_s7_wb_we   = current_slave == 4'd7 ? master_we  : 1'd0;
assign o_s7_wb_cyc  = current_slave == 4'd7 ? master_cyc : 1'd0;
assign o_s7_wb_stb  = current_slave == 4'd7 ? master_stb : 1'd0;
 
 
// Master Outputs
assign master_rdat  = current_slave == 4'd0  ? i_s0_wb_dat  :
                      current_slave == 4'd1  ? i_s1_wb_dat  :
                      current_slave == 4'd2  ? i_s2_wb_dat  :
                      current_slave == 4'd3  ? i_s3_wb_dat  :
                      current_slave == 4'd4  ? i_s4_wb_dat  :
                      current_slave == 4'd5  ? i_s5_wb_dat  :
                      current_slave == 4'd6  ? i_s6_wb_dat  :
                      current_slave == 4'd7  ? i_s7_wb_dat  :
                                               i_s2_wb_dat  ;
 
 
assign master_ack   = current_slave == 4'd0  ? i_s0_wb_ack  :
                      current_slave == 4'd1  ? i_s1_wb_ack  :
                      current_slave == 4'd2  ? i_s2_wb_ack  :
                      current_slave == 4'd3  ? i_s3_wb_ack  :
                      current_slave == 4'd4  ? i_s4_wb_ack  :
                      current_slave == 4'd5  ? i_s5_wb_ack  :
                      current_slave == 4'd6  ? i_s6_wb_ack  :
                      current_slave == 4'd7  ? i_s7_wb_ack  :
                                               i_s2_wb_ack  ; 
 
 
assign master_err   = current_slave == 4'd0  ? i_s0_wb_err  :
                      current_slave == 4'd1  ? i_s1_wb_err  :
                      current_slave == 4'd2  ? i_s2_wb_err  :
                      current_slave == 4'd3  ? i_s3_wb_err  :
                      current_slave == 4'd4  ? i_s4_wb_err  :
                      current_slave == 4'd5  ? i_s5_wb_err  :
                      current_slave == 4'd6  ? i_s6_wb_err  :
                      current_slave == 4'd7  ? i_s7_wb_err  :
                                               i_s2_wb_err  ; 
 
 
// Ethmac Master Outputs
// Switch endianess of ethmac Master
assign o_m0_wb_dat  = {master_rdat[7:0], master_rdat[15:8],
                       master_rdat[23:16],master_rdat[31:24]};
assign o_m0_wb_ack  = current_master  ? 1'd0 : master_ack ;
assign o_m0_wb_err  = current_master  ? 1'd0 : master_err ;
 
// Amber Master Outputs
assign o_m1_wb_dat  = master_rdat;
assign o_m1_wb_ack  = current_master  ?  master_ack : 1'd0 ;
assign o_m1_wb_err  = current_master  ?  master_err : 1'd0 ;
 
endmodule
 
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.