207 lines
6.2 KiB
Verilog
207 lines
6.2 KiB
Verilog
/*------------------------------------------------------------------------------
|
|
--------------------------------------------------------------------------------
|
|
Copyright (c) 2016, Loongson Technology Corporation Limited.
|
|
|
|
All rights reserved.
|
|
|
|
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.
|
|
|
|
3. Neither the name of Loongson Technology Corporation Limited nor the names of
|
|
its contributors may be used to endorse or promote products derived from this
|
|
software without specific prior written permission.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 LOONGSON TECHNOLOGY CORPORATION LIMITED BE LIABLE
|
|
TO ANY PARTY FOR 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.
|
|
--------------------------------------------------------------------------------
|
|
------------------------------------------------------------------------------*/
|
|
|
|
`define APB_DEV0 6'h00
|
|
|
|
`define APB_DEV1 6'h1e
|
|
|
|
module apb_mux2 (
|
|
clk,
|
|
rst_n,
|
|
apb_ack_cpu,
|
|
apb_rw_cpu,
|
|
apb_psel_cpu,
|
|
apb_enab_cpu,
|
|
apb_addr_cpu,
|
|
apb_datai_cpu,
|
|
apb_datao_cpu,
|
|
apb_high_24b_rd,
|
|
apb_high_24b_wr,
|
|
apb_word_trans_cpu,
|
|
|
|
apb_ready_dma,
|
|
apb_rw_dma,
|
|
apb_psel_dma,
|
|
apb_enab_dma,
|
|
apb_addr_dma,
|
|
apb_wdata_dma,
|
|
apb_rdata_dma,
|
|
apb_valid_dma,
|
|
apb_valid_cpu,
|
|
dma_grant,
|
|
|
|
apb0_req,
|
|
apb0_ack,
|
|
apb0_rw,
|
|
apb0_psel,
|
|
apb0_enab,
|
|
apb0_addr,
|
|
apb0_datai,
|
|
apb0_datao,
|
|
|
|
apb1_req,
|
|
apb1_ack,
|
|
apb1_rw,
|
|
apb1_psel,
|
|
apb1_enab,
|
|
apb1_addr,
|
|
apb1_datai,
|
|
apb1_datao
|
|
);
|
|
|
|
parameter ADDR_APB = 20,
|
|
DATA_APB = 8,
|
|
DATA_APB_32 = 32;
|
|
input clk,rst_n;
|
|
output apb_ready_dma;
|
|
input apb_rw_dma;
|
|
input apb_psel_dma;
|
|
input apb_enab_dma;
|
|
input [ADDR_APB-1:0] apb_addr_dma;
|
|
input [31:0] apb_wdata_dma;
|
|
output[31:0] apb_rdata_dma;
|
|
output dma_grant;
|
|
input apb_valid_dma;
|
|
input apb_valid_cpu;
|
|
|
|
output apb_ack_cpu;
|
|
input apb_rw_cpu;
|
|
input apb_psel_cpu;
|
|
input apb_enab_cpu;
|
|
input [ADDR_APB-1:0] apb_addr_cpu;
|
|
input [DATA_APB-1:0] apb_datai_cpu;
|
|
output[DATA_APB-1:0] apb_datao_cpu;
|
|
output [23:0] apb_high_24b_rd;
|
|
input [23:0] apb_high_24b_wr;
|
|
|
|
output apb_word_trans_cpu;
|
|
output apb0_req;
|
|
input apb0_ack;
|
|
output apb0_rw;
|
|
output apb0_psel;
|
|
output apb0_enab;
|
|
output[ADDR_APB-1:0] apb0_addr;
|
|
output[DATA_APB-1:0] apb0_datai;
|
|
input [DATA_APB-1:0] apb0_datao;
|
|
|
|
output apb1_req;
|
|
input apb1_ack;
|
|
output apb1_rw;
|
|
output apb1_psel;
|
|
output apb1_enab;
|
|
output[ADDR_APB-1:0] apb1_addr;
|
|
output[31:0] apb1_datai;
|
|
input [31:0] apb1_datao;
|
|
|
|
wire apb_ack;
|
|
wire apb_rw;
|
|
wire apb_psel;
|
|
wire apb_enab;
|
|
wire [ADDR_APB-1:0] apb_addr;
|
|
wire [DATA_APB-1:0] apb_datai;
|
|
wire [23:0]high_24b_wr;
|
|
wire [23:0]high_24b_rd;
|
|
wire [7:0]apb_datao ;
|
|
wire dma_grant;
|
|
|
|
arb_2_1 arb_2_1(.clk(clk), .rst_n(rst_n), .valid0(apb_valid_cpu), .valid1(apb_valid_dma), .dma_grant(dma_grant));
|
|
|
|
assign apb_addr = dma_grant ? apb_addr_dma:apb_addr_cpu;
|
|
assign apb_rw = dma_grant ? apb_rw_dma:apb_rw_cpu;
|
|
assign apb_psel = dma_grant ? apb_psel_dma:apb_psel_cpu;
|
|
assign apb_enab = dma_grant ? apb_enab_dma:apb_enab_cpu;
|
|
assign apb_datai = dma_grant ? apb_wdata_dma[7:0]:apb_datai_cpu;
|
|
assign high_24b_wr = dma_grant ? apb_wdata_dma[31:8]:apb_high_24b_wr;
|
|
assign high_24b_rd = apb1_req ? apb1_datao[31:8] : 24'h0;
|
|
|
|
assign apb_word_trans_cpu = dma_grant ? 1'h0: apb1_req;
|
|
|
|
assign apb_high_24b_rd = dma_grant ? 24'h0: high_24b_rd;
|
|
assign apb_datao_cpu = dma_grant ? 8'h0: apb_datao;
|
|
assign apb_rdata_dma = dma_grant ? {high_24b_rd,apb_datao }:32'h0;
|
|
assign apb_ack_cpu = ~dma_grant & apb_ack;
|
|
assign apb_ready_dma = dma_grant & apb_ack;
|
|
|
|
assign apb0_req = (apb_addr[ADDR_APB-1:14] ==`APB_DEV0);
|
|
//assign apb1_req = (apb_addr[ADDR_APB-1:14] ==`APB_DEV1);
|
|
assign apb1_req = !apb0_req;
|
|
|
|
assign apb0_psel = apb_psel && apb0_req ;
|
|
assign apb1_psel = apb_psel && apb1_req;
|
|
|
|
assign apb0_enab = apb_enab && apb0_req ;
|
|
assign apb1_enab = apb_enab && apb1_req;
|
|
|
|
assign apb_ack = apb0_req ? apb0_ack :
|
|
apb1_req ? apb1_ack :
|
|
1'b0;
|
|
|
|
assign apb_datao = apb0_req ? apb0_datao :
|
|
apb1_req ? apb1_datao[7:0] :
|
|
8'b0;
|
|
|
|
|
|
|
|
assign apb0_addr = apb_addr;
|
|
assign apb0_datai = apb_datai;
|
|
assign apb0_rw = apb_rw;
|
|
|
|
assign apb1_addr = apb_addr;
|
|
assign apb1_datai = {high_24b_wr,apb_datai};
|
|
assign apb1_rw = apb_rw;
|
|
|
|
endmodule
|
|
|
|
module arb_2_1( clk, rst_n, valid0, valid1, dma_grant);
|
|
input clk;
|
|
input rst_n;
|
|
input valid0;
|
|
input valid1;
|
|
output dma_grant;
|
|
reg dma_grant;
|
|
|
|
always @(posedge clk)
|
|
if(~rst_n)
|
|
dma_grant<= 1'b0;
|
|
else if(valid0&&~valid1)
|
|
dma_grant<= 1'b0;
|
|
else if(valid1&&~valid0)
|
|
dma_grant<= 1'b1;
|
|
else if(valid0&&valid1&&~dma_grant)
|
|
dma_grant<= 1'b0;
|
|
else if(valid0&&valid1&&dma_grant)
|
|
dma_grant<= 1'b1;
|
|
else dma_grant<= 1'b0;
|
|
|
|
endmodule
|