diff --git a/core/cache_subsystem/cache_ctrl.sv b/core/cache_subsystem/cache_ctrl.sv index 2cd60c1f5a3..9c7cf28ce82 100644 --- a/core/cache_subsystem/cache_ctrl.sv +++ b/core/cache_subsystem/cache_ctrl.sv @@ -298,18 +298,18 @@ module cache_ctrl // two memory look-ups on a single-ported SRAM and therefore is non-atomic if (!mshr_index_matches_i) begin // store data, write dirty bit - req_o = hit_way_q; - addr_o = mem_req_q.index; - we_o = 1'b1; + req_o = hit_way_q; + addr_o = mem_req_q.index; + we_o = 1'b1; - be_o.vldrty = hit_way_q; + be_o.vldrty = hit_way_q; // set the correct byte enable - be_o.data[cl_offset>>3+:8] = mem_req_q.be; - data_o.data[cl_offset+:64] = mem_req_q.wdata; + be_o.data[cl_offset>>3+:8] = mem_req_q.be; + data_o.data[cl_offset+:64] = mem_req_q.wdata; // ~> change the state - data_o.dirty = 1'b1; - data_o.valid = 1'b1; + data_o.dirty[cl_offset>>3+:8] = mem_req_q.be; + data_o.valid = 1'b1; // got a grant ~> this is finished now if (gnt_i) begin diff --git a/core/cache_subsystem/miss_handler.sv b/core/cache_subsystem/miss_handler.sv index cc06cd161cb..ae662295236 100644 --- a/core/cache_subsystem/miss_handler.sv +++ b/core/cache_subsystem/miss_handler.sv @@ -157,7 +157,7 @@ module miss_handler automatic logic [DCACHE_SET_ASSOC-1:0] evict_way, valid_way; for (int unsigned i = 0; i < DCACHE_SET_ASSOC; i++) begin - evict_way[i] = data_i[i].valid & data_i[i].dirty; + evict_way[i] = data_i[i].valid & (|data_i[i].dirty); valid_way[i] = data_i[i].valid; end // ---------------------- @@ -264,10 +264,11 @@ module miss_handler lfsr_enable = 1'b1; evict_way_d = lfsr_oh; // do we need to write back the cache line? - if (data_i[lfsr_bin].dirty) begin + if (|data_i[lfsr_bin].dirty) begin state_d = WB_CACHELINE_MISS; evict_cl_d.tag = data_i[lfsr_bin].tag; evict_cl_d.data = data_i[lfsr_bin].data; + evict_cl_d.dirty = data_i[lfsr_bin].dirty; cnt_d = mshr_q.addr[DCACHE_INDEX_WIDTH-1:0]; // no - we can request a cache line now end else state_d = REQ_CACHELINE; @@ -306,7 +307,7 @@ module miss_handler data_o.tag = mshr_q.addr[DCACHE_TAG_WIDTH+DCACHE_INDEX_WIDTH-1:DCACHE_INDEX_WIDTH]; data_o.data = data_miss_fsm; data_o.valid = 1'b1; - data_o.dirty = 1'b0; + data_o.dirty = '0; // is this a write? if (mshr_q.we) begin @@ -316,7 +317,7 @@ module miss_handler if (mshr_q.be[i]) data_o.data[(cl_offset+i*8)+:8] = mshr_q.wdata[i]; end // its immediately dirty if we write - data_o.dirty = 1'b1; + data_o.dirty[cl_offset>>3+:8] = mshr_q.be; end // reset MSHR mshr_d.valid = 1'b0; @@ -337,7 +338,7 @@ module miss_handler cnt_q[DCACHE_INDEX_WIDTH-1:DCACHE_BYTE_OFFSET], {{DCACHE_BYTE_OFFSET} {1'b0}} }; - req_fsm_miss_be = '1; + req_fsm_miss_be = evict_cl_q.dirty; req_fsm_miss_we = 1'b1; req_fsm_miss_wdata = evict_cl_q.data; diff --git a/core/cache_subsystem/std_nbdcache.sv b/core/cache_subsystem/std_nbdcache.sv index 4cdee7e4ce8..b82158de312 100644 --- a/core/cache_subsystem/std_nbdcache.sv +++ b/core/cache_subsystem/std_nbdcache.sv @@ -55,45 +55,46 @@ module std_nbdcache // 3. Load Unit // 4. Accelerator // 5. Store unit - logic [ NumPorts:0][ DCACHE_SET_ASSOC-1:0] req; - logic [ NumPorts:0][DCACHE_INDEX_WIDTH-1:0] addr; - logic [ NumPorts:0] gnt; - cache_line_t [ DCACHE_SET_ASSOC-1:0] rdata; - logic [ NumPorts:0][ DCACHE_TAG_WIDTH-1:0] tag; + logic [NumPorts:0][DCACHE_SET_ASSOC-1:0] req; + logic [NumPorts:0][DCACHE_INDEX_WIDTH-1:0] addr; + logic [NumPorts:0] gnt; + cache_line_t [DCACHE_SET_ASSOC-1:0] rdata; + logic [NumPorts:0][DCACHE_TAG_WIDTH-1:0] tag; - cache_line_t [ NumPorts:0] wdata; - logic [ NumPorts:0] we; - cl_be_t [ NumPorts:0] be; - logic [ DCACHE_SET_ASSOC-1:0] hit_way; + cache_line_t [NumPorts:0] wdata; + logic [NumPorts:0] we; + cl_be_t [NumPorts:0] be; + logic [DCACHE_SET_ASSOC-1:0] hit_way; // ------------------------------- // Controller <-> Miss unit // ------------------------------- - logic [ NumPorts-1:0] busy; - logic [ NumPorts-1:0][ 55:0] mshr_addr; - logic [ NumPorts-1:0] mshr_addr_matches; - logic [ NumPorts-1:0] mshr_index_matches; - logic [ 63:0] critical_word; - logic critical_word_valid; + logic [NumPorts-1:0] busy; + logic [NumPorts-1:0][55:0] mshr_addr; + logic [NumPorts-1:0] mshr_addr_matches; + logic [NumPorts-1:0] mshr_index_matches; + logic [63:0] critical_word; + logic critical_word_valid; - logic [ NumPorts-1:0][ $bits(miss_req_t)-1:0] miss_req; - logic [ NumPorts-1:0] miss_gnt; - logic [ NumPorts-1:0] active_serving; + logic [NumPorts-1:0][$bits(miss_req_t)-1:0] miss_req; + logic [NumPorts-1:0] miss_gnt; + logic [NumPorts-1:0] active_serving; - logic [ NumPorts-1:0] bypass_gnt; - logic [ NumPorts-1:0] bypass_valid; - logic [ NumPorts-1:0][ 63:0] bypass_data; + logic [NumPorts-1:0] bypass_gnt; + logic [NumPorts-1:0] bypass_valid; + logic [NumPorts-1:0][63:0] bypass_data; // ------------------------------- // Arbiter <-> Datram, // ------------------------------- - logic [ DCACHE_SET_ASSOC-1:0] req_ram; - logic [DCACHE_INDEX_WIDTH-1:0] addr_ram; - logic we_ram; - cache_line_t wdata_ram; - cache_line_t [ DCACHE_SET_ASSOC-1:0] rdata_ram; - cl_be_t be_ram; + logic [DCACHE_SET_ASSOC-1:0] req_ram; + logic [DCACHE_INDEX_WIDTH-1:0] addr_ram; + logic we_ram; + cache_line_t wdata_ram; + cache_line_t [DCACHE_SET_ASSOC-1:0] rdata_ram; + cl_be_t be_ram; + logic [(DCACHE_LINE_WIDTH/8+1)*DCACHE_SET_ASSOC-1:0] be_valid_dirty_ram; // Busy signals - logic miss_handler_busy; + logic miss_handler_busy; assign busy_o = |busy | miss_handler_busy; // ------------------ @@ -223,19 +224,28 @@ module std_nbdcache // align each valid/dirty bit pair to a byte boundary in order to leverage byte enable signals. // note: if you have an SRAM that supports flat bit enables for your target technology, - // you can use it here to save the extra 4x overhead introduced by this workaround. - logic [4*DCACHE_DIRTY_WIDTH-1:0] dirty_wdata, dirty_rdata; + // you can use it here to save the extra 17x overhead introduced by this workaround. + logic [(DCACHE_LINE_WIDTH+8)*DCACHE_SET_ASSOC-1:0] dirty_wdata, dirty_rdata; for (genvar i = 0; i < DCACHE_SET_ASSOC; i++) begin - assign dirty_wdata[8*i] = wdata_ram.dirty; - assign dirty_wdata[8*i+1] = wdata_ram.valid; - assign rdata_ram[i].dirty = dirty_rdata[8*i]; - assign rdata_ram[i].valid = dirty_rdata[8*i+1]; + for (genvar j = 0; j < DCACHE_LINE_WIDTH / 8; j++) begin + // dirty bits assignment + assign dirty_wdata[(DCACHE_LINE_WIDTH+8)*i+8*j] = wdata_ram.dirty[j]; + assign rdata_ram[i].dirty[j] = dirty_rdata[(DCACHE_LINE_WIDTH+8)*i+8*j]; + end + // valid bit assignment + assign dirty_wdata[DCACHE_LINE_WIDTH+(DCACHE_LINE_WIDTH+8)*i] = wdata_ram.valid; + assign rdata_ram[i].valid = dirty_rdata[DCACHE_LINE_WIDTH+(DCACHE_LINE_WIDTH+8)*i]; + end + + // be construction for valid_dirty_sram + for (genvar i = 0; i < DCACHE_SET_ASSOC; i++) begin + assign be_valid_dirty_ram[i*(DCACHE_LINE_WIDTH/8+1)+:(DCACHE_LINE_WIDTH/8+1)] = {be_ram.vldrty[i], be_ram.data} & {(DCACHE_LINE_WIDTH/8+1){be_ram.vldrty[i]}}; end sram #( .USER_WIDTH(1), - .DATA_WIDTH(4 * DCACHE_DIRTY_WIDTH), + .DATA_WIDTH((DCACHE_LINE_WIDTH + 8) * DCACHE_SET_ASSOC), .NUM_WORDS (DCACHE_NUM_WORDS) ) valid_dirty_sram ( .clk_i (clk_i), @@ -245,7 +255,7 @@ module std_nbdcache .addr_i (addr_ram[DCACHE_INDEX_WIDTH-1:DCACHE_BYTE_OFFSET]), .wuser_i('0), .wdata_i(dirty_wdata), - .be_i (be_ram.vldrty), + .be_i (be_valid_dirty_ram), .ruser_o(), .rdata_o(dirty_rdata) ); diff --git a/core/fpu_wrap.sv b/core/fpu_wrap.sv index 3ebc1acc7ea..c4217c64184 100644 --- a/core/fpu_wrap.sv +++ b/core/fpu_wrap.sv @@ -62,28 +62,40 @@ module fpu_wrap Width: unsigned'(riscv::XLEN), // parameterized using XLEN EnableVectors: CVA6Cfg.XFVec, EnableNanBox: 1'b1, - FpFmtMask: {CVA6Cfg.RVF, CVA6Cfg.RVD, CVA6Cfg.XF16, CVA6Cfg.XF8, CVA6Cfg.XF16ALT, CVA6Cfg.XF8ALT}, - IntFmtMask: {CVA6Cfg.XFVec && CVA6Cfg.XF8, CVA6Cfg.XFVec && (CVA6Cfg.XF16 || CVA6Cfg.XF16ALT), 1'b1, 1'b1} + FpFmtMask: { + CVA6Cfg.RVF, CVA6Cfg.RVD, CVA6Cfg.XF16, CVA6Cfg.XF8, CVA6Cfg.XF16ALT, CVA6Cfg.XF8ALT + }, + IntFmtMask: { + CVA6Cfg.XFVec && CVA6Cfg.XF8, + CVA6Cfg.XFVec && (CVA6Cfg.XF16 || CVA6Cfg.XF16ALT), + 1'b1, + 1'b1 + } }; // Implementation (number of registers etc) localparam fpnew_pkg::fpu_implementation_t FPU_IMPLEMENTATION = '{ - PipeRegs: '{// FP32, FP64, FP16, FP8, FP16alt, FP8alt - '{unsigned'(LAT_COMP_FP32 ), - unsigned'(LAT_COMP_FP64 ), - unsigned'(LAT_COMP_FP16 ), - unsigned'(LAT_COMP_FP8 ), - unsigned'(LAT_COMP_FP16ALT), - unsigned'(LAT_COMP_FP8ALT)}, // ADDMUL + PipeRegs: '{ // FP32, FP64, FP16, FP8, FP16alt, FP8alt + '{ + unsigned'(LAT_COMP_FP32), + unsigned'(LAT_COMP_FP64), + unsigned'(LAT_COMP_FP16), + unsigned'(LAT_COMP_FP8), + unsigned'(LAT_COMP_FP16ALT), + unsigned'(LAT_COMP_FP8ALT) + }, // ADDMUL '{default: unsigned'(LAT_DIVSQRT)}, // DIVSQRT '{default: unsigned'(LAT_NONCOMP)}, // NONCOMP - '{default: unsigned'(LAT_CONV)}, // CONV - '{default: unsigned'(LAT_SDOTP)}}, // DOTP - UnitTypes: '{'{default: fpnew_pkg::PARALLEL}, // ADDMUL + '{default: unsigned'(LAT_CONV)}, // CONV + '{default: unsigned'(LAT_SDOTP)} + }, // DOTP + UnitTypes: '{ + '{default: fpnew_pkg::PARALLEL}, // ADDMUL '{default: fpnew_pkg::MERGED}, // DIVSQRT '{default: fpnew_pkg::PARALLEL}, // NONCOMP - '{default: fpnew_pkg::MERGED}, // CONV - '{default: fpnew_pkg::DISABLED}}, // DOTP + '{default: fpnew_pkg::MERGED}, // CONV + '{default: fpnew_pkg::DISABLED} + }, // DOTP PipeConfig: fpnew_pkg::DISTRIBUTED }; @@ -526,19 +538,19 @@ module fpu_wrap ) i_fpnew_bulk ( .clk_i, .rst_ni, - .hart_id_i ( '0 ), - .operands_i ( fpu_operands ), - .rnd_mode_i ( fpnew_pkg::roundmode_e'(fpu_rm) ), - .op_i ( fpnew_pkg::operation_e'(fpu_op) ), - .op_mod_i ( fpu_op_mod ), - .src_fmt_i ( fpnew_pkg::fp_format_e'(fpu_srcfmt) ), - .dst_fmt_i ( fpnew_pkg::fp_format_e'(fpu_dstfmt) ), - .int_fmt_i ( fpnew_pkg::int_format_e'(fpu_ifmt) ), - .vectorial_op_i ( fpu_vec_op ), - .tag_i ( fpu_tag ), - .simd_mask_i ( '1 ), - .in_valid_i ( fpu_in_valid ), - .in_ready_o ( fpu_in_ready ), + .hart_id_i ('0), + .operands_i (fpu_operands), + .rnd_mode_i (fpnew_pkg::roundmode_e'(fpu_rm)), + .op_i (fpnew_pkg::operation_e'(fpu_op)), + .op_mod_i (fpu_op_mod), + .src_fmt_i (fpnew_pkg::fp_format_e'(fpu_srcfmt)), + .dst_fmt_i (fpnew_pkg::fp_format_e'(fpu_dstfmt)), + .int_fmt_i (fpnew_pkg::int_format_e'(fpu_ifmt)), + .vectorial_op_i(fpu_vec_op), + .tag_i (fpu_tag), + .simd_mask_i ('1), + .in_valid_i (fpu_in_valid), + .in_ready_o (fpu_in_ready), .flush_i, .result_o, .status_o (fpu_status), diff --git a/core/include/ariane_pkg.sv b/core/include/ariane_pkg.sv index fbda98956ec..477190ac204 100644 --- a/core/include/ariane_pkg.sv +++ b/core/include/ariane_pkg.sv @@ -62,11 +62,11 @@ package ariane_pkg; localparam int unsigned LAT_COMP_FP16 = 'd1; localparam int unsigned LAT_COMP_FP16ALT = 'd1; localparam int unsigned LAT_COMP_FP8 = 'd1; - localparam int unsigned LAT_COMP_FP8ALT = 'd1; + localparam int unsigned LAT_COMP_FP8ALT = 'd1; localparam int unsigned LAT_DIVSQRT = 'd2; localparam int unsigned LAT_NONCOMP = 'd1; localparam int unsigned LAT_CONV = 'd2; - localparam int unsigned LAT_SDOTP = 'd2; + localparam int unsigned LAT_SDOTP = 'd2; localparam riscv::xlen_t OPENHWGROUP_MVENDORID = {{riscv::XLEN - 32{1'b0}}, 32'h0602}; localparam riscv::xlen_t ARIANE_MARCHID = {{riscv::XLEN - 32{1'b0}}, 32'd3}; diff --git a/core/include/cv32a60x_config_pkg.sv b/core/include/cv32a60x_config_pkg.sv index e119abf60ab..3011335fe8a 100644 --- a/core/include/cv32a60x_config_pkg.sv +++ b/core/include/cv32a60x_config_pkg.sv @@ -16,7 +16,7 @@ package cva6_config_pkg; localparam CVA6ConfigF16En = 0; localparam CVA6ConfigF16AltEn = 0; localparam CVA6ConfigF8En = 0; - localparam CVA6ConfigF8AltEn = 0; + localparam CVA6ConfigF8AltEn = 0; localparam CVA6ConfigFVecEn = 0; localparam CVA6ConfigCvxifEn = 1; diff --git a/core/include/cv32a6_embedded_config_pkg.sv b/core/include/cv32a6_embedded_config_pkg.sv index 91d6e985fea..0dd1d4cfc45 100644 --- a/core/include/cv32a6_embedded_config_pkg.sv +++ b/core/include/cv32a6_embedded_config_pkg.sv @@ -15,7 +15,7 @@ package cva6_config_pkg; localparam CVA6ConfigF16En = 0; localparam CVA6ConfigF16AltEn = 0; localparam CVA6ConfigF8En = 0; - localparam CVA6ConfigF8AltEn = 0; + localparam CVA6ConfigF8AltEn = 0; localparam CVA6ConfigFVecEn = 0; localparam CVA6ConfigCvxifEn = 1; diff --git a/core/include/cv32a6_ima_sv32_fpga_config_pkg.sv b/core/include/cv32a6_ima_sv32_fpga_config_pkg.sv index 9832766418c..c22c2babb4f 100644 --- a/core/include/cv32a6_ima_sv32_fpga_config_pkg.sv +++ b/core/include/cv32a6_ima_sv32_fpga_config_pkg.sv @@ -16,7 +16,7 @@ package cva6_config_pkg; localparam CVA6ConfigF16En = 0; localparam CVA6ConfigF16AltEn = 0; localparam CVA6ConfigF8En = 0; - localparam CVA6ConfigF8AltEn = 0; + localparam CVA6ConfigF8AltEn = 0; localparam CVA6ConfigFVecEn = 0; localparam CVA6ConfigCvxifEn = 0; diff --git a/core/include/cv32a6_imac_sv0_config_pkg.sv b/core/include/cv32a6_imac_sv0_config_pkg.sv index 700d82cd2b0..66d28e7712d 100644 --- a/core/include/cv32a6_imac_sv0_config_pkg.sv +++ b/core/include/cv32a6_imac_sv0_config_pkg.sv @@ -16,7 +16,7 @@ package cva6_config_pkg; localparam CVA6ConfigF16En = 0; localparam CVA6ConfigF16AltEn = 0; localparam CVA6ConfigF8En = 0; - localparam CVA6ConfigF8AltEn = 0; + localparam CVA6ConfigF8AltEn = 0; localparam CVA6ConfigFVecEn = 0; localparam CVA6ConfigCvxifEn = 0; diff --git a/core/include/cv32a6_imac_sv32_config_pkg.sv b/core/include/cv32a6_imac_sv32_config_pkg.sv index 00fe43e8100..07fc82a0ecb 100644 --- a/core/include/cv32a6_imac_sv32_config_pkg.sv +++ b/core/include/cv32a6_imac_sv32_config_pkg.sv @@ -16,7 +16,7 @@ package cva6_config_pkg; localparam CVA6ConfigF16En = 0; localparam CVA6ConfigF16AltEn = 0; localparam CVA6ConfigF8En = 0; - localparam CVA6ConfigF8AltEn = 0; + localparam CVA6ConfigF8AltEn = 0; localparam CVA6ConfigFVecEn = 0; localparam CVA6ConfigCvxifEn = 0; diff --git a/core/include/cv32a6_imafc_sv32_config_pkg.sv b/core/include/cv32a6_imafc_sv32_config_pkg.sv index 0b98dda40c0..441f314e875 100644 --- a/core/include/cv32a6_imafc_sv32_config_pkg.sv +++ b/core/include/cv32a6_imafc_sv32_config_pkg.sv @@ -16,7 +16,7 @@ package cva6_config_pkg; localparam CVA6ConfigF16En = 0; localparam CVA6ConfigF16AltEn = 0; localparam CVA6ConfigF8En = 0; - localparam CVA6ConfigF8AltEn = 0; + localparam CVA6ConfigF8AltEn = 0; localparam CVA6ConfigFVecEn = 0; localparam CVA6ConfigCvxifEn = 0; diff --git a/core/include/cv64a6_imafdc_sv39_config_pkg.sv b/core/include/cv64a6_imafdc_sv39_config_pkg.sv index 5acccbb2431..e0290014f2f 100644 --- a/core/include/cv64a6_imafdc_sv39_config_pkg.sv +++ b/core/include/cv64a6_imafdc_sv39_config_pkg.sv @@ -16,7 +16,7 @@ package cva6_config_pkg; localparam CVA6ConfigF16En = 0; localparam CVA6ConfigF16AltEn = 0; localparam CVA6ConfigF8En = 0; - localparam CVA6ConfigF8AltEn = 0; + localparam CVA6ConfigF8AltEn = 0; localparam CVA6ConfigFVecEn = 0; localparam CVA6ConfigCvxifEn = 1; diff --git a/core/include/cv64a6_imafdc_sv39_openpiton_config_pkg.sv b/core/include/cv64a6_imafdc_sv39_openpiton_config_pkg.sv index 47f5e05b51b..f909c0b34bc 100644 --- a/core/include/cv64a6_imafdc_sv39_openpiton_config_pkg.sv +++ b/core/include/cv64a6_imafdc_sv39_openpiton_config_pkg.sv @@ -16,7 +16,7 @@ package cva6_config_pkg; localparam CVA6ConfigF16En = 0; localparam CVA6ConfigF16AltEn = 0; localparam CVA6ConfigF8En = 0; - localparam CVA6ConfigF8AltEn = 0; + localparam CVA6ConfigF8AltEn = 0; localparam CVA6ConfigFVecEn = 0; localparam CVA6ConfigCvxifEn = 0; diff --git a/core/include/cv64a6_imafdcsclic_sv39_config_pkg.sv b/core/include/cv64a6_imafdcsclic_sv39_config_pkg.sv index 723b4291aee..a11deb815e8 100644 --- a/core/include/cv64a6_imafdcsclic_sv39_config_pkg.sv +++ b/core/include/cv64a6_imafdcsclic_sv39_config_pkg.sv @@ -16,7 +16,7 @@ package cva6_config_pkg; localparam CVA6ConfigF16En = 0; localparam CVA6ConfigF16AltEn = 0; localparam CVA6ConfigF8En = 0; - localparam CVA6ConfigF8AltEn = 0; + localparam CVA6ConfigF8AltEn = 0; localparam CVA6ConfigFVecEn = 0; localparam CVA6ConfigCvxifEn = 0; diff --git a/core/include/std_cache_pkg.sv b/core/include/std_cache_pkg.sv index ae812c99740..7513cc866bf 100644 --- a/core/include/std_cache_pkg.sv +++ b/core/include/std_cache_pkg.sv @@ -65,7 +65,7 @@ package std_cache_pkg; logic [ariane_pkg::DCACHE_TAG_WIDTH-1:0] tag; // tag array logic [ariane_pkg::DCACHE_LINE_WIDTH-1:0] data; // data array logic valid; // state array - logic dirty; // state array + logic [(ariane_pkg::DCACHE_LINE_WIDTH+7)/8-1:0] dirty; // state array } cache_line_t; // cache line byte enable diff --git a/corev_apu/tb/common/tb_dcache_pkg.sv b/corev_apu/tb/common/tb_dcache_pkg.sv index 7584d81a868..4aa4ce6c59f 100644 --- a/corev_apu/tb/common/tb_dcache_pkg.sv +++ b/corev_apu/tb/common/tb_dcache_pkg.sv @@ -36,7 +36,7 @@ package tb_pkg; parameter ERROR_CNT_STOP_LEVEL = 1; // use 1 for debugging. 0 runs the complete simulation... // tb_readport sequences - typedef enum logic [2:0] { RANDOM_SEQ, LINEAR_SEQ, BURST_SEQ, IDLE_SEQ, WRAP_SEQ, SET_SEQ, CONST_SEQ } seq_t; + typedef enum logic [2:0] { RANDOM_SEQ, LINEAR_SEQ, BURST_SEQ, IDLE_SEQ, WRAP_SEQ, SET_SEQ, CONST_SEQ, HALF_SEQ } seq_t; typedef enum logic [1:0] { OTHER, BYPASS, CACHED } port_type_t; diff --git a/corev_apu/tb/common/tb_writeport.sv b/corev_apu/tb/common/tb_writeport.sv index babadd91c14..fcc48bca8ee 100644 --- a/corev_apu/tb/common/tb_writeport.sv +++ b/corev_apu/tb/common/tb_writeport.sv @@ -30,6 +30,8 @@ program tb_writeport import tb_pkg::*; import ariane_pkg::*; #( input logic rst_ni, // to testbench master + input logic half_i, + input logic [1:0] max_size_i, ref string test_name_i, input logic [6:0] req_rate_i, input seq_t seq_type_i, @@ -63,13 +65,13 @@ program tb_writeport import tb_pkg::*; import ariane_pkg::*; #( automatic logic [7:0] be; automatic logic [1:0] size; - void'(randomize(size)); + void'(randomize(size) with {size >= 2'b00; size <= max_size_i;}); // align to size, set correct byte enables be = '0; unique case(size) - 2'b00: be[paddr[2:0] +: 1] = '1; - 2'b01: be[paddr[2:1]<<1 +: 2] = '1; - 2'b10: be[paddr[2:2]<<2 +: 4] = '1; + 2'b00: be[int'(paddr[2:0]) +: 1] = '1; + 2'b01: be[int'(paddr[2:1]<<1) +: 2] = '1; + 2'b10: be[int'(paddr[2:2]<<2) +: 4] = '1; 2'b11: be = '1; default: ; endcase @@ -109,6 +111,7 @@ program tb_writeport import tb_pkg::*; import ariane_pkg::*; #( dut_req_port_o.data_req = 1'b1; // generate random address void'(randomize(paddr) with {paddr >= 0; paddr < (MemWords<<3);}); + if (seq_type_i == HALF_SEQ) paddr[int'(max_size_i)] = half_i; applyRandData(); `APPL_WAIT_COMB_SIG(clk_i, dut_req_port_i.data_gnt) end @@ -278,6 +281,11 @@ program tb_writeport import tb_pkg::*; import ariane_pkg::*; #( $display("%s> start random sequence with %04d vectors and req_rate %03d", PortName, seq_num_vect_i, req_rate_i); genRandReq(); end + HALF_SEQ: begin + $display("%s> start half random sequence with %04d vectors and req_rate %03d", PortName, seq_num_vect_i, req_rate_i); + $display("%s> half = %b and max size = %b", PortName, half_i, max_size_i); + genRandReq(); + end LINEAR_SEQ: begin $display("%s> start linear sequence with %04d vectors and req_rate %03d", PortName, seq_num_vect_i, req_rate_i); genSeqWrite(); diff --git a/corev_apu/tb/tb_wb_dcache/Makefile b/corev_apu/tb/tb_wb_dcache/Makefile index 5877d27e61c..affee866b3c 100755 --- a/corev_apu/tb/tb_wb_dcache/Makefile +++ b/corev_apu/tb/tb_wb_dcache/Makefile @@ -20,7 +20,7 @@ src := $(shell xargs printf '\n%s' < $(src-list) | cut -b 1-) compile_flag += +cover+i_dut -incr -64 -nologo -svinputport=compat -override_timescale 1ns/1ps -suppress 2583 -suppress 13262 +cover sim_opts += -64 -coverage -classdebug -voptargs="+acc" questa_version ?= ${QUESTASIM_VERSION} -incdir += ../common/ ../../axi/include/ +incdir += ../common/ ../../axi/include/ ../../../common/submodules/common_cells/include/ # Iterate over all include directories and write them with +incdir+ prefixed # +incdir+ works for Verilator and QuestaSim diff --git a/corev_apu/tb/tb_wb_dcache/hdl/tb.sv b/corev_apu/tb/tb_wb_dcache/hdl/tb.sv index 0b4550fec57..c09c6f9dd7b 100644 --- a/corev_apu/tb/tb_wb_dcache/hdl/tb.sv +++ b/corev_apu/tb/tb_wb_dcache/hdl/tb.sv @@ -94,6 +94,8 @@ module tb import ariane_pkg::*; import std_cache_pkg::*; import tb_pkg::*; #()() seq_t [2:0] seq_type; logic [3:0] seq_done; logic [6:0] req_rate[2:0]; + logic half; + logic [1:0] max_size; logic seq_run, seq_last; logic end_of_sim; @@ -234,6 +236,37 @@ module tb import ariane_pkg::*; import std_cache_pkg::*; import tb_pkg::*; #()() `APPL_WAIT_CYC(clk_i, 1) endtask : flushCache + //integer fd = $fopen("extern_write.txt","w"); + // Write directly the tb memory + function automatic void external_writer(int unsigned pos, int unsigned half); + automatic logic[7:0] val; + for (int k=0; k requests to cached region should use cache port, + // those to uncached regions should use bypass port + bypass_mem_port.set_region(0, CachedAddrBeg - 1); + data_mem_port.set_region(CachedAddrBeg, MemBytes - 1); + + runSeq(0,nWriteVectors,0); + external_writer(int'(max_size),int'(!half)); + flushCache(); + tb_mem_port_t::check_mem(); + + ////////////////////////////////////////////// + test_name = "TEST 20 -- random write on half memory(MSB) and external writer on the other half -- max size = 64b -- enabled cache + tlb, mem contentions + invalidations"; + + // Config + enable_i = 1; + tlb_rand_en = 1; + mem_rand_en = 1; + inv_rand_en = 1; + max_size = 2'b11; + half = 1; + seq_type = '{HALF_SEQ, RANDOM_SEQ, RANDOM_SEQ}; + req_rate = '{default:50}; + + // cache enabled ~> requests to cached region should use cache port, + // those to uncached regions should use bypass port + bypass_mem_port.set_region(0, CachedAddrBeg - 1); + data_mem_port.set_region(CachedAddrBeg, MemBytes - 1); + + runSeq(0,nWriteVectors,0); + external_writer(int'(max_size),int'(!half)); + flushCache(); + tb_mem_port_t::check_mem(); + + ////////////////////////////////////////////// + test_name = "TEST 21 -- random write on half memory(LSB) and external writer on the other half -- max size = 32b -- enabled cache + tlb, mem contentions + invalidations"; + + // Config + enable_i = 1; + tlb_rand_en = 1; + mem_rand_en = 1; + inv_rand_en = 1; + max_size = 2'b10; + half = 0; + seq_type = '{HALF_SEQ, RANDOM_SEQ, RANDOM_SEQ}; + req_rate = '{default:50}; + + // cache enabled ~> requests to cached region should use cache port, + // those to uncached regions should use bypass port + bypass_mem_port.set_region(0, CachedAddrBeg - 1); + data_mem_port.set_region(CachedAddrBeg, MemBytes - 1); + + runSeq(0,nWriteVectors,0); + external_writer(int'(max_size),int'(!half)); + flushCache(); + tb_mem_port_t::check_mem(); + + ////////////////////////////////////////////// + test_name = "TEST 22 -- random write on half memory(MSB) and external writer on the other half -- max size = 32b -- enabled cache + tlb, mem contentions + invalidations"; + + // Config + enable_i = 1; + tlb_rand_en = 1; + mem_rand_en = 1; + inv_rand_en = 1; + max_size = 2'b10; + half = 1; + seq_type = '{HALF_SEQ, RANDOM_SEQ, RANDOM_SEQ}; + req_rate = '{default:50}; + + // cache enabled ~> requests to cached region should use cache port, + // those to uncached regions should use bypass port + bypass_mem_port.set_region(0, CachedAddrBeg - 1); + data_mem_port.set_region(CachedAddrBeg, MemBytes - 1); + + runSeq(0,nWriteVectors,0); + external_writer(int'(max_size),int'(!half)); + flushCache(); + tb_mem_port_t::check_mem(); + + ////////////////////////////////////////////// + test_name = "TEST 23 -- random write on half memory(LSB) and external writer on the other half -- max size = 16b -- enabled cache + tlb, mem contentions + invalidations"; + + // Config + enable_i = 1; + tlb_rand_en = 1; + mem_rand_en = 1; + inv_rand_en = 1; + max_size = 2'b01; + half = 0; + seq_type = '{HALF_SEQ, RANDOM_SEQ, RANDOM_SEQ}; + req_rate = '{default:50}; + + // cache enabled ~> requests to cached region should use cache port, + // those to uncached regions should use bypass port + bypass_mem_port.set_region(0, CachedAddrBeg - 1); + data_mem_port.set_region(CachedAddrBeg, MemBytes - 1); + + runSeq(0,nWriteVectors,0); + external_writer(int'(max_size),int'(!half)); + flushCache(); + tb_mem_port_t::check_mem(); + + ////////////////////////////////////////////// + test_name = "TEST 24 -- random write on half memory(MSB) and external writer on the other half -- max size = 16b -- enabled cache + tlb, mem contentions + invalidations"; + + // Config + enable_i = 1; + tlb_rand_en = 1; + mem_rand_en = 1; + inv_rand_en = 1; + max_size = 2'b01; + half = 1; + seq_type = '{HALF_SEQ, RANDOM_SEQ, RANDOM_SEQ}; + req_rate = '{default:50}; + + // cache enabled ~> requests to cached region should use cache port, + // those to uncached regions should use bypass port + bypass_mem_port.set_region(0, CachedAddrBeg - 1); + data_mem_port.set_region(CachedAddrBeg, MemBytes - 1); + + runSeq(0,nWriteVectors,0); + external_writer(int'(max_size),int'(!half)); + flushCache(); + tb_mem_port_t::check_mem(); + + ////////////////////////////////////////////// + test_name = "TEST 25 -- random write on half memory(LSB) and external writer on the other half -- max size = 8b -- enabled cache + tlb, mem contentions + invalidations"; + + // Config + enable_i = 1; + tlb_rand_en = 1; + mem_rand_en = 1; + inv_rand_en = 1; + max_size = 2'b00; + half = 0; + seq_type = '{HALF_SEQ, RANDOM_SEQ, RANDOM_SEQ}; + req_rate = '{default:50}; + + // cache enabled ~> requests to cached region should use cache port, + // those to uncached regions should use bypass port + bypass_mem_port.set_region(0, CachedAddrBeg - 1); + data_mem_port.set_region(CachedAddrBeg, MemBytes - 1); + + runSeq(0,nWriteVectors,0); + external_writer(int'(max_size),int'(!half)); + flushCache(); + tb_mem_port_t::check_mem(); + + ////////////////////////////////////////////// + test_name = "TEST 26 -- random write on half memory(MSB) and external writer on the other half -- max size = 8b -- enabled cache + tlb, mem contentions + invalidations"; + + // Config + enable_i = 1; + tlb_rand_en = 1; + mem_rand_en = 1; + inv_rand_en = 1; + max_size = 2'b00; + half = 1; + seq_type = '{HALF_SEQ, RANDOM_SEQ, RANDOM_SEQ}; + req_rate = '{default:50}; + + // cache enabled ~> requests to cached region should use cache port, + // those to uncached regions should use bypass port + bypass_mem_port.set_region(0, CachedAddrBeg - 1); + data_mem_port.set_region(CachedAddrBeg, MemBytes - 1); + + runSeq(0,nWriteVectors,1); + external_writer(int'(max_size),int'(!half)); + flushCache(); + tb_mem_port_t::check_mem(); + + ////////////////////////////////////////////// + end_of_sim = 1; $display("TB> end test sequences"); tb_mem_port_t::report_mem(); diff --git a/corev_apu/tb/tb_wb_dcache/tb.list b/corev_apu/tb/tb_wb_dcache/tb.list index 05180e4ee1a..7d46ce5028c 100644 --- a/corev_apu/tb/tb_wb_dcache/tb.list +++ b/corev_apu/tb/tb_wb_dcache/tb.list @@ -35,12 +35,23 @@ ../../../vendor/pulp-platform/common_cells/src/stream_demux.sv ../../../core/axi_adapter.sv ../../../common/local/util/sram.sv +../../../common/local/util/tc_sram_wrapper.sv +../../src/tech_cells_generic/src/rtl/tc_sram.sv ../../src/axi_riscv_atomics/src/axi_res_tbl.sv ../../src/axi_riscv_atomics/src/axi_riscv_amos.sv ../../src/axi_riscv_atomics/src/axi_riscv_amos_alu.sv ../../src/axi_riscv_atomics/src/axi_riscv_lrsc.sv ../../src/axi_riscv_atomics/src/axi_riscv_atomics.sv ../../src/axi_riscv_atomics/src/axi_riscv_atomics_wrap.sv +../../../common/submodules/common_cells/src/id_queue.sv +../../../common/submodules/common_cells/src/stream_fork.sv +../../../common/submodules/common_cells/src/stream_filter.sv +../../../common/submodules/common_cells/src/fall_through_register.sv +../../../common/submodules/common_cells/src/stream_register.sv +../../../common/submodules/common_cells/src/spill_register_flushable.sv +../../../common/submodules/common_cells/src/spill_register.sv +../../../common/submodules/common_cells/src/onehot_to_bin.sv +../../axi/src/axi_multicut.sv ../common/tb_dcache_pkg.sv ../common/tb_readport.sv