🐛 First functional fixes

This commit is contained in:
Florian Zaruba 2017-10-25 18:22:08 +02:00
parent 7dd14cdf60
commit cd79a2318a
No known key found for this signature in database
GPG key ID: E742FFE8EC38A792
8 changed files with 59 additions and 47 deletions

3
.gitmodules vendored
View file

@ -19,3 +19,6 @@
[submodule "src/axi_slice"]
path = src/axi_slice
url = git@iis-git.ee.ethz.ch:pulp-open/axi_slice.git
[submodule "src/axi_node"]
path = src/axi_node
url = git@iis-git.ee.ethz.ch:kerbin/axi_node.git

View file

@ -27,7 +27,8 @@ test_pkg = $(wildcard tb/test/*/*sequence_pkg.sv*) $(wildcard tb/test/*/*_pkg.sv
# DPI
dpi = $(wildcard tb/dpi/*)
# this list contains the standalone components
src = $(wildcard src/*.sv) $(wildcard tb/common/*.sv) $(wildcard src/axi2per/*.sv) $(wildcard src/axi_slice/*.sv)
src = $(wildcard src/*.sv) $(wildcard tb/common/*.sv) $(wildcard src/axi2per/*.sv) $(wildcard src/axi_slice/*.sv) \
$(wildcard src/axi_node/*.sv)
# look for testbenches
tbs = $(wildcard tb/*_tb.sv)
# RISCV-tests path

View file

@ -19,7 +19,7 @@ package nbdcache_pkg;
localparam int unsigned AXI_USER_WIDTH = 10;
localparam int unsigned NR_MSHR = 1;
// Calculated paramater
// Calculated parameter
localparam BYTE_OFFSET = $clog2(CACHE_LINE_WIDTH/8);
localparam NUM_WORDS = 2**(INDEX_WIDTH-BYTE_OFFSET);
localparam DIRTY_WIDTH = (CACHE_LINE_WIDTH/64)*SET_ASSOCIATIVITY*2;

1
src/axi_node Submodule

@ -0,0 +1 @@
Subproject commit 18d1fe362cac76496e0a2f9447d7a26cb3445efa

View file

@ -112,6 +112,7 @@ module cache_ctrl #(
if (data_req_i) begin
// save index, be and we
mem_req_d.index = address_index_i;
mem_req_d.tag = address_tag_i;
mem_req_d.be = data_be_i;
mem_req_d.we = data_we_i;
mem_req_d.wdata = data_wdata_i;
@ -145,11 +146,12 @@ module cache_ctrl #(
// cache enabled and waiting for tag
WAIT_TAG, WAIT_TAG_SAVED: begin
// depending on where we come from
tag_o = (state_q == WAIT_TAG_SAVED) ? mem_req_q.tag : address_tag_i;
// For the store case the tag comes in the same cycle
tag_o = (state_q == WAIT_TAG_SAVED || mem_req_q.we) ? mem_req_q.tag : address_tag_i;
// check that the client really wants to do the request
if (!kill_req_i) begin
// HIT CASE
if (!hit_way_i) begin
if (|hit_way_i) begin
// we can request another cache-line if this was a load
// make another request
if (data_req_i && !mem_req_q.we) begin
@ -158,6 +160,7 @@ module cache_ctrl #(
mem_req_d.be = data_be_i;
mem_req_d.we = data_we_i;
mem_req_d.wdata = data_wdata_i;
mem_req_d.tag = address_tag_i;
mem_req_d.bypass = 1'b0;
req_o = 'b1;
@ -265,7 +268,7 @@ module cache_ctrl #(
state_d = WAIT_CRITICAL_WORD;
else if (miss_gnt_i) begin
state_d = IDLE;
data_rvalid_o = 1'b1;
data_gnt_o = 1'b1;
end
end
@ -282,6 +285,8 @@ module cache_ctrl #(
mem_req_d.be = data_be_i;
mem_req_d.we = data_we_i;
mem_req_d.wdata = data_wdata_i;
mem_req_d.tag = address_tag_i;
// request the cache line
req_o = 'b1;
addr_o = address_index_i;

View file

@ -46,11 +46,11 @@ module miss_handler #(
);
// FSM states
enum logic [3:0] { IDLE, FLUSHING, FLUSH, EVICT_WAY, EVICT_WAY_MISS, WAIT_GNT_SRAM, MISS,
LOAD_CACHELINE, MISS_REPL, REPL_CACHELINE } state_d, state_q;
LOAD_CACHELINE, MISS_REPL, REPL_CACHELINE, INIT } state_d, state_q;
// Registers
mshr_t mshr_d, mshr_q;
logic [INDEX_WIDTH-1:0] cnt_d, cnt_q;
logic [$clog2(SET_ASSOCIATIVITY)-1:0] evict_way_d, evict_way_q;
logic [SET_ASSOCIATIVITY-1:0] evict_way_d, evict_way_q;
// cache line to evict
cache_line_t evict_cl_d, evict_cl_q;
@ -107,6 +107,8 @@ module miss_handler #(
req_fsm_miss_wdata = '0;
req_fsm_miss_we = 1'b0;
req_fsm_miss_be = '0;
flush_ack_o = 1'b0;
// check MSHR for aliasing
// and the number of MSHR registers (i think one will be just the only sane choice here)
for (int i = 0; i < NR_PORTS; i++) begin
@ -143,6 +145,7 @@ module miss_handler #(
mshr_d.valid = 1'b1;
mshr_d.we = miss_req_we[i];
mshr_d.id = i;
mshr_d.addr = miss_req_addr[i][TAG_WIDTH+INDEX_WIDTH-1:0];
break;
end
end
@ -153,10 +156,8 @@ module miss_handler #(
// 1. Check if there is an empty cache-line
// 2. If not -> evict one
req_o = 1'b1;
addr_o = miss_req_addr[mshr_q.id][INDEX_WIDTH-1:0];
if (gnt_i)
state_d = MISS_REPL;
addr_o = mshr_q.addr[INDEX_WIDTH-1:0];
state_d = MISS_REPL;
end
// ~> second miss cycle
@ -202,7 +203,7 @@ module miss_handler #(
data_o.tag = miss_req_addr[mshr_q.id][INDEX_WIDTH+TAG_WIDTH+1:INDEX_WIDTH];
data_o.data = data_miss_fsm;
state_d = IDLE;
miss_gnt_o = 1'b1;
miss_gnt_o[mshr_q.id] = 1'b1;
// is this a write?
if (miss_req_we[mshr_q.id]) begin
// Yes, so safe the updated data now
@ -222,8 +223,10 @@ module miss_handler #(
state_d = FLUSH;
end
if (cnt_q == INDEX_WIDTH)
if (cnt_q == NUM_WORDS) begin
flush_ack_o = 1'b1;
state_d = IDLE;
end
end
FLUSH: begin
@ -274,6 +277,20 @@ module miss_handler #(
end
end
INIT: begin
// initialize status array
addr_o = cnt_q;
req_o = 1'b1;
we_o = 1'b1;
data_o = 'b0;
cnt_d = cnt_q + 1;
if (cnt_q == NUM_WORDS)
state_d = IDLE;
end
endcase
end
@ -283,7 +300,7 @@ module miss_handler #(
always_ff @(posedge clk_i or negedge rst_ni) begin
if (~rst_ni) begin
mshr_q <= '0;
state_q <= FLUSHING;
state_q <= INIT;
cnt_q <= '0;
evict_way_q <= '0;
evict_cl_q <= '0;
@ -300,7 +317,6 @@ module miss_handler #(
// ----------------------
// Connection Arbiter <-> AXI
logic req_fsm_bypass_valid;
logic req_fsm_bypass_bypass;
logic [63:0] req_fsm_bypass_addr;
logic [CACHE_LINE_WIDTH-1:0] req_fsm_bypass_wdata;
logic req_fsm_bypass_we;
@ -376,7 +392,7 @@ module miss_handler #(
.we_i ( req_fsm_miss_we ),
.wdata_i ( req_fsm_miss_wdata ),
.be_i ( req_fsm_miss_be ),
.id_i ( ),
.id_i ( '0 ),
.valid_o ( valid_miss_fsm ),
.rdata_o ( data_miss_fsm ),
.id_o ( ),

View file

@ -117,14 +117,14 @@ module nbdcache (
.data_rdata_o ( data_rdata_o [i] ),
.amo_op_i ( amo_op_i [i] ),
.req_o ( req [i] ),
.addr_o ( addr [i] ),
.gnt_i ( gnt [i] ),
.req_o ( req [i+1] ),
.addr_o ( addr [i+1] ),
.gnt_i ( gnt [i+1] ),
.data_i ( rdata ),
.tag_o ( tag [i] ),
.data_o ( wdata [i] ),
.we_o ( we [i] ),
.be_o ( be [i] ),
.tag_o ( tag [i+1] ),
.data_o ( wdata [i+1] ),
.we_o ( we [i+1] ),
.be_o ( be [i+1] ),
.hit_way_i ( hit_way ),
.miss_req_o ( miss_req [i] ),
@ -162,13 +162,13 @@ module nbdcache (
.critical_word_valid_o ( critical_word_valid ),
.mshr_addr_i ( mshr_addr ),
.mashr_addr_matches_o ( mshr_addr_matches ),
.req_o ( req [3] ),
.addr_o ( addr [3] ),
.gnt_i ( gnt [3] ),
.req_o ( req [0] ),
.addr_o ( addr [0] ),
.gnt_i ( gnt [0] ),
.data_i ( rdata ),
.be_o ( be [3] ),
.data_o ( wdata [3] ),
.we_o ( we [3] ),
.be_o ( be [0] ),
.data_o ( wdata [0] ),
.we_o ( we [0] ),
.*
);
@ -347,7 +347,7 @@ module tag_cmp #(
`ifndef VERILATOR
// assert that cache only hits on one way
assert property (
@(posedge clk_i) $onehot(hit_way_o)) else $warning("Hit should be one-hot encoded");
@(posedge clk_i) $onehot0(hit_way_o)) else $warning("Hit should be one-hot encoded");
`endif
`endif
end

View file

@ -55,10 +55,6 @@ module store_buffer (
// allocate more space for the commit buffer to be on the save side
localparam int unsigned DEPTH_COMMIT = 4;
// we need to keep the tag portion of the address for a cycle later
logic [43:0] address_tag_n, address_tag_q;
logic tag_valid_n, tag_valid_q;
// the store queue has two parts:
// 1. Speculative queue
// 2. Commit queue which is non-speculative, e.g.: the store will definitely happen.
@ -136,8 +132,8 @@ module store_buffer (
// those signals can directly be output to the memory
assign address_index_o = commit_queue_q[commit_read_pointer_q].address[11:0];
// if we got a new request we already saved the tag from the previous cycle
assign address_tag_o = address_tag_q;
assign tag_valid_o = tag_valid_q;
assign address_tag_o = commit_queue_q[commit_read_pointer_q].address[55:12];
assign tag_valid_o = 1'b0;
assign data_wdata_o = commit_queue_q[commit_read_pointer_q].data;
assign data_be_o = commit_queue_q[commit_read_pointer_q].be;
// we will never kill a request in the store buffer since we already know that the translation is valid
@ -154,10 +150,8 @@ module store_buffer (
commit_read_pointer_n = commit_read_pointer_q;
commit_write_pointer_n = commit_write_pointer_q;
address_tag_n = address_tag_q;
commit_queue_n = commit_queue_q;
tag_valid_n = 1'b0;
data_req_o = 1'b0;
// there should be no commit when we are flushing
@ -167,10 +161,6 @@ module store_buffer (
if (data_gnt_i) begin
// we can evict it from the commit buffer
commit_queue_n[commit_read_pointer_q].valid = 1'b0;
// save the tag portion
address_tag_n = commit_queue_q[commit_read_pointer_q].address[55:12];
// signal a valid tag the cycle afterwards
tag_valid_n = 1'b1;
// advance the read_pointer
commit_read_pointer_n = commit_read_pointer_q + 1'b1;
commit_status_cnt--;
@ -231,9 +221,7 @@ module store_buffer (
// registers
always_ff @(posedge clk_i or negedge rst_ni) begin : proc_
if(~rst_ni) begin
address_tag_q <= 'b0;
tag_valid_q <= 1'b0;
// initialize the queues
// initialize the queues
speculative_queue_q <= '{default: 0};
commit_queue_q <= '{default: 0};
commit_read_pointer_q <= '0;
@ -243,8 +231,6 @@ module store_buffer (
speculative_write_pointer_q <= '0;
speculative_status_cnt_q <= '0;
end else begin
address_tag_q <= address_tag_n;
tag_valid_q <= tag_valid_n;
speculative_queue_q <= speculative_queue_n;
commit_queue_q <= commit_queue_n;
commit_read_pointer_q <= commit_read_pointer_n;