From a7793c67410b18c33b0c06d51ddf55763ac68be8 Mon Sep 17 00:00:00 2001 From: Paul Pan Date: Mon, 1 Aug 2022 22:01:24 +0800 Subject: [PATCH] Another big update 1. refactor func test 2. fix CACHE inst 3. CP0 add Context Register 4. fix AXIWriter order --- .editorconfig | 5 + resources/soft/func/include/utils.h | 32 ++ resources/soft/func/inst/inst_test.h | 2 + resources/soft/func/inst/n99_cache_icache.S | 16 +- resources/soft/func/start.S | 549 +++++--------------- resources/tb.sv | 9 +- sim/Makefile | 11 +- sim/sim_main.cpp | 17 +- src/CP0/CP0.sv | 73 +-- src/Core/Controller.sv | 2 +- src/Core/Datapath.sv | 16 +- src/MU/AXIWriter.sv | 6 +- src/MU/MU.sv | 66 ++- src/MU/interface.sv | 5 +- src/include/CP0.svh | 2 +- src/include/TLB.svh | 6 + src/include/defines.svh | 2 +- tools/ctrl_maker.py | 2 +- tools/mctrl1.txt | 14 +- 19 files changed, 310 insertions(+), 525 deletions(-) create mode 100644 resources/soft/func/include/utils.h diff --git a/.editorconfig b/.editorconfig index 0886cb4..49e9f0e 100644 --- a/.editorconfig +++ b/.editorconfig @@ -19,6 +19,11 @@ end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true +[sim/logs/annotated/*] +charset = utf-8 +indent_style = tab +indent_size = 8 + [tools/*.txt] charset = utf-8 indent_style = tab diff --git a/resources/soft/func/include/utils.h b/resources/soft/func/include/utils.h new file mode 100644 index 0000000..0f6bdb4 --- /dev/null +++ b/resources/soft/func/include/utils.h @@ -0,0 +1,32 @@ +#include + +#define JUMP_TO_CACHED \ + la t1, 1f; \ + li t2, 0x20000000; \ + subu t9, t1, t2; \ + jr t9; \ + nop; \ + 1: + +#define JUMP_TO_UNCACHED \ + la t9, 1f; \ + jr t9; \ + nop; \ + 1: + +#define TEST_UNIT(test) \ + jal test; \ + nop; \ + jal wait_1s; \ + nop; + +#define TEST_UNIT_CACHE(test) \ + JUMP_TO_CACHED; \ + TEST_UNIT(test); \ + JUMP_TO_UNCACHED; \ + TEST_UNIT(test); + +#define TEST_UNIT_ONLY_CACHE(test) \ + JUMP_TO_CACHED; \ + TEST_UNIT(test); \ + JUMP_TO_UNCACHED; diff --git a/resources/soft/func/inst/inst_test.h b/resources/soft/func/inst/inst_test.h index 5ccad84..9330971 100644 --- a/resources/soft/func/inst/inst_test.h +++ b/resources/soft/func/inst/inst_test.h @@ -1462,6 +1462,7 @@ LI(t2, data1); \ LI(t3, data2); \ /* prepare -> hit writeback invalidate */ \ + sw t3, offset(t0); \ sw t2, offset(t1); \ cache 21, offset(t1); \ lw a0, offset(t0); \ @@ -1471,6 +1472,7 @@ bne t2, a0, inst_error; \ nop; \ /* test hit invalidate */ \ + sw t2, offset(t0); \ sw t3, offset(t1); \ cache 17, offset(t1); \ lw a0, offset(t0); \ diff --git a/resources/soft/func/inst/n99_cache_icache.S b/resources/soft/func/inst/n99_cache_icache.S index 4a49017..97d2d38 100644 --- a/resources/soft/func/inst/n99_cache_icache.S +++ b/resources/soft/func/inst/n99_cache_icache.S @@ -306,10 +306,10 @@ LEAF(n99_cache_icache_test) /* Enhanced test: - 1. fill 800d0000, 800D0800, 800D1000, 800D1800 with instructions - 2. jump to 800d0000, 800D0800, 800D1000, 800D1800 and execute + 1. fill 800d0000, 800d0800, 800d1000, 800d1800 with instructions + 2. jump to 800d0000, 800d0800, 800d1000, 800d1800 and execute 3. return back to here and check registers - 4. modify 800d0000, 800D0800, 800D1000, 800D1800 + 4. modify 800d0000, 800d0800, 800d1000, 800d1800 5. same as 2 3 20050000 addi $a1, $zero, 0 @@ -329,7 +329,7 @@ LEAF(n99_cache_icache_test) li a2, 0x03e00008 li a3, 0x20a50000 -.n98_en_step1: +.n99_en_step1: sw a1, 0(t0) sw a1, 0(t1) sw a1, 0(t2) @@ -352,7 +352,7 @@ LEAF(n99_cache_icache_test) cache 1, 0(zero) cache 0, 0(zero) -.n98_en_step23: +.n99_en_step23: li a1, 0 li a2, 0 jalr t0 @@ -381,7 +381,7 @@ LEAF(n99_cache_icache_test) bne a1, a2, inst_error nop -.n98_en_step4: +.n99_en_step4: sw a3, 8(t0) addi a3, a3, 1 sw a3, 8(t1) @@ -394,7 +394,7 @@ LEAF(n99_cache_icache_test) cache 1, 0(zero) cache 0, 0(zero) -.n98_en_step5: +.n99_en_step5: li a1, 0 li a2, 4 jalr t0 @@ -423,7 +423,7 @@ LEAF(n99_cache_icache_test) bne a1, a2, inst_error nop -.n98_en_rst: +.n99_en_rst: move ra, a0 ###detect exception diff --git a/resources/soft/func/start.S b/resources/soft/func/start.S index ad8973e..0384199 100644 --- a/resources/soft/func/start.S +++ b/resources/soft/func/start.S @@ -2,7 +2,9 @@ #include #include -#define TEST_NUM 101 +#include + +#define TEST_NUM 150 ##s0, number @@ -86,6 +88,8 @@ test_finish: li k0, 0x09 # trap beq k1, k0, trap_ex nop + b test_finish # Not recognized + nop syscall_ex: addu s2, zero, zero @@ -304,438 +308,121 @@ locate: lui s0, 0 ## initial run number - la t1, kseg1_kseg0 ##### - li t2, 0x20000000 ### - subu t9, t1, t2 #kseg1 -> kseg0 - jr t9 ### - nop ##### -kseg1_kseg0: inst_test: - jal n1_lui_test #lui - nop - jal wait_1s - nop - - la t9, kseg0_kseg1 ##### - jr t9 #kseg0 -> kseg1 - nop ##### - -kseg0_kseg1: - - jal n2_addu_test #addu - nop - jal wait_1s - nop - jal n3_addiu_test #addiu - nop - jal wait_1s - nop - jal n4_beq_test #beq - nop - jal wait_1s - nop - jal n5_bne_test #bne - nop - jal wait_1s - nop - jal n6_lw_test #lw - nop - jal wait_1s - nop - jal n7_or_test #or - nop - jal wait_1s - nop - jal n8_slt_test #slt - nop - jal wait_1s - nop - jal n9_slti_test #slti - nop - jal wait_1s - nop - jal n10_sltiu_test #sltiu - nop - jal wait_1s - nop - jal n11_sll_test #sll - nop - jal wait_1s - nop - jal n12_sw_test #sw - nop - jal wait_1s - nop - jal n13_j_test #j - nop - jal wait_1s - nop - jal n14_jal_test #jal - nop - jal wait_1s - nop - jal n15_jr_test #jr - nop - jal wait_1s - nop - jal n16_beq_ds_test #beq delay slot - nop - jal wait_1s - nop - jal n17_bne_ds_test #bne delay slot - nop - jal wait_1s - nop - jal n18_j_ds_test #j delay slot - nop - jal wait_1s - nop - jal n19_jal_ds_test #jal delay slot - nop - jal wait_1s - nop - jal n20_jr_ds_test #jr delay slot - nop - jal wait_1s - nop - jal n21_add_test #add - nop - jal wait_1s - nop - jal n22_addi_test #addi - nop - jal wait_1s - nop - jal n23_sub_test #sub - nop - jal wait_1s - nop - jal n24_subu_test #subu - nop - jal wait_1s - nop - jal n25_sltu_test #sltu - nop - jal wait_1s - nop - jal n26_and_test #and - nop - jal wait_1s - nop - jal n27_andi_test #andi - nop - jal wait_1s - nop - jal n28_nor_test #nor - nop - jal wait_1s - nop - jal n29_ori_test #ori - nop - jal wait_1s - nop - jal n30_xor_test #xor - nop - jal wait_1s - nop - jal n31_xori_test #xori - nop - jal wait_1s - nop - jal n32_sllv_test #sllv - nop - jal wait_1s - nop - jal n33_sra_test #sra - nop - jal wait_1s - nop - jal n34_srav_test #srav - nop - jal wait_1s - nop - jal n35_srl_test #srl - nop - jal wait_1s - nop - jal n36_srlv_test #srlv - nop - jal wait_1s - nop - jal n37_bgez_test #bgez - nop - jal wait_1s - nop - jal n38_bgtz_test #bgtz - nop - jal wait_1s - nop - jal n39_blez_test #blez - nop - jal wait_1s - nop - jal n40_bltz_test #bltz - nop - jal wait_1s - nop - jal n41_bltzal_test #bltzal - nop - jal wait_1s - nop - jal n42_bgezal_test #bgezal - nop - jal wait_1s - nop - jal n43_jalr_test #jalr - nop - jal wait_1s - nop - jal n44_div_test #div - nop - jal wait_1s - nop - jal n45_divu_test #divu - nop - jal wait_1s - nop - jal n46_mult_test #mult - nop - jal wait_1s - nop - jal n47_multu_test #multu - nop - jal wait_1s - nop - jal n48_mfhi_test #mfhi - nop - jal wait_1s - nop - jal n49_mflo_test #mflo - nop - jal wait_1s - nop - jal n50_mthi_test #mthi - nop - jal wait_1s - nop - jal n51_mtlo_test #mtlo - nop - jal wait_1s - nop - jal n52_bgez_ds_test #bgez delay slot - nop - jal wait_1s - nop - jal n53_bgtz_ds_test #bgtz delay slot - nop - jal wait_1s - nop - jal n54_blez_ds_test #blez delay slot - nop - jal wait_1s - nop - jal n55_bltz_ds_test #bltz delay slot - nop - jal wait_1s - nop - jal n56_bltzal_ds_test #bltzal delay slot - nop - jal wait_1s - nop - jal n57_bgezal_ds_test #bgezal delay slot - nop - jal wait_1s - nop - jal n58_jalr_ds_test #jalr delay slot - nop - jal wait_1s - nop - jal n59_lb_test #lb - nop - jal wait_1s - nop - jal n60_lbu_test #lbu - nop - jal wait_1s - nop - jal n61_lh_test #lh - nop - jal wait_1s - nop - jal n62_lhu_test #lhu - nop - jal wait_1s - nop - jal n63_sb_test #sb - nop - jal wait_1s - nop - jal n64_sh_test #sh - nop - jal wait_1s - nop - jal n65_syscall_ex_test #syscall - nop - jal wait_1s - nop - jal n66_break_ex_test #break ex - nop - jal wait_1s - nop - jal n67_add_ov_ex_test #add ov ex - nop - jal wait_1s - nop - jal n68_addi_ov_ex_test #addi ov ex - nop - jal wait_1s - nop - jal n69_sub_ov_ex_test #sub ov ex - nop - jal wait_1s - nop - jal n70_lw_adel_ex_test #lw adel ex - nop - jal wait_1s - nop - jal n71_lh_adel_ex_test #lh adel ex - nop - jal wait_1s - nop - jal n72_lhu_adel_ex_test #lhu adel ex - nop - jal wait_1s - nop - jal n73_sw_ades_ex_test #sw ades ex - nop - jal wait_1s - nop - jal n74_sh_ades_ex_test #sh ades ex - nop - jal wait_1s - nop - jal n75_ft_adel_ex_test #ft adel ex - nop - jal wait_1s - nop - jal n76_ri_ex_test #ri ex - nop - jal wait_1s - nop - jal n77_soft_int_ex_test #soft int ex - nop - jal wait_1s - nop - jal n78_beq_ds_ex_test #beq ds ex - nop - jal wait_1s - nop - jal n79_bne_ds_ex_test #bne ds ex - nop - jal wait_1s - nop - jal n80_bgez_ds_ex_test #bgez ds ex - nop - jal wait_1s - nop - jal n81_bgtz_ds_ex_test #bgtz ds ex - nop - jal wait_1s - nop - jal n82_blez_ds_ex_test #blez ds ex - nop - jal wait_1s - nop - jal n83_bltz_ds_ex_test #bltz ds ex - nop - jal wait_1s - nop - jal n84_bltzal_ds_ex_test #bltzal ds ex - nop - jal wait_1s - nop - jal n85_bgezal_ds_ex_test #bgezal ds ex - nop - jal wait_1s - nop - jal n86_j_ds_ex_test #j ds ex - nop - jal wait_1s - nop - jal n87_jal_ds_ex_test #jal ds ex - nop - jal wait_1s - nop - jal n88_jr_ds_ex_test #jr ds ex - nop - jal wait_1s - nop - jal n89_jalr_ds_ex_test #jalr ds ex - nop - jal wait_1s - nop - jal n90_lwl_test - nop - jal wait_1s - nop - jal n91_lwr_test - nop - jal wait_1s - nop - jal n92_swl_test - nop - jal wait_1s - nop - jal n93_swr_test - nop - jal wait_1s - nop - jal n94_perf_sync_nop_test - nop - jal wait_1s - nop - jal n95_madd_test - nop - jal wait_1s - nop - jal n96_maddu_test - nop - jal wait_1s - nop - jal n97_msub_msubu_test - nop - jal wait_1s - nop - - jal n98_cache_dcache_test - nop - jal wait_1s - nop - - la t1, n99_kseg1_kseg0 - li t2, 0x20000000 - subu t9, t1, t2 - jr t9 - nop -n99_kseg1_kseg0: - jal n99_cache_icache_test - nop - jal wait_1s - nop - - la t9, n99_kseg0_kseg1 - jr t9 - nop -n99_kseg0_kseg1: + TEST_UNIT_CACHE(n1_lui_test) # 1 2 + TEST_UNIT_CACHE(n2_addu_test) + TEST_UNIT_CACHE(n3_addiu_test) - jal n100_movz_movn_test - nop - jal wait_1s - nop - jal n101_trap_test - nop - jal wait_1s - nop + TEST_UNIT(n4_beq_test) # 7 + TEST_UNIT(n5_bne_test) + + TEST_UNIT_CACHE(n6_lw_test) # 9 10 + TEST_UNIT_CACHE(n7_or_test) + TEST_UNIT_CACHE(n8_slt_test) + TEST_UNIT_CACHE(n9_slti_test) + TEST_UNIT_CACHE(n10_sltiu_test) + TEST_UNIT_CACHE(n11_sll_test) + TEST_UNIT_CACHE(n12_sw_test) + + TEST_UNIT(n13_j_test) # 23 + TEST_UNIT(n14_jal_test) + TEST_UNIT(n15_jr_test) + TEST_UNIT(n16_beq_ds_test) + TEST_UNIT(n17_bne_ds_test) + TEST_UNIT(n18_j_ds_test) + TEST_UNIT(n19_jal_ds_test) + TEST_UNIT(n20_jr_ds_test) + + TEST_UNIT_CACHE(n21_add_test) # 31 32 + TEST_UNIT_CACHE(n22_addi_test) + TEST_UNIT_CACHE(n23_sub_test) + TEST_UNIT_CACHE(n24_subu_test) + TEST_UNIT_CACHE(n25_sltu_test) + TEST_UNIT_CACHE(n26_and_test) + TEST_UNIT_CACHE(n27_andi_test) + TEST_UNIT_CACHE(n28_nor_test) + TEST_UNIT_CACHE(n29_ori_test) + TEST_UNIT_CACHE(n30_xor_test) + TEST_UNIT_CACHE(n31_xori_test) + TEST_UNIT_CACHE(n32_sllv_test) + TEST_UNIT_CACHE(n33_sra_test) + TEST_UNIT_CACHE(n34_srav_test) + TEST_UNIT_CACHE(n35_srl_test) + TEST_UNIT_CACHE(n36_srlv_test) + + TEST_UNIT(n37_bgez_test) # 63 + TEST_UNIT(n38_bgtz_test) + TEST_UNIT(n39_blez_test) + TEST_UNIT(n40_bltz_test) + TEST_UNIT(n41_bltzal_test) + TEST_UNIT(n42_bgezal_test) + TEST_UNIT(n43_jalr_test) + + TEST_UNIT_CACHE(n44_div_test) # 70 71 + TEST_UNIT_CACHE(n45_divu_test) + TEST_UNIT_CACHE(n46_mult_test) + TEST_UNIT_CACHE(n47_multu_test) + TEST_UNIT_CACHE(n48_mfhi_test) + TEST_UNIT_CACHE(n49_mflo_test) + TEST_UNIT_CACHE(n50_mthi_test) + TEST_UNIT_CACHE(n51_mtlo_test) + + TEST_UNIT(n52_bgez_ds_test) # 86 + TEST_UNIT(n53_bgtz_ds_test) + TEST_UNIT(n54_blez_ds_test) + TEST_UNIT(n55_bltz_ds_test) + TEST_UNIT(n56_bltzal_ds_test) + TEST_UNIT(n57_bgezal_ds_test) + TEST_UNIT(n58_jalr_ds_test) + + TEST_UNIT_CACHE(n59_lb_test) # 93 94 + TEST_UNIT_CACHE(n60_lbu_test) + TEST_UNIT_CACHE(n61_lh_test) + TEST_UNIT_CACHE(n62_lhu_test) + TEST_UNIT_CACHE(n63_sb_test) + TEST_UNIT_CACHE(n64_sh_test) + + TEST_UNIT(n65_syscall_ex_test) # 105 + TEST_UNIT(n66_break_ex_test) + TEST_UNIT(n67_add_ov_ex_test) + TEST_UNIT(n68_addi_ov_ex_test) + TEST_UNIT(n69_sub_ov_ex_test) + TEST_UNIT(n70_lw_adel_ex_test) + TEST_UNIT(n71_lh_adel_ex_test) + TEST_UNIT(n72_lhu_adel_ex_test) + TEST_UNIT(n73_sw_ades_ex_test) + TEST_UNIT(n74_sh_ades_ex_test) + TEST_UNIT(n75_ft_adel_ex_test) + TEST_UNIT(n76_ri_ex_test) + TEST_UNIT(n77_soft_int_ex_test) + TEST_UNIT(n78_beq_ds_ex_test) + TEST_UNIT(n79_bne_ds_ex_test) + TEST_UNIT(n80_bgez_ds_ex_test) + TEST_UNIT(n81_bgtz_ds_ex_test) + TEST_UNIT(n82_blez_ds_ex_test) + TEST_UNIT(n83_bltz_ds_ex_test) + TEST_UNIT(n84_bltzal_ds_ex_test) + TEST_UNIT(n85_bgezal_ds_ex_test) + TEST_UNIT(n86_j_ds_ex_test) + TEST_UNIT(n87_jal_ds_ex_test) + TEST_UNIT(n88_jr_ds_ex_test) + TEST_UNIT(n89_jalr_ds_ex_test) + + TEST_UNIT_CACHE(n90_lwl_test) # 130 131 + TEST_UNIT_CACHE(n91_lwr_test) + TEST_UNIT_CACHE(n92_swl_test) + TEST_UNIT_CACHE(n93_swr_test) + TEST_UNIT_CACHE(n94_perf_sync_nop_test) + TEST_UNIT_CACHE(n95_madd_test) + TEST_UNIT_CACHE(n96_maddu_test) + TEST_UNIT_CACHE(n97_msub_msubu_test) + + TEST_UNIT(n98_cache_dcache_test) # 146 + TEST_UNIT_ONLY_CACHE(n99_cache_icache_test) + + TEST_UNIT_CACHE(n100_movz_movn_test) + + TEST_UNIT(n101_trap_test) ###check io access LI (a0, IO_SIMU_ADDR) diff --git a/resources/tb.sv b/resources/tb.sv index 0e6e9e4..c2b7e95 100644 --- a/resources/tb.sv +++ b/resources/tb.sv @@ -11,6 +11,7 @@ module testbench_top ( input clk, input resetn, + input [ 7:0] switch_sim, output [15:0] led, output [ 1:0] led_rg0, output [ 1:0] led_rg1, @@ -18,14 +19,13 @@ module testbench_top ( output [ 6:0] num_a_g ); initial begin - $display("[%0t] Tracing to logs/trace.vcd...", $time); - $dumpfile("logs/trace.vcd"); + $display("[%0t] Tracing to logs/trace.fst...", $time); + $dumpfile("logs/trace.fst"); $dumpvars(); $display("[%0t] Model running...", $time); end //gpio - logic [ 7:0] switch; logic [ 3:0] btn_key_col; logic [ 3:0] btn_key_row; logic [ 1:0] btn_step; @@ -35,7 +35,6 @@ module testbench_top ( logic [31:0] confreg_num_reg; logic [31:0] confreg_num_reg_r; - assign switch = 8'hff; assign btn_key_row = 4'd0; assign btn_step = 2'd3; assign uart_display = `CONFREG_UART_DISPLAY; @@ -168,7 +167,7 @@ module testbench_top ( .led (led), .led_rg0 (led_rg0), .led_rg1 (led_rg1), - .switch (switch), + .switch (switch_sim), .btn_key_col(btn_key_col), .btn_key_row(btn_key_row), .btn_step (btn_step) diff --git a/sim/Makefile b/sim/Makefile index 11b0159..6d8959b 100644 --- a/sim/Makefile +++ b/sim/Makefile @@ -24,7 +24,7 @@ VERILATOR_BUILD_FLAGS += --assert # Generate coverage analysis VERILATOR_BUILD_FLAGS += --coverage # Run make to compile model, with as many CPUs as are free -VERILATOR_BUILD_FLAGS += --build -j +VERILATOR_BUILD_FLAGS += --compiler clang -CFLAGS "-Wno-parentheses-equality" --build -j # Simulation Defines VERILATOR_FLAGS += -sv -DSIMULATION_VERILATOR -DSIMULATION_PC @@ -50,9 +50,9 @@ FUNC_SOURCE = $(wildcard ../resources/tb.sv ../resources/func_test/*.v ../resour #################### # Targets # #################### -.phony: test func_test func_coverage run clean +.phony: test func_test func_coverage func_run clean -default: run +default: func_run lint: $(VERILATOR) --lint-only $(VERILATOR_FLAGS) $(INCLUDE) $(SOURCE) -top mycpu_top @@ -64,11 +64,10 @@ func_coverage: func_build @rm -rf logs/annotated $(VERILATOR_COVERAGE) $(VERILATOR_COV_FLAGS) -run: func_build +func_run: func_build @rm -rf logs - @mkdir -p logs obj_dir/Vtestbench_top - gtkwave logs/trace.vcd + gtkwave logs/trace.fst clean: -rm -rf obj_dir logs diff --git a/sim/sim_main.cpp b/sim/sim_main.cpp index fb31caa..fd8dd6e 100644 --- a/sim/sim_main.cpp +++ b/sim/sim_main.cpp @@ -1,27 +1,40 @@ +#include #include #include +#include + #include "Vtestbench_top.h" #include +std::atomic ctrl_c_hit; +void ctrl_c_handler(int sig) { ctrl_c_hit = true; } + vluint64_t main_time = 0; double sc_time_stamp() { return main_time; } int main(int argc, char **argv, char **env) { + ctrl_c_hit = false; + signal(SIGINT, ctrl_c_handler); + Verilated::commandArgs(argc, argv); Verilated::randReset(2); Verilated::traceEverOn(true); Verilated::mkdir("logs"); const int reset_time = 10; - const int time_limit = 2100000; + const int time_limit = 2900000; // {0xff, 2900000} Vtestbench_top *top = new Vtestbench_top; std::cout << "<<< Simulation Started >>>" << std::endl; auto time_start = std::chrono::high_resolution_clock::now(); top->clk = 0; + top->switch_sim = 0xff; while (!Verilated::gotFinish() && main_time < time_limit) { + if (ctrl_c_hit) + break; + ++main_time; top->clk = !top->clk; top->resetn = (main_time < reset_time) ? 0 : 1; @@ -34,6 +47,8 @@ int main(int argc, char **argv, char **env) { if (main_time == time_limit) std::cout << "<<< Time Limit Reached >>>" << std::endl; + if (ctrl_c_hit) + std::cout << "<<< Ctrl-C >>>" << std::endl; std::cout << "<<< Simulation Ended >>>" << std::endl; std::cout << "Realworld Time: " << std::chrono::duration_cast(time_end - time_start).count() diff --git a/src/CP0/CP0.sv b/src/CP0/CP0.sv index 98f1eb8..a6fa3a1 100644 --- a/src/CP0/CP0.sv +++ b/src/CP0/CP0.sv @@ -52,6 +52,8 @@ module CP0 ( assign rf_cp0.Status.zero5 = 2'b0; assign rf_cp0.EntryHi.zero = 5'b0; assign rf_cp0.Wired.zero = 29'b0; + assign rf_cp0.Context.BadVPN2= 19'b0; + assign rf_cp0.Context.zero = 4'b0; assign rf_cp0.EntryLo1.zero = 6'b0; assign rf_cp0.EntryLo0.zero = 6'b0; assign rf_cp0.Random.zero = 29'b0; @@ -77,40 +79,41 @@ module CP0 ( always_ff @(posedge clk) if (rst) begin - rf_cp0.Config.K0 = 3'b011; - rf_cp0.EPC = 32'h0; - rf_cp0.Cause.BD = 1'b0; - rf_cp0.Cause.TI = 1'b0; - rf_cp0.Cause.IP[1:0] = 2'b0; - rf_cp0.Cause.ExcCode = 5'b0; - rf_cp0.Status.Bev = 1'b1; - rf_cp0.Status.IM = 8'b0; - rf_cp0.Status.UM = 1'b0; - rf_cp0.Status.EXL = 1'b0; - rf_cp0.Status.IE = 1'b0; - rf_cp0.Compare = 32'hFFFF_FFFF; - rf_cp0.EntryHi.VPN2 = 19'b0; - rf_cp0.EntryHi.ASID = 8'b0; - rf_cp0.Count = 32'h0; - rf_cp0.BadVAddr = 32'h0; - rf_cp0.Wired.Wired = 3'b0; - rf_cp0.EntryLo1.PFN = 20'b0; - rf_cp0.EntryLo1.C = 3'b0; - rf_cp0.EntryLo1.D = 1'b0; - rf_cp0.EntryLo1.V = 1'b0; - rf_cp0.EntryLo1.G = 1'b0; - rf_cp0.EntryLo0.PFN = 20'b0; - rf_cp0.EntryLo0.C = 3'b0; - rf_cp0.EntryLo0.D = 1'b0; - rf_cp0.EntryLo0.V = 1'b0; - rf_cp0.EntryLo0.G = 1'b0; - rf_cp0.Index.P = 1'b0; - rf_cp0.Index.Index = 3'b0; - rf_cp0.Random.Random = 3'b111; + rf_cp0.Config.K0 = 3'b011; + rf_cp0.EPC = 32'h0; + rf_cp0.Cause.BD = 1'b0; + rf_cp0.Cause.TI = 1'b0; + rf_cp0.Cause.IP[1:0] = 2'b0; + rf_cp0.Cause.ExcCode = 5'b0; + rf_cp0.Status.Bev = 1'b1; + rf_cp0.Status.IM = 8'b0; + rf_cp0.Status.UM = 1'b0; + rf_cp0.Status.EXL = 1'b0; + rf_cp0.Status.IE = 1'b0; + rf_cp0.Compare = 32'hFFFF_FFFF; + rf_cp0.EntryHi.VPN2 = 19'b0; + rf_cp0.EntryHi.ASID = 8'b0; + rf_cp0.Count = 32'h0; + rf_cp0.BadVAddr = 32'h0; + rf_cp0.Wired.Wired = 3'b0; + rf_cp0.Context.PTEBase = 9'b0; + rf_cp0.EntryLo1.PFN = 20'b0; + rf_cp0.EntryLo1.C = 3'b0; + rf_cp0.EntryLo1.D = 1'b0; + rf_cp0.EntryLo1.V = 1'b0; + rf_cp0.EntryLo1.G = 1'b0; + rf_cp0.EntryLo0.PFN = 20'b0; + rf_cp0.EntryLo0.C = 3'b0; + rf_cp0.EntryLo0.D = 1'b0; + rf_cp0.EntryLo0.V = 1'b0; + rf_cp0.EntryLo0.G = 1'b0; + rf_cp0.Index.P = 1'b0; + rf_cp0.Index.Index = 3'b0; + rf_cp0.Random.Random = 3'b111; - rf_cp0.EBase.EBase = 18'b0; + rf_cp0.EBase.EBase = 18'b0; - count_lo = 0; + count_lo = 0; end else begin // count count_lo = ~count_lo; @@ -163,7 +166,9 @@ module CP0 ( rf_cp0.Random.Random = 3'b111; end // 5: rf_cp0.PageMask.Mask = wdata[24:13]; - // 4: rf_cp0.Context = wdata; + 4: begin + rf_cp0.Context.PTEBase = wdata[31:23]; + end 3: begin rf_cp0.EntryLo1.PFN = wdata[25:6]; rf_cp0.EntryLo1.C = wdata[5:3]; @@ -267,7 +272,7 @@ module CP0 ( 6: rdata = rf_cp0.Wired; // 5: rdata = rf_cp0.PageMask; 5: rdata = 32'h0; - // 4: rdata = rf_cp0.Context; + 4: rdata = rf_cp0.Context; 3: rdata = rf_cp0.EntryLo1; 2: rdata = rf_cp0.EntryLo0; 1: rdata = rf_cp0.Random; diff --git a/src/Core/Controller.sv b/src/Core/Controller.sv index a026635..df742f5 100644 --- a/src/Core/Controller.sv +++ b/src/Core/Controller.sv @@ -73,7 +73,7 @@ module Controller ( assign ctrl.MCtrl0.SEL = inst[2:0]; assign ctrl.MCtrl0.RS0 = RS0_t'({~inst[30] & (~inst[4] | inst[5] | inst[29] | inst[26]), inst[30], ~inst[29] & (~inst[1] | inst[30])}); - assign ctrl.MCtrl1.MR = inst[31] & ~inst[30]; + assign ctrl.MCtrl1.MR = inst[31] & (~inst[26] | inst[26] & (~inst[27] | inst[27] & ~inst[28] & ~inst[30])); assign ctrl.MCtrl1.MWR = inst[29]; assign ctrl.MCtrl1.MX = ~inst[28]; assign ctrl.MCtrl1.ALR = ALR_t'({inst[28] & inst[27] & ~inst[26], ~inst[28] & inst[27] & ~inst[26]}); diff --git a/src/Core/Datapath.sv b/src/Core/Datapath.sv index 8ade3c9..62871a3 100644 --- a/src/Core/Datapath.sv +++ b/src/Core/Datapath.sv @@ -263,6 +263,7 @@ module Datapath ( logic M_I1_DataR_OK; word_t M_I1_DataR; + logic M_I1_CACHE_REQ; word_t HI; word_t LO; @@ -940,12 +941,12 @@ module Datapath ( assign cache_op.req = cache_op.op.icache_op | cache_op.op.dcache_op; assign cache_op.op = E.I1.MCtrl.CACHE_OP; - assign cache_op.addr = ~cache_op.op.index_or_hit ? E_I1_ADDR - : cache_op.op.dcache_op ? {E_I1_ADDR[32-`DC_INDEXL-1:0], `DC_INDEXL'b0} - : {E_I1_ADDR[32-`IC_INDEXL-1:0], `IC_INDEXL'b0}; + assign cache_op.addr = cache_op.op.index_or_hit ? E_I1_ADDR + : cache_op.op.dcache_op ? {E_I1_ADDR[32-`DC_INDEXL-1:0], `DC_INDEXL'b0} + : {E_I1_ADDR[32-`IC_INDEXL-1:0], `IC_INDEXL'b0}; assign E.en = E_go & M.en; - assign E_go = (~mem.req | mem.addr_ok) & cache_op.addr_ok; + assign E_go = (~mem.req | mem.addr_ok) & (~cache_op.req | cache_op.addr_ok); // E.Forwarding assign E_I0_FS_M_I0 = M.I0.WCtrl.RW & E.I0.RS == M.I0.RD; @@ -1317,9 +1318,11 @@ module Datapath ( M.I1.RDataW ); + assign M_I1_CACHE_REQ = M.I1.MCtrl.CACHE_OP.icache_op | M.I1.MCtrl.CACHE_OP.dcache_op; + myBuffer #(32) M_I1_DataR_buffer ( clk, rst, - mem.data_ok, + mem.data_ok | M_I1_CACHE_REQ & cache_op.data_ok, mem.rdata, M.en, M_I1_DataR_OK, @@ -1337,7 +1340,8 @@ module Datapath ( assign M_go = (M.I0.MCtrl.HLS[2:1] != 2'b10 | M_I0_MULT_bvalid) & (M.I0.MCtrl.HLS != DIV | M_I0_DIV_bvalid) & (M.I0.MCtrl.HLS != DIVU | M_I0_DIVU_bvalid) - & (~M.I1.MCtrl.MR | M_I1_NowExcValid | M_I1_DataR_OK) + & (~M.I1.MCtrl.MR | M_I1_NowExcValid | M_I1_DataR_OK) + & (~M_I1_CACHE_REQ | M_I1_DataR_OK) & (~M_exception.ExcValid | fetch.req & fetch.addr_ok); // M.Forwarding diff --git a/src/MU/AXIWriter.sv b/src/MU/AXIWriter.sv index 3def34a..e5da022 100644 --- a/src/MU/AXIWriter.sv +++ b/src/MU/AXIWriter.sv @@ -32,7 +32,7 @@ module AXIWriter #(parameter DATA_LEN = 8) logic [3:0] data_cntr; logic [DATA_LEN-1:0] data_select; - ffen #(4) cntr_ff (.*, .d((call ? len : data_cntr) - 4'b0001) , .en(shift | call), .q(data_cntr)); + ffen #(4) cntr_ff (.*, .d((call ? 4'b0 : data_cntr) + 4'b0001) , .en(shift | call), .q(data_cntr)); assign data_select = call ? data : stored_data; typedef enum bit [1:0] { DIDLE, DATA } data_state_t; @@ -53,10 +53,10 @@ module AXIWriter #(parameter DATA_LEN = 8) axi.wstrb = call ? wstrb : stored_wstrb; /*verilator lint_off WIDTH*/ - axi.wdata = data_select[(call ? len : data_cntr) * 32 +: 32]; + axi.wdata = data_select[(call ? 4'b0 : data_cntr) * 32 +: 32]; /*verilator lint_on WIDTH*/ axi.wvalid = 0; - axi.wlast = (call ? len : data_cntr) == 0; + axi.wlast = (call ? 4'b0 : data_cntr) == (call ? len : stored_len); case (cur_data_state) DIDLE: begin diff --git a/src/MU/MU.sv b/src/MU/MU.sv index b52a543..6eefa3f 100644 --- a/src/MU/MU.sv +++ b/src/MU/MU.sv @@ -22,20 +22,29 @@ module MU ( // NOTE: req and op and addr should be kept until addr_ok logic cop_i_req, cop_d_req; - assign cop_i_req = cacheop.req & cacheop.op.icache_op; - assign cop_d_req = cacheop.req & cacheop.op.dcache_op; - logic cop_i_ok, cop_d_ok; - assign cacheop.addr_ok = (~cop_i_req | cop_i_ok) | (~cop_d_req | cop_d_ok); + logic cacheop_handling; + assign cop_i_req = cacheop.req & cacheop.op.icache_op & ~cacheop_handling; + assign cop_d_req = cacheop.req & cacheop.op.dcache_op & ~cacheop_handling; + logic cop_i_ok, cop_d_ok; + logic cop_i_addr_ok, cop_d_addr_ok; + assign cacheop.addr_ok = (~cop_i_req | cop_i_addr_ok) & (~cop_d_req | cop_d_addr_ok) & ~cacheop_handling; + assign cacheop.data_ok = cop_i_ok | cop_d_ok; - word_t stored_cacheop_addr; + logic stored_icacheop_req, stored_dcacheop_req; CacheOp_t stored_cacheop_op; - ffen #(`XLEN + `CACHEOP_T_LEN) icacheop_store ( + word_t stored_cacheop_addr; + ffen #(`XLEN) cacheop_addr_store (.*, .d(cacheop.addr), .en(cacheop.req & cacheop.addr_ok), .q(stored_cacheop_addr)); + ffen #(`CACHEOP_T_LEN) cacheop_op_store (.*, .d(cacheop.op), .en(cacheop.req & cacheop.addr_ok), .q(stored_cacheop_op)); + ffenr #(2) cacheop_req_store ( .*, - .d({cacheop.addr, cacheop.op}), - .en(cacheop.req), - .q({stored_cacheop_addr, stored_cacheop_op}) + .rst(rst | cacheop.data_ok), + .d({cop_i_req, cop_d_req}), + .en(cacheop.addr_ok), + .q({stored_icacheop_req, stored_dcacheop_req}) ); + assign cacheop_handling = stored_icacheop_req | stored_dcacheop_req; + // ========================= // == InstFetch Functions == // ========================= @@ -90,6 +99,9 @@ module MU ( ffenr #(1) ifreq_store (.*, .d(instfetch.req), .en(in_if_ready), .q(if_req), .rst(rst | if_wait_cache)); ffen #(`XLEN) ifaddr_store (.*, .d(instfetch.addr), .en(in_if_ready), .q(stored_instfetch_addr)); + logic stored_if_handshake; + ffenr #(1) ifc_handshake_store (.*, .d(in_if_valid), .en(in_if_ready), .q(stored_if_handshake)); + // ============ // row data mux // ============ @@ -145,6 +157,7 @@ module MU ( // I$ cop_i_ok = 0; + cop_i_addr_ok = 0; icache.ctrl = 4'b0; icache.index_for_lookup = instfetch.addr[`IC_TAGL-1:`IC_INDEXL]; icache.index = stored_instfetch_addr[`IC_TAGL-1:`IC_INDEXL]; @@ -153,11 +166,11 @@ module MU ( case (ifc_cur_state) IFC_LOOKUP: begin - if (cop_i_req) begin + cop_i_addr_ok = ~stored_if_handshake; + + if (cop_i_req & ~stored_if_handshake) begin // Handle Cache Instruction ifc_nxt_state = IFC_CACHE_INVALID; - - cop_i_ok = 1; icache.index_for_lookup = cacheop.addr[`IC_TAGL-1:`IC_INDEXL]; end else if (~instfetch_valid) begin @@ -337,6 +350,9 @@ module MU ( ffen #(4) memwstrb_store (.*, .d(memory.wstrb), .en(mem_req), .q(stored_memory_wstrb)); ffen #(`XLEN) memwdata_store (.*, .d(memory.wdata), .en(mem_req), .q(stored_memory_wdata)); + logic stored_mem_handshake; + ffenr #(1) mem_handshake_store (.*, .d(in_mem_valid), .en(in_mem_ready), .q(stored_mem_handshake)); + // ============ // row data mux // ============ @@ -413,6 +429,7 @@ module MU ( // D$ cop_d_ok = 0; + cop_d_addr_ok = 0; dcache.ctrl = 8'b0; dcache.index_for_lookup = memory.addr[`DC_TAGL-1:`DC_INDEXL]; dcache.index = stored_memory_addr[`DC_TAGL-1:`DC_INDEXL]; @@ -421,7 +438,9 @@ module MU ( case (mem_cur_state) MEM_LOOKUP: begin - if (cop_d_req) begin + cop_d_addr_ok = ~stored_mem_handshake; + + if (cop_d_req & ~stored_mem_handshake) begin // Handle Cache Instruction mem_nxt_state = MEM_CACHE_INVALID; dcache.index_for_lookup = cacheop.addr[`DC_TAGL-1:`DC_INDEXL]; @@ -553,8 +572,13 @@ module MU ( // LOOKUP -> dache.dirt -> MEM_READ // CACHE_INVALID -> -> CACHE_INVALID - dcache.index_for_lookup = stored_memory_addr[`DC_TAGL-1:`DC_INDEXL]; - dcache.index = stored_memory_addr[`DC_TAGL-1:`DC_INDEXL]; + if (mem_pre_state == MEM_CACHE_INVALID) begin + dcache.index_for_lookup = stored_cacheop_addr[`DC_TAGL-1:`DC_INDEXL]; + dcache.index = stored_cacheop_addr[`DC_TAGL-1:`DC_INDEXL]; + end else begin + dcache.index_for_lookup = stored_memory_addr[`DC_TAGL-1:`DC_INDEXL]; + dcache.index = stored_memory_addr[`DC_TAGL-1:`DC_INDEXL]; + end if (amw_done) begin if (mem_pre_state == MEM_CACHE_INVALID) begin @@ -583,7 +607,7 @@ module MU ( MEM_CACHE_INVALID: begin dcache.index_for_lookup = stored_cacheop_addr[`DC_TAGL-1:`DC_INDEXL]; dcache.index = stored_cacheop_addr[`DC_TAGL-1:`DC_INDEXL]; - dcache.tag = stored_cacheop_addr[`XLEN-1:`DC_TAGL]; + dcache.tag = memory_phy_addr[`XLEN-1:`DC_TAGL]; if (~stored_cacheop_op.writeback) begin mem_nxt_state = MEM_LOOKUP; @@ -677,8 +701,14 @@ module MU ( ); logic choose_cop_i, choose_cop_d; - assign choose_cop_i = (ifc_cur_state == IFC_LOOKUP) & cop_i_req; - assign choose_cop_d = (mem_cur_state == MEM_LOOKUP) & cop_d_req; + assign choose_cop_i = (ifc_cur_state == IFC_LOOKUP) & cop_i_req & ~stored_if_handshake; + assign choose_cop_d = (mem_cur_state == MEM_LOOKUP) & cop_d_req & ~stored_mem_handshake; + + // TODO: Cache OP + // TLBL: Always + // TLBS: Never + // AdEL: Implementaion independent -> Effective Address references a portion of kernel address space + // non-aligned: Never // instfetch assign iVA = choose_cop_i ? cacheop.addr : (instfetch.req & ifc_nxt_state == IFC_LOOKUP ? instfetch.addr : stored_instfetch_addr); diff --git a/src/MU/interface.sv b/src/MU/interface.sv index 404ea04..6cfdb37 100644 --- a/src/MU/interface.sv +++ b/src/MU/interface.sv @@ -32,10 +32,11 @@ interface CacheOp_i; logic req; word_t addr; logic addr_ok; + logic data_ok; CacheOp_t op; - modport cpu(output req, addr, op, input addr_ok); - modport mu (input req, addr, op, output addr_ok); + modport cpu(output req, addr, op, input addr_ok, data_ok); + modport mu (input req, addr, op, output addr_ok, data_ok); endinterface interface ICache_i; diff --git a/src/include/CP0.svh b/src/include/CP0.svh index d34ee03..4c36723 100644 --- a/src/include/CP0.svh +++ b/src/include/CP0.svh @@ -120,7 +120,7 @@ typedef struct packed { word_t BadVAddr; // HWREna Wired_t Wired; - // Context, + Context_t Context; // word_t PageMask; EntryLo_t EntryLo1; EntryLo_t EntryLo0; diff --git a/src/include/TLB.svh b/src/include/TLB.svh index ff40297..0565967 100644 --- a/src/include/TLB.svh +++ b/src/include/TLB.svh @@ -7,6 +7,12 @@ typedef struct packed { logic [ 7:0] ASID; } EntryHi_t; +typedef struct packed { + logic [ 8:0] PTEBase; + logic [18:0] BadVPN2; + logic [ 3:0] zero; +} Context_t; + typedef struct packed { logic [ 5:0] zero; logic [19:0] PFN; diff --git a/src/include/defines.svh b/src/include/defines.svh index c8032af..ca33b55 100644 --- a/src/include/defines.svh +++ b/src/include/defines.svh @@ -12,7 +12,7 @@ // fetch_addr // fetch_tlb_refill // fetch_tlb_invalid -// ri +// ri, cpu // syscall, break, overflow, trap // mem_addr // mem_tlb_refill diff --git a/tools/ctrl_maker.py b/tools/ctrl_maker.py index 588fa16..1c42741 100644 --- a/tools/ctrl_maker.py +++ b/tools/ctrl_maker.py @@ -1,4 +1,4 @@ -with open('trap.txt') as f: +with open('mctrl1.txt') as f: lines = f.readlines() title = lines[0].split() items = [x.split() for x in lines[1:]] diff --git a/tools/mctrl1.txt b/tools/mctrl1.txt index 98e9386..0d1211c 100644 --- a/tools/mctrl1.txt +++ b/tools/mctrl1.txt @@ -84,11 +84,11 @@ 32'b101010?????????????????????????? 0 0 0 0 1 1 ? ULEFT 0 1 CNOP 0 0 ? ? // SWL 32'b101011?????????????????????????? 0 0 0 0 1 1 ? ALIGN 0 0 CNOP 0 0 ? ? // SW 32'b101110?????????????????????????? 0 0 0 0 1 1 ? URIGHT 1 0 CNOP 0 0 ? ? // SWR -32'b101111?????00000???????????????? 0 0 0 0 1 1 ? ALIGN 0 0 IC_I 1 0 0 0 // I-Cache Index Invalid -32'b101111?????01000???????????????? 0 0 0 0 1 1 ? ALIGN 0 0 IC_I 1 0 0 0 // I-Cache Index Store Tag -32'b101111?????10000???????????????? 0 0 0 0 1 1 ? ALIGN 0 0 IC_L 1 0 1 0 // I-Cache Hit Invalid -32'b101111?????00001???????????????? 0 0 0 0 1 1 ? ALIGN 0 0 DC_IB 0 1 0 1 // D-Cache Index Writeback Invalid -32'b101111?????01001???????????????? 0 0 0 0 1 1 ? ALIGN 0 0 DC_IO 0 1 0 0 // D-Cache Index Store Tag -32'b101111?????10001???????????????? 0 0 0 0 1 1 ? ALIGN 0 0 DC_LO 0 1 1 0 // D-Cache Hit Invalid -32'b101111?????10101???????????????? 0 0 0 0 1 1 ? ALIGN 0 0 DC_LB 0 1 1 1 // D-Cache Hit Writeback Invalid +32'b101111?????00000???????????????? 0 0 0 0 0 ? ? ALIGN 0 0 IC_I 1 0 0 0 // I-Cache Index Invalid +32'b101111?????01000???????????????? 0 0 0 0 0 ? ? ALIGN 0 0 IC_I 1 0 0 0 // I-Cache Index Store Tag +32'b101111?????10000???????????????? 0 0 0 0 0 ? ? ALIGN 0 0 IC_L 1 0 1 0 // I-Cache Hit Invalid +32'b101111?????00001???????????????? 0 0 0 0 0 ? ? ALIGN 0 0 DC_IB 0 1 0 1 // D-Cache Index Writeback Invalid +32'b101111?????01001???????????????? 0 0 0 0 0 ? ? ALIGN 0 0 DC_IO 0 1 0 0 // D-Cache Index Store Tag +32'b101111?????10001???????????????? 0 0 0 0 0 ? ? ALIGN 0 0 DC_LO 0 1 1 0 // D-Cache Hit Invalid +32'b101111?????10101???????????????? 0 0 0 0 0 ? ? ALIGN 0 0 DC_LB 0 1 1 1 // D-Cache Hit Writeback Invalid 32'b110011?????????????????????????? 0 0 0 0 0 ? ? ? ? ? CNOP 0 0 ? ? // PREF (NOP) \ No newline at end of file