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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [mp3/] [rtl/] [verilog/] [tcop_top.v] - Rev 1773

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

//////////////////////////////////////////////////////////////////////
////                                                              ////
////  MP3 demo Traffic Cop                                        ////
////                                                              ////
////  This file is part of the MP3 demo application               ////
////  http://www.opencores.org/cores/or1k/mp3/                    ////
////                                                              ////
////  Description                                                 ////
////  This block connectes the RISC, audio i/f and memory         ////
////  controller together.                                        ////
////                                                              ////
////  To Do:                                                      ////
////   - nothing really                                           ////
////                                                              ////
////  Author(s):                                                  ////
////      - Lior Shtram, lior.shtram@flextronicssemi.com          ////
////                                                              ////
//////////////////////////////////////////////////////////////////////
////                                                              ////
//// Copyright (C) 2001 Authors                                   ////
////                                                              ////
//// 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                     ////
////                                                              ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
//
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
 
// sr_input_sel
`define SR_RD	3'b001
`define SR_RI	3'b010
`define SR_VM	3'b011
`define SR_DM	3'b100
 
 
module tcop_top (
	rstn,
	clk,
 
        wb_vs_adr_i,
	wb_vs_dat_i,
	wb_vs_dat_o,
        wb_vs_sel_i,
        wb_vs_we_i,
        wb_vs_stb_i,
        wb_vs_cyc_i,
        wb_vs_ack_o,
        wb_vs_err_o,
 
        wb_vm_adr_o,
        wb_vm_dat_i,
        wb_vm_sel_o,
        wb_vm_we_o,
        wb_vm_stb_o,
        wb_vm_cyc_o,
        wb_vm_cab_o,
        wb_vm_ack_i,
        wb_vm_err_i,
 
        wb_dm_adr_o,
        wb_dm_dat_i,
	wb_dm_dat_o,
        wb_dm_sel_o,
        wb_dm_we_o,
        wb_dm_stb_o,
        wb_dm_cyc_o,
        wb_dm_cab_o,
        wb_dm_ack_i,
        wb_dm_err_i,
 
        wb_ri_cyc_o,
        wb_ri_adr_o,
        wb_ri_dat_i,
        wb_ri_dat_o,
        wb_ri_sel_o,
        wb_ri_ack_i,
        wb_ri_err_i,
        wb_ri_rty_i,
        wb_ri_we_o,
        wb_ri_stb_o,
 
        wb_rd_cyc_o,
        wb_rd_adr_o,
        wb_rd_dat_i,
        wb_rd_dat_o,
        wb_rd_sel_o,
        wb_rd_ack_i,
        wb_rd_err_i,
        wb_rd_rty_i,
        wb_rd_we_o,
        wb_rd_stb_o,
 
	wb_sr_dat_i,
	wb_sr_dat_o,
	wb_sr_adr_i,
	wb_sr_sel_i,
	wb_sr_we_i,
	wb_sr_cyc_i,
	wb_sr_stb_i,
	wb_sr_ack_o,
	wb_sr_err_o,
 
	wb_fl_dat_i,
	wb_fl_dat_o,
	wb_fl_adr_i,
	wb_fl_sel_i,
	wb_fl_we_i,
	wb_fl_cyc_i,
	wb_fl_stb_i,
	wb_fl_ack_o,
	wb_fl_err_o,
 
	wb_au_dat_i,
	wb_au_dat_o,
	wb_au_adr_i,
	wb_au_sel_i,
	wb_au_we_i,
	wb_au_cyc_i,
	wb_au_stb_i,
	wb_au_ack_o,
	wb_au_err_o
 
);
 
parameter data_width = 32;
parameter addr_width = 32;
 
parameter n_mast_i = (data_width + 2) ;
parameter n_mast_o = data_width + addr_width + 6 ;
 
input clk;
input rstn;
 
output [addr_width-1:0]     wb_vs_adr_i;
output [data_width-1:0]     wb_vs_dat_i;
input  [data_width-1:0]     wb_vs_dat_o;
output [3:0]      wb_vs_sel_i;
output            wb_vs_we_i;
output            wb_vs_stb_i;
output            wb_vs_cyc_i;
input             wb_vs_ack_o;
input             wb_vs_err_o;
 
