mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-23 21:57:11 -04:00
👕 First memory arbiter implementation
This commit is contained in:
parent
128104dea7
commit
bc0f29cc3c
3 changed files with 93 additions and 9 deletions
2
Makefile
2
Makefile
|
@ -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
|
||||
|
||||
|
|
2
fifo.sv
2
fifo.sv
|
@ -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
|
||||
|
|
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue