Merge pull request #7 from flmeisel/axi_wstrb_fix

L2: Move be (i.e. wstrb for AXI) into the data FIFO (Fixes #6)
This commit is contained in:
Mike Thompson 2023-04-18 13:24:13 -04:00 committed by GitHub
commit ea96a5ccb2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 75 additions and 57 deletions

View file

@ -182,7 +182,7 @@ module axi_to_arb
assign axi_wdata = read_modify_write ? amo_result_r : l2.wr_data;
assign axi_wstrb =read_modify_write ? '1 : l2.be;
assign axi_wstrb = read_modify_write ? '1 : l2.wr_data_be;
//Done when read request sent, or slave ack on write data

View file

@ -78,6 +78,7 @@ module l1_arbiter
//Dcache Specific
assign l2.wr_data_push = CONFIG.INCLUDE_DCACHE & (push_ready & l1_request[L1_DCACHE_ID].request & ~l1_request[L1_DCACHE_ID].rnw); //Assumes data cache has highest priority
assign l2.wr_data = l1_request[L1_DCACHE_ID].data;
assign l2.wr_data_be = l1_request[L1_DCACHE_ID].be;
assign l2.inv_ack = CONFIG.DCACHE.USE_EXTERNAL_INVALIDATIONS ? l1_response[L1_DCACHE_ID].inv_ack : l2.inv_valid;
assign l1_response[L1_DCACHE_ID].inv_addr = l2.inv_addr;
@ -89,7 +90,6 @@ module l1_arbiter
always_comb begin
l2_requests[i].addr = l1_request[i].addr[31:2];
l2_requests[i].rnw = l1_request[i].rnw;
l2_requests[i].be = l1_request[i].be;
l2_requests[i].is_amo = l1_request[i].is_amo;
l2_requests[i].amo_type_or_burst_size = l1_request[i].size;
l2_requests[i].sub_id = L2_SUB_ID_W'(i);
@ -113,7 +113,6 @@ module l1_arbiter
assign l2.addr = l2_requests[arb_sel].addr;
assign l2.rnw = l2_requests[arb_sel].rnw;
assign l2.be = l2_requests[arb_sel].be;
assign l2.is_amo = l2_requests[arb_sel].is_amo;
assign l2.amo_type_or_burst_size = l2_requests[arb_sel].amo_type_or_burst_size;
assign l2.sub_id = l2_requests[arb_sel].sub_id;

View file

@ -38,11 +38,14 @@ module l1_to_wishbone
localparam MAX_REQUESTS = 32;
fifo_interface #(.DATA_WIDTH($bits(l2_request_t))) request_fifo ();
fifo_interface #(.DATA_WIDTH(32)) data_fifo ();
fifo_interface #(.DATA_WIDTH($bits(l2_data_request_t))) data_fifo ();
l2_request_t request_in;
l2_request_t request;
l2_data_request_t data_request_in;
l2_data_request_t data_request;
logic request_complete;
////////////////////////////////////////////////////
//Implementation
@ -51,11 +54,10 @@ module l1_to_wishbone
//Repack input attributes
assign request_in.addr = cpu.addr;
assign request_in.be = cpu.be;
assign request_in.rnw = cpu.rnw;
assign request_in.is_amo = cpu.is_amo;
assign request_in.amo_type_or_burst_size = cpu.amo_type_or_burst_size;
assign request_in.sub_id = cpu.sub_id;
assign request_in.rnw = cpu.rnw;
assign request_in.is_amo = cpu.is_amo;
assign request_in.amo_type_or_burst_size = cpu.amo_type_or_burst_size;
assign request_in.sub_id = cpu.sub_id;
assign request_fifo.push = cpu.request_push;
assign request_fifo.potential_push = cpu.request_push;
@ -63,10 +65,14 @@ module l1_to_wishbone
assign request_fifo.data_in = request_in;
assign request = request_fifo.data_out;
assign data_request_in.data = cpu.wr_data;
assign data_request_in.be = cpu.wr_data_be;
assign data_fifo.push = cpu.wr_data_push;
assign data_fifo.potential_push = cpu.wr_data_push;
assign data_fifo.pop = wishbone.we & wishbone.ack;
assign data_fifo.data_in = cpu.wr_data;
assign data_fifo.data_in = data_request_in;
assign data_request = data_fifo.data_out;
cva5_fifo #(.DATA_WIDTH($bits(l2_request_t)), .FIFO_DEPTH(MAX_REQUESTS))
request_fifo_block (
@ -74,7 +80,7 @@ module l1_to_wishbone
.rst (rst),
.fifo (request_fifo)
);
cva5_fifo #(.DATA_WIDTH(32), .FIFO_DEPTH(MAX_REQUESTS))
cva5_fifo #(.DATA_WIDTH($bits(l2_data_request_t)), .FIFO_DEPTH(MAX_REQUESTS))
data_fifo_block (
.clk (clk),
.rst (rst),
@ -100,10 +106,10 @@ module l1_to_wishbone
assign wishbone.adr[29:5] = request.addr[29:5];
assign wishbone.adr[4:0] = (request.addr[4:0] & ~burst_size) | (burst_count & burst_size);
assign wishbone.sel = request.rnw ? '1 : request.be;
assign wishbone.sel = request.rnw ? '1 : data_request.be;
assign wishbone.we = ~request.rnw;
assign wishbone.dat_w = data_fifo.data_out;
assign wishbone.dat_w = data_request.data;
assign wishbone.stb = request_fifo.valid;
assign wishbone.cyc = request_fifo.valid;

View file

@ -38,19 +38,20 @@ module l2_arbiter
//FIFO interfaces
fifo_interface #(.DATA_WIDTH($bits(l2_request_t))) input_fifos [L2_NUM_PORTS-1:0]();
fifo_interface #(.DATA_WIDTH(32)) input_data_fifos [L2_NUM_PORTS-1:0]();
fifo_interface #(.DATA_WIDTH($bits(l2_data_request_t))) input_data_fifos [L2_NUM_PORTS-1:0]();
fifo_interface #(.DATA_WIDTH(30)) inv_response_fifos [L2_NUM_PORTS-1:0]();
fifo_interface #(.DATA_WIDTH(32 + L2_SUB_ID_W)) returndata_fifos [L2_NUM_PORTS-1:0]();
fifo_interface #(.DATA_WIDTH($bits(l2_mem_request_t))) mem_addr_fifo();
fifo_interface #(.DATA_WIDTH(32)) mem_data_fifo();
fifo_interface #(.DATA_WIDTH($bits(l2_data_request_t))) mem_data_fifo();
fifo_interface #(.DATA_WIDTH($bits(l2_data_attributes_t))) data_attributes();
fifo_interface #(.DATA_WIDTH(32 + L2_ID_W)) mem_returndata_fifo();
l2_mem_request_t mem_addr_fifo_data_out;
l2_request_t requests_in[L2_NUM_PORTS-1:0];
l2_data_request_t data_requests_in[L2_NUM_PORTS-1:0];
logic advance;
l2_request_t arb_request;
@ -70,7 +71,7 @@ module l2_arbiter
l2_data_attributes_t new_attr;
l2_data_attributes_t current_attr;
logic [31:0] input_data [L2_NUM_PORTS-1:0];
l2_data_request_t input_data [L2_NUM_PORTS-1:0];
l2_mem_return_data_t mem_return_data;
l2_return_data_t return_data [L2_NUM_PORTS-1:0];
@ -93,11 +94,10 @@ module l2_arbiter
//Repack input attributes
assign requests_in[i].addr = request[i].addr;
assign requests_in[i].be = request[i].be;
assign requests_in[i].rnw = request[i].rnw;
assign requests_in[i].is_amo = request[i].is_amo;
assign requests_in[i].amo_type_or_burst_size = request[i].amo_type_or_burst_size;
assign requests_in[i].sub_id = request[i].sub_id;
assign requests_in[i].rnw = request[i].rnw;
assign requests_in[i].is_amo = request[i].is_amo;
assign requests_in[i].amo_type_or_burst_size = request[i].amo_type_or_burst_size;
assign requests_in[i].sub_id = request[i].sub_id;
assign input_fifos[i].data_in = requests_in[i];
assign input_fifos[i].pop = input_fifos[i].valid & arb.grantee_v[i] & ~mem_addr_fifo.full;
@ -121,12 +121,14 @@ module l2_arbiter
assign input_data_fifos[i].push = request[i].wr_data_push;
assign input_data_fifos[i].potential_push = request[i].wr_data_push;
assign input_data_fifos[i].data_in = request[i].wr_data;
assign data_requests_in[i].data = request[i].wr_data;
assign data_requests_in[i].be = request[i].wr_data_be;
assign input_data_fifos[i].data_in = data_requests_in[i];
assign request[i].data_full = input_data_fifos[i].full;
//FIFO instantiation
cva5_fifo #(.DATA_WIDTH(32), .FIFO_DEPTH(L2_INPUT_FIFO_DEPTHS)) input_data_fifo (.*, .fifo(input_data_fifos[i]));
cva5_fifo #(.DATA_WIDTH($bits(l2_data_request_t)), .FIFO_DEPTH(L2_INPUT_FIFO_DEPTHS)) input_data_fifo (.*, .fifo(input_data_fifos[i]));
//Arbiter FIFO side
assign input_data_fifos[i].pop = (data_attributes.valid && (current_attr.id == i) && ~mem_data_fifo.full);
@ -152,7 +154,6 @@ module l2_arbiter
assign arb_request = requests[arb.grantee_i];
assign mem_request.addr = arb_request.addr;
assign mem_request.be = arb_request.be;
assign mem_request.rnw = arb_request.rnw;
assign mem_request.is_amo = arb_request.is_amo;
assign mem_request.amo_type_or_burst_size = arb_request.amo_type_or_burst_size;
@ -162,11 +163,10 @@ module l2_arbiter
//unpack memory request attributes
assign mem_addr_fifo_data_out = mem_addr_fifo.data_out;
assign mem.addr = mem_addr_fifo_data_out.addr;
assign mem.rnw = mem_addr_fifo_data_out.rnw;
assign mem.be = mem_addr_fifo_data_out.be;
assign mem.is_amo = mem_addr_fifo_data_out.is_amo;
assign mem.amo_type_or_burst_size = mem_addr_fifo_data_out.amo_type_or_burst_size;
assign mem.addr = mem_addr_fifo_data_out.addr;
assign mem.rnw = mem_addr_fifo_data_out.rnw;
assign mem.is_amo = mem_addr_fifo_data_out.is_amo;
assign mem.amo_type_or_burst_size = mem_addr_fifo_data_out.amo_type_or_burst_size;
assign mem.id = mem_addr_fifo_data_out.id;
cva5_fifo #(.DATA_WIDTH($bits(l2_mem_request_t)), .FIFO_DEPTH(L2_MEM_ADDR_FIFO_DEPTH)) input_fifo (.*, .fifo(mem_addr_fifo));
@ -261,14 +261,17 @@ module l2_arbiter
assign write_done = data_attributes.valid & ~mem_data_fifo.full & (burst_count == current_attr.burst_size);
cva5_fifo #(.DATA_WIDTH($bits(32)), .FIFO_DEPTH(L2_MEM_ADDR_FIFO_DEPTH)) mem_data (.*, .fifo(mem_data_fifo));
cva5_fifo #(.DATA_WIDTH($bits(l2_data_request_t)), .FIFO_DEPTH(L2_MEM_ADDR_FIFO_DEPTH)) mem_data (.*, .fifo(mem_data_fifo));
assign mem_data_fifo.push = data_attributes.valid & ~mem_data_fifo.full & ~current_attr.abort_request;
assign mem_data_fifo.potential_push = data_attributes.valid & ~mem_data_fifo.full & ~current_attr.abort_request;
assign mem_data_fifo.data_in = input_data[current_attr.id];
assign mem.wr_data = mem_data_fifo.data_out;
l2_data_request_t mem_data_request;
assign mem_data_request = mem_data_fifo.data_out;
assign mem.wr_data = mem_data_request.data;
assign mem.wr_data_be = mem_data_request.be;
assign mem.wr_data_valid = mem_data_fifo.valid;
assign mem_data_fifo.pop = mem.wr_data_read;
@ -306,4 +309,4 @@ module l2_arbiter
end
endgenerate
endmodule
endmodule

View file

@ -48,13 +48,17 @@ package l2_config_and_types;
typedef struct packed{
logic [29:0] addr;
logic [3:0] be;
logic rnw;
logic is_amo;
logic [4:0] amo_type_or_burst_size;
logic [L2_SUB_ID_W-1:0] sub_id;
} l2_request_t;
typedef struct packed{
logic [31:0] data;
logic [3:0] be;
} l2_data_request_t;
typedef struct packed{
logic [29:0] addr;
logic [3:0] be;

View file

@ -25,7 +25,6 @@ interface l2_requester_interface;
//l2_request_t request;
logic [29:0] addr;
logic [3:0] be;
logic rnw;
logic is_amo;
logic [4:0] amo_type_or_burst_size;
@ -42,6 +41,7 @@ interface l2_requester_interface;
logic con_valid;
logic [31:0] wr_data;
logic [3:0] wr_data_be;
logic wr_data_push;
logic data_full;
@ -50,26 +50,26 @@ interface l2_requester_interface;
logic rd_data_valid;
logic rd_data_ack;
modport master (output addr, be, rnw, is_amo, amo_type_or_burst_size, sub_id,
modport master (output addr, rnw, is_amo, amo_type_or_burst_size, sub_id,
output request_push, input request_full,
input inv_addr, inv_valid, output inv_ack,
input con_result, con_valid,
output wr_data, wr_data_push, input data_full,
output wr_data, wr_data_be, wr_data_push, input data_full,
input rd_data, rd_sub_id, rd_data_valid, output rd_data_ack);
modport slave (input addr, be, rnw, is_amo, amo_type_or_burst_size, sub_id,
modport slave (input addr, rnw, is_amo, amo_type_or_burst_size, sub_id,
input request_push, output request_full,
output inv_addr, inv_valid, input inv_ack,
output con_result, con_valid,
input wr_data, wr_data_push, output data_full,
input wr_data, wr_data_be, wr_data_push, output data_full,
output rd_data, rd_sub_id, rd_data_valid, input rd_data_ack);
`ifdef __CVA5_FORMAL__
modport formal (input addr, be, rnw, is_amo, amo_type_or_burst_size, sub_id,
modport formal (input addr, rnw, is_amo, amo_type_or_burst_size, sub_id,
request_push, output request_full,
inv_addr, inv_valid, input inv_ack,
con_result, con_valid,
wr_data, wr_data_push, output data_full,
wr_data, wr_data_be, wr_data_push, output data_full,
rd_data, rd_sub_id, rd_data_valid, input rd_data_ack);
`endif
@ -81,7 +81,6 @@ interface l2_memory_interface;
localparam L2_ID_W = $clog2(L2_NUM_PORTS) + L2_SUB_ID_W;
logic [29:0] addr;
logic [3:0] be;
logic rnw;
logic is_amo;
logic [4:0] amo_type_or_burst_size;
@ -93,6 +92,7 @@ interface l2_memory_interface;
logic abort_request;
logic [31:0] wr_data;
logic [3:0] wr_data_be;
logic wr_data_valid;
logic wr_data_read;
@ -100,20 +100,20 @@ interface l2_memory_interface;
logic [L2_ID_W-1:0] rd_id;
logic rd_data_valid;
modport master (output addr, be, rnw, is_amo, amo_type_or_burst_size, id,
modport master (output addr, rnw, is_amo, amo_type_or_burst_size, id,
output request_valid, abort_request, input request_pop,
output wr_data, wr_data_valid, input wr_data_read,
output wr_data, wr_data_be, wr_data_valid, input wr_data_read,
input rd_data, rd_id, rd_data_valid);
modport slave (input addr, be, rnw, is_amo, amo_type_or_burst_size, id,
modport slave (input addr, rnw, is_amo, amo_type_or_burst_size, id,
input request_valid, abort_request, output request_pop,
input wr_data, wr_data_valid, output wr_data_read,
input wr_data, wr_data_be, wr_data_valid, output wr_data_read,
output rd_data, rd_id, rd_data_valid);
`ifdef __CVA5_FORMAL__
modport formal (input addr, be, rnw, is_amo, amo_type_or_burst_size, id,
modport formal (input addr, rnw, is_amo, amo_type_or_burst_size, id,
request_valid, abort_request, output request_pop,
wr_data, wr_data_valid, output wr_data_read,
wr_data, wr_data_be, wr_data_valid, output wr_data_read,
rd_data, rd_id, rd_data_valid);
`endif

View file

@ -17,6 +17,10 @@ struct l2_arb_inputs{
uint32_t sub_id;
uint32_t be;
};
struct l2_data_inputs{
uint32_t data;
uint32_t be;
};
struct l2_arb_expected_output{
uint32_t rd_data;
uint32_t rd_sub_id;
@ -24,7 +28,7 @@ struct l2_arb_expected_output{
queue<l2_arb_inputs> test_inputs;
queue<l2_arb_expected_output> test_expected_output;
queue<uint32_t> test_data_inputs;
queue<l2_data_inputs> test_data_inputs;
void assign_read_input(uint32_t address, uint32_t burst_length, uint32_t sub_id){
l2_arb_inputs in_elem{address, 1, burst_length, sub_id};
@ -32,17 +36,19 @@ void assign_read_input(uint32_t address, uint32_t burst_length, uint32_t sub_id)
};
void assign_write_input(uint32_t address, uint32_t burst_length, uint32_t sub_id, uint32_t be){
l2_arb_inputs in_elem{address, 0, burst_length, sub_id, be};
l2_arb_inputs in_elem{address, 0, burst_length, sub_id};
test_inputs.push(in_elem);
for(int i = burst_length-1 ; i >= 0; i--){
test_data_inputs.push(i+71);
l2_data_inputs in_data_elem{i+71, be};
test_data_inputs.push(in_data_elem);
}
};
void assign_single_write_input(uint32_t address, uint32_t sub_id, uint32_t data, uint32_t be){
l2_arb_inputs in_elem{address, 0, 1, sub_id, be};
l2_arb_inputs in_elem{address, 0, 1, sub_id};
test_inputs.push(in_elem);
test_data_inputs.push(data);
l2_data_inputs in_data_elem{data, be};
test_data_inputs.push(in_data_elem);
};
vluint64_t main_time = 0; // Current simulation time
@ -142,7 +148,6 @@ int main(int argc, char **argv) {
tb->is_amo = 0;
tb->amo_type_or_burst_size = elem.burst_length - 1;
tb->sub_id = elem.sub_id;
tb->be = elem.be;
number_of_data_left = elem.burst_length;
tb->request_push = 1;
tb->wr_data_push = 0;
@ -151,9 +156,10 @@ int main(int argc, char **argv) {
tb->request_push = 0;
if(!tb->data_full){
uint32_t data = test_data_inputs.front();
l2_data_inputs data_elem = test_data_inputs.front();
test_data_inputs.pop();
tb->wr_data = data;
tb->wr_data = data_elem.data;
tb->wr_data_be = data_elem.be;
tb->wr_data_push = 1;
number_of_data_left--;

View file

@ -77,7 +77,6 @@ module axi_l2_test # (
//L2 interface
input logic [29:0] addr,
input logic [3:0] be,
input logic rnw,
input logic is_amo,
input logic [4:0] amo_type_or_burst_size,
@ -94,6 +93,7 @@ module axi_l2_test # (
output logic con_valid,
input logic [31:0] wr_data,
input logic [3:0] wr_data_be,
input logic wr_data_push,
output logic data_full,
@ -224,7 +224,6 @@ module axi_l2_test # (
// assign m_axi.bresp = bus_axi_bresp;
assign l2[0].addr = addr;
assign l2[0].be = be;
assign l2[0].rnw = rnw;
assign l2[0].is_amo = is_amo;
assign l2[0].amo_type_or_burst_size = amo_type_or_burst_size;
@ -241,6 +240,7 @@ module axi_l2_test # (
assign con_valid = l2[0].con_valid;
assign l2[0].wr_data = wr_data;
assign l2[0].wr_data_be = wr_data_be;
assign l2[0].wr_data_push = wr_data_push;
assign data_full = l2[0].data_full;