URL
https://opencores.org/ocsvn/pss/pss/trunk
Subversion Repositories pss
[/] [pss/] [trunk/] [pss/] [hdl/] [pss/] [zpu_uc/] [motherblock/] [pss_ic.v] - Rev 7
Go to most recent revision | 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
Go to most recent revision | Compare with Previous | Blame | View Log