👕 First memory arbiter implementation

This commit is contained in:
Florian Zaruba 2017-04-24 16:56:29 +02:00
parent 128104dea7
commit bc0f29cc3c
3 changed files with 93 additions and 9 deletions

View file

@ -17,7 +17,7 @@ interfaces = include/debug_if.svh include/mem_if.svh tb/agents/fifo_if/fifo_if.s
src = alu.sv tb/sequences/alu_sequence_pkg.sv tb/env/alu_env_pkg.sv tb/test/alu_lib_pkg.sv tb/alu_tb.sv \
tb/scoreboard_tb.sv \
if_stage.sv compressed_decoder.sv fetch_fifo.sv commit_stage.sv prefetch_buffer.sv \
mmu.sv lsu.sv fifo.sv tb/fifo_tb.sv \
mmu.sv lsu.sv fifo.sv tb/fifo_tb.sv mem_arbiter.sv \
scoreboard.sv issue_read_operands.sv decoder.sv id_stage.sv util/cluster_clock_gating.sv regfile.sv ex_stage.sv ariane.sv \
tb/core_tb.sv

View file

@ -40,7 +40,7 @@ module fifo #(
// actual memory
dtype [DEPTH-1:0] mem_n, mem_q;
assign full_o = (status_cnt_q == DEPTH);
assign full_o = (status_cnt_q == DEPTH - 1);
assign empty_o = (status_cnt_q == 0);
// read and write queue logic

View file

@ -21,16 +21,100 @@ module mem_arbiter #(
parameter int NR_PORTS = 3
)
(
input logic clk_i, // Clock
input logic rst_ni, // Asynchronous reset active low
mem_if.Master [NR_PORTS-1:0] masters,
mem_if.Slave slave
input logic clk_i, // Clock
input logic rst_ni, // Asynchronous reset active low
// slave port
output logic [63:0] address_o,
output logic [63:0] data_wdata_o,
output logic data_req_o,
output logic data_we_o,
output logic [7:0] data_be_o,
input logic data_gnt_i,
input logic data_rvalid_i,
input logic [63:0] data_rdata_i,
// master ports
input logic [NR_PORTS-1:0][63:0] address_i,
input logic [NR_PORTS-1:0][63:0] data_wdata_i,
input logic [NR_PORTS-1:0] data_req_i,
input logic [NR_PORTS-1:0] data_we_i,
input logic [NR_PORTS-1:0][7:0] data_be_i,
output logic [NR_PORTS-1:0] data_gnt_o,
output logic [NR_PORTS-1:0] data_rvalid_o,
output logic [NR_PORTS-1:0][63:0] data_rdata_o
);
// addressing read and write
logic full_o;
logic empty_o;
logic [NR_PORTS-1:0] data_i;
logic push_i;
logic [NR_PORTS-1:0] data_o;
logic pop_i;
// results
fifo #(
.dtype ( logic [NR_PORTS-1:0] ),
.DEPTH ( 4 )
) fifo_i (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.full_o ( full_o ),
.empty_o ( empty_o ),
.data_i ( data_i ),
.push_i ( push_i ),
.data_o ( data_o ),
.pop_i ( pop_i )
);
// addressing read and full write
always_comb begin : read_req_write
// default assignment
data_req_o = data_req_i[0];
address_o = address_i[0];
data_wdata_o = data_wdata_i[0];
data_be_o = data_be_i[0];
data_we_o = data_we_i[0];
data_i = '{default: 0};
push_i = 1'b0;
// only go for a new request if we can wait for the valid
if (~full_o) begin
for (int i = 0; i < NR_PORTS; i++) begin
if (data_req_i[i] == 1'b1) begin
// pass through all signals from the correct slave port
data_req_o = data_req_i[i];
address_o = address_i[i];
data_wdata_o = data_wdata_i[i];
data_be_o = data_be_i[i];
data_we_o = data_we_i[i];
// wait on the grant
if (data_gnt_i) begin
data_gnt_o[i] = data_gnt_i;
// set the slave on which we are waiting
data_i = i;
push_i = 1'b1;
end
break; // break here as this is a priority select
end
end
end
end
// results, listening on the input signals of the slave port
always_comb begin : slave_read_port
pop_i = 1'b0;
// default assignment
for (int i = 0; i < NR_PORTS; i++) begin
data_rvalid_o[i] = 1'b0;
data_rdata_o[i] = 64'b0;
end
// if there is an entry in the queue we are waiting for a read to return
// there is a valid signal and the FIFO should not be empty anyway
if (data_rvalid_i) begin
// pass the read through to the appropriate slave
pop_i = 1'b1;
data_rvalid_o[data_o] = data_rvalid_i;
data_rdata_o[data_o] = data_rdata_i;
end
end
endmodule