input  [addr_width-1:0]     wb_vm_adr_o;
output [data_width-1:0]     wb_vm_dat_i;
input  [3:0]      wb_vm_sel_o;
input             wb_vm_stb_o;
input		  wb_vm_we_o;
input             wb_vm_cyc_o;
input             wb_vm_cab_o;
output            wb_vm_ack_i;
output            wb_vm_err_i;
 
input  [addr_width-1:0]     wb_dm_adr_o;
output [data_width-1:0]     wb_dm_dat_i;
input  [data_width-1:0]     wb_dm_dat_o;
input  [3:0]      wb_dm_sel_o;
input             wb_dm_stb_o;
input		  wb_dm_we_o;
input             wb_dm_cyc_o;
input             wb_dm_cab_o;
output            wb_dm_ack_i;
output            wb_dm_err_i;
 
input  [addr_width-1:0]     wb_ri_adr_o;
input             wb_ri_cyc_o;
output [data_width-1:0]     wb_ri_dat_i;
input  [data_width-1:0]     wb_ri_dat_o;
input  [3:0]      wb_ri_sel_o;
output            wb_ri_ack_i;
output            wb_ri_err_i;
output            wb_ri_rty_i;
input             wb_ri_we_o;
input             wb_ri_stb_o;
 
input  [addr_width-1:0]     wb_rd_adr_o;
input             wb_rd_cyc_o;
output [data_width-1:0]     wb_rd_dat_i;
input  [data_width-1:0]     wb_rd_dat_o;
input  [3:0]      wb_rd_sel_o;
output            wb_rd_ack_i;
output            wb_rd_err_i;
output            wb_rd_rty_i;
input             wb_rd_we_o;
input             wb_rd_stb_o;
 
output [data_width-1:0]     wb_sr_dat_i;
input  [data_width-1:0]     wb_sr_dat_o;
output [addr_width-1:0]     wb_sr_adr_i;
output [3:0]      wb_sr_sel_i;
output            wb_sr_we_i;
output            wb_sr_cyc_i;
output            wb_sr_stb_i;
input             wb_sr_ack_o;
input             wb_sr_err_o;
 
output [data_width-1:0]     wb_fl_dat_i;
input  [data_width-1:0]     wb_fl_dat_o;
output [addr_width-1:0]     wb_fl_adr_i;
output [3:0]      wb_fl_sel_i;
output            wb_fl_we_i;
output            wb_fl_cyc_i;
output            wb_fl_stb_i;
input             wb_fl_ack_o;
input             wb_fl_err_o;
 
output [data_width-1:0]     wb_au_dat_i;
input  [data_width-1:0]     wb_au_dat_o;
output [addr_width-1:0]     wb_au_adr_i;
output [3:0]      wb_au_sel_i;
output            wb_au_we_i;
output            wb_au_cyc_i;
output            wb_au_stb_i;
input             wb_au_ack_o;
input             wb_au_err_o;
 
 
wire [data_width-1:0]	data_width_zeros;
assign	data_width_zeros = 0;
wire [n_mast_i-1:0]	n_mast_i_zeros;
assign	n_mast_i_zeros = 0;
wire [n_mast_o-1:0]	n_mast_o_zeros;
wire [n_mast_i-1:0]	ri_inputs;
wire [n_mast_o-1:0]	ri_outputs;
wire [n_mast_i-1:0]	rd_inputs;
wire [n_mast_o-1:0]	rd_outputs;
wire [n_mast_i-1:0]	vm_inputs;
wire [n_mast_o-1:0]	vm_outputs;
wire [n_mast_i-1:0]	dm_inputs;
wire [n_mast_o-1:0]	dm_outputs;
wire [n_mast_o-1:0]	vs_inputs;
wire [n_mast_i-1:0]	vs_outputs;
reg [n_mast_o-1:0]	sr_inputs;
wire [n_mast_i-1:0]	sr_outputs;
wire [n_mast_o-1:0]	fl_inputs;
wire [n_mast_i-1:0]	fl_outputs;
wire [n_mast_o-1:0]	au_inputs;
wire [n_mast_i-1:0]	au_outputs;
wire [n_mast_i-1:0]	sr_to_dm;
wire [n_mast_i-1:0]	fl_to_dm;
wire [n_mast_i-1:0]	au_to_rd;
wire [n_mast_i-1:0]	vs_to_rd;
wire [n_mast_i-1:0]	sr_to_rd;
wire [n_mast_i-1:0]	fl_to_rd;
wire [n_mast_i-1:0]	sr_to_ri;
wire [n_mast_i-1:0]	fl_to_ri;
wire			fl_input_sel;
reg [2:0]		sr_input_sel;
reg [3:0]		dm_cs;
reg [3:0]		rd_cs;
wire			dm_fl_cs;
wire			dm_sr_cs;
wire			dm_au_cs;
wire			dm_vs_cs;
wire			rd_fl_cs;
wire			rd_sr_cs;
wire			rd_au_cs;
wire			rd_vs_cs;
wire			ri_fl_cs;
wire			ri_sr_cs;
//reg			rd_sr_con;
reg			dm_fl_con;
reg			rd_fl_con;
reg			ri_fl_con;
 
