383 lines
13 KiB
Verilog
383 lines
13 KiB
Verilog
/*
|
|
Copyright 2020 Blue Liang, liangkangnan@163.com
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
`include "defines.v"
|
|
|
|
|
|
|
|
module rib(
|
|
|
|
input wire clk,
|
|
input wire rst,
|
|
|
|
// master 0 interface
|
|
input wire[`MemAddrBus] m0_addr_i,
|
|
input wire[`MemBus] m0_data_i,
|
|
output reg[`MemBus] m0_data_o,
|
|
output reg m0_ack_o,
|
|
input wire m0_req_i,
|
|
input wire m0_we_i,
|
|
|
|
// master 1 interface
|
|
input wire[`MemAddrBus] m1_addr_i,
|
|
input wire[`MemBus] m1_data_i,
|
|
output reg[`MemBus] m1_data_o,
|
|
output reg m1_ack_o,
|
|
input wire m1_req_i,
|
|
input wire m1_we_i,
|
|
|
|
// master 2 interface
|
|
input wire[`MemAddrBus] m2_addr_i,
|
|
input wire[`MemBus] m2_data_i,
|
|
output reg[`MemBus] m2_data_o,
|
|
output reg m2_ack_o,
|
|
input wire m2_req_i,
|
|
input wire m2_we_i,
|
|
|
|
// slave 0 interface
|
|
output reg[`MemAddrBus] s0_addr_o,
|
|
output reg[`MemBus] s0_data_o,
|
|
input wire[`MemBus] s0_data_i,
|
|
input wire s0_ack_i,
|
|
output reg s0_req_o,
|
|
output reg s0_we_o,
|
|
|
|
// slave 1 interface
|
|
output reg[`MemAddrBus] s1_addr_o,
|
|
output reg[`MemBus] s1_data_o,
|
|
input wire[`MemBus] s1_data_i,
|
|
input wire s1_ack_i,
|
|
output reg s1_req_o,
|
|
output reg s1_we_o,
|
|
|
|
// slave 2 interface
|
|
output reg[`MemAddrBus] s2_addr_o,
|
|
output reg[`MemBus] s2_data_o,
|
|
input wire[`MemBus] s2_data_i,
|
|
input wire s2_ack_i,
|
|
output reg s2_req_o,
|
|
output reg s2_we_o,
|
|
|
|
// slave 3 interface
|
|
output reg[`MemAddrBus] s3_addr_o,
|
|
output reg[`MemBus] s3_data_o,
|
|
input wire[`MemBus] s3_data_i,
|
|
input wire s3_ack_i,
|
|
output reg s3_req_o,
|
|
output reg s3_we_o,
|
|
|
|
// slave 4 interface
|
|
output reg[`MemAddrBus] s4_addr_o,
|
|
output reg[`MemBus] s4_data_o,
|
|
input wire[`MemBus] s4_data_i,
|
|
input wire s4_ack_i,
|
|
output reg s4_req_o,
|
|
output reg s4_we_o,
|
|
|
|
output reg hold_flag_o
|
|
|
|
);
|
|
|
|
|
|
parameter [3:0]slave_0 = 4'b0000;
|
|
parameter [3:0]slave_1 = 4'b0001;
|
|
parameter [3:0]slave_2 = 4'b0010;
|
|
parameter [3:0]slave_3 = 4'b0011;
|
|
parameter [3:0]slave_4 = 4'b0100;
|
|
|
|
parameter [1:0]grant0 = 2'h0;
|
|
parameter [1:0]grant1 = 2'h1;
|
|
parameter [1:0]grant2 = 2'h2;
|
|
|
|
|
|
wire[2:0] req;
|
|
reg[1:0] grant;
|
|
reg[1:0] next_grant;
|
|
|
|
|
|
assign req = {m2_req_i, m1_req_i, m0_req_i};
|
|
|
|
|
|
|
|
always @ (posedge clk) begin
|
|
if (rst == `RstEnable) begin
|
|
grant <= grant1;
|
|
end else begin
|
|
grant <= next_grant;
|
|
end
|
|
end
|
|
|
|
// arb
|
|
always @ (*) begin
|
|
if (rst == `RstEnable) begin
|
|
next_grant <= grant1;
|
|
hold_flag_o <= `HoldDisable;
|
|
end else begin
|
|
case (grant)
|
|
grant0: begin
|
|
if (req[0]) begin
|
|
next_grant <= grant0;
|
|
hold_flag_o <= `HoldEnable;
|
|
end else if (req[2]) begin
|
|
next_grant <= grant2;
|
|
hold_flag_o <= `HoldEnable;
|
|
end else begin
|
|
next_grant <= grant1;
|
|
hold_flag_o <= `HoldDisable;
|
|
end
|
|
end
|
|
grant1: begin
|
|
if (req[0]) begin
|
|
next_grant <= grant0;
|
|
hold_flag_o <= `HoldEnable;
|
|
end else if (req[2]) begin
|
|
next_grant <= grant2;
|
|
hold_flag_o <= `HoldEnable;
|
|
end else begin
|
|
next_grant <= grant1;
|
|
hold_flag_o <= `HoldDisable;
|
|
end
|
|
end
|
|
grant2: begin
|
|
if (req[0]) begin
|
|
next_grant <= grant0;
|
|
hold_flag_o <= `HoldEnable;
|
|
end else if (req[2]) begin
|
|
next_grant <= grant2;
|
|
hold_flag_o <= `HoldEnable;
|
|
end else begin
|
|
next_grant <= grant1;
|
|
hold_flag_o <= `HoldDisable;
|
|
end
|
|
end
|
|
default: begin
|
|
next_grant <= grant1;
|
|
hold_flag_o <= `HoldDisable;
|
|
end
|
|
endcase
|
|
end
|
|
end
|
|
|
|
|
|
always @ (*) begin
|
|
if (rst == `RstEnable) begin
|
|
m0_ack_o <= `RIB_NACK;
|
|
m1_ack_o <= `RIB_NACK;
|
|
m2_ack_o <= `RIB_NACK;
|
|
m0_data_o <= `ZeroWord;
|
|
m1_data_o <= `INST_NOP;
|
|
m2_data_o <= `ZeroWord;
|
|
|
|
s0_addr_o <= `ZeroWord;
|
|
s1_addr_o <= `ZeroWord;
|
|
s2_addr_o <= `ZeroWord;
|
|
s3_addr_o <= `ZeroWord;
|
|
s4_addr_o <= `ZeroWord;
|
|
s0_data_o <= `ZeroWord;
|
|
s1_data_o <= `ZeroWord;
|
|
s2_data_o <= `ZeroWord;
|
|
s3_data_o <= `ZeroWord;
|
|
s4_data_o <= `ZeroWord;
|
|
s0_req_o <= `RIB_NREQ;
|
|
s1_req_o <= `RIB_NREQ;
|
|
s2_req_o <= `RIB_NREQ;
|
|
s3_req_o <= `RIB_NREQ;
|
|
s4_req_o <= `RIB_NREQ;
|
|
s0_we_o <= `WriteDisable;
|
|
s1_we_o <= `WriteDisable;
|
|
s2_we_o <= `WriteDisable;
|
|
s3_we_o <= `WriteDisable;
|
|
s4_we_o <= `WriteDisable;
|
|
end else begin
|
|
m0_ack_o <= `RIB_NACK;
|
|
m1_ack_o <= `RIB_NACK;
|
|
m2_ack_o <= `RIB_NACK;
|
|
m0_data_o <= `ZeroWord;
|
|
m1_data_o <= `INST_NOP;
|
|
m2_data_o <= `ZeroWord;
|
|
|
|
s0_addr_o <= `ZeroWord;
|
|
s1_addr_o <= `ZeroWord;
|
|
s2_addr_o <= `ZeroWord;
|
|
s3_addr_o <= `ZeroWord;
|
|
s4_addr_o <= `ZeroWord;
|
|
s0_data_o <= `ZeroWord;
|
|
s1_data_o <= `ZeroWord;
|
|
s2_data_o <= `ZeroWord;
|
|
s3_data_o <= `ZeroWord;
|
|
s4_data_o <= `ZeroWord;
|
|
s0_req_o <= `RIB_NREQ;
|
|
s1_req_o <= `RIB_NREQ;
|
|
s2_req_o <= `RIB_NREQ;
|
|
s3_req_o <= `RIB_NREQ;
|
|
s4_req_o <= `RIB_NREQ;
|
|
s0_we_o <= `WriteDisable;
|
|
s1_we_o <= `WriteDisable;
|
|
s2_we_o <= `WriteDisable;
|
|
s3_we_o <= `WriteDisable;
|
|
s4_we_o <= `WriteDisable;
|
|
|
|
case (grant)
|
|
grant0: begin
|
|
case (m0_addr_i[31:28])
|
|
slave_0: begin
|
|
s0_req_o <= m0_req_i;
|
|
s0_we_o <= m0_we_i;
|
|
s0_addr_o <= {{4'h0}, {m0_addr_i[27:0]}};
|
|
s0_data_o <= m0_data_i;
|
|
m0_ack_o <= s0_ack_i;
|
|
m0_data_o <= s0_data_i;
|
|
end
|
|
slave_1: begin
|
|
s1_req_o <= m0_req_i;
|
|
s1_we_o <= m0_we_i;
|
|
s1_addr_o <= {{4'h0}, {m0_addr_i[27:0]}};
|
|
s1_data_o <= m0_data_i;
|
|
m0_ack_o <= s1_ack_i;
|
|
m0_data_o <= s1_data_i;
|
|
end
|
|
slave_2: begin
|
|
s2_req_o <= m0_req_i;
|
|
s2_we_o <= m0_we_i;
|
|
s2_addr_o <= {{4'h0}, {m0_addr_i[27:0]}};
|
|
s2_data_o <= m0_data_i;
|
|
m0_ack_o <= s2_ack_i;
|
|
m0_data_o <= s2_data_i;
|
|
end
|
|
slave_3: begin
|
|
s3_req_o <= m0_req_i;
|
|
s3_we_o <= m0_we_i;
|
|
s3_addr_o <= {{4'h0}, {m0_addr_i[27:0]}};
|
|
s3_data_o <= m0_data_i;
|
|
m0_ack_o <= s3_ack_i;
|
|
m0_data_o <= s3_data_i;
|
|
end
|
|
slave_4: begin
|
|
s4_req_o <= m0_req_i;
|
|
s4_we_o <= m0_we_i;
|
|
s4_addr_o <= {{4'h0}, {m0_addr_i[27:0]}};
|
|
s4_data_o <= m0_data_i;
|
|
m0_ack_o <= s4_ack_i;
|
|
m0_data_o <= s4_data_i;
|
|
end
|
|
default: begin
|
|
|
|
end
|
|
endcase
|
|
end
|
|
grant1: begin
|
|
case (m1_addr_i[31:28])
|
|
slave_0: begin
|
|
s0_req_o <= m1_req_i;
|
|
s0_we_o <= m1_we_i;
|
|
s0_addr_o <= {{4'h0}, {m1_addr_i[27:0]}};
|
|
s0_data_o <= m1_data_i;
|
|
m1_ack_o <= s0_ack_i;
|
|
m1_data_o <= s0_data_i;
|
|
end
|
|
slave_1: begin
|
|
s1_req_o <= m1_req_i;
|
|
s1_we_o <= m1_we_i;
|
|
s1_addr_o <= {{4'h0}, {m1_addr_i[27:0]}};
|
|
s1_data_o <= m1_data_i;
|
|
m1_ack_o <= s1_ack_i;
|
|
m1_data_o <= s1_data_i;
|
|
end
|
|
slave_2: begin
|
|
s2_req_o <= m1_req_i;
|
|
s2_we_o <= m1_we_i;
|
|
s2_addr_o <= {{4'h0}, {m1_addr_i[27:0]}};
|
|
s2_data_o <= m1_data_i;
|
|
m1_ack_o <= s2_ack_i;
|
|
m1_data_o <= s2_data_i;
|
|
end
|
|
slave_3: begin
|
|
s3_req_o <= m1_req_i;
|
|
s3_we_o <= m1_we_i;
|
|
s3_addr_o <= {{4'h0}, {m1_addr_i[27:0]}};
|
|
s3_data_o <= m1_data_i;
|
|
m1_ack_o <= s3_ack_i;
|
|
m1_data_o <= s3_data_i;
|
|
end
|
|
slave_4: begin
|
|
s4_req_o <= m1_req_i;
|
|
s4_we_o <= m1_we_i;
|
|
s4_addr_o <= {{4'h0}, {m1_addr_i[27:0]}};
|
|
s4_data_o <= m1_data_i;
|
|
m1_ack_o <= s4_ack_i;
|
|
m1_data_o <= s4_data_i;
|
|
end
|
|
default: begin
|
|
|
|
end
|
|
endcase
|
|
end
|
|
grant2: begin
|
|
case (m2_addr_i[31:28])
|
|
slave_0: begin
|
|
s0_req_o <= m2_req_i;
|
|
s0_we_o <= m2_we_i;
|
|
s0_addr_o <= {{4'h0}, {m2_addr_i[27:0]}};
|
|
s0_data_o <= m2_data_i;
|
|
m2_ack_o <= s0_ack_i;
|
|
m2_data_o <= s0_data_i;
|
|
end
|
|
slave_1: begin
|
|
s1_req_o <= m2_req_i;
|
|
s1_we_o <= m2_we_i;
|
|
s1_addr_o <= {{4'h0}, {m2_addr_i[27:0]}};
|
|
s1_data_o <= m2_data_i;
|
|
m2_ack_o <= s1_ack_i;
|
|
m2_data_o <= s1_data_i;
|
|
end
|
|
slave_2: begin
|
|
s2_req_o <= m2_req_i;
|
|
s2_we_o <= m2_we_i;
|
|
s2_addr_o <= {{4'h0}, {m2_addr_i[27:0]}};
|
|
s2_data_o <= m2_data_i;
|
|
m2_ack_o <= s2_ack_i;
|
|
m2_data_o <= s2_data_i;
|
|
end
|
|
slave_3: begin
|
|
s3_req_o <= m2_req_i;
|
|
s3_we_o <= m2_we_i;
|
|
s3_addr_o <= {{4'h0}, {m2_addr_i[27:0]}};
|
|
s3_data_o <= m2_data_i;
|
|
m2_ack_o <= s3_ack_i;
|
|
m2_data_o <= s3_data_i;
|
|
end
|
|
slave_4: begin
|
|
s4_req_o <= m2_req_i;
|
|
s4_we_o <= m2_we_i;
|
|
s4_addr_o <= {{4'h0}, {m2_addr_i[27:0]}};
|
|
s4_data_o <= m2_data_i;
|
|
m2_ack_o <= s4_ack_i;
|
|
m2_data_o <= s4_data_i;
|
|
end
|
|
default: begin
|
|
|
|
end
|
|
endcase
|
|
end
|
|
default: begin
|
|
|
|
end
|
|
endcase
|
|
end
|
|
end
|
|
|
|
endmodule
|