unified fetch and load-store sub_unit interfaces

Signed-off-by: Eric Matthews <ematthew@sfu.ca>
This commit is contained in:
Eric Matthews 2022-03-25 13:27:07 -04:00
parent 1f0a43e5f1
commit 90c9dd6343
11 changed files with 205 additions and 291 deletions

View file

@ -31,20 +31,16 @@ module avalon_master
input logic rst,
avalon_interface.master m_avalon,
output logic[31:0] data_out,
input data_access_shared_inputs_t ls_inputs,
ls_sub_unit_interface.sub_unit ls
memory_sub_unit_interface.responder ls
);
//implementation
////////////////////////////////////////////////////
always_ff @ (posedge clk) begin
if (ls.new_request) begin
m_avalon.addr <= ls_inputs.addr;
m_avalon.byteenable <= ls_inputs.be;
m_avalon.writedata <= ls_inputs.data_in;
m_avalon.addr <= ls.addr;
m_avalon.byteenable <= ls.be;
m_avalon.writedata <= ls.data_in;
end
end
@ -68,15 +64,15 @@ module avalon_master
always_ff @ (posedge clk) begin
if (m_avalon.read & ~m_avalon.waitrequest)
data_out <= m_avalon.readdata;
ls.data_out <= m_avalon.readdata;
else
data_out <= 0;
ls.data_out <= 0;
end
always_ff @ (posedge clk) begin
if (rst)
m_avalon.read <= 0;
else if (ls.new_request & ls_inputs.load)
else if (ls.new_request & ls.re)
m_avalon.read <= 1;
else if (~m_avalon.waitrequest)
m_avalon.read <= 0;
@ -85,7 +81,7 @@ module avalon_master
always_ff @ (posedge clk) begin
if (rst)
m_avalon.write <= 0;
else if (ls.new_request & ls_inputs.store)
else if (ls.new_request & ls.we)
m_avalon.write <= 1;
else if (~m_avalon.waitrequest)
m_avalon.write <= 0;

View file

@ -32,10 +32,7 @@ module axi_master
axi_interface.master m_axi,
input logic [2:0] size,
output logic[31:0] data_out,
input data_access_shared_inputs_t ls_inputs,
ls_sub_unit_interface.sub_unit ls
memory_sub_unit_interface.responder ls
);
logic ready;
@ -48,12 +45,12 @@ module axi_master
always_ff @ (posedge clk) begin
if (ls.new_request) begin
m_axi.araddr <= ls_inputs.addr;
m_axi.araddr <= ls.addr;
m_axi.arsize <= size;
m_axi.awsize <= size;
m_axi.awaddr <= ls_inputs.addr;
m_axi.wdata <= ls_inputs.data_in;
m_axi.wstrb <= ls_inputs.be;
m_axi.awaddr <= ls.addr;
m_axi.wdata <= ls.data_in;
m_axi.wstrb <= ls.be;
end
end
@ -80,27 +77,27 @@ module axi_master
//read channel
set_clr_reg_with_rst #(.SET_OVER_CLR(1), .WIDTH(1), .RST_VALUE(0)) arvalid_m (
.clk, .rst,
.set(ls.new_request & ls_inputs.load),
.set(ls.new_request & ls.re),
.clr(m_axi.arready),
.result(m_axi.arvalid)
);
always_ff @ (posedge clk) begin
if (m_axi.rvalid)
data_out <= m_axi.rdata;
ls.data_out <= m_axi.rdata;
end
//write channel
set_clr_reg_with_rst #(.SET_OVER_CLR(1), .WIDTH(1), .RST_VALUE(0)) awvalid_m (
.clk, .rst,
.set(ls.new_request & ls_inputs.store),
.set(ls.new_request & ls.we),
.clr(m_axi.awready),
.result(m_axi.awvalid)
);
set_clr_reg_with_rst #(.SET_OVER_CLR(1), .WIDTH(1), .RST_VALUE(0)) wvalid_m (
.clk, .rst,
.set(ls.new_request & ls_inputs.store),
.set(ls.new_request & ls.we),
.clr(m_axi.wready),
.result(m_axi.wvalid)
);

View file

