diff --git a/core/avalon_master.sv b/core/avalon_master.sv index 3d1797e..b9cd606 100644 --- a/core/avalon_master.sv +++ b/core/avalon_master.sv @@ -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; diff --git a/core/axi_master.sv b/core/axi_master.sv index ea7ed10..c43fed0 100755 --- a/core/axi_master.sv +++ b/core/axi_master.sv @@ -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) ); diff --git a/core/dcache.sv b/core/dcache.sv index 778ee0a..533e797 100755 --- a/core/dcache.sv +++ b/core/dcache.sv @@ -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 diff --git a/core/fetch.sv b/core/fetch.sv index 0e1757d..283c2e4 100755 --- a/core/fetch.sv +++ b/core/fetch.sv @@ -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 diff --git a/core/ibram.sv b/core/ibram.sv deleted file mode 100755 index b0db683..0000000 --- a/core/ibram.sv +++ /dev/null @@ -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 - */ - -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 diff --git a/core/icache.sv b/core/icache.sv index 953aae3..2df92a6 100755 --- a/core/icache.sv +++ b/core/icache.sv @@ -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 diff --git a/core/interfaces.sv b/core/interfaces.sv index 320a532..8fe07a4 100755 --- a/core/interfaces.sv +++ b/core/interfaces.sv @@ -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 diff --git a/core/load_store_unit.sv b/core/load_store_unit.sv index a8530de..21d21f8 100755 --- a/core/load_store_unit.sv +++ b/core/load_store_unit.sv @@ -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 diff --git a/core/dbram.sv b/core/local_mem_sub_unit.sv similarity index 65% rename from core/dbram.sv rename to core/local_mem_sub_unit.sv index 0ae584c..ae55897 100755 --- a/core/dbram.sv +++ b/core/local_mem_sub_unit.sv @@ -20,36 +20,33 @@ * Eric Matthews */ -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 diff --git a/core/wishbone_master.sv b/core/wishbone_master.sv index 6c160a7..23c57b2 100644 --- a/core/wishbone_master.sv +++ b/core/wishbone_master.sv @@ -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 diff --git a/tools/compile_order b/tools/compile_order index 996183d..36b2150 100644 --- a/tools/compile_order +++ b/tools/compile_order @@ -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