// We don't support retries
assign wb_ri_rty_i = 1'b0;
assign wb_rd_rty_i = 1'b0;
 
//////////////////////////////////
// Gathering all inputs and outputs together
 
assign { wb_ri_dat_i, wb_ri_ack_i, wb_ri_err_i } = ri_inputs ;
assign ri_outputs = { wb_ri_dat_o, wb_ri_adr_o, wb_ri_sel_o, wb_ri_we_o, wb_ri_stb_o };
 
assign { wb_rd_dat_i, wb_rd_ack_i, wb_rd_err_i } = rd_inputs ;
assign rd_outputs = { wb_rd_dat_o, wb_rd_adr_o, wb_rd_sel_o, wb_rd_we_o, wb_rd_stb_o };
 
assign { wb_vm_dat_i, wb_vm_ack_i, wb_vm_err_i } = vm_inputs ;
// This is a problem !!!!!!!!!!!!!!!
assign vm_outputs = { data_width_zeros, wb_vm_adr_o, wb_vm_sel_o, wb_vm_we_o, wb_vm_stb_o };
 
assign { wb_dm_dat_i, wb_dm_ack_i, wb_dm_err_i } = dm_inputs ;
assign dm_outputs = { wb_dm_dat_o, wb_dm_adr_o, wb_dm_sel_o, wb_dm_we_o, wb_dm_stb_o };
 
assign { wb_vs_dat_i, wb_vs_adr_i, wb_vs_sel_i, wb_vs_we_i, wb_vs_stb_i } = vs_inputs;
assign vs_outputs = { wb_vs_dat_o, wb_vs_ack_o, wb_vs_err_o };
 
assign { wb_fl_dat_i, wb_fl_adr_i, wb_fl_sel_i, wb_fl_we_i, wb_fl_stb_i } = fl_inputs;
assign fl_outputs = { wb_fl_dat_o, wb_fl_ack_o, wb_fl_err_o };
 
assign { wb_sr_dat_i, wb_sr_adr_i, wb_sr_sel_i, wb_sr_we_i, wb_sr_stb_i } = sr_inputs;
assign sr_outputs = { wb_sr_dat_o, wb_sr_ack_o, wb_sr_err_o };
 
assign { wb_au_dat_i, wb_au_adr_i, wb_au_sel_i, wb_au_we_i, wb_au_stb_i } = au_inputs;
assign au_outputs = { wb_au_dat_o, wb_au_ack_o, wb_au_err_o };
 
//////////////////////////////////////////////////////////////////////////
// Connectivity
 
// VGA slave is only accessable by RISC Data
assign vs_inputs = rd_outputs;
// Audio is only accessable by RISC Data
assign au_inputs = rd_outputs;
 