@ -39,12 +39,8 @@ module dcache
input logic sc_complete,
input logic sc_success,
input logic clear_reservation,
input data_access_shared_inputs_t ls_inputs,
output logic[31:0] data_out,
input amo_details_t amo,
ls_sub_unit_interface.sub_unit ls
memory_sub_unit_interface.responder ls
);
localparam DCACHE_SIZE_IN_WORDS = CONFIG.DCACHE.LINES*CONFIG.DCACHE.LINE_W*CONFIG.DCACHE.WAYS;
@ -76,7 +72,6 @@ module dcache
logic stage2_load;
logic stage2_store;
logic [3:0] stage2_be;
logic [2:0] stage2_fn3;
logic [31:0] stage2_data;
amo_details_t stage2_amo;
@ -115,12 +110,11 @@ module dcache
//2nd Cycle Control Signals
always_ff @ (posedge clk) begin
if (ls.new_request) begin
stage2_addr <= ls_inputs.addr;
stage2_be <= ls_inputs.be;
stage2_load <= ls_inputs.load;
stage2_store <= ls_inputs.store;
stage2_fn3 <= ls_inputs.fn3;
stage2_data <= ls_inputs.data_in;
stage2_addr <= ls.addr;
stage2_be <= ls.be;
stage2_load <= ls.re;
stage2_store <= ls.we;
stage2_data <= ls.data_in;
stage2_amo <= amo;
end
end
@ -130,7 +124,7 @@ module dcache
//LR and AMO ops are forced misses (if there is a tag hit they will reuse the same way)
//Signal is valid for a single cycle, RAM enables are used to hold outputs in case of pipeline stalls
always_ff @ (posedge clk) begin
read_hit_allowed <= ls.new_request & ls_inputs.load & dcache_on & ~(amo.is_lr | amo.is_amo);
read_hit_allowed <= ls.new_request & ls.re & dcache_on & ~(amo.is_lr | amo.is_amo);
read_hit_data_valid <= read_hit_allowed;
second_cycle <= ls.new_request;
tag_update <= second_cycle & dcache_on & stage2_load & ~tag_hit;//Cache enabled, read miss
@ -214,7 +208,7 @@ module dcache
dcache_tag_banks (
.clk (clk),
.rst (rst),
.stage1_addr (ls_inputs.addr),
.stage1_addr (ls.addr),
.stage2_addr (stage2_addr),
.inv_addr ({l1_response.inv_addr, 2'b00}),
.update_way (tag_update_way),
@ -287,7 +281,7 @@ module dcache
miss_data <= {31'b0, sc_success};
end
assign data_out = read_hit_data_valid ? dbank_data_out : miss_data;
assign ls.data_out = read_hit_data_valid ? dbank_data_out : miss_data;
////////////////////////////////////////////////////
//Pipeline Advancement

View file

@ -68,14 +68,15 @@ module fetch
localparam NUM_SUB_UNITS = int'(CONFIG.INCLUDE_ILOCAL_MEM) + int'(CONFIG.INCLUDE_ICACHE);
localparam NUM_SUB_UNITS_W = (NUM_SUB_UNITS == 1) ? 1 : $clog2(NUM_SUB_UNITS);
localparam BRAM_ID = 0;
localparam LOCAL_MEM_ID = 0;
localparam ICACHE_ID = int'(CONFIG.INCLUDE_ILOCAL_MEM);
localparam NEXT_ID_DEPTH = CONFIG.INCLUDE_ICACHE ? 2 : 1;
//Subunit signals
fetch_sub_unit_interface #(.BASE_ADDR(CONFIG.ILOCAL_MEM_ADDR.L), .UPPER_BOUND(CONFIG.ILOCAL_MEM_ADDR.H)) bram();
fetch_sub_unit_interface #(.BASE_ADDR(CONFIG.ICACHE_ADDR.L), .UPPER_BOUND(CONFIG.ICACHE_ADDR.H)) cache();
addr_utils_interface #(CONFIG.ILOCAL_MEM_ADDR.L, CONFIG.ILOCAL_MEM_ADDR.H) ilocal_mem_addr_utils ();
addr_utils_interface #(CONFIG.ICACHE_ADDR.L, CONFIG.ICACHE_ADDR.H) icache_addr_utils ();
memory_sub_unit_interface sub_unit[NUM_SUB_UNITS-1:0]();
logic [NUM_SUB_UNITS-1:0] sub_unit_address_match;
logic [NUM_SUB_UNITS-1:0] unit_ready;
@ -110,9 +111,6 @@ module fetch
logic [31:0] translated_address;
//Cache related
logic [31:0] stage2_phys_address;
genvar i;
////////////////////////////////////////////////////
//Implementation
@ -168,11 +166,6 @@ module fetch
assign tlb.new_request = tlb.ready & (CONFIG.INCLUDE_S_MODE & tlb_on);
assign translated_address = (CONFIG.INCLUDE_S_MODE & tlb_on) ? tlb.physical_address : pc;
always_ff @(posedge clk) begin
if (new_mem_request)
stage2_phys_address <= translated_address;
end
//////////////////////////////////////////////
//Issue Control Signals
assign flush_or_rst = (rst | gc.fetch_flush | early_branch_flush);
@ -211,41 +204,42 @@ module fetch
//In the case of a gc.fetch_flush, a request may already be in progress
//for any sub unit. That request can either be completed or aborted.
//In either case, data_valid must NOT be asserted.
generate if (CONFIG.INCLUDE_ILOCAL_MEM) begin : gen_fetch_local_mem
assign sub_unit_address_match[BRAM_ID] = bram.address_range_check(translated_address);
assign unit_ready[BRAM_ID] = bram.ready;
assign unit_data_valid[BRAM_ID] = bram.data_valid;
assign bram.new_request = new_mem_request & sub_unit_address_match[BRAM_ID];
assign bram.stage1_addr = translated_address;
assign bram.stage2_addr = stage2_phys_address;
assign bram.flush = gc.fetch_flush;
assign unit_data_array[BRAM_ID] = bram.data_out;
generate for (i=0; i < NUM_SUB_UNITS; i++) begin : gen_fetch_sources
assign sub_unit[i].new_request = new_mem_request & sub_unit_address_match[i] & ~gc.fetch_flush;
assign sub_unit[i].addr = translated_address;
assign sub_unit[i].re = 1;
assign sub_unit[i].we = 0;
assign sub_unit[i].be = '0;
assign sub_unit[i].data_in = '0;
ibram i_bram (
assign unit_ready[i] = sub_unit[i].ready;
assign unit_data_valid[i] = sub_unit[i].data_valid;
assign unit_data_array[i] = sub_unit[i].data_out;
end
endgenerate
generate if (CONFIG.INCLUDE_ILOCAL_MEM) begin : gen_fetch_local_mem
assign sub_unit_address_match[LOCAL_MEM_ID] = ilocal_mem_addr_utils.address_range_check(translated_address);
local_mem_sub_unit i_local_mem (
.clk (clk),
.rst (rst),
.fetch_sub (bram),
.instruction_bram (instruction_bram)
.unit (sub_unit[LOCAL_MEM_ID]),
.local_mem (instruction_bram)
);
end
endgenerate
generate if (CONFIG.INCLUDE_ICACHE) begin : gen_fetch_icache
assign sub_unit_address_match[ICACHE_ID] = cache.address_range_check(translated_address);
assign unit_ready[ICACHE_ID] = cache.ready;
assign unit_data_valid[ICACHE_ID] = cache.data_valid;
assign cache.new_request = new_mem_request & sub_unit_address_match[ICACHE_ID];
assign cache.stage1_addr = translated_address;
assign cache.stage2_addr = stage2_phys_address;
assign cache.flush = gc.fetch_flush;
assign unit_data_array[ICACHE_ID] = cache.data_out;
assign sub_unit_address_match[ICACHE_ID] = icache_addr_utils.address_range_check(translated_address);
icache #(.CONFIG(CONFIG))
i_cache (
.clk (clk),
.rst (rst),
.gc (gc),
.icache_on (icache_on),
.l1_request (l1_request),
.l1_response (l1_response),
.fetch_sub (cache)
.fetch_sub (sub_unit[ICACHE_ID])
);
end
endgenerate

View file

@ -1,51 +0,0 @@
/*
* Copyright © 2017 Eric Matthews, Lesley Shannon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Initial code developed under the supervision of Dr. Lesley Shannon,
* Reconfigurable Computing Lab, Simon Fraser University.
*
* Author(s):
* Eric Matthews <ematthew@sfu.ca>
*/
module ibram
import cva5_config::*;
import cva5_types::*;
(
input logic clk,
input logic rst,
fetch_sub_unit_interface.sub_unit fetch_sub,
local_memory_interface.master instruction_bram
);
assign fetch_sub.ready = 1;
assign instruction_bram.addr = fetch_sub.stage1_addr[31:2];
assign instruction_bram.en = fetch_sub.new_request;
assign instruction_bram.be = '0;
assign instruction_bram.data_in = '0;
assign fetch_sub.data_out = instruction_bram.data_out;
always_ff @ (posedge clk) begin
if (rst | fetch_sub.flush)
fetch_sub.data_valid <= 0;
else
fetch_sub.data_valid <= fetch_sub.new_request;
end
endmodule

View file

@ -33,11 +33,12 @@ module icache
(
input logic clk,
input logic rst,
input gc_outputs_t gc,
input logic icache_on,
l1_arbiter_request_interface.master l1_request,
l1_arbiter_return_interface.master l1_response,
fetch_sub_unit_interface.sub_unit fetch_sub
memory_sub_unit_interface.responder fetch_sub
);
localparam derived_cache_config_t SCONFIG = get_derived_cache_params(CONFIG, CONFIG.ICACHE, CONFIG.ICACHE_ADDR);
@ -61,6 +62,7 @@ module icache
logic miss_data_valid;
logic second_cycle;
logic [31:0] second_cycle_addr;
logic idle;
logic memory_complete;
@ -86,7 +88,12 @@ module icache
if (rst)
second_cycle <= 0;
else
second_cycle <= fetch_sub.new_request & ~fetch_sub.flush;
second_cycle <= fetch_sub.new_request & ~gc.fetch_flush;
end
always_ff @(posedge clk) begin
if (fetch_sub.new_request)
second_cycle_addr <= fetch_sub.addr;
end
//As request can be aborted on any cycle, only update tags if memory request is in progress
@ -114,7 +121,7 @@ module icache
logic initiate_l1_request;
logic request_r;
assign l1_request.addr = fetch_sub.stage2_addr;
assign l1_request.addr = second_cycle_addr;
assign l1_request.data = 0;
assign l1_request.rnw = 1;
assign l1_request.be = 0;
@ -124,12 +131,12 @@ module icache
assign initiate_l1_request = second_cycle & (~tag_hit | ~icache_on);
always_ff @ (posedge clk) begin
if (rst | fetch_sub.flush)
if (rst | gc.fetch_flush)
request_r <= 0;
else
request_r <= (initiate_l1_request | request_r) & ~l1_request.ack;
end
assign l1_request.request = request_r & ~fetch_sub.flush;
assign l1_request.request = request_r & ~gc.fetch_flush;
////////////////////////////////////////////////////
//Miss state tracking
@ -144,7 +151,7 @@ module icache
if (rst)
miss_aborted_by_flush <= 0;
else
miss_aborted_by_flush <= (~line_complete) & ((miss_in_progress & fetch_sub.flush) | miss_aborted_by_flush);
miss_aborted_by_flush <= (~line_complete) & ((miss_in_progress & gc.fetch_flush) | miss_aborted_by_flush);
end
////////////////////////////////////////////////////
@ -152,9 +159,9 @@ module icache
itag_banks #(.CONFIG(CONFIG), .SCONFIG(SCONFIG))
icache_tag_banks (
.clk(clk),
.rst(rst | fetch_sub.flush), //clears the read_hit_allowed flag
.stage1_addr(fetch_sub.stage1_addr),
.stage2_addr(fetch_sub.stage2_addr),
.rst(rst | gc.fetch_flush), //clears the read_hit_allowed flag
.stage1_addr(fetch_sub.addr),
.stage2_addr(second_cycle_addr),
.update_way(tag_update_way),
.update(tag_update),
.stage1_adv(fetch_sub.new_request & icache_on),
@ -168,8 +175,8 @@ module icache
generate for (i=0; i < CONFIG.ICACHE.WAYS; i++) begin : idata_bank_gen
byte_en_BRAM #(CONFIG.ICACHE.LINES*CONFIG.ICACHE.LINE_W) idata_bank (
.clk(clk),
.addr_a(fetch_sub.stage1_addr[2 +: SCONFIG.LINE_ADDR_W+SCONFIG.SUB_LINE_ADDR_W]),
.addr_b({fetch_sub.stage2_addr[(2+SCONFIG.SUB_LINE_ADDR_W) +: SCONFIG.LINE_ADDR_W], word_count}),
.addr_a(fetch_sub.addr[2 +: SCONFIG.LINE_ADDR_W+SCONFIG.SUB_LINE_ADDR_W]),
.addr_b({second_cycle_addr[(2+SCONFIG.SUB_LINE_ADDR_W) +: SCONFIG.LINE_ADDR_W], word_count}),
.en_a(fetch_sub.new_request),
.en_b(tag_update_way[i] & l1_response.data_valid),
.be_a('0),
@ -190,7 +197,7 @@ module icache
word_count <= word_count + 1;
end
assign is_target_word = (fetch_sub.stage2_addr[2 +: SCONFIG.SUB_LINE_ADDR_W] == word_count);
assign is_target_word = (second_cycle_addr[2 +: SCONFIG.SUB_LINE_ADDR_W] == word_count);
always_ff @ (posedge clk) begin
if (l1_response.data_valid & is_target_word)
@ -200,7 +207,7 @@ module icache
end
always_ff @ (posedge clk) begin
if (rst | fetch_sub.flush)
if (rst | gc.fetch_flush)
miss_data_valid <= 0;
else
miss_data_valid <= (miss_in_progress & ~miss_aborted_by_flush) & l1_response.data_valid & is_target_word;
@ -230,9 +237,9 @@ module icache
always_ff @ (posedge clk) begin
if (rst)
idle <= 1;
else if (fetch_sub.new_request & ~fetch_sub.flush)
else if (fetch_sub.new_request & ~gc.fetch_flush)
idle <= 0;
else if (memory_complete | tag_hit | (second_cycle & fetch_sub.flush) | (~miss_in_progress & fetch_sub.flush)) //read miss OR write through complete
else if (memory_complete | tag_hit | (second_cycle & gc.fetch_flush) | (~miss_in_progress & gc.fetch_flush)) //read miss OR write through complete
idle <= 1;
end

View file

@ -271,38 +271,46 @@ interface ls_sub_unit_interface #(parameter bit [31:0] BASE_ADDR = 32'h00000000,
endinterface
interface addr_utils_interface #(parameter bit [31:0] BASE_ADDR = 32'h00000000, parameter bit [31:0] UPPER_BOUND = 32'hFFFFFFFF);
//Based on the lower and upper address ranges,
//find the number of bits needed to uniquely identify this memory range.
//Assumption: address range is aligned to its size
function automatic int unsigned bit_range ();
int unsigned i;
for(i=0; i < 32; i++) begin
if (BASE_ADDR[i] == UPPER_BOUND[i])
break;
end
return (32 - i);
endfunction
interface fetch_sub_unit_interface #(parameter bit [31:0] BASE_ADDR = 32'h00000000, parameter bit [31:0] UPPER_BOUND = 32'hFFFFFFFF);
logic [31:0] stage1_addr;
logic [31:0] stage2_addr;
localparam int unsigned BIT_RANGE = bit_range();
function address_range_check (input logic[31:0] addr);
return (addr[31:32-BIT_RANGE] == BASE_ADDR[31:32-BIT_RANGE]);
endfunction
endinterface
interface memory_sub_unit_interface;
logic new_request;
logic [31:0] addr;
logic re;
logic we;
logic [3:0] be;
logic [31:0] data_in;
logic [31:0] data_out;
logic data_valid;
logic ready;
logic new_request;
logic flush;
//Based on the lower and upper address ranges,
//find the number of bits needed to uniquely identify this memory range.
//Assumption: address range is aligned to its size
function automatic int unsigned bit_range ();
int unsigned i;
for(i=0; i < 32; i++) begin
if (BASE_ADDR[i] == UPPER_BOUND[i])
break;
end
return (32 - i);
endfunction
localparam int unsigned BIT_RANGE = bit_range();
function address_range_check (input logic[31:0] addr);
return (addr[31:32-BIT_RANGE] == BASE_ADDR[31:32-BIT_RANGE]);
endfunction
modport sub_unit (input stage1_addr, stage2_addr, new_request, flush, output data_out, data_valid, ready);
modport fetch (output stage1_addr, stage2_addr, new_request, flush, input data_out, data_valid, ready);
modport responder (
input addr, re, we, be, data_in, new_request,
output data_out, data_valid, ready
);
modport controller (
input data_out, data_valid, ready,
output addr, re, we, be, data_in, new_request
);
endinterface
//start and done are cycle cycle pulses

View file

@ -73,17 +73,25 @@ module load_store_unit
localparam NUM_SUB_UNITS = int'(CONFIG.INCLUDE_DLOCAL_MEM) + int'(CONFIG.INCLUDE_PERIPHERAL_BUS) + int'(CONFIG.INCLUDE_DCACHE);
localparam NUM_SUB_UNITS_W = (NUM_SUB_UNITS == 1) ? 1 : $clog2(NUM_SUB_UNITS);
localparam BRAM_ID = 0;
localparam LOCAL_MEM_ID = 0;
localparam BUS_ID = int'(CONFIG.INCLUDE_DLOCAL_MEM);
localparam DCACHE_ID = int'(CONFIG.INCLUDE_DLOCAL_MEM) + int'(CONFIG.INCLUDE_PERIPHERAL_BUS);
//Should be equal to pipeline depth of longest load/store subunit
localparam ATTRIBUTES_DEPTH = CONFIG.INCLUDE_DCACHE ? 2 : 1;
//Subunit signals
addr_utils_interface #(CONFIG.DLOCAL_MEM_ADDR.L, CONFIG.DLOCAL_MEM_ADDR.H) dlocal_mem_addr_utils ();
addr_utils_interface #(CONFIG.PERIPHERAL_BUS_ADDR.L, CONFIG.PERIPHERAL_BUS_ADDR.H) dpbus_addr_utils ();
addr_utils_interface #(CONFIG.DCACHE_ADDR.L, CONFIG.DCACHE_ADDR.H) dcache_addr_utils ();
memory_sub_unit_interface sub_unit[NUM_SUB_UNITS-1:0]();
data_access_shared_inputs_t shared_inputs;
ls_sub_unit_interface #(.BASE_ADDR(CONFIG.DLOCAL_MEM_ADDR.L), .UPPER_BOUND(CONFIG.DLOCAL_MEM_ADDR.H)) bram();
ls_sub_unit_interface #(.BASE_ADDR(CONFIG.PERIPHERAL_BUS_ADDR.L), .UPPER_BOUND(CONFIG.PERIPHERAL_BUS_ADDR.H)) bus();
ls_sub_unit_interface #(.BASE_ADDR(CONFIG.DCACHE_ADDR.L), .UPPER_BOUND(CONFIG.DCACHE_ADDR.H)) cache();
logic [31:0] unit_data_array [NUM_SUB_UNITS-1:0];
logic [NUM_SUB_UNITS-1:0] unit_ready;
logic [NUM_SUB_UNITS-1:0] unit_data_valid;
logic [NUM_SUB_UNITS-1:0] last_unit;
logic [NUM_SUB_UNITS-1:0] current_unit;
logic units_ready;
logic unit_switch_stall;
@ -97,11 +105,6 @@ module load_store_unit
logic [31:0] aligned_load_data;
logic [31:0] final_load_data;
logic [31:0] unit_data_array [NUM_SUB_UNITS-1:0];
logic [NUM_SUB_UNITS-1:0] unit_ready;
logic [NUM_SUB_UNITS-1:0] unit_data_valid;
logic [NUM_SUB_UNITS-1:0] last_unit;
logic [NUM_SUB_UNITS-1:0] current_unit;
logic unaligned_addr;
logic load_exception_complete;
@ -227,7 +230,7 @@ endgenerate
//Unit tracking
assign current_unit = sub_unit_address_match;
initial last_unit = BRAM_ID;
initial last_unit = LOCAL_MEM_ID;
always_ff @ (posedge clk) begin
if (load_attributes.push)
last_unit <= sub_unit_address_match;
@ -296,85 +299,73 @@ endgenerate
////////////////////////////////////////////////////
//Unit Instantiation
generate for (genvar i=0; i < NUM_SUB_UNITS; i++) begin : gen_load_store_sources
assign sub_unit[i].new_request = issue_request & sub_unit_address_match[i];
assign sub_unit[i].addr = shared_inputs.addr;
assign sub_unit[i].re = shared_inputs.load;
assign sub_unit[i].we = shared_inputs.store;
assign sub_unit[i].be = shared_inputs.be;
assign sub_unit[i].data_in = shared_inputs.data_in;
assign unit_ready[i] = sub_unit[i].ready;
assign unit_data_valid[i] = sub_unit[i].data_valid;
assign unit_data_array[i] = sub_unit[i].data_out;
end
endgenerate
generate if (CONFIG.INCLUDE_DLOCAL_MEM) begin : gen_ls_local_mem
assign sub_unit_address_match[BRAM_ID] = bram.address_range_check(shared_inputs.addr);
assign bram.new_request = sub_unit_address_match[BRAM_ID] & issue_request;
assign unit_ready[BRAM_ID] = bram.ready;
assign unit_data_valid[BRAM_ID] = bram.data_valid;
dbram d_bram (
.clk (clk),
.rst (rst),
.ls_inputs (shared_inputs),
.ls (bram),
.data_out (unit_data_array[BRAM_ID]),
.data_bram (data_bram)
);
assign sub_unit_address_match[LOCAL_MEM_ID] = dlocal_mem_addr_utils.address_range_check(shared_inputs.addr);
local_mem_sub_unit d_local_mem (
.clk (clk),
.rst (rst),
.unit (sub_unit[LOCAL_MEM_ID]),
.local_mem (data_bram)
);
end
endgenerate
generate if (CONFIG.INCLUDE_PERIPHERAL_BUS) begin : gen_ls_pbus
assign sub_unit_address_match[BUS_ID] = bus.address_range_check(shared_inputs.addr);
assign bus.new_request = sub_unit_address_match[BUS_ID] & issue_request;
assign unit_ready[BUS_ID] = bus.ready;
assign unit_data_valid[BUS_ID] = bus.data_valid;
assign sub_unit_address_match[BUS_ID] = dpbus_addr_utils.address_range_check(shared_inputs.addr);
if(CONFIG.PERIPHERAL_BUS_TYPE == AXI_BUS)
axi_master axi_bus (
.clk (clk),
.rst (rst),
.m_axi (m_axi),
.size ({1'b0,shared_inputs.fn3[1:0]}),
.data_out (unit_data_array[BUS_ID]),
.ls_inputs (shared_inputs),
.ls (bus)
.clk (clk),
.rst (rst),
.m_axi (m_axi),
.size ({1'b0,shared_inputs.fn3[1:0]}),
.ls (sub_unit[BUS_ID])
); //Lower two bits of fn3 match AXI specification for request size (byte/halfword/word)
else if (CONFIG.PERIPHERAL_BUS_TYPE == WISHBONE_BUS)
wishbone_master wishbone_bus (
.clk (clk),
.rst (rst),
.m_wishbone (m_wishbone),
.data_out (unit_data_array[BUS_ID]),
.ls_inputs (shared_inputs),
.ls (bus)
.clk (clk),
.rst (rst),
.m_wishbone (m_wishbone),
.ls (sub_unit[BUS_ID])
);
else if (CONFIG.PERIPHERAL_BUS_TYPE == AVALON_BUS) begin
avalon_master avalon_bus (
.clk (clk),
.rst (rst),
.ls_inputs (shared_inputs),
.m_avalon (m_avalon),
.ls (bus),
.data_out (unit_data_array[BUS_ID])
.clk (clk),
.rst (rst),
.m_avalon (m_avalon),
.ls (sub_unit[BUS_ID])
);
end
end
endgenerate
generate if (CONFIG.INCLUDE_DCACHE) begin : gen_ls_dcache
assign sub_unit_address_match[DCACHE_ID] = cache.address_range_check(shared_inputs.addr);
assign cache.new_request = sub_unit_address_match[DCACHE_ID] & issue_request;
assign unit_ready[DCACHE_ID] = cache.ready;
assign unit_data_valid[DCACHE_ID] = cache.data_valid;
assign sub_unit_address_match[DCACHE_ID] = dcache_addr_utils.address_range_check(shared_inputs.addr);
dcache # (.CONFIG(CONFIG))
data_cache (
.clk (clk),
.rst (rst),
.dcache_on (dcache_on),
.l1_request (l1_request),
.l1_response (l1_response),
.sc_complete (sc_complete),
.sc_success (sc_success),
.clear_reservation (clear_reservation),
.ls_inputs (shared_inputs),
.data_out (unit_data_array[DCACHE_ID]),
.amo (ls_inputs.amo),
.ls (cache)
.clk (clk),
.rst (rst),
.dcache_on (dcache_on),
.l1_request (l1_request),
.l1_response (l1_response),
.sc_complete (sc_complete),
.sc_success (sc_success),
.clear_reservation (clear_reservation),
.amo (ls_inputs.amo),
.ls (sub_unit[DCACHE_ID])
);
end
endgenerate

View file

@ -20,36 +20,33 @@
* Eric Matthews <ematthew@sfu.ca>
*/
module dbram
module local_mem_sub_unit
import cva5_config::*;
import riscv_types::*;
import cva5_types::*;
(
input logic clk,
input logic rst,
input data_access_shared_inputs_t ls_inputs,
ls_sub_unit_interface.sub_unit ls,
output logic[31:0] data_out,
local_memory_interface.master data_bram
memory_sub_unit_interface.responder unit,
local_memory_interface.master local_mem
);
assign ls.ready = 1;
assign unit.ready = 1;
assign data_bram.addr = ls_inputs.addr[31:2];
assign data_bram.en = ls.new_request;
assign data_bram.be = ls_inputs.be;
assign data_bram.data_in = ls_inputs.data_in;
assign data_out = data_bram.data_out;
assign local_mem.addr = unit.addr[31:2];
assign local_mem.en = unit.new_request;
assign local_mem.be = unit.be;
assign local_mem.data_in = unit.data_in;
assign unit.data_out = local_mem.data_out;
always_ff @ (posedge clk) begin
if (rst)
ls.data_valid <= 0;
unit.data_valid <= 0;
else
ls.data_valid <= ls.new_request & ls_inputs.load;
unit.data_valid <= unit.new_request & unit.re;
end
endmodule

View file

@ -31,21 +31,17 @@ module wishbone_master
input logic rst,
wishbone_interface.master m_wishbone,
output logic[31:0] data_out,
input data_access_shared_inputs_t ls_inputs,
ls_sub_unit_interface.sub_unit ls
memory_sub_unit_interface.responder ls
);
//implementation
////////////////////////////////////////////////////
always_ff @ (posedge clk) begin
if (ls.new_request) begin
m_wishbone.addr <= ls_inputs.addr;
m_wishbone.we <= ls_inputs.store;
m_wishbone.sel <= ls_inputs.be;
m_wishbone.writedata <= ls_inputs.data_in;
m_wishbone.addr <= ls.addr;
m_wishbone.we <= ls.we;
m_wishbone.sel <= ls.be;
m_wishbone.writedata <= ls.data_in;
end
end
@ -67,9 +63,9 @@ module wishbone_master
always_ff @ (posedge clk) begin
if (m_wishbone.ack)
data_out <= m_wishbone.readdata;
ls.data_out <= m_wishbone.readdata;
else
data_out <= 0;
ls.data_out <= 0;
end
always_ff @ (posedge clk) begin

View file

@ -14,7 +14,22 @@ core/external_interfaces.sv
core/lutrams/lutram_1w_1r.sv
core/lutrams/lutram_1w_mr.sv
core/set_clr_reg_with_rst.sv
core/one_hot_occupancy.sv
core/binary_occupancy.sv
core/one_hot_to_integer.sv
core/cycler.sv
core/lfsr.sv
core/cva5_fifo.sv
core/shift_counter.sv
core/priority_encoder.sv
core/toggle_memory.sv
core/toggle_memory_set.sv
core/intel/intel_byte_enable_ram.sv
core/xilinx/xilinx_byte_enable_ram.sv
core/byte_en_BRAM.sv
core/csr_unit.sv
core/gc_unit.sv
@ -25,30 +40,13 @@ core/branch_unit.sv
core/barrel_shifter.sv
core/alu_unit.sv
core/local_mem_sub_unit.sv
core/axi_master.sv
core/avalon_master.sv
core/wishbone_master.sv
core/axi_to_arb.sv
core/one_hot_occupancy.sv
core/binary_occupancy.sv
core/cva5_fifo.sv
core/shift_counter.sv
core/priority_encoder.sv
core/set_clr_reg_with_rst.sv
core/intel/intel_byte_enable_ram.sv
core/xilinx/xilinx_byte_enable_ram.sv
core/byte_en_BRAM.sv
core/one_hot_to_integer.sv
core/cycler.sv
core/tag_bank.sv
core/dbram.sv
core/ddata_bank.sv
core/dtag_banks.sv
core/amo_alu.sv
@ -59,17 +57,9 @@ core/store_queue.sv
core/load_store_queue.sv
core/load_store_unit.sv
core/ibram.sv
core/itag_banks.sv
core/icache.sv
core/clz.sv
core/div_core.sv
core/div_unit.sv
@ -79,10 +69,6 @@ core/mmu.sv
core/mul_unit.sv
core/l1_arbiter.sv
core/ras.sv
core/branch_predictor_ram.sv
core/branch_predictor.sv
@ -97,16 +83,15 @@ core/register_bank.sv
core/register_file.sv
core/writeback.sv
core/placer_randomizer.sv
l2_arbiter/l2_fifo.sv
l2_arbiter/l2_reservation_logic.sv
l2_arbiter/l2_round_robin.sv
l2_arbiter/l2_arbiter.sv
core/axi_to_arb.sv
core/toggle_memory.sv
core/toggle_memory_set.sv
core/instruction_metadata_and_id_management.sv
core/l1_arbiter.sv
core/cva5.sv