From bc0f29cc3cb48af158c05a289153cab0031b2a1a Mon Sep 17 00:00:00 2001 From: Florian Zaruba Date: Mon, 24 Apr 2017 16:56:29 +0200 Subject: [PATCH] :shirt: First memory arbiter implementation --- Makefile | 2 +- fifo.sv | 2 +- mem_arbiter.sv | 98 ++++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 93 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 6b8503de8..16ee81998 100644 --- a/Makefile +++ b/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 diff --git a/fifo.sv b/fifo.sv index af810da48..b67ded85d 100644 --- a/fifo.sv +++ b/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 diff --git a/mem_arbiter.sv b/mem_arbiter.sv index 19fff2a28..8d61f288c 100644 --- a/mem_arbiter.sv +++ b/mem_arbiter.sv @@ -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 \ No newline at end of file