├── SIM ├── .gitignore ├── pulp_soc_defines.sv ├── enable_icache_with_prefetch.tcl ├── enable_icache_no_prefetch.tcl ├── compile.sh └── pulp_interfaces.sv ├── DOC ├── HierIcache.png ├── icache_hier.docx ├── icache_hier.pdf └── CLUSTER_ICACHE_CTRL_reference.xlsx ├── RTL ├── .gitignore ├── L1_CACHE │ ├── register_file_1w_multi_port_read_test_wrap.sv │ ├── register_file_1w_multi_port_read.sv │ ├── refill_arbiter.sv │ └── pri_icache.sv ├── L1.5_CACHE │ ├── ram_ws_rs_tag_scm.sv │ ├── RefillTracker_4.sv │ ├── ram_ws_rs_data_scm.sv │ ├── REP_buffer_4.sv │ ├── AXI4_REFILL_Resp_Deserializer.sv │ └── share_icache.sv └── TOP │ └── icache_hier_top.sv ├── src_files.yml ├── Bender.yml ├── README.md ├── TB ├── l2_generic.sv ├── generic_memory_with_grant.sv ├── ibus_lint_memory_128.sv ├── tgen_128.sv └── tb.sv ├── CTRL_UNIT └── hier_icache_ctrl_unit_wrap.sv └── LICENSE /SIM/.gitignore: -------------------------------------------------------------------------------- 1 | transcript 2 | vsim.wlf 3 | work/ 4 | modelsim.ini 5 | -------------------------------------------------------------------------------- /DOC/HierIcache.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pulp-platform/hier-icache/HEAD/DOC/HierIcache.png -------------------------------------------------------------------------------- /DOC/icache_hier.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pulp-platform/hier-icache/HEAD/DOC/icache_hier.docx -------------------------------------------------------------------------------- /DOC/icache_hier.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pulp-platform/hier-icache/HEAD/DOC/icache_hier.pdf -------------------------------------------------------------------------------- /RTL/.gitignore: -------------------------------------------------------------------------------- 1 | axi 2 | axi_slice 3 | common_cells 4 | icache-intc 5 | scm 6 | tech_cells_generic 7 | -------------------------------------------------------------------------------- /DOC/CLUSTER_ICACHE_CTRL_reference.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pulp-platform/hier-icache/HEAD/DOC/CLUSTER_ICACHE_CTRL_reference.xlsx -------------------------------------------------------------------------------- /SIM/pulp_soc_defines.sv: -------------------------------------------------------------------------------- 1 | `define FEATURE_ICACHE_STAT 2 | // Width of byte enable for a given data width 3 | `define EVAL_BE_WIDTH(DATAWIDTH) (DATAWIDTH/8) 4 | 5 | 6 | `define NB_CORES 8 7 | `define SH_NB_CACHE_BANKS 2 8 | -------------------------------------------------------------------------------- /SIM/enable_icache_with_prefetch.tcl: -------------------------------------------------------------------------------- 1 | force -freeze sim:/tb/sh_req_disable 8'b00000_0000 0 2 | force -freeze sim:/tb/sh_req_enable 8'b11111_1111 0 3 | force -freeze sim:/tb/pri_bypass_req 8'b00000_0000 0 4 | force -freeze sim:/tb/enable_l1_l15_prefetch 8'b11111_1111 0 5 | -------------------------------------------------------------------------------- /src_files.yml: -------------------------------------------------------------------------------- 1 | hier-icache: 2 | vlog_opts: [ 3 | -L common_cells_lib, 4 | -L axi_lib, 5 | ] 6 | incdirs: [ 7 | ../../rtl/includes, 8 | ../axi/axi/include, 9 | ] 10 | files: [ 11 | RTL/TOP/icache_hier_top.sv, 12 | RTL/L1_CACHE/pri_icache_controller.sv, 13 | RTL/L1_CACHE/refill_arbiter.sv, 14 | RTL/L1_CACHE/pri_icache.sv, 15 | RTL/L1_CACHE/register_file_1w_multi_port_read.sv, 16 | RTL/L1_CACHE/register_file_1w_multi_port_read_test_wrap.sv, 17 | RTL/L1.5_CACHE/AXI4_REFILL_Resp_Deserializer.sv, 18 | RTL/L1.5_CACHE/share_icache.sv, 19 | RTL/L1.5_CACHE/share_icache_controller.sv, 20 | RTL/L1.5_CACHE/RefillTracker_4.sv, 21 | RTL/L1.5_CACHE/REP_buffer_4.sv, 22 | RTL/L1.5_CACHE/ram_ws_rs_data_scm.sv, 23 | RTL/L1.5_CACHE/ram_ws_rs_tag_scm.sv, 24 | CTRL_UNIT/hier_icache_ctrl_unit.sv, 25 | CTRL_UNIT/hier_icache_ctrl_unit_wrap.sv, 26 | ] 27 | -------------------------------------------------------------------------------- /SIM/enable_icache_no_prefetch.tcl: -------------------------------------------------------------------------------- 1 | force -freeze sim:/tb/sh_req_disable 8'b00000_0000 0 2 | force -freeze sim:/tb/sh_req_enable 8'b11111_1111 0 3 | force -freeze sim:/tb/pri_bypass_req 8'b00000_0000 0 4 | 5 | run 8us 6 | force -freeze sim:/tb/pri_bypass_req 8'b11111_1111 0 7 | run 7us 8 | force -freeze sim:/tb/pri_bypass_req 8'b00000_0000 0 9 | 10 | run 8us 11 | force -freeze sim:/tb/pri_bypass_req 8'b11111_1111 0 12 | run 7us 13 | force -freeze sim:/tb/pri_bypass_req 8'b00000_0000 0 14 | 15 | run 8us 16 | force -freeze sim:/tb/pri_bypass_req 8'b11111_1111 0 17 | run 7us 18 | force -freeze sim:/tb/pri_bypass_req 8'b00000_0000 0 19 | 20 | run 8us 21 | force -freeze sim:/tb/pri_bypass_req 8'b11111_1111 0 22 | run 7us 23 | force -freeze sim:/tb/pri_bypass_req 8'b00000_0000 0 24 | 25 | run 8us 26 | force -freeze sim:/tb/pri_bypass_req 8'b11111_1111 0 27 | run 7us 28 | force -freeze sim:/tb/pri_bypass_req 8'b00000_0000 0 29 | 30 | run 8us 31 | force -freeze sim:/tb/pri_bypass_req 8'b11111_1111 0 32 | run 7us 33 | force -freeze sim:/tb/pri_bypass_req 8'b00000_0000 0 34 | 35 | run 8us 36 | force -freeze sim:/tb/pri_bypass_req 8'b11111_1111 0 37 | run 7us 38 | force -freeze sim:/tb/pri_bypass_req 8'b00000_0000 0 39 | 40 | run 8us 41 | force -freeze sim:/tb/pri_bypass_req 8'b11111_1111 0 42 | run 7us 43 | force -freeze sim:/tb/pri_bypass_req 8'b00000_0000 0 44 | -------------------------------------------------------------------------------- /Bender.yml: -------------------------------------------------------------------------------- 1 | package: 2 | name: hier-icache 3 | authors: 4 | - "Jie Chen " 5 | - "Angelo Garofalo " 6 | 7 | dependencies: 8 | common_cells: { git: "https://github.com/pulp-platform/common_cells.git", version: 1.13.1 } 9 | tech_cells_generic: { git: "https://github.com/pulp-platform/tech_cells_generic", version: 0.2.11 } 10 | scm: { git: "https://github.com/pulp-platform/scm.git", rev: 74426dee36f28ae1c02f7635cf844a0156145320 } 11 | icache-intc: { git: "https://github.com/pulp-platform/icache-intc.git", version: 1.0.1 } 12 | axi_slice: { git: "https://github.com/pulp-platform/axi_slice.git", version: 1.1.4 } # deprecated, replaced by axi_cut (in axi repo) 13 | axi: { git: "https://github.com/pulp-platform/axi.git", version: 0.39 } 14 | 15 | sources: 16 | # Source files grouped in levels. Files in level 0 have no dependencies on files in this 17 | # package. Files in level 1 only depend on files in level 0, files in level 2 on files in 18 | # levels 1 and 0, etc. Files within a level are ordered alphabetically. 19 | # Level 0 20 | - CTRL_UNIT/hier_icache_ctrl_unit.sv 21 | - RTL/L1.5_CACHE/ram_ws_rs_data_scm.sv 22 | - RTL/L1.5_CACHE/ram_ws_rs_tag_scm.sv 23 | - RTL/L1.5_CACHE/RefillTracker_4.sv 24 | - RTL/L1.5_CACHE/REP_buffer_4.sv 25 | - RTL/L1_CACHE/pri_icache_controller.sv 26 | - RTL/L1_CACHE/refill_arbiter.sv 27 | # Level 1 28 | - CTRL_UNIT/hier_icache_ctrl_unit_wrap.sv 29 | - RTL/L1.5_CACHE/AXI4_REFILL_Resp_Deserializer.sv 30 | - RTL/L1.5_CACHE/share_icache_controller.sv 31 | - RTL/L1_CACHE/register_file_1w_multi_port_read_test_wrap.sv 32 | # Level 2 33 | - RTL/L1.5_CACHE/share_icache.sv 34 | - RTL/L1_CACHE/pri_icache.sv 35 | # Level 3 36 | - RTL/TOP/icache_hier_top.sv 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Structure of the REPO 2 | 3 | - README.md 4 | - RTL 5 | - L1.5_CACHE 6 | - AXI4_REFILL_Resp_Deserializer.sv 7 | - icache_controller.sv 8 | - ram_ws_rs_data_scm.sv 9 | - ram_ws_rs_tag_scm.sv 10 | - RefillTracker_4.sv 11 | - REP_buffer_4.sv 12 | - share_icache.sv 13 | - L1_CACHE 14 | - pri_icache_controller.sv 15 | - pri_icache.sv 16 | - TOP 17 | - icache_hier_top.sv 18 | - SIM 19 | - compile.csh 20 | - enable_icache_no_prefetch_9th_core_seperation.tcl 21 | - enable_icache_no_prefetch.tcl 22 | - enable_icache_with_prefetch_9th_core_seperation.tcl 23 | - enable_icache_with_prefetch.tcl 24 | - pulp_interfaces.sv 25 | - ulpsoc_defines.sv 26 | - wawe.do 27 | - TB 28 | - axi_mem_if.sv 29 | - generic_memory_with_grant.sv 30 | - ibus_lint_memory_128.sv 31 | - l2_generic.sv 32 | - tb.sv 33 | - tgen_128.sv 34 | 35 | # Description 36 | This Ip implements a 2 Level Instruction caches tailored for Tigthly coupled Processor (Eg Cluster of Processing elements in PULP). It is composed By a private L1 Instruction cache, SCM based with small footprint and 2 way set associative, followed by a central L2 instruction cache, shared among the cores, and tuned for high capacity. The benefit of this IP is to alleviate the timing pressure on the prcessor fetch interface. 37 | 38 | # Run 39 | In the SIM folder source the compile script. 40 | 41 | ``` 42 | source ./compile.csh 43 | ``` 44 | 45 | Caches are by default disabled. To control them, a icache control unit is required. 46 | Temporarely, user can enable it forcing the enable req from simulator command line using tcl script: 47 | 48 | 49 | To enable the ICACHES without L1 to L1.5 prefetch feature 50 | ``` 51 | source enable_icache_no_prefetch.tcl 52 | ``` 53 | 54 | Self checking logic will check every transaction made. 55 | 56 | # Block diagram 57 | ![HierIcache](./DOC/HierIcache.png) 58 | -------------------------------------------------------------------------------- /TB/l2_generic.sv: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ETH Zurich and University of Bologna. 2 | // Copyright and related rights are licensed under the Solderpad Hardware 3 | // License, Version 0.51 (the "License"); you may not use this file except in 4 | // compliance with the License. You may obtain a copy of the License at 5 | // http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law 6 | // or agreed to in writing, software, hardware and materials distributed under 7 | // this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 8 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 9 | // specific language governing permissions and limitations under the License. 10 | 11 | 12 | //******************************************************** 13 | //************* L2 RAM MEMORY WRAPPER ******************** 14 | //******************************************************** 15 | 16 | module l2_generic 17 | #( 18 | parameter ADDR_WIDTH = 12 19 | ) 20 | ( 21 | input logic CLK, 22 | input logic RSTN, 23 | 24 | input logic CEN, 25 | input logic WEN, 26 | input logic [ADDR_WIDTH-1:0] A, 27 | input logic [63:0] D, 28 | input logic [7:0] BE, 29 | output logic [63:0] Q 30 | ); 31 | 32 | logic s_cen; 33 | logic s_wen; 34 | 35 | // GENERATION OF CEN 36 | always_comb 37 | begin 38 | s_cen = 1'b1; 39 | if (CEN == 1'b0) 40 | s_cen = 1'b0; 41 | end 42 | 43 | // GENERATION OF WEN 44 | always_comb 45 | begin 46 | s_wen = 1'b1; 47 | if (WEN == 1'b0) 48 | s_wen = 1'b0; 49 | end 50 | 51 | 52 | 53 | generic_memory_with_grant 54 | #( 55 | .ADDR_WIDTH (ADDR_WIDTH), 56 | .DATA_WIDTH (64) 57 | ) 58 | cut 59 | ( 60 | .CLK (CLK), 61 | .INITN (RSTN), 62 | 63 | .CEN (s_cen), 64 | .A (A[ADDR_WIDTH-1:0]), 65 | .GNT (), 66 | .WEN (s_wen), 67 | .D (D), 68 | .BE (BE), 69 | .Q (Q), 70 | .RVAL () 71 | ); 72 | 73 | endmodule -------------------------------------------------------------------------------- /TB/generic_memory_with_grant.sv: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ETH Zurich and University of Bologna. 2 | // Copyright and related rights are licensed under the Solderpad Hardware 3 | // License, Version 0.51 (the "License"); you may not use this file except in 4 | // compliance with the License. You may obtain a copy of the License at 5 | // http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law 6 | // or agreed to in writing, software, hardware and materials distributed under 7 | // this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 8 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 9 | // specific language governing permissions and limitations under the License. 10 | 11 | module generic_memory_with_grant 12 | #( 13 | parameter ADDR_WIDTH = 12, 14 | parameter DATA_WIDTH = 64, 15 | parameter BE_WIDTH = DATA_WIDTH/8 16 | ) 17 | ( 18 | input logic CLK, 19 | input logic INITN, 20 | 21 | input logic CEN, 22 | input logic [ADDR_WIDTH-1:0] A, 23 | output logic GNT, 24 | input logic WEN, 25 | input logic [BE_WIDTH-1:0][7:0] D, 26 | input logic [BE_WIDTH-1:0] BE, 27 | 28 | output logic [DATA_WIDTH-1:0] Q, 29 | output logic RVAL 30 | ); 31 | 32 | localparam NUM_WORDS = 2**ADDR_WIDTH; 33 | 34 | // always_ff @(posedge CLK or negedge INITN) 35 | // begin 36 | // if(~INITN) 37 | // begin 38 | // GNT <= 1'b0; 39 | // end 40 | // else 41 | // begin 42 | // GNT <= $random()%2; 43 | // end 44 | // end 45 | 46 | assign GNT = 1; 47 | 48 | logic [BE_WIDTH-1:0][7:0] MEM [NUM_WORDS-1:0]; 49 | logic [31:0] temp_32_bit; 50 | 51 | int unsigned i; 52 | 53 | 54 | assign req_int = (CEN == 1'b0 ) & (GNT == 1'b1); 55 | 56 | 57 | always @(posedge CLK) 58 | begin 59 | if ( req_int ) 60 | begin 61 | RVAL <= 1'b1; 62 | if ( WEN == 1'b0 ) 63 | begin 64 | Q <= 'X; 65 | 66 | for (i=0; i < BE_WIDTH; i++) 67 | begin 68 | if ( BE[i] == 1'b1 ) 69 | begin 70 | MEM[A][i] <= D[i]; 71 | end 72 | end 73 | end 74 | else 75 | begin 76 | Q <= MEM[A]; 77 | end 78 | end 79 | else // req_int == 0 80 | begin 81 | RVAL <= 1'b0; 82 | Q <= 'X; 83 | end 84 | end 85 | 86 | initial 87 | begin 88 | for(i=0;i<2**ADDR_WIDTH-1;i++) 89 | begin 90 | temp_32_bit = i*8; 91 | MEM[i] = {temp_32_bit+4,temp_32_bit}; 92 | end 93 | 94 | end 95 | 96 | 97 | endmodule 98 | -------------------------------------------------------------------------------- /TB/ibus_lint_memory_128.sv: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ETH Zurich and University of Bologna. 2 | // Copyright and related rights are licensed under the Solderpad Hardware 3 | // License, Version 0.51 (the "License"); you may not use this file except in 4 | // compliance with the License. You may obtain a copy of the License at 5 | // http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law 6 | // or agreed to in writing, software, hardware and materials distributed under 7 | // this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 8 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 9 | // specific language governing permissions and limitations under the License. 10 | 11 | 12 | module ibus_lint_memory_128 13 | #( 14 | parameter addr_width = 16 15 | //parameter INIT_MEM_FILE = "slm_files/l2_stim.slm" 16 | ) 17 | ( 18 | input logic clk, 19 | input logic rst_n, 20 | 21 | // Interface to Instruction Logaritmic interconnect 22 | input logic lint_req_i, 23 | output logic lint_grant_o, 24 | input logic [addr_width-1:0] lint_addr_i, 25 | 26 | input logic [1:0] lint_addr_offset_i, 27 | 28 | output logic [3:0][31:0] lint_r_rdata_o, 29 | output logic [31:0] lint_r_rdata_32_o, 30 | output logic lint_r_valid_o 31 | ); 32 | 33 | localparam numwords = 2**addr_width; 34 | int unsigned i; 35 | logic [3:0][31:0] ARRAY [numwords]; 36 | logic r_valid; 37 | logic [3:0][31:0] r_rdata; 38 | logic [31:0] r_rdata_32; 39 | logic lint_grant_int; 40 | 41 | 42 | 43 | 44 | assign lint_grant_o = 1'b1; //lint_grant_int & lint_req_i; 45 | 46 | always_ff @(posedge clk, negedge rst_n) 47 | begin 48 | if(rst_n == 1'b0) 49 | begin 50 | lint_grant_int <= 1'b0; 51 | end 52 | else 53 | begin 54 | lint_grant_int <= $random() % 2; 55 | end 56 | end 57 | 58 | 59 | 60 | 61 | always_ff @(posedge clk, negedge rst_n) 62 | begin 63 | if(rst_n == 1'b0) 64 | begin 65 | r_valid <= 1'b0; 66 | r_rdata <= '0; 67 | r_rdata_32 <= '0; 68 | end 69 | else 70 | begin 71 | if(lint_req_i & lint_grant_o) 72 | begin 73 | r_valid <= 1'b1; 74 | r_rdata <= ARRAY [lint_addr_i]; 75 | r_rdata_32 <= ARRAY [lint_addr_i][lint_addr_offset_i]; 76 | end 77 | else 78 | begin 79 | r_valid <= 1'b0; 80 | end 81 | end 82 | end 83 | 84 | assign lint_r_valid_o = r_valid; 85 | assign lint_r_rdata_o = r_rdata; 86 | assign lint_r_rdata_32_o = r_rdata_32; 87 | 88 | initial 89 | begin 90 | 91 | for(i = 0; i< numwords; i++) 92 | begin 93 | ARRAY[i][0] = i*16+4'h0; 94 | ARRAY[i][1] = i*16+4'h4; 95 | ARRAY[i][2] = i*16+4'h8; 96 | ARRAY[i][3] = i*16+4'hC; 97 | end 98 | //$readmemh(INIT_MEM_FILE, ARRAY); 99 | end 100 | 101 | endmodule 102 | -------------------------------------------------------------------------------- /RTL/L1_CACHE/register_file_1w_multi_port_read_test_wrap.sv: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2018 ETH Zurich and University of Bologna. 2 | // Copyright and related rights are licensed under the Solderpad Hardware 3 | // License, Version 0.51 (the "License"); you may not use this file except in 4 | // compliance with the License. You may obtain a copy of the License at 5 | // http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law 6 | // or agreed to in writing, software, hardware and materials distributed under 7 | // this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 8 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 9 | // specific language governing permissions and limitations under the License. 10 | 11 | module register_file_1w_multi_port_read_test_wrap 12 | #( 13 | parameter ADDR_WIDTH = 5, 14 | parameter DATA_WIDTH = 32, 15 | 16 | parameter N_READ = 2 17 | ) 18 | ( 19 | input logic clk, 20 | input logic rst_n, 21 | input logic test_en_i, 22 | 23 | // Read port 24 | input logic [N_READ-1:0] ReadEnable, 25 | input logic [N_READ-1:0][ADDR_WIDTH-1:0] ReadAddr, 26 | output logic [N_READ-1:0][DATA_WIDTH-1:0] ReadData, 27 | 28 | // Write port 29 | input logic WriteEnable, 30 | input logic [ADDR_WIDTH-1:0] WriteAddr, 31 | input logic [DATA_WIDTH-1:0] WriteData, 32 | 33 | // BIST ENABLE 34 | input logic BIST, 35 | //BIST ports 36 | input logic CSN_T, 37 | input logic WEN_T, 38 | input logic [ADDR_WIDTH-1:0] A_T, 39 | input logic [DATA_WIDTH-1:0] D_T, 40 | output logic [DATA_WIDTH-1:0] Q_T 41 | ); 42 | 43 | logic [N_READ-1:0] ReadEnable_muxed; 44 | logic [N_READ-1:0][ADDR_WIDTH-1:0] ReadAddr_muxed; 45 | 46 | logic WriteEnable_muxed; 47 | logic [ADDR_WIDTH-1:0] WriteAddr_muxed; 48 | logic [DATA_WIDTH-1:0] WriteData_muxed; 49 | 50 | 51 | always_comb 52 | begin 53 | 54 | ReadEnable_muxed = ReadEnable; 55 | ReadAddr_muxed = ReadAddr; 56 | 57 | if(BIST) 58 | begin 59 | ReadEnable_muxed[0] = (( CSN_T == 1'b0 ) && ( WEN_T == 1'b1)); 60 | ReadAddr_muxed[0] = A_T; 61 | 62 | ReadEnable_muxed[N_READ-1:1] = ReadEnable[N_READ-1:1]; 63 | ReadAddr_muxed[N_READ-1:1] = ReadAddr[N_READ-1:1]; 64 | 65 | 66 | WriteEnable_muxed = (( CSN_T == 1'b0 ) && ( WEN_T == 1'b0)); 67 | WriteAddr_muxed = A_T; 68 | WriteData_muxed = D_T; 69 | end 70 | else 71 | begin 72 | ReadEnable_muxed = ReadEnable; 73 | ReadAddr_muxed = ReadAddr; 74 | 75 | WriteEnable_muxed = WriteEnable; 76 | WriteAddr_muxed = WriteAddr; 77 | WriteData_muxed = WriteData; 78 | end 79 | end 80 | 81 | assign Q_T = ReadData[0]; 82 | 83 | 84 | register_file_1w_multi_port_read 85 | #( 86 | .ADDR_WIDTH ( ADDR_WIDTH ), 87 | .DATA_WIDTH ( DATA_WIDTH ), 88 | 89 | .N_READ ( N_READ ), 90 | .N_WRITE ( 1 ) 91 | ) 92 | register_file_1w_multi_port_read_i 93 | ( 94 | .clk ( clk ), 95 | .rst_n ( rst_n ), 96 | .test_en_i ( test_en_i ), 97 | 98 | .ReadEnable ( ReadEnable_muxed ), 99 | .ReadAddr ( ReadAddr_muxed ), 100 | .ReadData ( ReadData ), 101 | 102 | .WriteEnable ( WriteEnable_muxed ), 103 | .WriteAddr ( WriteAddr_muxed ), 104 | .WriteData ( WriteData_muxed ) 105 | ); 106 | 107 | endmodule 108 | -------------------------------------------------------------------------------- /RTL/L1.5_CACHE/ram_ws_rs_tag_scm.sv: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ETH Zurich and University of Bologna. 2 | // Copyright and related rights are licensed under the Solderpad Hardware 3 | // License, Version 0.51 (the "License"); you may not use this file except in 4 | // compliance with the License. You may obtain a copy of the License at 5 | // http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law 6 | // or agreed to in writing, software, hardware and materials distributed under 7 | // this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 8 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 9 | // specific language governing permissions and limitations under the License. 10 | 11 | 12 | // `define USE_SRAM 13 | `ifdef PULP_FPGA_EMUL 14 | `define ICAHE_USE_FF 15 | `endif 16 | 17 | module ram_ws_rs_tag_scm 18 | #( 19 | parameter data_width = 7, 20 | parameter addr_width = 6 21 | ) 22 | ( 23 | input logic clk, 24 | input logic rst_n, 25 | input logic [addr_width-1:0] addr, 26 | input logic req, 27 | input logic write, 28 | input logic [data_width-1:0] wdata, 29 | output logic [data_width-1:0] rdata 30 | ); 31 | 32 | `ifdef USE_TAG_SRAM 33 | logic cs_n; 34 | logic we_n; 35 | 36 | assign cs_n = ~req; 37 | assign we_n = ~write; 38 | 39 | generate 40 | if(data_width==10 && addr_width==5) 41 | begin : SRAM_CUT 42 | 43 | logic [2:0] n_aw; 44 | logic [1:0] n_ac; 45 | logic [9:0] bw; 46 | assign {n_aw, n_ac} = addr; 47 | assign bw = (we_n) ? '0 : '1; 48 | 49 | // GF22 50 | SPREG_32w_10b sram_tag 51 | ( 52 | 53 | .CLK ( clk ), // input 54 | .CEN ( cs_n ), // input 55 | .RDWEN ( we_n ), // input 56 | .AW ( n_aw ), // input [3:0] 57 | .AC ( n_ac ), // input 58 | .D ( wdata ), // input [9:0] 59 | .BW ( '1 ), // input [9:0] 60 | .T_LOGIC ( 1'b0 ), // input 61 | .MA_SAWL ( '0 ), // input 62 | .MA_WL ( '0 ), // input 63 | .MA_WRAS ( '0 ), // input 64 | .MA_WRASD ( '0 ), // input 65 | .Q ( rdata ), // output [9:0] 66 | .OBSV_CTL ( ) // output 67 | ); 68 | /* 69 | SRAM_SP_32w_10b sram_tag 70 | ( 71 | .CS_N ( cs_n ), 72 | .CLK ( clk ), 73 | .WR_N ( we_n ), 74 | .RW_ADDR ( addr ), 75 | .RST_N ( rst_n ), 76 | .DATA_IN ( wdata ), 77 | .DATA_OUT( rdata ) 78 | ); 79 | */ 80 | end 81 | 82 | 83 | endgenerate 84 | 85 | `else 86 | 87 | `ifdef ICAHE_USE_FF 88 | register_file_1r_1w 89 | `else 90 | register_file_1r_1w_test_wrap 91 | `endif 92 | #( 93 | .ADDR_WIDTH(addr_width), 94 | .DATA_WIDTH(data_width) 95 | ) 96 | scm_tag 97 | ( 98 | .clk (clk), 99 | `ifdef ICAHE_USE_FF 100 | .rst_n (rst_n), 101 | `endif 102 | 103 | // Read port 104 | .ReadEnable ( req & ~write ), 105 | .ReadAddr ( addr ), 106 | .ReadData ( rdata ), 107 | 108 | // Write port 109 | .WriteEnable ( req & write ), 110 | .WriteAddr ( addr ), 111 | .WriteData ( wdata ) 112 | `ifndef ICAHE_USE_FF 113 | , 114 | // BIST ENABLE 115 | .BIST ( 1'b0 ), // PLEASE CONNECT ME; 116 | 117 | // BIST ports 118 | .CSN_T ( ), // PLEASE CONNECT ME; Synthesis will remove me if unconnected 119 | .WEN_T ( ), // PLEASE CONNECT ME; Synthesis will remove me if unconnected 120 | .A_T ( ), // PLEASE CONNECT ME; Synthesis will remove me if unconnected 121 | .D_T ( ), // PLEASE CONNECT ME; Synthesis will remove me if unconnected 122 | .Q_T ( ) 123 | `endif 124 | ); 125 | `endif 126 | 127 | endmodule 128 | -------------------------------------------------------------------------------- /RTL/L1.5_CACHE/RefillTracker_4.sv: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ETH Zurich and University of Bologna. 2 | // Copyright and related rights are licensed under the Solderpad Hardware 3 | // License, Version 0.51 (the "License"); you may not use this file except in 4 | // compliance with the License. You may obtain a copy of the License at 5 | // http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law 6 | // or agreed to in writing, software, hardware and materials distributed under 7 | // this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 8 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 9 | // specific language governing permissions and limitations under the License. 10 | 11 | 12 | module RefillTracker_4 13 | #( 14 | parameter ID_WIDTH = 14 15 | ) 16 | ( 17 | input logic clk, 18 | input logic rst_n, 19 | input logic push_i, 20 | input logic [ID_WIDTH-1:0] push_ID_i, 21 | output logic push_full_o, 22 | 23 | input logic pop_i, 24 | input logic [ID_WIDTH-1:0] pop_ID_i, 25 | output logic pop_empty_o, 26 | output logic pop_error_o, 27 | 28 | input logic [ID_WIDTH-1:0] RESP_check_ID_i, 29 | input logic RESP_check_req_i, 30 | output logic RESP_check_is_valid_o 31 | ); 32 | 33 | 34 | localparam DEPTH = 4; 35 | 36 | integer i,j,k,z; 37 | 38 | logic [DEPTH-1:0] check_Match_addr; 39 | 40 | logic [$clog2(DEPTH)-1:0] MATCH_index; 41 | 42 | logic [DEPTH-1:0] LOOKUP_TABLE; 43 | logic [ID_WIDTH-1:0] ID_TABLE[DEPTH-1:0]; 44 | 45 | 46 | logic [DEPTH-1:0] Match_RESP_addr; 47 | 48 | 49 | 50 | 51 | 52 | 53 | always_ff @(posedge clk, negedge rst_n) 54 | begin 55 | if(rst_n == 1'b0) 56 | begin 57 | for(i=0; i fetch_granted; 65 | end 66 | 67 | always @(posedge clk) 68 | begin 69 | if(fetch_gnt_i & fetch_req_o) 70 | count_trans++; 71 | end 72 | 73 | always @(posedge clk) 74 | begin 75 | if(rst_n == 1'b1) 76 | -> reset_deasserted; 77 | end 78 | 79 | 80 | initial 81 | begin 82 | 83 | 84 | @(reset_deasserted); 85 | @(negedge clk); 86 | @(negedge clk); 87 | @(negedge clk); 88 | @(negedge clk); 89 | @(negedge clk); 90 | @(negedge clk); 91 | @(negedge clk); 92 | end 93 | 94 | 95 | always_ff @(posedge clk, negedge rst_n) 96 | begin 97 | if(~rst_n) 98 | begin 99 | CS <= IDLE; 100 | inst_num <= '0; 101 | delay_cnt <= '0; 102 | end 103 | else 104 | begin 105 | CS <= NS; 106 | 107 | delay_cnt <= delay_cnt + 1; 108 | 109 | if(fetch_rvalid_i) 110 | inst_num <= inst_num + 1; 111 | end 112 | end 113 | 114 | 115 | always_comb 116 | begin 117 | fetch_req_int = 1'b0; 118 | fetch_addr_int = address[count_trans]; 119 | eoc_o = 1'b0; 120 | 121 | 122 | 123 | case(CS) 124 | IDLE: 125 | begin 126 | if(fetch_enable_i) 127 | begin 128 | fetch_req_int = 1'b1; 129 | 130 | if(fetch_gnt_i) 131 | NS = WAIT_RVALID; 132 | else 133 | NS = IDLE; 134 | end 135 | else 136 | begin 137 | NS = IDLE; 138 | end 139 | end 140 | 141 | WAIT_RVALID: 142 | begin 143 | 144 | if(fetch_rvalid_i) 145 | begin 146 | if(count_trans == N_TRANS-1 ) 147 | begin 148 | NS = DONE; 149 | fetch_req_int = 1'b0; 150 | end 151 | else 152 | begin 153 | if ($random() % 3 == 0) begin 154 | fetch_req_int = 1'b1; 155 | 156 | if(fetch_gnt_i) 157 | begin 158 | NS = WAIT_RVALID; 159 | end 160 | else 161 | begin 162 | NS = WAIT_GNT; 163 | end 164 | end else begin 165 | NS = DELAY_REQ; 166 | end 167 | end 168 | end 169 | else 170 | begin 171 | NS = WAIT_RVALID; 172 | fetch_req_int = 1'b0; 173 | end 174 | end 175 | 176 | DELAY_REQ: 177 | begin 178 | if (delay_cnt == 3) begin 179 | fetch_req_int = 1'b1; 180 | if(fetch_gnt_i) 181 | begin 182 | NS = WAIT_RVALID; 183 | end 184 | else 185 | begin 186 | NS = WAIT_GNT; 187 | end 188 | end else begin // if (delay_cnt == 3) 189 | NS = DELAY_REQ; 190 | end 191 | end 192 | 193 | WAIT_GNT: 194 | begin 195 | fetch_req_int = 1'b1; 196 | if(fetch_gnt_i) 197 | NS = WAIT_RVALID; 198 | else 199 | NS = WAIT_GNT; 200 | end 201 | 202 | DONE: 203 | begin 204 | NS = DONE; 205 | eoc_o = 1'b1; 206 | end 207 | default: 208 | NS = IDLE; 209 | 210 | endcase // CS 211 | end 212 | 213 | 214 | endmodule // tgen_emu 215 | -------------------------------------------------------------------------------- /RTL/L1_CACHE/register_file_1w_multi_port_read.sv: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2018 ETH Zurich and University of Bologna. 2 | // Copyright and related rights are licensed under the Solderpad Hardware 3 | // License, Version 0.51 (the "License"); you may not use this file except in 4 | // compliance with the License. You may obtain a copy of the License at 5 | // http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law 6 | // or agreed to in writing, software, hardware and materials distributed under 7 | // this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 8 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 9 | // specific language governing permissions and limitations under the License. 10 | 11 | module register_file_1w_multi_port_read 12 | #( 13 | parameter ADDR_WIDTH = 5, 14 | parameter DATA_WIDTH = 32, 15 | 16 | parameter N_READ = 2, 17 | parameter N_WRITE = 1 18 | ) 19 | ( 20 | input logic clk, 21 | input logic rst_n, 22 | input logic test_en_i, 23 | 24 | // Read port 25 | input logic [N_READ-1:0] ReadEnable, 26 | input logic [N_READ-1:0][ADDR_WIDTH-1:0] ReadAddr, 27 | output logic [N_READ-1:0][DATA_WIDTH-1:0] ReadData, 28 | 29 | // Write port 30 | input logic WriteEnable, 31 | input logic [ADDR_WIDTH-1:0] WriteAddr, 32 | input logic [DATA_WIDTH-1:0] WriteData 33 | ); 34 | 35 | localparam NUM_WORDS = 2**ADDR_WIDTH; 36 | 37 | // Read address register, located at the input of the address decoder 38 | logic [N_READ-1:0][ADDR_WIDTH-1:0] RAddrRegxDP; 39 | logic [N_READ-1:0][NUM_WORDS-1:0] RAddrOneHotxD; 40 | 41 | logic [DATA_WIDTH-1:0] MemContentxDP[NUM_WORDS]; 42 | 43 | logic [NUM_WORDS-1:0] WAddrOneHotxD; 44 | logic [NUM_WORDS-1:0] ClocksxC; 45 | logic [DATA_WIDTH-1:0] WDataIntxD; 46 | 47 | logic clk_int; 48 | 49 | int unsigned i; 50 | int unsigned k; 51 | 52 | genvar x; 53 | genvar z; 54 | 55 | tc_clk_gating CG_WE_GLOBAL 56 | ( 57 | .clk_o ( clk_int ), 58 | .en_i ( WriteEnable ), 59 | .test_en_i ( test_en_i ), 60 | .clk_i ( clk ) 61 | ); 62 | 63 | //----------------------------------------------------------------------------- 64 | //-- READ : Read address register 65 | //----------------------------------------------------------------------------- 66 | 67 | generate 68 | for(z=0; z PERIPHERAL INTERFACE 130 | .speriph_slave_req_i ( speriph_slave.req ), 131 | .speriph_slave_addr_i ( speriph_slave.add ), 132 | .speriph_slave_wen_i ( speriph_slave.wen ), 133 | .speriph_slave_wdata_i ( speriph_slave.wdata ), 134 | .speriph_slave_be_i ( speriph_slave.be ), 135 | .speriph_slave_gnt_o ( speriph_slave.gnt ), 136 | .speriph_slave_id_i ( speriph_slave.id ), 137 | .speriph_slave_r_valid_o ( speriph_slave.r_valid ), 138 | .speriph_slave_r_opc_o ( speriph_slave.r_opc ), 139 | .speriph_slave_r_id_o ( speriph_slave.r_id ), 140 | .speriph_slave_r_rdata_o ( speriph_slave.r_rdata ), 141 | 142 | .L1_icache_bypass_req_o ( IC_ctrl_unit_bus_pri_bypass_req ), 143 | .L1_icache_bypass_ack_i ( IC_ctrl_unit_bus_pri_bypass_ack ), 144 | .L1_icache_flush_req_o ( IC_ctrl_unit_bus_pri_flush_req ), 145 | .L1_icache_flush_ack_i ( IC_ctrl_unit_bus_pri_flush_ack ), 146 | .L1_icache_sel_flush_req_o ( IC_ctrl_unit_bus_pri_sel_flush_req ), 147 | .L1_icache_sel_flush_addr_o ( IC_ctrl_unit_bus_pri_sel_flush_addr ), 148 | .L1_icache_sel_flush_ack_i ( IC_ctrl_unit_bus_pri_sel_flush_ack ), 149 | 150 | .L2_icache_enable_req_o ( IC_ctrl_unit_bus_main_enable_req ), 151 | .L2_icache_enable_ack_i ( IC_ctrl_unit_bus_main_enable_ack ), 152 | .L2_icache_disable_req_o ( IC_ctrl_unit_bus_main_disable_req ), 153 | .L2_icache_disable_ack_i ( IC_ctrl_unit_bus_main_disable_ack ), 154 | .L2_icache_flush_req_o ( IC_ctrl_unit_bus_main_flush_req ), 155 | .L2_icache_flush_ack_i ( IC_ctrl_unit_bus_main_flush_ack ), 156 | .L2_icache_sel_flush_req_o ( IC_ctrl_unit_bus_main_sel_flush_req ), 157 | .L2_icache_sel_flush_addr_o ( IC_ctrl_unit_bus_main_sel_flush_addr ), 158 | .L2_icache_sel_flush_ack_i ( IC_ctrl_unit_bus_main_sel_flush_ack ), 159 | .enable_l1_l15_prefetch_o ( enable_l1_l15_prefetch_o ) 160 | 161 | 162 | 163 | `ifdef FEATURE_ICACHE_STAT 164 | , 165 | .L1_hit_count_i ( IC_ctrl_unit_bus_pri_L1_hit_count ), 166 | .L1_trans_count_i ( IC_ctrl_unit_bus_pri_L1_trans_count ), 167 | .L1_miss_count_i ( IC_ctrl_unit_bus_pri_L1_miss_count ), 168 | .L1_cong_count_i ( IC_ctrl_unit_bus_pri_L1_cong_count ), 169 | .L1_clear_regs_o ( IC_ctrl_unit_bus_pri_L1_clear_regs ), 170 | .L1_enable_regs_o ( IC_ctrl_unit_bus_pri_L1_enable_regs ), 171 | 172 | .L2_hit_count_i ( IC_ctrl_unit_bus_main_L2_hit_count ), 173 | .L2_trans_count_i ( IC_ctrl_unit_bus_main_L2_trans_count ), 174 | .L2_miss_count_i ( IC_ctrl_unit_bus_main_L2_miss_count ), 175 | .L2_clear_regs_o ( IC_ctrl_unit_bus_main_L2_clear_regs ), 176 | .L2_enable_regs_o ( IC_ctrl_unit_bus_main_L2_enable_regs ) 177 | `endif 178 | 179 | ); 180 | 181 | 182 | endmodule // hier_icache_ctrl_unit 183 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | SOLDERPAD HARDWARE LICENSE version 0.51 2 | 3 | This license is based closely on the Apache License Version 2.0, but is not 4 | approved or endorsed by the Apache Foundation. A copy of the non-modified 5 | Apache License 2.0 can be found at http://www.apache.org/licenses/LICENSE-2.0. 6 | 7 | As this license is not currently OSI or FSF approved, the Licensor permits any 8 | Work licensed under this License, at the option of the Licensee, to be treated 9 | as licensed under the Apache License Version 2.0 (which is so approved). 10 | 11 | This License is licensed under the terms of this License and in particular 12 | clause 7 below (Disclaimer of Warranties) applies in relation to its use. 13 | 14 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 15 | 16 | 1. Definitions. 17 | 18 | "License" shall mean the terms and conditions for use, reproduction, and 19 | distribution as defined by Sections 1 through 9 of this document. 20 | 21 | "Licensor" shall mean the Rights owner or entity authorized by the Rights owner 22 | that is granting the License. 23 | 24 | "Legal Entity" shall mean the union of the acting entity and all other entities 25 | that control, are controlled by, or are under common control with that entity. 26 | For the purposes of this definition, "control" means (i) the power, direct or 27 | indirect, to cause the direction or management of such entity, whether by 28 | contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the 29 | outstanding shares, or (iii) beneficial ownership of such entity. 30 | 31 | "You" (or "Your") shall mean an individual or Legal Entity exercising 32 | permissions granted by this License. 33 | 34 | "Rights" means copyright and any similar right including design right (whether 35 | registered or unregistered), semiconductor topography (mask) rights and 36 | database rights (but excluding Patents and Trademarks). 37 | 38 | "Source" form shall mean the preferred form for making modifications, including 39 | but not limited to source code, net lists, board layouts, CAD files, 40 | documentation source, and configuration files. 41 | 42 | "Object" form shall mean any form resulting from mechanical transformation or 43 | translation of a Source form, including but not limited to compiled object 44 | code, generated documentation, the instantiation of a hardware design and 45 | conversions to other media types, including intermediate forms such as 46 | bytecodes, FPGA bitstreams, artwork and semiconductor topographies (mask 47 | works). 48 | 49 | "Work" shall mean the work of authorship, whether in Source form or other 50 | Object form, made available under the License, as indicated by a Rights notice 51 | that is included in or attached to the work (an example is provided in the 52 | Appendix below). 53 | 54 | "Derivative Works" shall mean any work, whether in Source or Object form, that 55 | is based on (or derived from) the Work and for which the editorial revisions, 56 | annotations, elaborations, or other modifications represent, as a whole, an 57 | original work of authorship. For the purposes of this License, Derivative Works 58 | shall not include works that remain separable from, or merely link (or bind by 59 | name) or physically connect to or interoperate with the interfaces of, the Work 60 | and Derivative Works thereof. 61 | 62 | "Contribution" shall mean any design or work of authorship, including the 63 | original version of the Work and any modifications or additions to that Work or 64 | Derivative Works thereof, that is intentionally submitted to Licensor for 65 | inclusion in the Work by the Rights owner or by an individual or Legal Entity 66 | authorized to submit on behalf of the Rights owner. For the purposes of this 67 | definition, "submitted" means any form of electronic, verbal, or written 68 | communication sent to the Licensor or its representatives, including but not 69 | limited to communication on electronic mailing lists, source code control 70 | systems, and issue tracking systems that are managed by, or on behalf of, the 71 | Licensor for the purpose of discussing and improving the Work, but excluding 72 | communication that is conspicuously marked or otherwise designated in writing 73 | by the Rights owner as "Not a Contribution." 74 | 75 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf 76 | of whom a Contribution has been received by Licensor and subsequently 77 | incorporated within the Work. 78 | 79 | 2. Grant of License. Subject to the terms and conditions of this License, each 80 | Contributor hereby grants to You a perpetual, worldwide, non-exclusive, 81 | no-charge, royalty-free, irrevocable license under the Rights to reproduce, 82 | prepare Derivative Works of, publicly display, publicly perform, sublicense, 83 | and distribute the Work and such Derivative Works in Source or Object form and 84 | do anything in relation to the Work as if the Rights did not exist. 85 | 86 | 3. Grant of Patent License. Subject to the terms and conditions of this 87 | License, each Contributor hereby grants to You a perpetual, worldwide, 88 | non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this 89 | section) patent license to make, have made, use, offer to sell, sell, import, 90 | and otherwise transfer the Work, where such license applies only to those 91 | patent claims licensable by such Contributor that are necessarily infringed by 92 | their Contribution(s) alone or by combination of their Contribution(s) with the 93 | Work to which such Contribution(s) was submitted. If You institute patent 94 | litigation against any entity (including a cross-claim or counterclaim in a 95 | lawsuit) alleging that the Work or a Contribution incorporated within the Work 96 | constitutes direct or contributory patent infringement, then any patent 97 | licenses granted to You under this License for that Work shall terminate as of 98 | the date such litigation is filed. 99 | 100 | 4. Redistribution. You may reproduce and distribute copies of the Work or 101 | Derivative Works thereof in any medium, with or without modifications, and in 102 | Source or Object form, provided that You meet the following conditions: 103 | 104 | You must give any other recipients of the Work or Derivative Works a copy 105 | of this License; and 106 | 107 | You must cause any modified files to carry prominent notices stating that 108 | You changed the files; and 109 | 110 | You must retain, in the Source form of any Derivative Works that You 111 | distribute, all copyright, patent, trademark, and attribution notices from 112 | the Source form of the Work, excluding those notices that do not pertain to 113 | any part of the Derivative Works; and 114 | 115 | If the Work includes a "NOTICE" text file as part of its distribution, then 116 | any Derivative Works that You distribute must include a readable copy of 117 | the attribution notices contained within such NOTICE file, excluding those 118 | notices that do not pertain to any part of the Derivative Works, in at 119 | least one of the following places: within a NOTICE text file distributed as 120 | part of the Derivative Works; within the Source form or documentation, if 121 | provided along with the Derivative Works; or, within a display generated by 122 | the Derivative Works, if and wherever such third-party notices normally 123 | appear. The contents of the NOTICE file are for informational purposes only 124 | and do not modify the License. You may add Your own attribution notices 125 | within Derivative Works that You distribute, alongside or as an addendum to 126 | the NOTICE text from the Work, provided that such additional attribution 127 | notices cannot be construed as modifying the License. You may add Your own 128 | copyright statement to Your modifications and may provide additional or 129 | different license terms and conditions for use, reproduction, or 130 | distribution of Your modifications, or for any such Derivative Works as a 131 | whole, provided Your use, reproduction, and distribution of the Work 132 | otherwise complies with the conditions stated in this License. 133 | 134 | 5. Submission of Contributions. Unless You explicitly state otherwise, any 135 | Contribution intentionally submitted for inclusion in the Work by You to the 136 | Licensor shall be under the terms and conditions of this License, without any 137 | additional terms or conditions. Notwithstanding the above, nothing herein shall 138 | supersede or modify the terms of any separate license agreement you may have 139 | executed with Licensor regarding such Contributions. 140 | 141 | 6. Trademarks. This License does not grant permission to use the trade names, 142 | trademarks, service marks, or product names of the Licensor, except as required 143 | for reasonable and customary use in describing the origin of the Work and 144 | reproducing the content of the NOTICE file. 145 | 146 | 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in 147 | writing, Licensor provides the Work (and each Contributor provides its 148 | Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 149 | KIND, either express or implied, including, without limitation, any warranties 150 | or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 151 | PARTICULAR PURPOSE. You are solely responsible for determining the 152 | appropriateness of using or redistributing the Work and assume any risks 153 | associated with Your exercise of permissions under this License. 154 | 155 | 8. Limitation of Liability. In no event and under no legal theory, whether in 156 | tort (including negligence), contract, or otherwise, unless required by 157 | applicable law (such as deliberate and grossly negligent acts) or agreed to in 158 | writing, shall any Contributor be liable to You for damages, including any 159 | direct, indirect, special, incidental, or consequential damages of any 160 | character arising as a result of this License or out of the use or inability to 161 | use the Work (including but not limited to damages for loss of goodwill, work 162 | stoppage, computer failure or malfunction, or any and all other commercial 163 | damages or losses), even if such Contributor has been advised of the 164 | possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing the Work or 167 | Derivative Works thereof, You may choose to offer, and charge a fee for, 168 | acceptance of support, warranty, indemnity, or other liability obligations 169 | and/or rights consistent with this License. However, in accepting such 170 | obligations, You may act only on Your own behalf and on Your sole 171 | responsibility, not on behalf of any other Contributor, and only if You agree 172 | to indemnify, defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason of your 174 | accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | -------------------------------------------------------------------------------- /RTL/L1.5_CACHE/AXI4_REFILL_Resp_Deserializer.sv: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ETH Zurich and University of Bologna. 2 | // Copyright and related rights are licensed under the Solderpad Hardware 3 | // License, Version 0.51 (the "License"); you may not use this file except in 4 | // compliance with the License. You may obtain a copy of the License at 5 | // http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law 6 | // or agreed to in writing, software, hardware and materials distributed under 7 | // this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 8 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 9 | // specific language governing permissions and limitations under the License. 10 | 11 | 12 | `define OKAY 2'b00 13 | `define EXOKAY 2'b01 14 | `define SLVERR 2'b10 15 | `define DECERR 2'b11 16 | 17 | module AXI4_REFILL_Resp_Deserializer 18 | #( 19 | parameter CACHE_LINE = 4, 20 | parameter ICACHE_DATA_WIDTH = 32, 21 | parameter FIFO_DEPTH = 8, 22 | parameter AXI_ID = 6, 23 | parameter AXI_DATA = 64, 24 | parameter AXI_USER = 8 25 | ) 26 | ( 27 | input logic rst_n, 28 | input logic clk, 29 | input logic test_en_i, 30 | 31 | input logic bypass_icache_i, 32 | 33 | input logic [AXI_ID-1:0] init_rid_i, 34 | input logic [AXI_DATA-1:0] init_rdata_i, 35 | input logic [ 1:0] init_rresp_i, 36 | input logic init_rlast_i, 37 | input logic [ AXI_USER-1:0] init_ruser_i, 38 | input logic init_rvalid_i, 39 | output logic init_rready_o, 40 | 41 | output logic [AXI_ID-1:0] init_rid_o, 42 | output logic [CACHE_LINE-1:0][ICACHE_DATA_WIDTH-1:0] init_rdata_o, 43 | output logic [ 1:0] init_rresp_o, 44 | output logic [ AXI_USER-1:0] init_ruser_o, 45 | output logic init_rvalid_o, 46 | input logic init_rready_i 47 | ); 48 | 49 | localparam FIFO_DATA_WIDTH = 1 + AXI_ID + 2 + AXI_USER + AXI_DATA ; 50 | localparam WIDE_FIFO_DATA_WIDTH = AXI_ID + 2 + AXI_USER + ICACHE_DATA_WIDTH * CACHE_LINE ; 51 | 52 | 53 | // FIFO 64 bit to COMPACTOR (WIDE FIFO) 54 | logic [AXI_ID-1:0] init_rid_int; 55 | logic [AXI_DATA-1:0] init_rdata_int; 56 | logic [ 1:0] init_rresp_int; 57 | logic init_rlast_int; 58 | logic [ AXI_USER-1:0] init_ruser_int; 59 | logic init_rvalid_int; 60 | logic init_rready_int; 61 | 62 | logic [AXI_ID-1:0] init_rid_latched; 63 | logic [ (ICACHE_DATA_WIDTH*CACHE_LINE)/AXI_DATA-1:0][AXI_DATA-1:0] init_rdata_latched; 64 | logic [ 1:0] init_rresp_latched; 65 | logic init_rlast_latched; 66 | logic [ AXI_USER-1:0] init_ruser_latched; 67 | logic init_rvalid_latched; 68 | logic init_rready_latched; 69 | 70 | enum logic [1:0] { IDLE, DISP_SINGLE_DATA, COLLECT_BURST} CS, NS; 71 | 72 | 73 | logic latch_data; 74 | logic latch_ctrl; 75 | 76 | 77 | logic r_valid_wfifo; 78 | logic r_ready_wfifo; 79 | 80 | logic r_ready_int; 81 | logic r_valid_int; 82 | 83 | logic [$clog2(CACHE_LINE*ICACHE_DATA_WIDTH/AXI_DATA)-1:0] BurstCounterCS, BurstCounterNS; 84 | 85 | // CODE STARTs HERE!!!!!!!!!!!!!!!!!!!!!!!! 86 | 87 | 88 | 89 | 90 | 91 | 92 | // Narrow FIFO concatenated Signals 93 | logic [FIFO_DATA_WIDTH-1:0] D_IN; 94 | logic [FIFO_DATA_WIDTH-1:0] D_INT; 95 | 96 | // Wide FIFO concatenated Signals 97 | logic [WIDE_FIFO_DATA_WIDTH-1:0] DIN; 98 | logic [WIDE_FIFO_DATA_WIDTH-1:0] DOUT; 99 | 100 | 101 | assign {init_ruser_int, init_rid_int, init_rlast_int, init_rresp_int, init_rdata_int } = D_INT; 102 | assign D_IN = {init_ruser_i, init_rid_i, init_rlast_i, init_rresp_i, init_rdata_i }; 103 | 104 | // Input and output array used on the WIDE INPUT FIFO: takes data from The latched array and it moves on the 105 | assign DIN = {init_ruser_latched, init_rid_latched, init_rresp_latched, init_rdata_latched}; 106 | assign {init_ruser_o, init_rid_o, init_rresp_o, init_rdata_o } = DOUT; 107 | 108 | 109 | 110 | 111 | // DESERIALIZER SEQUENTIAL BLOCK 112 | always_ff @(posedge clk, negedge rst_n) 113 | begin : UPDATE_CS 114 | if(rst_n == 1'b0) 115 | begin 116 | CS <= IDLE; 117 | BurstCounterCS <= '0; 118 | init_ruser_latched <= '0; 119 | init_rid_latched <= 1'b0; 120 | init_rresp_latched <= `OKAY; 121 | init_rdata_latched <= '0; 122 | end 123 | else // ~ rst_n == 1'b0 124 | begin 125 | CS <= NS; 126 | BurstCounterCS <= BurstCounterNS; 127 | 128 | if(latch_ctrl) 129 | begin 130 | init_rresp_latched <= init_rresp_int; 131 | init_ruser_latched <= init_ruser_int; 132 | init_rid_latched <= init_rid_int; 133 | end 134 | 135 | 136 | if(latch_data) 137 | begin 138 | init_rdata_latched[BurstCounterCS] <= init_rdata_int; 139 | end 140 | 141 | end // ~ rst_n == 1'b1 142 | end 143 | 144 | 145 | 146 | // DESERIALIZER COMB BLOCK: FSM 147 | always_comb 148 | begin : UPDATE_NS_AND_OUT 149 | 150 | r_valid_wfifo = 1'b0; 151 | r_ready_int = 1'b0; 152 | latch_ctrl = 1'b0; 153 | latch_data = 1'b0; 154 | BurstCounterNS = BurstCounterCS; 155 | 156 | case(CS) 157 | 158 | IDLE: 159 | begin 160 | r_ready_int = 1'b1; 161 | r_valid_wfifo = 1'b0; 162 | 163 | if(r_valid_int) 164 | begin 165 | latch_ctrl = 1'b1; 166 | latch_data = 1'b1; 167 | 168 | if(init_rlast_int) 169 | begin 170 | BurstCounterNS = '0; 171 | NS = DISP_SINGLE_DATA; 172 | end 173 | else 174 | begin 175 | BurstCounterNS = BurstCounterCS+1'b1; 176 | NS = COLLECT_BURST; 177 | end 178 | 179 | 180 | end 181 | else 182 | begin 183 | latch_ctrl = 1'b0; 184 | latch_data = 1'b0; 185 | NS = IDLE; 186 | BurstCounterNS = '0; 187 | end 188 | end //~IDLE 189 | 190 | 191 | DISP_SINGLE_DATA: 192 | begin 193 | r_ready_int = r_ready_wfifo; 194 | r_valid_wfifo = 1'b1; 195 | 196 | if(r_ready_wfifo) 197 | begin 198 | 199 | if(r_valid_int) 200 | begin 201 | latch_ctrl = 1'b1; 202 | latch_data = 1'b1; 203 | 204 | if(init_rlast_int) 205 | begin 206 | BurstCounterNS = '0; 207 | NS = DISP_SINGLE_DATA; 208 | end 209 | else 210 | begin 211 | BurstCounterNS = BurstCounterCS+1'b1; 212 | NS = COLLECT_BURST; 213 | end 214 | 215 | 216 | end 217 | else 218 | begin 219 | latch_ctrl = 1'b0; 220 | latch_data = 1'b0; 221 | NS = IDLE; 222 | BurstCounterNS = '0; 223 | end 224 | end 225 | else //~if(r_ready_wfifo) 226 | begin 227 | NS = DISP_SINGLE_DATA; 228 | BurstCounterNS = BurstCounterCS; 229 | latch_ctrl = 1'b0; 230 | latch_data = 1'b0; 231 | end 232 | end //~ DISP_SINGLE_DATA 233 | 234 | 235 | COLLECT_BURST: 236 | begin 237 | r_ready_int = 1'b1; 238 | if(r_valid_int) 239 | begin 240 | if( init_rlast_int) 241 | begin 242 | NS = DISP_SINGLE_DATA; 243 | BurstCounterNS = '0; 244 | latch_ctrl = 1'b0; 245 | latch_data = 1'b1; 246 | end 247 | else 248 | begin 249 | NS = COLLECT_BURST; 250 | BurstCounterNS = BurstCounterCS+1'b1; 251 | latch_ctrl = 1'b0; 252 | latch_data = 1'b1; 253 | end 254 | end 255 | else 256 | begin 257 | NS = COLLECT_BURST; 258 | BurstCounterNS = BurstCounterCS; 259 | latch_ctrl = 1'b0; 260 | latch_data = 1'b0; 261 | end 262 | end //~COLLECT_BURST 263 | 264 | default: 265 | begin 266 | NS = IDLE; 267 | end //~default 268 | endcase 269 | 270 | end 271 | 272 | 273 | // OUTPUT FIFO (CACHE_LINE*64 bit on the Cache Controller Side): Atomic Transactions 274 | REP_buffer_4 275 | #( 276 | .DATAWIDTH ( WIDE_FIFO_DATA_WIDTH) 277 | ) 278 | REPEATER 279 | ( 280 | .clk ( clk ), 281 | .rst_n ( rst_n ), 282 | //PUSH 283 | .DATA_in ( DIN ), 284 | .VALID_in ( r_valid_wfifo ), 285 | .GRANT_out ( r_ready_wfifo ), 286 | // POP 287 | .DATA_out ( DOUT ), 288 | .VALID_out ( init_rvalid_o ), 289 | .GRANT_in ( init_rready_i ) 290 | ); 291 | 292 | generate 293 | 294 | case(ICACHE_DATA_WIDTH) 295 | 128,256,512: 296 | begin 297 | // Input FIFO (64 bit on the AXI REFILL RESP Side) 298 | generic_fifo 299 | #( 300 | .DATA_WIDTH(FIFO_DATA_WIDTH), 301 | .DATA_DEPTH(FIFO_DEPTH) 302 | ) 303 | REQUEST_FIFO 304 | ( 305 | .clk ( clk ), 306 | .rst_n ( rst_n ), 307 | .test_mode_i ( test_en_i ), 308 | .data_i ( D_IN ), 309 | .valid_i ( init_rvalid_i ), 310 | .grant_o ( init_rready_o ), 311 | .data_o ( D_INT ), 312 | .valid_o ( r_valid_int ), 313 | .grant_i ( r_ready_int ) 314 | ); 315 | end 316 | 317 | default: 318 | begin 319 | // Input FIFO (64 bit on the AXI REFILL RESP Side) 320 | generic_fifo 321 | #( 322 | .DATA_WIDTH(FIFO_DATA_WIDTH), 323 | .DATA_DEPTH(FIFO_DEPTH) 324 | ) 325 | REQUEST_FIFO 326 | ( 327 | .clk ( clk ), 328 | .rst_n ( rst_n ), 329 | .test_mode_i ( test_en_i ), 330 | .data_i ( D_IN ), 331 | .valid_i ( init_rvalid_i & ~bypass_icache_i ), 332 | .grant_o ( init_rready_o ), 333 | .data_o ( D_INT ), 334 | .valid_o ( r_valid_int ), 335 | .grant_i ( r_ready_int ) 336 | ); 337 | end 338 | endcase 339 | 340 | endgenerate 341 | 342 | endmodule 343 | -------------------------------------------------------------------------------- /RTL/L1_CACHE/pri_icache.sv: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ETH Zurich and University of Bologna. 2 | // Copyright and related rights are licensed under the Solderpad Hardware 3 | // License, Version 0.51 (the "License"); you may not use this file except in 4 | // compliance with the License. You may obtain a copy of the License at 5 | // http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law 6 | // or agreed to in writing, software, hardware and materials distributed under 7 | // this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 8 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 9 | // specific language governing permissions and limitations under the License. 10 | 11 | 12 | 13 | 14 | //////////////////////////////////////////////////////////////////////////////// 15 | // Company: Multitherman Laboratory @ DEIS - University of Bologna // 16 | // Viale Risorgimento 2 40136 // 17 | // Bologna - fax 0512093785 - // 18 | // // 19 | // Engineer: Igor Loi - igor.loi@unibo.it // 20 | // // 21 | // Additional contributions by: // 22 | // // 23 | // // 24 | // Create Date: 22/03/2016 // 25 | // Design Name: ULPSoC // 26 | // Module Name: pri_icache // 27 | // Project Name: icache_expl // 28 | // Language: SystemVerilog // 29 | // // 30 | // Description: Top module for the private program cache, which istanciates// 31 | // the cache controller and SCM banks. // 32 | // // 33 | // Revision: // 34 | // Revision v0.1 - File Created // 35 | // // 36 | //////////////////////////////////////////////////////////////////////////////// 37 | 38 | `define USE_REQ_BUFF 39 | 40 | `ifdef PULP_FPGA_EMUL 41 | `define ICAHE_USE_FF 42 | `endif 43 | 44 | module pri_icache 45 | #( 46 | parameter FETCH_ADDR_WIDTH = 32, // Size of the fetch address 47 | parameter FETCH_DATA_WIDTH = 32, // Size of the fetch data 48 | parameter REFILL_DATA_WIDTH = 128, // Size of the fetch data 49 | 50 | parameter NB_WAYS = 4, // Cache associativity 51 | parameter CACHE_SIZE = 4096, // Ccache capacity in Byte 52 | parameter CACHE_LINE = 1, // in word of [FETCH_DATA_WIDTH] 53 | 54 | parameter USE_REDUCED_TAG = "TRUE", // TRUE | FALSE 55 | parameter L2_SIZE = 512*1024 // Size of max(L2 ,ROM) program memory in Byte 56 | ) 57 | ( 58 | input logic clk, 59 | input logic rst_n, 60 | input logic test_en_i, 61 | 62 | // interface with processor 63 | input logic fetch_req_i, 64 | input logic [FETCH_ADDR_WIDTH-1:0] fetch_addr_i, 65 | output logic fetch_gnt_o, 66 | output logic fetch_rvalid_o, 67 | output logic [FETCH_DATA_WIDTH-1:0] fetch_rdata_o, 68 | 69 | output logic refill_req_o, 70 | input logic refill_gnt_i, 71 | output logic [31:0] refill_addr_o, 72 | input logic refill_r_valid_i, 73 | input logic [REFILL_DATA_WIDTH-1:0] refill_r_data_i, 74 | 75 | input logic enable_l1_l15_prefetch_i, 76 | 77 | input logic bypass_icache_i, 78 | output logic cache_is_bypassed_o, 79 | input logic flush_icache_i, 80 | output logic cache_is_flushed_o, 81 | input logic flush_set_ID_req_i, 82 | input logic [FETCH_ADDR_WIDTH-1:0] flush_set_ID_addr_i, 83 | output logic flush_set_ID_ack_o 84 | 85 | `ifdef FEATURE_ICACHE_STAT 86 | , 87 | output logic [31:0] bank_hit_count_o, 88 | output logic [31:0] bank_trans_count_o, 89 | output logic [31:0] bank_miss_count_o, 90 | 91 | input logic ctrl_clear_regs_i, 92 | input logic ctrl_enable_regs_i 93 | `endif 94 | ); 95 | 96 | localparam REDUCE_TAG_WIDTH = $clog2(L2_SIZE/CACHE_SIZE)+$clog2(NB_WAYS)+1; // add one bit for TAG valid info field 97 | 98 | localparam OFFSET = $clog2(REFILL_DATA_WIDTH)-3; 99 | localparam WAY_SIZE = CACHE_SIZE/NB_WAYS; 100 | localparam SCM_NUM_ROWS = WAY_SIZE/(CACHE_LINE*REFILL_DATA_WIDTH/8); // TAG 101 | localparam SCM_TAG_ADDR_WIDTH = $clog2(SCM_NUM_ROWS); 102 | 103 | localparam TAG_WIDTH = (USE_REDUCED_TAG == "TRUE") ? REDUCE_TAG_WIDTH : (FETCH_ADDR_WIDTH - SCM_TAG_ADDR_WIDTH - $clog2(CACHE_LINE) - OFFSET + 1); 104 | 105 | localparam DATA_WIDTH = REFILL_DATA_WIDTH; 106 | localparam SCM_DATA_ADDR_WIDTH = $clog2(SCM_NUM_ROWS)+$clog2(CACHE_LINE); // Because of 32 Access 107 | 108 | localparam SET_ID_LSB = $clog2(DATA_WIDTH*CACHE_LINE)-3; 109 | localparam SET_ID_MSB = SET_ID_LSB + SCM_TAG_ADDR_WIDTH - 1; 110 | localparam TAG_LSB = SET_ID_MSB + 1; 111 | localparam TAG_MSB = TAG_LSB + TAG_WIDTH - 2 ; //1 bit is count for valid 112 | 113 | 114 | 115 | // interface with READ PORT --> SCM DATA 116 | logic [NB_WAYS-1:0] DATA_rd_req_int; 117 | logic [NB_WAYS-1:0] DATA_wr_req_int; 118 | logic [SCM_DATA_ADDR_WIDTH-1:0] DATA_rd_addr_int; 119 | logic [SCM_DATA_ADDR_WIDTH-1:0] DATA_wr_addr_int; 120 | logic [NB_WAYS-1:0][DATA_WIDTH-1:0] DATA_rdata_int; 121 | logic [DATA_WIDTH-1:0] DATA_wdata_int; 122 | 123 | // interface with READ PORT --> SCM TAG 124 | logic [1:0][NB_WAYS-1:0] TAG_req_int; 125 | logic TAG_we_int; 126 | logic [1:0][SCM_TAG_ADDR_WIDTH-1:0] TAG_addr_int; 127 | logic [NB_WAYS-1:0][1:0][TAG_WIDTH-1:0]TAG_rdata_int; 128 | logic [TAG_WIDTH-1:0] TAG_wdata_int; 129 | 130 | logic [NB_WAYS-1:0][1:0] TAG_read_enable; 131 | logic [NB_WAYS-1:0] TAG_write_enable; 132 | 133 | logic [31:0] refill_addr_int; 134 | logic refill_req_int; 135 | logic refill_gnt_int; 136 | logic refill_r_valid_int; 137 | logic [REFILL_DATA_WIDTH-1:0] refill_r_data_int; 138 | 139 | logic [31:0] pre_refill_addr_int; 140 | logic pre_refill_req_int; 141 | logic pre_refill_gnt_int; 142 | logic pre_refill_r_valid_int; 143 | logic [REFILL_DATA_WIDTH-1:0] pre_refill_r_data_int; 144 | 145 | 146 | // ██████╗ █████╗ ██████╗██╗ ██╗███████╗ ██████╗ ██████╗ ███╗ ██╗████████╗██████╗ ██████╗ ██╗ ██╗ ███████╗██████╗ 147 | // ██╔════╝██╔══██╗██╔════╝██║ ██║██╔════╝ ██╔════╝██╔═══██╗████╗ ██║╚══██╔══╝██╔══██╗██╔═══██╗██║ ██║ ██╔════╝██╔══██╗ 148 | // ██║ ███████║██║ ███████║█████╗ ██║ ██║ ██║██╔██╗ ██║ ██║ ██████╔╝██║ ██║██║ ██║ █████╗ ██████╔╝ 149 | // ██║ ██╔══██║██║ ██╔══██║██╔══╝ ██║ ██║ ██║██║╚██╗██║ ██║ ██╔══██╗██║ ██║██║ ██║ ██╔══╝ ██╔══██╗ 150 | // ╚██████╗██║ ██║╚██████╗██║ ██║███████╗███████╗╚██████╗╚██████╔╝██║ ╚████║ ██║ ██║ ██║╚██████╔╝███████╗███████╗███████╗██║ ██║ 151 | // ╚═════╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚══════╝╚══════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝╚══════╝╚══════╝╚═╝ ╚═╝ 152 | pri_icache_controller 153 | #( 154 | .FETCH_ADDR_WIDTH ( FETCH_ADDR_WIDTH ), 155 | .FETCH_DATA_WIDTH ( FETCH_DATA_WIDTH ), 156 | .REFILL_DATA_WIDTH ( REFILL_DATA_WIDTH ), 157 | 158 | .NB_CORES ( 1 ), 159 | .NB_WAYS ( NB_WAYS ), 160 | .CACHE_LINE ( CACHE_LINE ), 161 | 162 | .SCM_TAG_ADDR_WIDTH ( SCM_TAG_ADDR_WIDTH ), 163 | .SCM_DATA_ADDR_WIDTH ( SCM_DATA_ADDR_WIDTH ), 164 | .SCM_TAG_WIDTH ( TAG_WIDTH ), 165 | .SCM_DATA_WIDTH ( DATA_WIDTH ), 166 | 167 | .SET_ID_LSB ( SET_ID_LSB ), 168 | .SET_ID_MSB ( SET_ID_MSB ), 169 | .TAG_LSB ( TAG_LSB ), 170 | .TAG_MSB ( TAG_MSB ) 171 | ) 172 | i_pri_icache_controller 173 | ( 174 | .clk ( clk ), 175 | .rst_n ( rst_n ), 176 | 177 | .bypass_icache_i ( bypass_icache_i ), 178 | .cache_is_bypassed_o ( cache_is_bypassed_o ), 179 | .flush_icache_i ( flush_icache_i ), 180 | .cache_is_flushed_o ( cache_is_flushed_o ), 181 | .flush_set_ID_req_i ( flush_set_ID_req_i ), 182 | .flush_set_ID_addr_i ( flush_set_ID_addr_i ), 183 | .flush_set_ID_ack_o ( flush_set_ID_ack_o ), 184 | 185 | `ifdef FEATURE_ICACHE_STAT 186 | .bank_hit_count_o ( bank_hit_count_o ), 187 | .bank_trans_count_o ( bank_trans_count_o ), 188 | .bank_miss_count_o ( bank_miss_count_o ), 189 | 190 | .ctrl_clear_regs_i ( ctrl_clear_regs_i ), 191 | .ctrl_enable_regs_i ( ctrl_enable_regs_i ), 192 | `endif 193 | 194 | .enable_l1_l15_prefetch_i ( enable_l1_l15_prefetch_i ), 195 | 196 | // interface with processor 197 | .fetch_req_i ( fetch_req_i ), 198 | .fetch_addr_i ( fetch_addr_i ), 199 | .fetch_gnt_o ( fetch_gnt_o ), 200 | .fetch_rvalid_o ( fetch_rvalid_o ), 201 | .fetch_rdata_o ( fetch_rdata_o ), 202 | 203 | 204 | // interface with READ PORT --> SCM DATA 205 | .DATA_rd_req_o ( DATA_rd_req_int ), 206 | .DATA_wr_req_o ( DATA_wr_req_int ), 207 | .DATA_rd_addr_o ( DATA_rd_addr_int ), 208 | .DATA_wr_addr_o ( DATA_wr_addr_int ), 209 | .DATA_rdata_i ( DATA_rdata_int ), 210 | .DATA_wdata_o ( DATA_wdata_int ), 211 | 212 | // interface with READ PORT --> SCM TAG 213 | .TAG_req_o ( TAG_req_int ), 214 | .TAG_addr_o ( TAG_addr_int ), 215 | .TAG_rdata_i ( TAG_rdata_int ), 216 | .TAG_wdata_o ( TAG_wdata_int ), 217 | .TAG_we_o ( TAG_we_int ), 218 | 219 | // Interface to cache_controller_to Icache L1.5 port 220 | .pre_refill_req_o ( pre_refill_req_int ), 221 | .pre_refill_gnt_i ( pre_refill_gnt_int ), 222 | .pre_refill_addr_o ( pre_refill_addr_int ), 223 | .pre_refill_r_valid_i ( pre_refill_r_valid_int ), 224 | .pre_refill_r_data_i ( pre_refill_r_data_int ), 225 | 226 | .refill_req_o ( refill_req_int ), 227 | .refill_gnt_i ( refill_gnt_int ), 228 | .refill_addr_o ( refill_addr_int ), 229 | .refill_r_valid_i ( refill_r_valid_int ), 230 | .refill_r_data_i ( refill_r_data_int ) 231 | ); 232 | 233 | 234 | genvar i; 235 | generate 236 | 237 | // ████████╗ █████╗ ██████╗ ███████╗ ██████╗███╗ ███╗ 238 | // ╚══██╔══╝██╔══██╗██╔════╝ ██╔════╝██╔════╝████╗ ████║ 239 | // ██║ ███████║██║ ███╗ ███████╗██║ ██╔████╔██║ 240 | // ██║ ██╔══██║██║ ██║ ╚════██║██║ ██║╚██╔╝██║ 241 | // ██║ ██║ ██║╚██████╔╝███████╗███████║╚██████╗██║ ╚═╝ ██║ 242 | // ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝╚══════╝ ╚═════╝╚═╝ ╚═╝ 243 | for(i=0; i eoc_event; 144 | end 145 | 146 | always 147 | begin 148 | #(CLK_PERIOD/2.0); 149 | clk <= ~clk; 150 | end 151 | 152 | 153 | logic [SH_NB_BANKS - 1 : 0] sh_clear_regs; 154 | logic [SH_NB_BANKS - 1 : 0] sh_enable_regs; 155 | logic [SH_NB_BANKS - 1 : 0] sh_req_enable; 156 | logic [SH_NB_BANKS - 1 : 0] sh_req_disable; 157 | logic [SH_NB_BANKS - 1 : 0] sh_flush_req; 158 | logic [SH_NB_BANKS - 1 : 0] sh_sel_flush_req; 159 | logic [SH_NB_BANKS - 1 : 0] [FETCH_ADDR_WIDTH - 1 : 0] sh_sel_flush_addr; 160 | 161 | logic [NB_CORES - 1 : 0] pri_bypass_req; 162 | logic [NB_CORES - 1 : 0] pri_flush_req; 163 | logic [NB_CORES - 1 : 0] pri_sel_flush_req; 164 | 165 | logic [NB_CORES - 1 : 0] enable_l1_l15_prefetch; 166 | 167 | genvar i; 168 | 169 | generate 170 | begin 171 | for(i=0;i1, accept only incr burst=01 67 | output logic init_awlock_o, // only normal access supported axs_awlock=00 68 | output logic [ 3:0] init_awcache_o, // 69 | output logic [ 2:0] init_awprot_o, // 70 | output logic [ 3:0] init_awregion_o, // 71 | output logic [ AXI_USER-1:0] init_awuser_o, // 72 | output logic [ 3:0] init_awqos_o, // 73 | output logic init_awvalid_o, // master addr valid 74 | input logic init_awready_i, // slave ready to accept 75 | // --------------------------------------------------------------- 76 | 77 | //AXI write data bus -------------- // // -------------- 78 | output logic [AXI_DATA-1:0] init_wdata_o, 79 | output logic [AXI_DATA/8-1:0] init_wstrb_o, //1 strobe per byte 80 | output logic init_wlast_o, //last transfer in burst 81 | output logic [ AXI_USER-1:0] init_wuser_o, //user sideband signals 82 | output logic init_wvalid_o, //master data valid 83 | input logic init_wready_i, //slave ready to accept 84 | // --------------------------------------------------------------- 85 | 86 | //AXI BACKWARD write response bus -------------- // // -------------- 87 | input logic [AXI_ID-1:0] init_bid_i, 88 | input logic [ 1:0] init_bresp_i, 89 | input logic [ AXI_USER-1:0] init_buser_i, 90 | input logic init_bvalid_i, 91 | output logic init_bready_o, 92 | // --------------------------------------------------------------- 93 | 94 | 95 | 96 | //AXI read address bus ------------------------------------------- 97 | output logic [AXI_ID-1:0] init_arid_o, 98 | output logic [AXI_ADDR-1:0] init_araddr_o, 99 | output logic [ 7:0] init_arlen_o, //burst length - 1 to 16 100 | output logic [ 2:0] init_arsize_o, //size of each transfer in burst 101 | output logic [ 1:0] init_arburst_o, //for bursts>1, accept only incr burst=01 102 | output logic init_arlock_o, //only normal access supported axs_awlock=00 103 | output logic [ 3:0] init_arcache_o, 104 | output logic [ 2:0] init_arprot_o, 105 | output logic [ 3:0] init_arregion_o, // 106 | output logic [ AXI_USER-1:0] init_aruser_o, // 107 | output logic [ 3:0] init_arqos_o, // 108 | output logic init_arvalid_o, //master addr valid 109 | input logic init_arready_i, //slave ready to accept 110 | // --------------------------------------------------------------- 111 | 112 | 113 | //AXI BACKWARD read data bus ---------------------------------------------- 114 | input logic [AXI_ID-1:0] init_rid_i, 115 | input logic [AXI_DATA-1:0] init_rdata_i, 116 | input logic [ 1:0] init_rresp_i, 117 | input logic init_rlast_i, //last transfer in burst 118 | input logic [ AXI_USER-1:0] init_ruser_i, 119 | input logic init_rvalid_i, //slave data valid 120 | output logic init_rready_o, //master ready to accept 121 | 122 | 123 | // Control ports 124 | input logic ctrl_req_enable_icache_i, 125 | output logic ctrl_ack_enable_icache_o, 126 | 127 | input logic ctrl_req_disable_icache_i, 128 | output logic ctrl_ack_disable_icache_o, 129 | 130 | input logic ctrl_req_flush_icache_i, 131 | output logic ctrl_ack_flush_icache_o, 132 | 133 | output logic ctrl_pending_trans_icache_o, 134 | 135 | input logic ctrl_sel_flush_req_i, 136 | input logic [31:0] ctrl_sel_flush_addr_i, 137 | output logic ctrl_sel_flush_ack_o 138 | 139 | `ifdef FEATURE_ICACHE_STAT 140 | , 141 | output logic [31:0] ctrl_hit_count_icache_o, 142 | output logic [31:0] ctrl_trans_count_icache_o, 143 | output logic [31:0] ctrl_miss_count_icache_o, 144 | input logic ctrl_clear_regs_icache_i, 145 | input logic ctrl_enable_regs_icache_i 146 | `endif 147 | ); 148 | 149 | localparam REDUCE_TAG_WIDTH = $clog2(L2_SIZE/CACHE_SIZE)+$clog2(SET_ASSOCIATIVE)-$clog2(N_BANKS); 150 | 151 | localparam OFFSET_BIT = $clog2(ICACHE_DATA_WIDTH/8); 152 | localparam WAY_SIZE = CACHE_SIZE/SET_ASSOCIATIVE; // in Bytes 153 | 154 | localparam DATARAM_DATA_WIDTH = ICACHE_DATA_WIDTH*CACHE_LINE; 155 | localparam DATARAM_BE_WIDTH = DATARAM_DATA_WIDTH/8; 156 | localparam DATARAM_NROWS = CACHE_SIZE*8/(SET_ASSOCIATIVE*DATARAM_DATA_WIDTH); 157 | localparam DATARAM_ADDR_WIDTH = $clog2(DATARAM_NROWS); 158 | 159 | localparam TAGRAM_ADDR_NROWS = CACHE_SIZE*8/(SET_ASSOCIATIVE*DATARAM_DATA_WIDTH); 160 | localparam TAGRAM_ADDR_WIDTH = $clog2(TAGRAM_ADDR_NROWS); 161 | 162 | 163 | localparam TAGRAM_DATA_WIDTH = (USE_REDUCED_TAG == "TRUE") ? (REDUCE_TAG_WIDTH + 1) : (ICACHE_ADDR_WIDTH - OFFSET_BIT - $clog2(CACHE_LINE) -$clog2(N_BANKS) - TAGRAM_ADDR_WIDTH + 1); 164 | 165 | 166 | `ifdef DEBUG_INFO 167 | //synopsys translate_off 168 | function automatic void print_icache_cfg(); 169 | // Introduction Message to console 170 | $display ("//-------------------------------------------------------------------//"); 171 | $display ("%m: - ICACHE MODULE info"); 172 | `ifdef PRIVATE_ICACHE 173 | $display ("PRIVATE ICACHE CONFIGURATION"); 174 | `else 175 | $display ("SHARED ICACHE CONFIGURATION"); 176 | `endif 177 | 178 | $display ("SET_ASSOCIATIVE = %d", SET_ASSOCIATIVE); 179 | $display ("CACHE_LINE = %d", CACHE_LINE); 180 | $display ("CACHE_SIZE = %d [B]", CACHE_SIZE); 181 | $display ("N_BANKS = %d", N_BANKS); 182 | $display ("OFFSET_BIT = %d",OFFSET_BIT ); 183 | $display ("WAY_SIZE = %d [B]",WAY_SIZE ); 184 | $display ("DATARAM_DATA_WIDTH = %d",DATARAM_DATA_WIDTH ); 185 | $display ("DATARAM_NROWS = %d [Rows]" ,DATARAM_NROWS ); 186 | $display ("DATARAM_ADDR_WIDTH = %d",DATARAM_ADDR_WIDTH ); 187 | $display ("TAGRAM_ADDR_NROWS = %d [Rows]",TAGRAM_ADDR_NROWS ); 188 | $display ("TAGRAM_ADDR_WIDTH = %d",TAGRAM_ADDR_WIDTH ); 189 | $display ("TAGRAM_DATA_WIDTH = %d",TAGRAM_DATA_WIDTH ); 190 | $display ("\n"); 191 | $display ("FETCH_DATA_WIDTH = %d",ICACHE_DATA_WIDTH ); 192 | $display ("FETCH_ADDR_WIDTH = %d",ICACHE_ADDR_WIDTH ); 193 | $display ("FETCH_ID_WIDTH = %d",ICACHE_ID_WIDTH ); 194 | $display ("//-------------------------------------------------------------------//"); 195 | endfunction 196 | 197 | initial 198 | begin 199 | print_icache_cfg(); 200 | end 201 | // synopsys translate_on 202 | `endif 203 | 204 | 205 | 206 | 207 | 208 | 209 | // Signals connected to tagram 210 | logic [TAGRAM_ADDR_WIDTH-1:0] TAG_addr; 211 | logic [SET_ASSOCIATIVE-1:0] TAG_req; 212 | logic TAG_write; 213 | logic [TAGRAM_DATA_WIDTH-1:0] TAG_wdata; 214 | logic [SET_ASSOCIATIVE-1:0] [TAGRAM_DATA_WIDTH-1:0] TAG_rdata; 215 | 216 | // Signals connected to dataram 217 | logic [DATARAM_ADDR_WIDTH-1:0] DATA_addr; 218 | logic [SET_ASSOCIATIVE-1:0] DATA_req; 219 | logic DATA_write; 220 | logic [DATARAM_DATA_WIDTH-1:0] DATA_wdata; 221 | logic [DATARAM_BE_WIDTH-1:0] DATA_be; 222 | logic [SET_ASSOCIATIVE-1:0][DATARAM_DATA_WIDTH-1:0] DATA_rdata; 223 | 224 | 225 | // Multiplexer that select read data between the N WAYS (NOT USED IF CACHE IS DIRECT MAPPED 226 | logic [$clog2(SET_ASSOCIATIVE)-1:0] DATA_way_muxsel; 227 | logic [DATARAM_DATA_WIDTH-1:0] DATA_rdata_int; 228 | 229 | logic bypass_icache; 230 | 231 | 232 | 233 | //AXI read address bus -------------------------------------------------------- 234 | logic [AXI_ID-1:0] init_arid_int; 235 | logic [AXI_ADDR-1:0] init_araddr_int; 236 | logic [ 7:0] init_arlen_int; 237 | logic [ 2:0] init_arsize_int; 238 | logic [ 1:0] init_arburst_int; 239 | logic init_arlock_int; 240 | logic [ 3:0] init_arcache_int; 241 | logic [ 2:0] init_arprot_int; 242 | logic [ 3:0] init_arregion_int; 243 | logic [ AXI_USER-1:0] init_aruser_int; 244 | logic [ 3:0] init_arqos_int; 245 | logic init_arvalid_int; 246 | logic init_arready_int; 247 | // ----------------------------------------------------------------------------- 248 | 249 | 250 | //AXI BACKWARD read data bus ---------------------------------------------- 251 | logic [AXI_ID-1:0] init_rid_int; 252 | logic [CACHE_LINE-1:0][ICACHE_DATA_WIDTH-1:0] init_rdata_int; 253 | logic [1:0][AXI_DATA-1:0] init_rdata_delay; 254 | logic init_rdata_index; 255 | logic [ 1:0] init_rresp_int; 256 | logic init_rlast_int; 257 | logic [ AXI_USER-1:0] init_ruser_int; 258 | logic init_rvalid_int; 259 | logic init_rready_int; 260 | 261 | 262 | logic [AXI_ID-1:0] init_rid_mux; 263 | logic [CACHE_LINE-1:0][ICACHE_DATA_WIDTH-1:0] init_rdata_mux; 264 | logic [ 1:0] init_rresp_mux; 265 | logic init_rlast_mux; 266 | logic [ AXI_USER-1:0] init_ruser_mux; 267 | logic init_rvalid_mux; 268 | logic init_rready_mux; 269 | 270 | share_icache_controller 271 | #( 272 | .SET_ASSOCIATIVE ( SET_ASSOCIATIVE ), 273 | .CACHE_LINE ( CACHE_LINE ), // WORDS in each cache line allowed value are 1 - 2 - 4 - 8 274 | .CACHE_SIZE ( CACHE_SIZE ), // In Byte 275 | .N_BANKS ( N_BANKS ), 276 | .ICACHE_DATA_WIDTH ( ICACHE_DATA_WIDTH ), 277 | .ICACHE_ID_WIDTH ( ICACHE_ID_WIDTH ), 278 | .ICACHE_ADDR_WIDTH ( ICACHE_ADDR_WIDTH ), 279 | 280 | .TAGRAM_ADDR_WIDTH ( TAGRAM_ADDR_WIDTH ), 281 | .TAGRAM_DATA_WIDTH ( TAGRAM_DATA_WIDTH ), 282 | .DATARAM_ADDR_WIDTH ( DATARAM_ADDR_WIDTH ), 283 | .DATARAM_DATA_WIDTH ( DATARAM_DATA_WIDTH ), 284 | .DATARAM_BE_WIDTH ( DATARAM_BE_WIDTH ), 285 | .CACHE_ID ( CACHE_ID ), 286 | 287 | .DIRECT_MAPPED_FEATURE ( DIRECT_MAPPED_FEATURE ), 288 | 289 | .AXI_ADDR ( AXI_ADDR ), 290 | .AXI_DATA ( AXI_DATA ), 291 | .AXI_ID ( AXI_ID ), 292 | .AXI_USER ( AXI_USER ), 293 | .USE_REDUCED_TAG ( USE_REDUCED_TAG ), 294 | .REDUCE_TAG_WIDTH ( REDUCE_TAG_WIDTH ) 295 | ) 296 | u_icache_controller 297 | ( 298 | // --------------------------------------------------------------- 299 | // I/O Port Declarations ----------------------------------------- 300 | // --------------------------------------------------------------- 301 | .clk ( clk ), 302 | .rst_n ( rst_n ), 303 | .test_en_i ( test_en_i ), 304 | 305 | 306 | // --------------------------------------------------------------- 307 | // SHARED_ICACHE_INTERCONNECT Port Declarations ----------------------------------------- 308 | // --------------------------------------------------------------- 309 | .fetch_req_i ( fetch_req_i ), 310 | .fetch_grant_o ( fetch_grant_o ), 311 | .fetch_addr_i ( fetch_addr_i ), 312 | .fetch_ID_i ( fetch_ID_i ), 313 | 314 | .fetch_r_rdata_o ( fetch_r_rdata_o ), 315 | .fetch_r_valid_o ( fetch_r_valid_o ), 316 | .fetch_r_ID_o ( fetch_r_ID_o ), 317 | 318 | 319 | // Signals connected to tagram 320 | .TAG_addr_o ( TAG_addr ), 321 | .TAG_req_o ( TAG_req ), 322 | .TAG_write_o ( TAG_write ), 323 | .TAG_wdata_o ( TAG_wdata ), 324 | .TAG_rdata_i ( TAG_rdata ), 325 | 326 | // Signals connected to dataram 327 | .DATA_addr_o ( DATA_addr ), 328 | .DATA_req_o ( DATA_req ), 329 | .DATA_write_o ( DATA_write ), 330 | .DATA_wdata_o ( DATA_wdata ), 331 | .DATA_be_o ( DATA_be ), 332 | .DATA_rdata_i ( DATA_rdata_int ), 333 | 334 | .DATA_way_muxsel_o ( DATA_way_muxsel ), // USED only for MultiWay CACHES 335 | 336 | .bypass_icache_o ( bypass_icache ), 337 | 338 | // --------------------------------------------------------------- 339 | // AXI4 INITIATOR Port Declarations ----------------------------------------- 340 | // --------------------------------------------------------------- 341 | //AXI read address bus ------------------------------------------- 342 | .init_arid_o ( init_arid_int ), 343 | .init_araddr_o ( init_araddr_int ), 344 | .init_arlen_o ( init_arlen_int ), 345 | .init_arsize_o ( init_arsize_int ), 346 | .init_arburst_o ( init_arburst_int ), 347 | .init_arlock_o ( init_arlock_int ), 348 | .init_arcache_o ( init_arcache_int ), 349 | .init_arprot_o ( init_arprot_int ), 350 | .init_arregion_o ( init_arregion_int ), 351 | .init_aruser_o ( init_aruser_int ), 352 | .init_arqos_o ( init_arqos_int ), 353 | .init_arvalid_o ( init_arvalid_int ), 354 | .init_arready_i ( init_arready_int ), 355 | 356 | //AXI BACKWARD read data bus ---------------------------------------------- 357 | .init_rid_i ( init_rid_mux ), 358 | .init_rdata_i ( init_rdata_mux ), 359 | .init_rresp_i ( init_rresp_mux ), 360 | .init_ruser_i ( init_ruser_mux ), 361 | .init_rvalid_i ( init_rvalid_mux ), 362 | .init_rready_o ( init_rready_mux ), 363 | 364 | // Control ports 365 | .ctrl_req_enable_icache_i ( ctrl_req_enable_icache_i ), 366 | .ctrl_ack_enable_icache_o ( ctrl_ack_enable_icache_o ), 367 | .ctrl_req_disable_icache_i ( ctrl_req_disable_icache_i ), 368 | .ctrl_ack_disable_icache_o ( ctrl_ack_disable_icache_o ), 369 | .ctrl_pending_trans_icache_o ( ctrl_pending_trans_icache_o ), 370 | 371 | .ctrl_req_flush_icache_i ( ctrl_req_flush_icache_i ), 372 | .ctrl_ack_flush_icache_o ( ctrl_ack_flush_icache_o ), 373 | 374 | .ctrl_sel_flush_req_i ( ctrl_sel_flush_req_i ), 375 | .ctrl_sel_flush_addr_i ( ctrl_sel_flush_addr_i ), 376 | .ctrl_sel_flush_ack_o ( ctrl_sel_flush_ack_o ) 377 | `ifdef FEATURE_ICACHE_STAT 378 | , 379 | .ctrl_hit_count_icache_o ( ctrl_hit_count_icache_o ), 380 | .ctrl_trans_count_icache_o ( ctrl_trans_count_icache_o ), 381 | .ctrl_miss_count_icache_o ( ctrl_miss_count_icache_o ), 382 | .ctrl_clear_regs_icache_i ( ctrl_clear_regs_icache_i ), 383 | .ctrl_enable_regs_icache_i ( ctrl_enable_regs_icache_i ) 384 | `endif 385 | ); 386 | 387 | generate 388 | case(ICACHE_DATA_WIDTH) 389 | 128,256,512: 390 | begin 391 | assign init_rid_mux = init_rid_int; 392 | assign init_rdata_mux = init_rdata_int; 393 | assign init_rresp_mux = init_rresp_int; 394 | assign init_ruser_mux = init_ruser_int; 395 | assign init_rvalid_mux = init_rvalid_int; 396 | assign init_rready_o = init_rready_int; 397 | end 398 | 32,64: 399 | begin 400 | assign init_rid_mux = ( bypass_icache ) ? init_rid_i : init_rid_int; 401 | assign init_rdata_mux = ( bypass_icache ) ? init_rdata_i : init_rdata_int; 402 | assign init_rresp_mux = ( bypass_icache ) ? init_rresp_i : init_rresp_int; 403 | assign init_ruser_mux = ( bypass_icache ) ? init_ruser_i : init_ruser_int; 404 | assign init_rvalid_mux = ( bypass_icache ) ? init_rvalid_i : init_rvalid_int; 405 | assign init_rready_o = ( bypass_icache ) ? init_rready_mux : init_rready_int; 406 | end 407 | endcase 408 | endgenerate 409 | 410 | `ifndef SYNTHESIS 411 | property valid_2_ready; 412 | @(posedge clk) 413 | disable iff (~rst_n) 414 | $rose(init_rvalid_int) |-> ##[0:1] init_rready_mux; 415 | endproperty 416 | 417 | property ready_2_valid; 418 | @(posedge clk) 419 | disable iff (~rst_n) 420 | $rose(init_rready_mux) |=> (~init_rvalid_int); 421 | endproperty 422 | 423 | assert property (valid_2_ready) 424 | else 425 | $display("@%0dns shared icache valid_2_ready assertion Failed", $time); 426 | 427 | assert property (ready_2_valid) 428 | else 429 | $display("@%0dns shared icache ready_2_valid assertion Failed", $time); 430 | `endif 431 | 432 | // Wait two 64 bits to combine 128 data// 433 | assign init_rdata_int = {init_rdata_delay[1], init_rdata_delay[0]}; 434 | assign init_rready_int = ~init_rvalid_int; 435 | 436 | always_ff @(posedge clk, negedge rst_n) 437 | begin 438 | if(~rst_n) 439 | begin 440 | init_rdata_delay <= '0; 441 | init_rvalid_int <= '0; 442 | 443 | init_rdata_index <= '0; 444 | end 445 | else 446 | begin 447 | if(init_rvalid_i & init_rready_int) 448 | begin 449 | init_rdata_delay[init_rdata_index] <= init_rdata_i; 450 | init_rdata_index <= ~init_rdata_index; 451 | end 452 | 453 | if(init_rvalid_i & init_rlast_i) 454 | begin 455 | init_rvalid_int <= 1'b1; 456 | end else if (init_rready_mux) begin 457 | init_rvalid_int <= 1'b0; 458 | end else begin 459 | init_rvalid_int <= init_rvalid_int; 460 | end 461 | end 462 | end 463 | 464 | //Adress Request FIFO 465 | axi_ar_buffer 466 | #( 467 | .ID_WIDTH (AXI_ID), 468 | .ADDR_WIDTH (AXI_ADDR), 469 | .USER_WIDTH (AXI_USER), 470 | .BUFFER_DEPTH (2) 471 | ) 472 | axi_ar_buffer_i 473 | ( 474 | .clk_i ( clk ), 475 | .rst_ni ( rst_n ), 476 | .test_en_i ( test_en_i ), 477 | 478 | .slave_valid_i ( init_arvalid_int ), 479 | .slave_addr_i ( init_araddr_int ), 480 | .slave_prot_i ( init_arprot_int ), 481 | .slave_region_i ( init_arregion_int ), 482 | .slave_len_i ( init_arlen_int ), 483 | .slave_size_i ( init_arsize_int ), 484 | .slave_burst_i ( init_arburst_int ), 485 | .slave_lock_i ( init_arlock_int ), 486 | .slave_cache_i ( init_arcache_int ), 487 | .slave_qos_i ( init_arqos_int ), 488 | .slave_id_i ( init_arid_int ), 489 | .slave_user_i ( init_aruser_int ), 490 | .slave_ready_o ( init_arready_int ), 491 | 492 | .master_valid_o ( init_arvalid_o ), 493 | .master_addr_o ( init_araddr_o ), 494 | .master_prot_o ( init_arprot_o ), 495 | .master_region_o ( init_arregion_o ), 496 | .master_len_o ( init_arlen_o ), 497 | .master_size_o ( init_arsize_o ), 498 | .master_burst_o ( init_arburst_o ), 499 | .master_lock_o ( init_arlock_o ), 500 | .master_cache_o ( init_arcache_o ), 501 | .master_qos_o ( init_arqos_o ), 502 | .master_id_o ( init_arid_o ), 503 | .master_user_o ( init_aruser_o ), 504 | .master_ready_i ( init_arready_i ) 505 | ); 506 | 507 | 508 | 509 | genvar i; 510 | generate 511 | 512 | // DATA RAM SET OF MEMORY MACROS --> COULD BE REPLACED BY A SINGLE CUT but with more rows 513 | for(i = 0; i< SET_ASSOCIATIVE; i++) 514 | begin : DATA_RAM_WAY 515 | ram_ws_rs_data_scm 516 | #( 517 | .data_width( DATARAM_DATA_WIDTH ), 518 | .addr_width( DATARAM_ADDR_WIDTH ) 519 | ) 520 | DATA_RAM 521 | ( 522 | .clk ( clk ), 523 | .rst_n ( rst_n ), 524 | .addr ( DATA_addr ), 525 | .req ( DATA_req[i] ), 526 | .write ( DATA_write ), 527 | .be ( DATA_be ), 528 | .wdata ( DATA_wdata ), 529 | .rdata ( DATA_rdata[i] ) 530 | ); 531 | end 532 | 533 | 534 | // TAG RAM SET OF MEMORY MACROS --> THEY ARE READ IN PARALLEL 535 | for(i = 0; i< SET_ASSOCIATIVE; i++) 536 | begin : TAG_RAM_WAY 537 | ram_ws_rs_tag_scm 538 | #( 539 | .data_width(TAGRAM_DATA_WIDTH), 540 | .addr_width(TAGRAM_ADDR_WIDTH) 541 | ) 542 | TAG_RAM 543 | ( 544 | .clk ( clk ), 545 | .rst_n ( rst_n ), 546 | .addr ( TAG_addr ), 547 | .req ( TAG_req[i] ), 548 | .write ( TAG_write ), 549 | .wdata ( TAG_wdata ), 550 | .rdata ( TAG_rdata[i] ) 551 | ); 552 | end 553 | 554 | if(DIRECT_MAPPED_FEATURE == "ENABLED") 555 | assign DATA_rdata_int = DATA_rdata[0]; 556 | else 557 | assign DATA_rdata_int = DATA_rdata[DATA_way_muxsel]; 558 | 559 | endgenerate 560 | 561 | 562 | // Bindo to Zero WRITE, ADDRESS WRITE and BACKWARD WRITE AXI CHANNELS 563 | assign init_awid_o = '0; 564 | assign init_awaddr_o = '0; 565 | assign init_awlen_o = '0; 566 | assign init_awsize_o = '0; 567 | assign init_awburst_o = '0; 568 | assign init_awlock_o = 1'b0; 569 | assign init_awcache_o = '0; 570 | assign init_awprot_o = '0; 571 | assign init_awregion_o = '0; 572 | assign init_awuser_o = '0; 573 | assign init_awqos_o = '0; 574 | assign init_awvalid_o = 1'b0; 575 | assign init_wdata_o = '0; 576 | assign init_wstrb_o = '0; 577 | assign init_wlast_o = 1'b0; 578 | assign init_wuser_o = '0; 579 | assign init_wvalid_o = 1'b0; 580 | assign init_bready_o = 1'b0; 581 | 582 | endmodule 583 | -------------------------------------------------------------------------------- /RTL/TOP/icache_hier_top.sv: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // Copyright 2019 ETH Zurich and University of Bologna. 3 | // Copyright and related rights are licensed under the Solderpad Hardware 4 | // License, Version 0.51 (the "License"); you may not use this file except in 5 | // compliance with the License. You may obtain a copy of the License at 6 | // http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law 7 | // or agreed to in writing, software, hardware and materials distributed under 8 | // this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 9 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 10 | // specific language governing permissions and limitations under the License. 11 | 12 | // // 13 | // Company: Micrel Lab @ DEIS - University of Bologna // 14 | // Viale Risorgimento 2 40136 // 15 | // Bologna - fax 0512093785 - // 16 | // // 17 | // Engineer: Igor Loi - igor.loi@unibo.it // 18 | // // 19 | // Additional contributions by: // 20 | // // 21 | // // 22 | // // 23 | // Create Date: 20/10/2019 // 24 | // Design Name: ICACHE EXPL // 25 | // Module Name: icache_hier_top // 26 | // Project Name: PULP // 27 | // Language: SystemVerilog // 28 | // // 29 | // Description: This block represents the top module for the shared cache // 30 | // It instanciates the master cache controller, the TAG/DATA // 31 | // array and the HW prefetcher. // 32 | // // 33 | // // 34 | // Revision: // 35 | // Revision v0.1 - 23/01/2018 : File Created // 36 | // Additional Comments: // 37 | // // 38 | // // 39 | // // 40 | // // 41 | //////////////////////////////////////////////////////////////////////////////// 42 | 43 | module icache_hier_top 44 | #( 45 | parameter FETCH_ADDR_WIDTH = 32, 46 | parameter PRI_FETCH_DATA_WIDTH = 32, 47 | parameter SH_FETCH_DATA_WIDTH = 128, 48 | 49 | parameter NB_CORES = 9, 50 | 51 | parameter SH_NB_BANKS = 2, 52 | parameter SH_NB_WAYS = 4, 53 | parameter SH_CACHE_SIZE = 4*1024, // in Byte 54 | parameter SH_CACHE_LINE = 1, // in word of [SH_FETCH_DATA_WIDTH] 55 | 56 | parameter PRI_NB_WAYS = 2, 57 | parameter PRI_CACHE_SIZE = 512, // in Byte 58 | parameter PRI_CACHE_LINE = 1, // in word of [PRI_FETCH_DATA_WIDTH] 59 | 60 | parameter AXI_ID = 6, 61 | parameter AXI_ADDR = 32, 62 | parameter AXI_USER = 6, 63 | parameter AXI_DATA = 64, 64 | 65 | parameter USE_REDUCED_TAG = "TRUE", // TRUE | FALSE 66 | parameter L2_SIZE = 512*1024 // Size of max(L2 ,ROM) program memory in Byte 67 | ) 68 | ( 69 | input logic clk, 70 | input logic rst_n, 71 | input logic test_en_i, 72 | 73 | // interface with processors 74 | input logic [NB_CORES-1:0] fetch_req_i, 75 | input logic [NB_CORES-1:0][FETCH_ADDR_WIDTH-1:0] fetch_addr_i, 76 | output logic [NB_CORES-1:0] fetch_gnt_o, 77 | 78 | output logic [NB_CORES-1:0] fetch_rvalid_o, 79 | output logic [NB_CORES-1:0][PRI_FETCH_DATA_WIDTH-1:0]fetch_rdata_o, 80 | 81 | 82 | 83 | //AXI read address bus ------------------------------------------- 84 | output logic [AXI_ID-1:0] axi_master_arid_o, 85 | output logic [AXI_ADDR-1:0] axi_master_araddr_o, 86 | output logic [ 7:0] axi_master_arlen_o, //burst length - 1 to 16 87 | output logic [ 2:0] axi_master_arsize_o, //size of each transfer in burst 88 | output logic [ 1:0] axi_master_arburst_o, //for bursts>1, accept only incr burst=01 89 | output logic axi_master_arlock_o, //only normal access supported axs_awlock=00 90 | output logic [ 3:0] axi_master_arcache_o, 91 | output logic [ 2:0] axi_master_arprot_o, 92 | output logic [ 3:0] axi_master_arregion_o, // 93 | output logic [ AXI_USER-1:0] axi_master_aruser_o, // 94 | output logic [ 3:0] axi_master_arqos_o, // 95 | output logic axi_master_arvalid_o, //master addr valid 96 | input logic axi_master_arready_i, //slave ready to accept 97 | // -------------------------------------------------------------- 98 | 99 | 100 | //AXI BACKWARD read data bus --------------------------------------------- 101 | input logic [AXI_ID-1:0] axi_master_rid_i, 102 | input logic [AXI_DATA-1:0] axi_master_rdata_i, 103 | input logic [1:0] axi_master_rresp_i, 104 | input logic axi_master_rlast_i, //last transfer in burst 105 | input logic [AXI_USER-1:0] axi_master_ruser_i, 106 | input logic axi_master_rvalid_i, //slave data valid 107 | output logic axi_master_rready_o, //master ready to accept 108 | 109 | // NOT USED ---------------------------------------------- 110 | output logic [AXI_ID-1:0] axi_master_awid_o, 111 | output logic [AXI_ADDR-1:0] axi_master_awaddr_o, 112 | output logic [ 7:0] axi_master_awlen_o, 113 | output logic [ 2:0] axi_master_awsize_o, 114 | output logic [ 1:0] axi_master_awburst_o, 115 | output logic axi_master_awlock_o, 116 | output logic [ 3:0] axi_master_awcache_o, 117 | output logic [ 2:0] axi_master_awprot_o, 118 | output logic [ 3:0] axi_master_awregion_o, 119 | output logic [ AXI_USER-1:0] axi_master_awuser_o, 120 | output logic [ 3:0] axi_master_awqos_o, 121 | output logic axi_master_awvalid_o, 122 | input logic axi_master_awready_i, 123 | 124 | // NOT USED ---------------------------------------------- 125 | output logic [AXI_DATA-1:0] axi_master_wdata_o, 126 | output logic [AXI_DATA/8-1:0] axi_master_wstrb_o, 127 | output logic axi_master_wlast_o, 128 | output logic [ AXI_USER-1:0] axi_master_wuser_o, 129 | output logic axi_master_wvalid_o, 130 | input logic axi_master_wready_i, 131 | // --------------------------------------------------------------- 132 | 133 | // NOT USED ---------------------------------------------- 134 | input logic [AXI_ID-1:0] axi_master_bid_i, 135 | input logic [ 1:0] axi_master_bresp_i, 136 | input logic [ AXI_USER-1:0] axi_master_buser_i, 137 | input logic axi_master_bvalid_i, 138 | output logic axi_master_bready_o, 139 | // --------------------------------------------------------------- 140 | 141 | input logic [NB_CORES-1:0] enable_l1_l15_prefetch_i, 142 | 143 | SP_ICACHE_CTRL_UNIT_BUS.Slave IC_ctrl_unit_bus_main[SH_NB_BANKS-1:0], 144 | PRI_ICACHE_CTRL_UNIT_BUS.Slave IC_ctrl_unit_bus_pri[NB_CORES-1:0] 145 | ); 146 | 147 | // signals from PRI cache and interconnect 148 | logic [NB_CORES-1:0] refill_req_int; 149 | logic [NB_CORES-1:0] refill_gnt_int; 150 | logic [NB_CORES-1:0][ FETCH_ADDR_WIDTH-1:0] refill_addr_int; 151 | logic [NB_CORES-1:0] refill_r_valid_int; 152 | logic [NB_CORES-1:0][SH_FETCH_DATA_WIDTH-1:0] refill_r_data_int; 153 | 154 | // signal from icache-int to main icache 155 | logic [SH_NB_BANKS-1:0] fetch_req_to_main_cache; 156 | logic [SH_NB_BANKS-1:0][ FETCH_ADDR_WIDTH-1:0] fetch_addr_to_main_cache; 157 | logic [SH_NB_BANKS-1:0][ NB_CORES-1:0] fetch_ID_to_main_cache; 158 | logic [SH_NB_BANKS-1:0] fetch_gnt_from_main_cache; 159 | logic [SH_NB_BANKS-1:0][SH_FETCH_DATA_WIDTH-1:0] fetch_rdata_from_main_cache; 160 | logic [SH_NB_BANKS-1:0] fetch_rvalid_from_to_main_cache; 161 | logic [SH_NB_BANKS-1:0][ NB_CORES-1:0] fetch_rID_from_main_cache; 162 | 163 | // signal from icache-sh banks to axi node 164 | localparam AXI_ID_INT = AXI_ID - $clog2(SH_NB_BANKS); 165 | localparam ADDR_OFFSET = $clog2(SH_FETCH_DATA_WIDTH)-3; 166 | 167 | AXI_BUS #( 168 | .AXI_ADDR_WIDTH ( AXI_ADDR ), 169 | .AXI_DATA_WIDTH ( AXI_DATA ), 170 | .AXI_ID_WIDTH ( AXI_ID_INT ), 171 | .AXI_USER_WIDTH ( AXI_USER ) 172 | ) axi_master_int_intf [SH_NB_BANKS-1:0] (); 173 | AXI_BUS #( 174 | .AXI_ADDR_WIDTH ( AXI_ADDR ), 175 | .AXI_DATA_WIDTH ( AXI_DATA ), 176 | .AXI_ID_WIDTH ( AXI_ID ), 177 | .AXI_USER_WIDTH ( AXI_USER ) 178 | ) axi_out_intf (); 179 | 180 | logic [NB_CORES-1:0][31:0] congestion_counter; 181 | 182 | `ifdef FEATURE_ICACHE_STAT 183 | 184 | case (SH_NB_BANKS) 185 | 1: begin 186 | for(genvar i=0;i NCH_0 = 8, NCH_1= 1; 303 | localparam N_CH0 = (2**$clog2( NB_CORES ) == NB_CORES) ? NB_CORES : 2**($clog2( NB_CORES)-1); 304 | localparam N_CH1 = (2**$clog2( NB_CORES ) == NB_CORES) ? 0 : NB_CORES - 2**($clog2( NB_CORES)-1); 305 | 306 | icache_intc #( 307 | .ADDRESS_WIDTH(FETCH_ADDR_WIDTH ), 308 | .N_CORES (N_CH0 ), 309 | .N_AUX_CHANNEL(N_CH1 ), 310 | .UID_WIDTH (NB_CORES ), 311 | .DATA_WIDTH (SH_FETCH_DATA_WIDTH), 312 | .N_CACHE_BANKS(SH_NB_BANKS ) // Single L1.5 cache 313 | ) ICACHE_INTERCONNECT ( 314 | .clk_i (clk ), 315 | .rst_ni (rst_n ), 316 | 317 | .request_i (refill_req_int ), // Data request 318 | .address_i (refill_addr_int ), // Data request Address 319 | .grant_o (refill_gnt_int ), // 320 | .response_o (refill_r_valid_int ), // Data Response Valid (For LOAD/STORE commands) 321 | .read_data_o (refill_r_data_int ), // Data Response DATA (For LOAD commands) 322 | 323 | .request_o (fetch_req_to_main_cache ), // Data request 324 | .address_o (fetch_addr_to_main_cache ), // Data request Address 325 | .UID_o (fetch_ID_to_main_cache ), // Data request Address 326 | .grant_i (fetch_gnt_from_main_cache ), // Data Grant 327 | .read_data_i (fetch_rdata_from_main_cache ), // valid REspone (must be accepted always) 328 | .response_i (fetch_rvalid_from_to_main_cache), // Data Response ID (For LOAD commands) 329 | .response_UID_i(fetch_rID_from_main_cache ) // Data Response DATA (For LOAD and STORE) 330 | ); 331 | 332 | 333 | 334 | 335 | 336 | 337 | ///////////////////////////////////////////////////////////////////////////////////////// 338 | // ███╗ ███╗ █████╗ ██╗███╗ ██╗ ██╗ ██████╗ █████╗ ██████╗██╗ ██╗███████╗ // 339 | // ████╗ ████║██╔══██╗██║████╗ ██║ ██║██╔════╝██╔══██╗██╔════╝██║ ██║██╔════╝ // 340 | // ██╔████╔██║███████║██║██╔██╗ ██║ ██║██║ ███████║██║ ███████║█████╗ // 341 | // ██║╚██╔╝██║██╔══██║██║██║╚██╗██║ ██║██║ ██╔══██║██║ ██╔══██║██╔══╝ // 342 | // ██║ ╚═╝ ██║██║ ██║██║██║ ╚████║███████╗██║╚██████╗██║ ██║╚██████╗██║ ██║███████╗ // 343 | // ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝╚══════╝╚═╝ ╚═════╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚══════╝ // 344 | ///////////////////////////////////////////////////////////////////////////////////////// 345 | for (genvar i=0; i< SH_NB_BANKS; i++) begin : Main_Icache 346 | share_icache #( 347 | .N_BANKS ( SH_NB_BANKS ), 348 | .SET_ASSOCIATIVE ( SH_NB_WAYS ), 349 | .CACHE_LINE ( SH_CACHE_LINE ), 350 | .CACHE_SIZE ( SH_CACHE_SIZE/SH_NB_BANKS ), //In Byte 351 | .CACHE_ID ( i ), 352 | .FIFO_DEPTH ( 4 ), 353 | 354 | .ICACHE_DATA_WIDTH ( SH_FETCH_DATA_WIDTH ), 355 | .ICACHE_ID_WIDTH ( NB_CORES ), 356 | .ICACHE_ADDR_WIDTH ( FETCH_ADDR_WIDTH ), 357 | 358 | .DIRECT_MAPPED_FEATURE ( "DISABLED" ), 359 | 360 | .AXI_ID ( AXI_ID_INT ), 361 | .AXI_ADDR ( AXI_ADDR ), 362 | .AXI_DATA ( AXI_DATA ), 363 | .AXI_USER ( AXI_USER ), 364 | 365 | .USE_REDUCED_TAG ( USE_REDUCED_TAG ), 366 | .L2_SIZE ( L2_SIZE ) 367 | ) i_main_shared_icache ( 368 | // --------------------------------------------------------------- 369 | // I/O Port Declarations ----------------------------------------- 370 | // --------------------------------------------------------------- 371 | .clk ( clk ), 372 | .rst_n ( rst_n ), 373 | .test_en_i ( test_en_i ), 374 | 375 | // --------------------------------------------------------------- 376 | // SHARED_ICACHE_INTERCONNECT Port Declarations ----------------------------------------- 377 | // ----------------- ---------------------------------------------- 378 | .fetch_req_i ( fetch_req_to_main_cache[i] ), 379 | .fetch_grant_o ( fetch_gnt_from_main_cache[i] ), 380 | .fetch_addr_i ( fetch_addr_to_main_cache[i] ), 381 | .fetch_ID_i ( fetch_ID_to_main_cache[i] ), 382 | .fetch_r_rdata_o ( fetch_rdata_from_main_cache[i] ), 383 | .fetch_r_valid_o ( fetch_rvalid_from_to_main_cache[i] ), 384 | .fetch_r_ID_o ( fetch_rID_from_main_cache[i] ), 385 | 386 | // §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§ // 387 | // §§§§§§§§§§§§§§§§§§§ REFILL Request side §§§§§§§§§§§§§§§§§§§§§§§ // 388 | // §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§ // 389 | .init_awid_o ( axi_master_int_intf[i].aw_id ), 390 | .init_awaddr_o ( axi_master_int_intf[i].aw_addr ), 391 | .init_awlen_o ( axi_master_int_intf[i].aw_len ), 392 | .init_awsize_o ( axi_master_int_intf[i].aw_size ), 393 | .init_awburst_o ( axi_master_int_intf[i].aw_burst ), 394 | .init_awlock_o ( axi_master_int_intf[i].aw_lock ), 395 | .init_awcache_o ( axi_master_int_intf[i].aw_cache ), 396 | .init_awprot_o ( axi_master_int_intf[i].aw_prot ), 397 | .init_awregion_o ( axi_master_int_intf[i].aw_region ), 398 | .init_awuser_o ( axi_master_int_intf[i].aw_user ), 399 | .init_awqos_o ( axi_master_int_intf[i].aw_qos ), 400 | .init_awvalid_o ( axi_master_int_intf[i].aw_valid ), 401 | .init_awready_i ( axi_master_int_intf[i].aw_ready ), 402 | 403 | .init_wdata_o ( axi_master_int_intf[i].w_data ), 404 | .init_wstrb_o ( axi_master_int_intf[i].w_strb ), 405 | .init_wlast_o ( axi_master_int_intf[i].w_last ), 406 | .init_wuser_o ( axi_master_int_intf[i].w_user ), 407 | .init_wvalid_o ( axi_master_int_intf[i].w_valid ), 408 | .init_wready_i ( axi_master_int_intf[i].w_ready ), 409 | 410 | .init_bid_i ( axi_master_int_intf[i].b_id ), 411 | .init_bresp_i ( axi_master_int_intf[i].b_resp ), 412 | .init_buser_i ( axi_master_int_intf[i].b_user ), 413 | .init_bvalid_i ( axi_master_int_intf[i].b_valid ), 414 | .init_bready_o ( axi_master_int_intf[i].b_ready ), 415 | 416 | .init_arid_o ( axi_master_int_intf[i].ar_id ), 417 | .init_araddr_o ( axi_master_int_intf[i].ar_addr ), 418 | .init_arlen_o ( axi_master_int_intf[i].ar_len ), 419 | .init_arsize_o ( axi_master_int_intf[i].ar_size ), 420 | .init_arburst_o ( axi_master_int_intf[i].ar_burst ), 421 | .init_arlock_o ( axi_master_int_intf[i].ar_lock ), 422 | .init_arcache_o ( axi_master_int_intf[i].ar_cache ), 423 | .init_arprot_o ( axi_master_int_intf[i].ar_prot ), 424 | .init_arregion_o ( axi_master_int_intf[i].ar_region ), 425 | .init_aruser_o ( axi_master_int_intf[i].ar_user ), 426 | .init_arqos_o ( axi_master_int_intf[i].ar_qos ), 427 | .init_arvalid_o ( axi_master_int_intf[i].ar_valid ), 428 | .init_arready_i ( axi_master_int_intf[i].ar_ready ), 429 | 430 | .init_rid_i ( axi_master_int_intf[i].r_id ), 431 | .init_rdata_i ( axi_master_int_intf[i].r_data ), 432 | .init_rresp_i ( axi_master_int_intf[i].r_resp ), 433 | .init_rlast_i ( axi_master_int_intf[i].r_last ), 434 | .init_ruser_i ( axi_master_int_intf[i].r_user ), 435 | .init_rvalid_i ( axi_master_int_intf[i].r_valid ), 436 | .init_rready_o ( axi_master_int_intf[i].r_ready ), 437 | 438 | // Control ports 439 | .ctrl_req_enable_icache_i ( IC_ctrl_unit_bus_main[i].ctrl_req_enable ), 440 | .ctrl_ack_enable_icache_o ( IC_ctrl_unit_bus_main[i].ctrl_ack_enable ), 441 | .ctrl_req_disable_icache_i ( IC_ctrl_unit_bus_main[i].ctrl_req_disable ), 442 | .ctrl_ack_disable_icache_o ( IC_ctrl_unit_bus_main[i].ctrl_ack_disable ), 443 | .ctrl_req_flush_icache_i ( IC_ctrl_unit_bus_main[i].ctrl_flush_req ), 444 | .ctrl_ack_flush_icache_o ( IC_ctrl_unit_bus_main[i].ctrl_flush_ack ), 445 | .ctrl_pending_trans_icache_o ( IC_ctrl_unit_bus_main[i].ctrl_pending_trans ), 446 | .ctrl_sel_flush_req_i ( IC_ctrl_unit_bus_main[i].sel_flush_req ), 447 | .ctrl_sel_flush_addr_i ( IC_ctrl_unit_bus_main[i].sel_flush_addr ), 448 | .ctrl_sel_flush_ack_o ( IC_ctrl_unit_bus_main[i].sel_flush_ack ) 449 | `ifdef FEATURE_ICACHE_STAT 450 | , 451 | .ctrl_hit_count_icache_o ( IC_ctrl_unit_bus_main[i].ctrl_hit_count ), 452 | .ctrl_trans_count_icache_o ( IC_ctrl_unit_bus_main[i].ctrl_trans_count ), 453 | .ctrl_miss_count_icache_o ( IC_ctrl_unit_bus_main[i].ctrl_miss_count ), 454 | .ctrl_clear_regs_icache_i ( IC_ctrl_unit_bus_main[i].ctrl_clear_regs ), 455 | .ctrl_enable_regs_icache_i ( IC_ctrl_unit_bus_main[i].ctrl_enable_regs ) 456 | `endif 457 | ); 458 | end 459 | 460 | 461 | 462 | 463 | 464 | 465 | ///////////////////////////////////////////////////////////////// 466 | // █████╗ ██╗ ██╗██╗ ███╗ ██╗ ██████╗ ██████╗ ███████╗ // 467 | // ██╔══██╗╚██╗██╔╝██║ ████╗ ██║██╔═══██╗██╔══██╗██╔════╝ // 468 | // ███████║ ╚███╔╝ ██║ ██╔██╗ ██║██║ ██║██║ ██║█████╗ // 469 | // ██╔══██║ ██╔██╗ ██║ ██║╚██╗██║██║ ██║██║ ██║██╔══╝ // 470 | // ██║ ██║██╔╝ ██╗██║ ██║ ╚████║╚██████╔╝██████╔╝███████╗ // 471 | // ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═══╝ ╚═════╝ ╚═════╝ ╚══════╝ // 472 | ///////////////////////////////////////////////////////////////// 473 | 474 | 475 | assign axi_master_awid_o = axi_out_intf.aw_id; 476 | assign axi_master_awaddr_o = axi_out_intf.aw_addr; 477 | assign axi_master_awlen_o = axi_out_intf.aw_len; 478 | assign axi_master_awsize_o = axi_out_intf.aw_size; 479 | assign axi_master_awburst_o = axi_out_intf.aw_burst; 480 | assign axi_master_awlock_o = axi_out_intf.aw_lock; 481 | assign axi_master_awcache_o = axi_out_intf.aw_cache; 482 | assign axi_master_awprot_o = axi_out_intf.aw_prot; 483 | assign axi_master_awregion_o = axi_out_intf.aw_region; 484 | assign axi_master_awuser_o = axi_out_intf.aw_user; 485 | assign axi_master_awqos_o = axi_out_intf.aw_qos; 486 | assign axi_master_awvalid_o = axi_out_intf.aw_valid; 487 | assign axi_out_intf.aw_ready = axi_master_awready_i; 488 | 489 | assign axi_master_wdata_o = axi_out_intf.w_data; 490 | assign axi_master_wstrb_o = axi_out_intf.w_strb; 491 | assign axi_master_wlast_o = axi_out_intf.w_last; 492 | assign axi_master_wuser_o = axi_out_intf.w_user; 493 | assign axi_master_wvalid_o = axi_out_intf.w_valid; 494 | assign axi_out_intf.w_ready = axi_master_wready_i; 495 | 496 | assign axi_out_intf.b_id = axi_master_bid_i; 497 | assign axi_out_intf.b_resp = axi_master_bresp_i; 498 | assign axi_out_intf.b_user = axi_master_buser_i; 499 | assign axi_out_intf.b_valid = axi_master_bvalid_i; 500 | assign axi_master_bready_o = axi_out_intf.b_ready; 501 | 502 | assign axi_master_arid_o = axi_out_intf.ar_id; 503 | assign axi_master_araddr_o = axi_out_intf.ar_addr; 504 | assign axi_master_arlen_o = axi_out_intf.ar_len; 505 | assign axi_master_arsize_o = axi_out_intf.ar_size; 506 | assign axi_master_arburst_o = axi_out_intf.ar_burst; 507 | assign axi_master_arlock_o = axi_out_intf.ar_lock; 508 | assign axi_master_arcache_o = axi_out_intf.ar_cache; 509 | assign axi_master_arprot_o = axi_out_intf.ar_prot; 510 | assign axi_master_arregion_o = axi_out_intf.ar_region; 511 | assign axi_master_aruser_o = axi_out_intf.ar_user; 512 | assign axi_master_arqos_o = axi_out_intf.ar_qos; 513 | assign axi_master_arvalid_o = axi_out_intf.ar_valid; 514 | assign axi_out_intf.ar_ready = axi_master_arready_i; 515 | 516 | assign axi_out_intf.r_id = axi_master_rid_i; 517 | assign axi_out_intf.r_data = axi_master_rdata_i; 518 | assign axi_out_intf.r_resp = axi_master_rresp_i; 519 | assign axi_out_intf.r_last = axi_master_rlast_i; 520 | assign axi_out_intf.r_user = axi_master_ruser_i; 521 | assign axi_out_intf.r_valid = axi_master_rvalid_i; 522 | assign axi_master_rready_o = axi_out_intf.r_ready; 523 | 524 | axi_mux_intf #( 525 | .SLV_AXI_ID_WIDTH( AXI_ID_INT ), 526 | .MST_AXI_ID_WIDTH( AXI_ID ), 527 | .AXI_ADDR_WIDTH ( AXI_ADDR ), 528 | .AXI_DATA_WIDTH ( AXI_DATA ), 529 | .AXI_USER_WIDTH ( AXI_USER ), 530 | .NO_SLV_PORTS ( SH_NB_BANKS ), 531 | .MAX_W_TRANS ( 32'd1 ), // no writes through this interface 532 | .FALL_THROUGH ( 1'b0 ), 533 | .SPILL_AW ( 1'b0 ), 534 | .SPILL_W ( 1'b0 ), 535 | .SPILL_B ( 1'b0 ), 536 | .SPILL_AR ( 1'b0 ), 537 | .SPILL_R ( 1'b0 ) 538 | ) i_axi_mux ( 539 | .clk_i ( clk ), 540 | .rst_ni( rst_n ), 541 | .test_i( test_en_i ), 542 | .slv ( axi_master_int_intf ), 543 | .mst ( axi_out_intf ) 544 | ); 545 | 546 | `ifndef VERILATOR 547 | initial begin 548 | assert (AXI_ID > $clog2(SH_NB_BANKS)) 549 | else $error("AXI input ID width must be larger than $clog2(SH_NB_BANKS) which is %d but width was %d", $clog2(SH_NB_BANKS), AXI_ID); 550 | end 551 | `endif 552 | 553 | endmodule // icache_hier_top 554 | --------------------------------------------------------------------------------