// SRAM is accessable by either RISC Data or VGA Master
always @(sr_input_sel or rd_outputs or vm_outputs or ri_outputs or dm_outputs or n_mast_i_zeros)
begin
	case (sr_input_sel)
	`SR_RD: sr_inputs <= rd_outputs;
	`SR_RI: sr_inputs <= ri_outputs;
	`SR_VM: sr_inputs <= vm_outputs;
	`SR_DM: sr_inputs <= dm_outputs;
	default: sr_inputs <= n_mast_i_zeros;
	endcase
end
 
// FLASH is accessable by either RISC Instruction, RISC Data or Development I/F
assign fl_inputs = ( ri_fl_con ? ri_outputs : rd_fl_con ? rd_outputs : dm_outputs );
 
// RISC Instruction access
assign sr_to_ri = ( sr_input_sel == `SR_RI ? sr_outputs : n_mast_i_zeros );
assign fl_to_ri = ( ri_fl_con ? fl_outputs : n_mast_i_zeros );
assign ri_inputs = sr_to_ri | fl_to_ri;
 
// Development I/F access
assign sr_to_dm = ( sr_input_sel == `SR_DM ? sr_outputs : n_mast_i_zeros );
assign fl_to_dm = ( dm_fl_con ? fl_outputs : n_mast_i_zeros );
assign dm_inputs = sr_to_dm | fl_to_dm;
 
