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

Subversion Repositories pss

[/] [pss/] [trunk/] [pss/] [hdl/] [pss/] [zpu_uc/] [motherblock/] [pss_ic.v] - Rev 5

Compare with Previous | Blame | View Log

/*
 PSS
 
 Copyright (c) 2016 Alexander Antonov <153287@niuitmo.ru>
 All rights reserved.
 
 Version 0.9
 
 The FreeBSD license
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:
 
 1. Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.
 2. Redistributions in binary form must reproduce the above
    copyright notice, this list of conditions and the following
    disclaimer in the documentation and/or other materials
    provided with the distribution.
 
 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 PSS PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
 
module PSS_IC
#(
	parameter MEM_SIZE_KB = 1
)
(
	input clk_i,
	input rst_i,
 
	//// Masters ////
	input m0_enb_i,
	input m0_we_i,
	input [31:0] m0_addr_bi,
	input [31:0] m0_wdata_bi,
	input [3:0] m0_writemask_bi,
	output reg m0_ack_o,
	output reg [31:0] m0_rdata_bo,
 
	input m1_enb_i,
	input m1_we_i,
	input [31:0] m1_addr_bi,
	input [31:0] m1_wdata_bi,
	input [3:0] m1_writemask_bi,
	output reg m1_ack_o,
	output reg [31:0] m1_rdata_bo,
 
	//// Slaves ////
	output reg s0_enb_o,
	output reg s0_we_o,
	output reg [31:0] s0_addr_bo,
	output reg [31:0] s0_wdata_bo,
	output reg [3:0] s0_writemask_bo,
	input s0_ack_i,
	input [31:0] s0_rdata_bi,
 
	output reg s1_enb_o,
	output reg s1_we_o,
	output reg [31:0] s1_addr_bo,
	output reg [31:0] s1_wdata_bo,
	output reg [3:0] s1_writemask_bo,
	input s1_ack_i,
	input [31:0] s1_rdata_bi,
 
	output reg s2_enb_o,
	output reg s2_we_o,
	output reg [31:0] s2_addr_bo,
	output reg [31:0] s2_wdata_bo,
	output reg [3:0] s2_writemask_bo,
	input s2_ack_i,
	input [31:0] s2_rdata_bi,
 
	output reg error_o,
	output reg [31:0] error_addr_bo
);
 
reg m0_s0_enb, m0_s1_enb, m0_s2_enb, m0_err_enb;
reg m1_s0_enb, m1_s1_enb, m1_s2_enb, m1_err_enb;
 
always @*
	begin
	m0_s0_enb = 1'b0;
	m0_s1_enb = 1'b0;
	m0_s2_enb = 1'b0;
	m0_err_enb = 1'b0;
 
	if (m0_enb_i == 1'b1)
		begin
		if (m0_addr_bi[31:10] < MEM_SIZE_KB)
			m0_s0_enb = 1'b1;
		else if (m0_addr_bi[31:16] == 16'h4000)
			m0_s1_enb = 1'b1;
		else if (m0_addr_bi[31] == 1'b1)
			m0_s2_enb = 1'b1;
		else m0_err_enb = 1'b1;
		end
	end
 
always @*
	begin
	m1_s0_enb = 1'b0;
	m1_s1_enb = 1'b0;
	m1_s2_enb = 1'b0;
	m1_err_enb = 1'b0;
 
	if (m1_enb_i == 1'b1)
		begin
		if (m1_addr_bi[31:10] < MEM_SIZE_KB)
			m1_s0_enb = 1'b1;
		else if (m1_addr_bi[31:16] == 16'h4000)
			m1_s1_enb = 1'b1;
		else if (m1_addr_bi[31] == 1'b1)
			m1_s2_enb = 1'b1;
		else m1_err_enb = 1'b1;
		end
	end
 
reg s0_pending, s1_pending, s2_pending;
reg s0_curmaster, s1_curmaster, s2_curmaster;
 
// Transaction drivers
always @(posedge clk_i)
	begin
	if (rst_i)
		begin
		s0_pending <= 1'b0;
		s0_curmaster <= 1'bx;
		end
	else 
		begin
		if ((s0_pending == 1'b0) && (s0_ack_i == 1'b0))
			begin
			if (m0_s0_enb == 1'b1)
				begin
				s0_pending <= 1'b1;
				s0_curmaster <= 1'b0;
				end
			else if (m1_s0_enb == 1'b1)
				begin
				s0_pending <= 1'b1;
				s0_curmaster <= 1'b1;
				end
			end
		else 
			begin
			if (s0_ack_i == 1'b1)
				begin
				s0_pending <= 1'b0;
				s0_curmaster <= 1'bx;
				end
			end
		end
	end
 
always @(posedge clk_i)
	begin
	if (rst_i)
		begin
		s1_pending <= 1'b0;
		s1_curmaster <= 1'bx;
		end
	else 
		begin
		if ((s1_pending == 1'b0) && (s1_ack_i == 1'b0))
			begin
			if (m0_s1_enb == 1'b1)
				begin
				s1_pending <= 1'b1;
				s1_curmaster <= 1'b0;
				end
			else if (m1_s1_enb == 1'b1)
				begin
				s1_pending <= 1'b1;
				s1_curmaster <= 1'b1;
				end
			end
		else 
			begin
			if (s1_ack_i == 1'b1)
				begin
				s1_pending <= 1'b0;
				s1_curmaster <= 1'bx;
				end
			end
		end
	end
 
always @(posedge clk_i)
	begin
	if (rst_i)
		begin
		s2_pending <= 1'b0;
		s2_curmaster <= 1'bx;
		end
	else 
		begin
		if ((s2_pending == 1'b0) && (s2_ack_i == 1'b0))
			begin
			if (m0_s2_enb == 1'b1)
				begin
				s2_pending <= 1'b1;
				s2_curmaster <= 1'b0;
				end
			else if (m1_s2_enb == 1'b1)
				begin
				s2_pending <= 1'b1;
				s2_curmaster <= 1'b1;
				end
			end
		else 
			begin
			if (s2_ack_i == 1'b1)
				begin
				s2_pending <= 1'b0;
				s2_curmaster <= 1'bx;
				end
			end
		end
	end
 
// Slave drivers
always @*
	begin
	s0_enb_o = 1'b0;
	s0_we_o = 1'b0;
	s0_addr_bo = 32'hx;
	s0_wdata_bo = 32'hx;
	s0_writemask_bo = 4'hx;
	if (s0_pending == 1'b1)
		begin
		if (s0_curmaster == 1'b0)
			begin
			s0_enb_o = m0_enb_i;
			s0_we_o = m0_we_i;
			s0_addr_bo = m0_addr_bi;
			s0_wdata_bo = m0_wdata_bi;
			s0_writemask_bo = m0_writemask_bi;
			end
		else 
			begin
			s0_enb_o = m1_enb_i;
			s0_we_o = m1_we_i;
			s0_addr_bo = m1_addr_bi;
			s0_wdata_bo = m1_wdata_bi;
			s0_writemask_bo = m1_writemask_bi;
			end
		end
	else if (m0_s0_enb == 1'b1)
		begin
		s0_enb_o = m0_enb_i;
		s0_we_o = m0_we_i;
		s0_addr_bo = m0_addr_bi;
		s0_wdata_bo = m0_wdata_bi;
		s0_writemask_bo = m0_writemask_bi;
		end
	else if (m1_s0_enb == 1'b1)
		begin
		s0_enb_o = m1_enb_i;
		s0_we_o = m1_we_i;
		s0_addr_bo = m1_addr_bi;
		s0_wdata_bo = m1_wdata_bi;
		s0_writemask_bo = m1_writemask_bi;
		end
	end
 
always @*
	begin
	s1_enb_o = 1'b0;
	s1_we_o = 1'b0;
	s1_addr_bo = 32'hx;
	s1_wdata_bo = 32'hx;
	s1_writemask_bo = 4'hx;
	if (s1_pending == 1'b1)
		begin
		if (s1_curmaster == 1'b0)
			begin
			s1_enb_o = m0_enb_i;
			s1_we_o = m0_we_i;
			s1_addr_bo = m0_addr_bi;
			s1_wdata_bo = m0_wdata_bi;
			s1_writemask_bo = m0_writemask_bi;
			end
		else 
			begin
			s1_enb_o = m1_enb_i;
			s1_we_o = m1_we_i;
			s1_addr_bo = m1_addr_bi;
			s1_wdata_bo = m1_wdata_bi;
			s1_writemask_bo = m1_writemask_bi;
			end
		end
	else if (m0_s1_enb == 1'b1)
		begin
		s1_enb_o = m0_enb_i;
		s1_we_o = m0_we_i;
		s1_addr_bo = m0_addr_bi;
		s1_wdata_bo = m0_wdata_bi;
		s1_writemask_bo = m0_writemask_bi;
		end
	else if (m1_s1_enb == 1'b1)
		begin
		s1_enb_o = m1_enb_i;
		s1_we_o = m1_we_i;
		s1_addr_bo = m1_addr_bi;
		s1_wdata_bo = m1_wdata_bi;
		s1_writemask_bo = m1_writemask_bi;
		end
	end
 
always @*
	begin
	s2_enb_o = 1'b0;
	s2_we_o = 1'b0;
	s2_addr_bo = 32'hx;
	s2_wdata_bo = 32'hx;
	s2_writemask_bo = 4'hx;
	if (s2_pending == 1'b1)
		begin
		if (s2_curmaster == 1'b0)
			begin
			s2_enb_o = m0_enb_i;
			s2_we_o = m0_we_i;
			s2_addr_bo = m0_addr_bi;
			s2_wdata_bo = m0_wdata_bi;
			s2_writemask_bo = m0_writemask_bi;
			end
		else 
			begin
			s2_enb_o = m1_enb_i;
			s2_we_o = m1_we_i;
			s2_addr_bo = m1_addr_bi;
			s2_wdata_bo = m1_wdata_bi;
			s2_writemask_bo = m1_writemask_bi;
			end
		end
	else if (m0_s2_enb == 1'b1)
		begin
		s2_enb_o = m0_enb_i;
		s2_we_o = m0_we_i;
		s2_addr_bo = m0_addr_bi;
		s2_wdata_bo = m0_wdata_bi;
		s2_writemask_bo = m0_writemask_bi;
		end
	else if (m1_s2_enb == 1'b1)
		begin
		s2_enb_o = m1_enb_i;
		s2_we_o = m1_we_i;
		s2_addr_bo = m1_addr_bi;
		s2_wdata_bo = m1_wdata_bi;
		s2_writemask_bo = m1_writemask_bi;
		end
	end
 
// Master drivers
always @*
	begin
	m0_ack_o = 1'b0;
	m0_rdata_bo = 32'hx;
	if ((s0_pending == 1'b1) && (s0_curmaster == 1'b0))
		begin
		m0_ack_o = s0_ack_i;
		m0_rdata_bo = s0_rdata_bi;
		end
	else if ((s1_pending == 1'b1) && (s1_curmaster == 1'b0))
		begin
		m0_ack_o = s1_ack_i;
		m0_rdata_bo = s1_rdata_bi;
		end
	else if ((s2_pending == 1'b1) && (s2_curmaster == 1'b0))
		begin
		m0_ack_o = s2_ack_i;
		m0_rdata_bo = s2_rdata_bi;
		end
	else if (m0_s0_enb == 1'b1)
		begin
		m0_ack_o = s0_ack_i;
		m0_rdata_bo = s0_rdata_bi;
		end
	else if (m0_s1_enb == 1'b1)
		begin
		m0_ack_o = s1_ack_i;
		m0_rdata_bo = s1_rdata_bi;
		end
	else if (m0_s2_enb == 1'b1)
		begin
		m0_ack_o = s2_ack_i;
		m0_rdata_bo = s2_rdata_bi;
		end
	end
 
always @*
	begin
	m1_ack_o = 1'b0;
	m1_rdata_bo = 32'hx;
	if ((s0_pending == 1'b1) && (s0_curmaster == 1'b1))
		begin
		m1_ack_o = s0_ack_i;
		m1_rdata_bo = s0_rdata_bi;
		end
	else if ((s1_pending == 1'b1) && (s1_curmaster == 1'b1))
		begin
		m1_ack_o = s1_ack_i;
		m1_rdata_bo = s1_rdata_bi;
		end
	else if ((s2_pending == 1'b1) && (s2_curmaster == 1'b1))
		begin
		m1_ack_o = s2_ack_i;
		m1_rdata_bo = s2_rdata_bi;
		end
	else if (m1_s0_enb == 1'b1)
		begin
		m1_ack_o = s0_ack_i;
		m1_rdata_bo = s0_rdata_bi;
		end
	else if (m1_s1_enb == 1'b1)
		begin
		m1_ack_o = s1_ack_i;
		m1_rdata_bo = s1_rdata_bi;
		end
	else if (m1_s2_enb == 1'b1)
		begin
		m1_ack_o = s2_ack_i;
		m1_rdata_bo = s2_rdata_bi;
		end
	end
 
endmodule
 

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.