// VGA Master can only access SRAM
assign vm_inputs = ( sr_input_sel == 2'b11 ? sr_outputs : n_mast_i_zeros );
 
// RISC Data can access all 4 slaves
// SRAM can go to two masters
assign sr_to_rd = ( sr_input_sel == `SR_RD ? sr_outputs : n_mast_i_zeros );
// FLASH can go to two masters
assign fl_to_rd = ( ( ri_fl_con | !rd_fl_cs ) ? n_mast_i_zeros : fl_outputs );
// Audio can go to RISC Data
assign au_to_rd = ( ( !rd_au_cs ) ? n_mast_i_zeros : au_outputs );
// Video slave can go to RISC Data
assign vs_to_rd = ( ( !rd_vs_cs ) ? n_mast_i_zeros : vs_outputs );
// Now we just OR all slave outputs
assign rd_inputs = sr_to_rd | fl_to_rd | au_to_rd | vs_to_rd;
 
 
///////////////////////////////////////////////////////////////////////////
// Decoding
 
// decoding address of RISC data
always @( wb_rd_adr_o[addr_width-1:addr_width-2] )
begin
   case ( wb_rd_adr_o[addr_width-1:addr_width-2] )
   2'b00: rd_cs = 4'b0001;	
   2'b01: rd_cs = 4'b0010;
   2'b10: rd_cs = 4'b0100;
   2'b11: rd_cs = 4'b1000;
   default: rd_cs = 4'bx;
   endcase
end
 
assign rd_sr_cs = rd_cs[2];
assign rd_fl_cs = rd_cs[0];
assign rd_au_cs = rd_cs[1];
assign rd_vs_cs = rd_cs[3];
 
// decoding address of Development I/F
always @( wb_dm_adr_o[addr_width-1:addr_width-2] )
begin
   case ( wb_dm_adr_o[addr_width-1:addr_width-2] )
   2'b00: dm_cs = 4'b0001;	
   2'b01: dm_cs = 4'b0010;
   2'b10: dm_cs = 4'b0100;
   2'b11: dm_cs = 4'b1000;
   default: dm_cs = 4'bx;
   endcase
end
 
assign dm_sr_cs = dm_cs[2];
assign dm_fl_cs = dm_cs[0];
assign dm_au_cs = dm_cs[1];
assign dm_vs_cs = dm_cs[3];
 
// decoding of address of RISC instruction
assign ri_sr_cs = wb_ri_adr_o[addr_width-1];
assign ri_fl_cs = ~wb_ri_adr_o[addr_width-1];
 
// Priority mechanism for Flash slave between RISC Data, RISC Insn, and Development I/F  masters
always @( posedge clk or negedge rstn )
   if (!rstn) begin
	dm_fl_con <= 1'b0;
	rd_fl_con <= 1'b0;
	ri_fl_con <= 1'b0;
     end
   else 
      case ( { dm_fl_con, rd_fl_con, ri_fl_con } )
      3'b000: if ( wb_dm_cyc_o & wb_dm_stb_o & dm_fl_cs ) dm_fl_con <= #1 1'b1;
             else if ( wb_rd_cyc_o & wb_rd_stb_o & rd_fl_cs ) rd_fl_con <= #1 1'b1;
             else if ( wb_ri_cyc_o & wb_ri_stb_o & ri_fl_cs ) ri_fl_con <= #1 1'b1;
      3'b001: if ( (wb_ri_cyc_o & wb_ri_stb_o & ri_fl_cs)
		& !(wb_rd_cyc_o & wb_rd_stb_o & rd_fl_cs & wb_fl_ack_o)
		& !(wb_dm_cyc_o & wb_dm_stb_o & dm_fl_cs & wb_fl_ack_o) ) ri_fl_con <= #1 1'b1;
	     else ri_fl_con <= #1 1'b0;
      3'b010: if ( wb_rd_cyc_o & wb_rd_stb_o & rd_fl_cs ) rd_fl_con <= #1 1'b1;
             else rd_fl_con <= #1 1'b0;
      3'b100: if ( wb_dm_cyc_o & wb_dm_stb_o & dm_fl_cs ) dm_fl_con <= #1 1'b1;
             else dm_fl_con <= #1 1'b0;
      default: $display("Error, two or more masters currently accessing FLASH");
      endcase
 
// Priority mechanism between RISC Data, VGA Master and Development I/F Master
always @( posedge clk or negedge rstn )
   if (!rstn) 
	sr_input_sel <= 3'b000;
   else 
      case ( sr_input_sel )
      3'b000: if ( wb_vm_cyc_o & wb_vm_stb_o ) sr_input_sel <= #1 `SR_VM;
             else
		 if ( wb_dm_cyc_o & wb_dm_stb_o & dm_sr_cs ) sr_input_sel <= #1 `SR_DM;
		 else if ( wb_rd_cyc_o & wb_rd_stb_o & rd_sr_cs ) sr_input_sel <= #1 `SR_RD;
		      else if ( wb_ri_cyc_o & wb_ri_stb_o & ri_sr_cs ) sr_input_sel <= #1 `SR_RI;
      `SR_VM: if ( wb_vm_cyc_o & wb_vm_stb_o ) sr_input_sel <= #1 `SR_VM;
	     else sr_input_sel <= #1 3'b000;
      `SR_RI: if ( ( wb_ri_cyc_o & wb_ri_stb_o & ri_sr_cs ) & !(wb_rd_cyc_o & rd_sr_cs & wb_sr_ack_o)) sr_input_sel <= #1 `SR_RI;
	     else sr_input_sel <= #1 3'b000;
      `SR_RD: if ( wb_rd_cyc_o & wb_rd_stb_o & rd_sr_cs & ~wb_rd_ack_i) sr_input_sel <= #1 `SR_RD;
             else sr_input_sel <= #1 3'b000;
      `SR_DM: if ( wb_dm_cyc_o & wb_dm_stb_o & dm_sr_cs & ~wb_dm_ack_i) sr_input_sel <= #1 `SR_DM;
             else sr_input_sel <= #1 3'b000;
      default: $display("Error, two or more masters currently accessing SRAM");
      endcase
 
// Connecting the cyc signals
assign wb_fl_cyc_i = dm_fl_con ? wb_dm_cyc_o : rd_fl_con ? wb_rd_cyc_o : ri_fl_con ? wb_ri_cyc_o : 1'b0;
assign wb_sr_cyc_i = sr_input_sel == `SR_VM ? wb_vm_cyc_o : sr_input_sel == `SR_RD ? wb_rd_cyc_o : sr_input_sel == `SR_RI ? wb_ri_cyc_o : sr_input_sel == `SR_DM ? wb_dm_cyc_o : 1'b0;
assign wb_au_cyc_i = rd_au_cs ? wb_rd_cyc_o : 1'b0 ;
assign wb_vs_cyc_i = rd_vs_cs ? wb_rd_cyc_o : 1'b0 ;
 
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.