vertigo_vhdl 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/vertigo +7 -0
- data/lib/vertigo.rb +4 -0
- data/lib/vertigo/ast.rb +87 -0
- data/lib/vertigo/ast_vertigo_rkgen.rb +607 -0
- data/lib/vertigo/code.rb +57 -0
- data/lib/vertigo/compiler.rb +61 -0
- data/lib/vertigo/generic_lexer.rb +61 -0
- data/lib/vertigo/generic_parser.rb +44 -0
- data/lib/vertigo/indent.rb +20 -0
- data/lib/vertigo/lexer.rb +172 -0
- data/lib/vertigo/parser.rb +1458 -0
- data/lib/vertigo/pretty_printer.rb +749 -0
- data/lib/vertigo/runner.rb +115 -0
- data/lib/vertigo/tb_generator.rb +81 -0
- data/lib/vertigo/template.tb.vhd +72 -0
- data/lib/vertigo/token.rb +67 -0
- data/lib/vertigo/version.rb +3 -0
- data/lib/vertigo/vertigo.rkg +354 -0
- data/lib/vertigo/visitor_vertigo_rkgen.rb +447 -0
- data/tests/ghdl_tests/fsm.vhd +98 -0
- data/tests/ghdl_tests/fsm_synth.vhd +248 -0
- data/tests/ghdl_tests/test_fsm.vhd +162 -0
- data/tests/parser_tests/else.vhd +64 -0
- data/tests/parser_tests/test_MUST_fail.vhd +1 -0
- data/tests/parser_tests/test_accelerator.vhd +160 -0
- data/tests/parser_tests/test_accelerator_pp.vhd +144 -0
- data/tests/parser_tests/test_aggregate.vhd +17 -0
- data/tests/parser_tests/test_aggregate_pp.vhd +15 -0
- data/tests/parser_tests/test_archi_1.vhd +45 -0
- data/tests/parser_tests/test_archi_1_pp.vhd +41 -0
- data/tests/parser_tests/test_array_array_00.vhd +25 -0
- data/tests/parser_tests/test_array_array_00_pp.vhd +25 -0
- data/tests/parser_tests/test_array_urange.vhd +25 -0
- data/tests/parser_tests/test_array_urange_pp.vhd +25 -0
- data/tests/parser_tests/test_chu-1.vhd +80 -0
- data/tests/parser_tests/test_chu-1_pp.vhd +104 -0
- data/tests/parser_tests/test_concat.vhd +11 -0
- data/tests/parser_tests/test_concat_pp.vhd +14 -0
- data/tests/parser_tests/test_counter.vhd +35 -0
- data/tests/parser_tests/test_counter_pp.vhd +35 -0
- data/tests/parser_tests/test_de2.vhd +358 -0
- data/tests/parser_tests/test_de2_pp.vhd +274 -0
- data/tests/parser_tests/test_encode.vhd +2679 -0
- data/tests/parser_tests/test_encode_pp.vhd +2549 -0
- data/tests/parser_tests/test_fsm.vhd +162 -0
- data/tests/parser_tests/test_fsm_pp.vhd +125 -0
- data/tests/parser_tests/test_fsm_synth.vhd +248 -0
- data/tests/parser_tests/test_fsm_synth_pp.vhd +197 -0
- data/tests/parser_tests/test_function-01.vhd +33 -0
- data/tests/parser_tests/test_function-01_pp.vhd +18 -0
- data/tests/parser_tests/test_lfsr.vhd +75 -0
- data/tests/parser_tests/test_lfsr_pp.vhd +44 -0
- data/tests/parser_tests/test_microwatt_cache_ram.vhd +1 -0
- data/tests/parser_tests/test_microwatt_cache_ram_pp.vhd +68 -0
- data/tests/parser_tests/test_microwatt_common.vhd +1 -0
- data/tests/parser_tests/test_microwatt_common_pp.vhd +336 -0
- data/tests/parser_tests/test_microwatt_control.vhd +1 -0
- data/tests/parser_tests/test_microwatt_control_pp.vhd +187 -0
- data/tests/parser_tests/test_microwatt_core.vhd +1 -0
- data/tests/parser_tests/test_microwatt_core_debug.vhd +1 -0
- data/tests/parser_tests/test_microwatt_core_debug_pp.vhd +104 -0
- data/tests/parser_tests/test_microwatt_core_pp.vhd +231 -0
- data/tests/parser_tests/test_microwatt_core_tb.vhd +1 -0
- data/tests/parser_tests/test_microwatt_core_tb_pp.vhd +43 -0
- data/tests/parser_tests/test_microwatt_countzero.vhd +1 -0
- data/tests/parser_tests/test_microwatt_countzero_pp.vhd +120 -0
- data/tests/parser_tests/test_microwatt_countzero_tb.vhd +1 -0
- data/tests/parser_tests/test_microwatt_countzero_tb_pp.vhd +70 -0
- data/tests/parser_tests/test_microwatt_cr_file.vhd +1 -0
- data/tests/parser_tests/test_microwatt_cr_file_pp.vhd +74 -0
- data/tests/parser_tests/test_microwatt_cr_hazard.vhd +1 -0
- data/tests/parser_tests/test_microwatt_cr_hazard_pp.vhd +51 -0
- data/tests/parser_tests/test_microwatt_crhelpers.vhd +1 -0
- data/tests/parser_tests/test_microwatt_crhelpers_pp.vhd +48 -0
- data/tests/parser_tests/test_microwatt_dcache.vhd +1 -0
- data/tests/parser_tests/test_microwatt_dcache_pp.vhd +481 -0
- data/tests/parser_tests/test_microwatt_dcache_tb.vhd +1 -0
- data/tests/parser_tests/test_microwatt_dcache_tb_pp.vhd +98 -0
- data/tests/parser_tests/test_microwatt_decode1.vhd +1 -0
- data/tests/parser_tests/test_microwatt_decode1_pp.vhd +138 -0
- data/tests/parser_tests/test_microwatt_decode2.vhd +1 -0
- data/tests/parser_tests/test_microwatt_decode2_pp.vhd +300 -0
- data/tests/parser_tests/test_microwatt_decode_types.vhd +1 -0
- data/tests/parser_tests/test_microwatt_decode_types_pp.vhd +67 -0
- data/tests/parser_tests/test_microwatt_divider.vhd +1 -0
- data/tests/parser_tests/test_microwatt_divider_pp.vhd +132 -0
- data/tests/parser_tests/test_microwatt_divider_tb.vhd +1 -0
- data/tests/parser_tests/test_microwatt_divider_tb_pp.vhd +95 -0
- data/tests/parser_tests/test_microwatt_dmi_dtm_dummy.vhd +1 -0
- data/tests/parser_tests/test_microwatt_dmi_dtm_dummy_pp.vhd +29 -0
- data/tests/parser_tests/test_microwatt_dmi_dtm_tb.vhd +1 -0
- data/tests/parser_tests/test_microwatt_dmi_dtm_tb_pp.vhd +197 -0
- data/tests/parser_tests/test_microwatt_dmi_dtm_xilinx.vhd +1 -0
- data/tests/parser_tests/test_microwatt_dmi_dtm_xilinx_pp.vhd +139 -0
- data/tests/parser_tests/test_microwatt_execute1.vhd +1 -0
- data/tests/parser_tests/test_microwatt_execute1_pp.vhd +689 -0
- data/tests/parser_tests/test_microwatt_fetch1.vhd +1 -0
- data/tests/parser_tests/test_microwatt_fetch1_pp.vhd +88 -0
- data/tests/parser_tests/test_microwatt_fetch2.vhd +1 -0
- data/tests/parser_tests/test_microwatt_fetch2_pp.vhd +79 -0
- data/tests/parser_tests/test_microwatt_glibc_random.vhd +1 -0
- data/tests/parser_tests/test_microwatt_glibc_random_helpers.vhd +1 -0
- data/tests/parser_tests/test_microwatt_glibc_random_helpers_pp.vhd +25 -0
- data/tests/parser_tests/test_microwatt_glibc_random_pp.vhd +41 -0
- data/tests/parser_tests/test_microwatt_gpr_hazard.vhd +1 -0
- data/tests/parser_tests/test_microwatt_gpr_hazard_pp.vhd +68 -0
- data/tests/parser_tests/test_microwatt_helpers.vhd +1 -0
- data/tests/parser_tests/test_microwatt_helpers_pp.vhd +153 -0
- data/tests/parser_tests/test_microwatt_icache.vhd +1 -0
- data/tests/parser_tests/test_microwatt_icache_pp.vhd +337 -0
- data/tests/parser_tests/test_microwatt_icache_tb.vhd +1 -0
- data/tests/parser_tests/test_microwatt_icache_tb_pp.vhd +104 -0
- data/tests/parser_tests/test_microwatt_insn_helpers.vhd +1 -0
- data/tests/parser_tests/test_microwatt_insn_helpers_pp.vhd +208 -0
- data/tests/parser_tests/test_microwatt_loadstore1.vhd +1 -0
- data/tests/parser_tests/test_microwatt_loadstore1_pp.vhd +222 -0
- data/tests/parser_tests/test_microwatt_logical.vhd +1 -0
- data/tests/parser_tests/test_microwatt_logical_pp.vhd +87 -0
- data/tests/parser_tests/test_microwatt_multiply.vhd +1 -0
- data/tests/parser_tests/test_microwatt_multiply_pp.vhd +84 -0
- data/tests/parser_tests/test_microwatt_multiply_tb.vhd +1 -0
- data/tests/parser_tests/test_microwatt_multiply_tb_pp.vhd +75 -0
- data/tests/parser_tests/test_microwatt_plru.vhd +1 -0
- data/tests/parser_tests/test_microwatt_plru_pp.vhd +46 -0
- data/tests/parser_tests/test_microwatt_plru_tb.vhd +1 -0
- data/tests/parser_tests/test_microwatt_plru_tb_pp.vhd +93 -0
- data/tests/parser_tests/test_microwatt_ppc_fx_insns.vhd +1 -0
- data/tests/parser_tests/test_microwatt_ppc_fx_insns_pp.vhd +665 -0
- data/tests/parser_tests/test_microwatt_register_file.vhd +1 -0
- data/tests/parser_tests/test_microwatt_register_file_pp.vhd +86 -0
- data/tests/parser_tests/test_microwatt_rotator.vhd +1 -0
- data/tests/parser_tests/test_microwatt_rotator_pp.vhd +149 -0
- data/tests/parser_tests/test_microwatt_rotator_tb.vhd +1 -0
- data/tests/parser_tests/test_microwatt_rotator_tb_pp.vhd +134 -0
- data/tests/parser_tests/test_microwatt_sim_bram.vhd +1 -0
- data/tests/parser_tests/test_microwatt_sim_bram_helpers.vhd +1 -0
- data/tests/parser_tests/test_microwatt_sim_bram_helpers_pp.vhd +52 -0
- data/tests/parser_tests/test_microwatt_sim_bram_pp.vhd +53 -0
- data/tests/parser_tests/test_microwatt_sim_console.vhd +1 -0
- data/tests/parser_tests/test_microwatt_sim_console_pp.vhd +43 -0
- data/tests/parser_tests/test_microwatt_sim_jtag.vhd +1 -0
- data/tests/parser_tests/test_microwatt_sim_jtag_pp.vhd +64 -0
- data/tests/parser_tests/test_microwatt_sim_jtag_socket.vhd +1 -0
- data/tests/parser_tests/test_microwatt_sim_jtag_socket_pp.vhd +36 -0
- data/tests/parser_tests/test_microwatt_sim_uart.vhd +1 -0
- data/tests/parser_tests/test_microwatt_sim_uart_pp.vhd +90 -0
- data/tests/parser_tests/test_microwatt_soc.vhd +1 -0
- data/tests/parser_tests/test_microwatt_soc_pp.vhd +195 -0
- data/tests/parser_tests/test_microwatt_utils.vhd +1 -0
- data/tests/parser_tests/test_microwatt_utils_pp.vhd +39 -0
- data/tests/parser_tests/test_microwatt_wishbone_arbiter.vhd +1 -0
- data/tests/parser_tests/test_microwatt_wishbone_arbiter_pp.vhd +54 -0
- data/tests/parser_tests/test_microwatt_wishbone_bram_tb.vhd +1 -0
- data/tests/parser_tests/test_microwatt_wishbone_bram_tb_pp.vhd +157 -0
- data/tests/parser_tests/test_microwatt_wishbone_bram_wrapper.vhd +1 -0
- data/tests/parser_tests/test_microwatt_wishbone_bram_wrapper_pp.vhd +62 -0
- data/tests/parser_tests/test_microwatt_wishbone_debug_master.vhd +1 -0
- data/tests/parser_tests/test_microwatt_wishbone_debug_master_pp.vhd +124 -0
- data/tests/parser_tests/test_microwatt_wishbone_types.vhd +1 -0
- data/tests/parser_tests/test_microwatt_wishbone_types_pp.vhd +38 -0
- data/tests/parser_tests/test_microwatt_writeback.vhd +1 -0
- data/tests/parser_tests/test_microwatt_writeback_pp.vhd +87 -0
- data/tests/parser_tests/test_package-1.vhd +68 -0
- data/tests/parser_tests/test_package-1_pp.vhd +53 -0
- data/tests/parser_tests/test_precedence.vhd +13 -0
- data/tests/parser_tests/test_precedence_pp.vhd +16 -0
- data/tests/parser_tests/test_selected_sig.vhd +14 -0
- data/tests/parser_tests/test_selected_sig_pp.vhd +10 -0
- data/tests/parser_tests/test_slice.vhd +15 -0
- data/tests/parser_tests/test_slice_pp.vhd +16 -0
- data/tests/parser_tests/test_tb-00.vhd +94 -0
- data/tests/parser_tests/test_tb-00_pp.vhd +71 -0
- data/tests/parser_tests/test_type_decl_02.vhd +9 -0
- data/tests/parser_tests/test_type_decl_02_pp.vhd +11 -0
- data/tests/parser_tests/test_use.vhd +7 -0
- data/tests/parser_tests/test_use_pp.vhd +10 -0
- data/tests/parser_tests/test_while_1.vhd +38 -0
- data/tests/parser_tests/test_while_1_pp.vhd +26 -0
- data/tests/parser_tests/test_with-00.vhd +21 -0
- data/tests/parser_tests/test_with-00_pp.vhd +12 -0
- data/tests/tb_gen_tests/test_accelerator.vhd +160 -0
- metadata +224 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
../microwatt/countzero_tb.vhdl
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
-- generated by Vertigo VHDL tool
|
|
2
|
+
library ieee;
|
|
3
|
+
use ieee.std_logic_1164.all;
|
|
4
|
+
use ieee.numeric_std.all;
|
|
5
|
+
library work;
|
|
6
|
+
use work.common.all;
|
|
7
|
+
use work.glibc_random.all;
|
|
8
|
+
|
|
9
|
+
entity countzero_tb is
|
|
10
|
+
end entity countzero_tb;
|
|
11
|
+
|
|
12
|
+
architecture behave of countzero_tb is
|
|
13
|
+
constant clk_period : time := 10 ns;
|
|
14
|
+
signal rs : std_ulogic_vector(63 downto 0);
|
|
15
|
+
signal is_32bit : std_ulogic;
|
|
16
|
+
signal count_right : std_ulogic := '0';
|
|
17
|
+
signal result : std_ulogic_vector(63 downto 0);
|
|
18
|
+
signal randno : std_ulogic_vector(63 downto 0);
|
|
19
|
+
signal clk : std_ulogic;
|
|
20
|
+
begin
|
|
21
|
+
|
|
22
|
+
zerocounter_0 : entity work.zero_counter
|
|
23
|
+
port map(
|
|
24
|
+
clk => clk,
|
|
25
|
+
rs => rs,
|
|
26
|
+
result => result,
|
|
27
|
+
count_right => count_right,
|
|
28
|
+
is_32bit => is_32bit);
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
clk_process : process
|
|
32
|
+
begin
|
|
33
|
+
clk <= '0';
|
|
34
|
+
wait clk_period / 2;
|
|
35
|
+
clk <= '1';
|
|
36
|
+
wait clk_period / 2;
|
|
37
|
+
end process;
|
|
38
|
+
|
|
39
|
+
stim_process : process
|
|
40
|
+
variable r : std_ulogic_vector(63 downto 0);
|
|
41
|
+
begin
|
|
42
|
+
report "test zero input";
|
|
43
|
+
rs <= (others => '0');
|
|
44
|
+
is_32bit <= '0';
|
|
45
|
+
count_right <= '0';
|
|
46
|
+
wait clk_period;
|
|
47
|
+
assert result = x"0000000000000040"
|
|
48
|
+
report "bad cntlzd 0 = " & to_hstring(result);
|
|
49
|
+
count_right <= '1';
|
|
50
|
+
wait clk_period;
|
|
51
|
+
assert result = x"0000000000000040"
|
|
52
|
+
report "bad cnttzd 0 = " & to_hstring(result);
|
|
53
|
+
is_32bit <= '1';
|
|
54
|
+
count_right <= '0';
|
|
55
|
+
wait clk_period;
|
|
56
|
+
assert result = x"0000000000000020"
|
|
57
|
+
report "bad cntlzw 0 = " & to_hstring(result);
|
|
58
|
+
count_right <= '1';
|
|
59
|
+
wait clk_period;
|
|
60
|
+
assert result = x"0000000000000020"
|
|
61
|
+
report "bad cnttzw 0 = " & to_hstring(result);
|
|
62
|
+
report "test cntlzd/w";
|
|
63
|
+
count_right <= '0';
|
|
64
|
+
report "test cnttzd/w";
|
|
65
|
+
count_right <= '1';
|
|
66
|
+
assert false
|
|
67
|
+
report "end of test" severity failure;
|
|
68
|
+
wait ;
|
|
69
|
+
end process;
|
|
70
|
+
end behave;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
../microwatt/cr_file.vhdl
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
-- generated by Vertigo VHDL tool
|
|
2
|
+
library ieee;
|
|
3
|
+
use ieee.std_logic_1164.all;
|
|
4
|
+
use ieee.numeric_std.all;
|
|
5
|
+
library work;
|
|
6
|
+
use work.common.all;
|
|
7
|
+
|
|
8
|
+
entity cr_file is
|
|
9
|
+
generic(
|
|
10
|
+
sim : booleanfalse := false);
|
|
11
|
+
port(
|
|
12
|
+
clk : in std_logic;
|
|
13
|
+
d_in : in decode2tocrfiletype;
|
|
14
|
+
d_out : out crfiletodecode2type;
|
|
15
|
+
w_in : in writebacktocrfiletype;
|
|
16
|
+
sim_dump : in std_ulogic);
|
|
17
|
+
end entity cr_file;
|
|
18
|
+
|
|
19
|
+
architecture behaviour of cr_file is
|
|
20
|
+
signal crs : std_ulogic_vector(31 downto 0) := (others => '0');
|
|
21
|
+
signal crs_updated : std_ulogic_vector(31 downto 0);
|
|
22
|
+
signal xerc : xer_common_t := xerc_init;
|
|
23
|
+
signal xerc_updated : xer_common_t;
|
|
24
|
+
begin
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
cr_create_0 : process(all)
|
|
28
|
+
variable hi : integer;
|
|
29
|
+
variable lo : integer := 0;
|
|
30
|
+
variable cr_tmp : std_ulogic_vector(31 downto 0) := (others => '0');
|
|
31
|
+
begin
|
|
32
|
+
cr_tmp := crs;
|
|
33
|
+
crs_updated <= cr_tmp;
|
|
34
|
+
if w_in.write_xerc_enable = '1' then
|
|
35
|
+
xerc_updated <= w_in.write_xerc_data;
|
|
36
|
+
else
|
|
37
|
+
xerc_updated <= xerc;
|
|
38
|
+
end if;
|
|
39
|
+
end process;
|
|
40
|
+
|
|
41
|
+
cr_write_0 : process(clk)
|
|
42
|
+
begin
|
|
43
|
+
if rising_edge(clk) then
|
|
44
|
+
if w_in.write_cr_enable = '1' then
|
|
45
|
+
report "writing " & to_hstring(w_in.write_cr_data) & " to cr mask " & to_hstring(w_in.write_cr_mask);
|
|
46
|
+
crs <= crs_updated;
|
|
47
|
+
end if;
|
|
48
|
+
if w_in.write_xerc_enable = '1' then
|
|
49
|
+
report "writing xerc";
|
|
50
|
+
xerc <= xerc_updated;
|
|
51
|
+
end if;
|
|
52
|
+
end if;
|
|
53
|
+
end process;
|
|
54
|
+
|
|
55
|
+
cr_read_0 : process(all)
|
|
56
|
+
begin
|
|
57
|
+
if d_in.read = '1' then
|
|
58
|
+
report "reading cr " & to_hstring(crs_updated);
|
|
59
|
+
end if;
|
|
60
|
+
d_out.read_cr_data <= crs_updated;
|
|
61
|
+
d_out.read_xerc_data <= xerc_updated;
|
|
62
|
+
end process;
|
|
63
|
+
if sim generate
|
|
64
|
+
|
|
65
|
+
dump_cr : process(all)
|
|
66
|
+
begin
|
|
67
|
+
if sim_dump = '1' then
|
|
68
|
+
report "cr 00000000" & to_hstring(crs);
|
|
69
|
+
assert false
|
|
70
|
+
report "end of test" severity failure;
|
|
71
|
+
end if;
|
|
72
|
+
end process;
|
|
73
|
+
end generate;
|
|
74
|
+
end behaviour;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
../microwatt/cr_hazard.vhdl
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
-- generated by Vertigo VHDL tool
|
|
2
|
+
library ieee;
|
|
3
|
+
use ieee.std_logic_1164.all;
|
|
4
|
+
use ieee.numeric_std.all;
|
|
5
|
+
|
|
6
|
+
entity cr_hazard is
|
|
7
|
+
generic(
|
|
8
|
+
pipeline_depth : natural2 := 2);
|
|
9
|
+
port(
|
|
10
|
+
clk : in std_ulogic;
|
|
11
|
+
stall_in : in std_ulogic;
|
|
12
|
+
cr_read_in : in std_ulogic;
|
|
13
|
+
cr_write_in : in std_ulogic;
|
|
14
|
+
stall_out : out std_ulogic);
|
|
15
|
+
end entity cr_hazard;
|
|
16
|
+
|
|
17
|
+
architecture behaviour of cr_hazard is
|
|
18
|
+
|
|
19
|
+
type pipeline_entry_type is record
|
|
20
|
+
valid : std_ulogic;
|
|
21
|
+
end record;
|
|
22
|
+
constant pipeline_entry_init : pipeline_entry_type := (valid => '0');
|
|
23
|
+
|
|
24
|
+
type pipeline_t is array(range 0 to pipeline_depth - 1) of pipeline_entry_type;
|
|
25
|
+
constant pipeline_t_init : pipeline_t := (others => pipeline_entry_init);
|
|
26
|
+
signal r : pipeline_t;
|
|
27
|
+
signal rin : pipeline_t := pipeline_t_init;
|
|
28
|
+
begin
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
cr_hazard0 : process(clk)
|
|
32
|
+
begin
|
|
33
|
+
if rising_edge(clk) then
|
|
34
|
+
if stall_in = '0' then
|
|
35
|
+
r <= rin;
|
|
36
|
+
end if;
|
|
37
|
+
end if;
|
|
38
|
+
end process;
|
|
39
|
+
|
|
40
|
+
cr_hazard1 : process(all)
|
|
41
|
+
variable v : pipeline_t;
|
|
42
|
+
begin
|
|
43
|
+
v := r;
|
|
44
|
+
stall_out <= '0';
|
|
45
|
+
v(0).valid := cr_write_in;
|
|
46
|
+
if cr_read_in = '0' then
|
|
47
|
+
stall_out <= '0';
|
|
48
|
+
end if;
|
|
49
|
+
rin <= v;
|
|
50
|
+
end process;
|
|
51
|
+
end behaviour;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
../microwatt/crhelpers.vhdl
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
-- generated by Vertigo VHDL tool
|
|
2
|
+
library ieee;
|
|
3
|
+
use ieee.std_logic_1164.all;
|
|
4
|
+
library work;
|
|
5
|
+
use work.common.all;
|
|
6
|
+
|
|
7
|
+
package crhelpers is
|
|
8
|
+
|
|
9
|
+
subtype crnum_t is integer range 0 to 7;
|
|
10
|
+
|
|
11
|
+
subtype crmask_t is std_ulogic_vector(7 downto 0);
|
|
12
|
+
function fxm_to_num(fxm : crmask_t) return crnum_t
|
|
13
|
+
function num_to_fxm(num : crnum_t) return crmask_t
|
|
14
|
+
|
|
15
|
+
end crhelpers;
|
|
16
|
+
|
|
17
|
+
package body crhelpers is
|
|
18
|
+
|
|
19
|
+
function fxm_to_num(fxm : crmask_t) return crnum_t is
|
|
20
|
+
begin
|
|
21
|
+
;
|
|
22
|
+
return 7;
|
|
23
|
+
end function fxm_to_num;
|
|
24
|
+
|
|
25
|
+
function num_to_fxm(num : crnum_t) return crmask_t is
|
|
26
|
+
begin
|
|
27
|
+
case num is
|
|
28
|
+
when 0 =>
|
|
29
|
+
return "10000000";
|
|
30
|
+
when 1 =>
|
|
31
|
+
return "01000000";
|
|
32
|
+
when 2 =>
|
|
33
|
+
return "00100000";
|
|
34
|
+
when 3 =>
|
|
35
|
+
return "00010000";
|
|
36
|
+
when 4 =>
|
|
37
|
+
return "00001000";
|
|
38
|
+
when 5 =>
|
|
39
|
+
return "00000100";
|
|
40
|
+
when 6 =>
|
|
41
|
+
return "00000010";
|
|
42
|
+
when 7 =>
|
|
43
|
+
return "00000001";
|
|
44
|
+
when others =>
|
|
45
|
+
return "00000000";
|
|
46
|
+
end case;
|
|
47
|
+
end function num_to_fxm;
|
|
48
|
+
end crhelpers;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
../microwatt/dcache.vhdl
|
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
-- generated by Vertigo VHDL tool
|
|
2
|
+
library ieee;
|
|
3
|
+
use ieee.std_logic_1164.all;
|
|
4
|
+
use ieee.numeric_std.all;
|
|
5
|
+
library work;
|
|
6
|
+
use work.utils.all;
|
|
7
|
+
use work.common.all;
|
|
8
|
+
use work.helpers.all;
|
|
9
|
+
use work.wishbone_types.all;
|
|
10
|
+
|
|
11
|
+
entity dcache is
|
|
12
|
+
generic(
|
|
13
|
+
line_size : positive64 := 64;
|
|
14
|
+
num_lines : positive32 := 32;
|
|
15
|
+
num_ways : positive4 := 4);
|
|
16
|
+
port(
|
|
17
|
+
clk : in std_ulogic;
|
|
18
|
+
rst : in std_ulogic;
|
|
19
|
+
d_in : in loadstore1todcachetype;
|
|
20
|
+
d_out : out dcachetoloadstore1type;
|
|
21
|
+
stall_out : out std_ulogic;
|
|
22
|
+
wishbone_out : out wishbone_master_out;
|
|
23
|
+
wishbone_in : in wishbone_slave_out);
|
|
24
|
+
end entity dcache;
|
|
25
|
+
|
|
26
|
+
architecture rtl of dcache is
|
|
27
|
+
constant row_size : natural := wishbone_data_bits / 8;
|
|
28
|
+
constant row_per_line : natural := line_size / row_size;
|
|
29
|
+
constant bram_rows : natural := num_lines * row_per_line;
|
|
30
|
+
constant row_bits : natural := log2(bram_rows);
|
|
31
|
+
constant row_linebits : natural := log2(row_per_line);
|
|
32
|
+
constant line_off_bits : natural := log2(line_size);
|
|
33
|
+
constant row_off_bits : natural := log2(row_size);
|
|
34
|
+
constant index_bits : natural := log2(num_lines);
|
|
35
|
+
constant tag_bits : natural := 64 - line_off_bits - index_bits;
|
|
36
|
+
constant way_bits : natural := log2(num_ways);
|
|
37
|
+
|
|
38
|
+
subtype row_t is integer range 0 to bram_rows - 1;
|
|
39
|
+
|
|
40
|
+
subtype index_t is integer range 0 to num_lines - 1;
|
|
41
|
+
|
|
42
|
+
subtype way_t is integer range 0 to num_ways - 1;
|
|
43
|
+
|
|
44
|
+
subtype cache_row_t is std_ulogic_vector(wishbone_data_bits - 1 downto 0);
|
|
45
|
+
|
|
46
|
+
subtype cache_tag_t is std_logic_vector(tag_bits - 1 downto 0);
|
|
47
|
+
constant tag_ram_width : natural := tag_bits * num_ways;
|
|
48
|
+
|
|
49
|
+
subtype cache_tags_set_t is std_logic_vector(tag_ram_width - 1 downto 0);
|
|
50
|
+
|
|
51
|
+
type cache_tags_array_t is array(range index_t) of cache_tags_set_t;
|
|
52
|
+
|
|
53
|
+
subtype cache_way_valids_t is std_ulogic_vector(num_ways - 1 downto 0);
|
|
54
|
+
|
|
55
|
+
type cache_valids_t is array(range index_t) of cache_way_valids_t;
|
|
56
|
+
signal cache_tags : cache_tags_array_t;
|
|
57
|
+
signal cache_valids : cache_valids_t;
|
|
58
|
+
attribute ram_style : string;
|
|
59
|
+
attribute ram_style of cache_tags : signal is "distributed";
|
|
60
|
+
signal r0 : loadstore1todcachetype;
|
|
61
|
+
|
|
62
|
+
type op_t is (op_none,op_load_hit,op_load_miss,op_load_nc,op_bad,op_store_hit,op_store_miss);
|
|
63
|
+
|
|
64
|
+
type state_t is (idle,reload_wait_ack,finish_ld_miss,store_wait_ack,nc_load_wait_ack);
|
|
65
|
+
|
|
66
|
+
type reg_stage_1_t is record
|
|
67
|
+
req : loadstore1todcachetype;
|
|
68
|
+
hit_way : way_t;
|
|
69
|
+
hit_load_valid : std_ulogic;
|
|
70
|
+
slow_data : std_ulogic_vector(63 downto 0);
|
|
71
|
+
slow_valid : std_ulogic;
|
|
72
|
+
stcx_fail : std_ulogic;
|
|
73
|
+
state : state_t;
|
|
74
|
+
wb : wishbone_master_out;
|
|
75
|
+
store_way : way_t;
|
|
76
|
+
store_row : row_t;
|
|
77
|
+
store_index : index_t;
|
|
78
|
+
end record;
|
|
79
|
+
signal r1 : reg_stage_1_t;
|
|
80
|
+
|
|
81
|
+
type reservation_t is record
|
|
82
|
+
valid : std_ulogic;
|
|
83
|
+
addr : std_ulogic_vector(63 downto line_off_bits);
|
|
84
|
+
end record;
|
|
85
|
+
signal reservation : reservation_t;
|
|
86
|
+
signal req_index : index_t;
|
|
87
|
+
signal req_row : row_t;
|
|
88
|
+
signal req_hit_way : way_t;
|
|
89
|
+
signal req_tag : cache_tag_t;
|
|
90
|
+
signal req_op : op_t;
|
|
91
|
+
signal req_data : std_ulogic_vector(63 downto 0);
|
|
92
|
+
signal req_laddr : std_ulogic_vector(63 downto 0);
|
|
93
|
+
signal early_req_row : row_t;
|
|
94
|
+
signal cancel_store : std_ulogic;
|
|
95
|
+
signal set_rsrv : std_ulogic;
|
|
96
|
+
signal clear_rsrv : std_ulogic;
|
|
97
|
+
|
|
98
|
+
type cache_ram_out_t is array(range way_t) of cache_row_t;
|
|
99
|
+
signal cache_out : cache_ram_out_t;
|
|
100
|
+
|
|
101
|
+
type plru_out_t is array(range index_t) of std_ulogic_vector(way_bits - 1 downto 0);
|
|
102
|
+
signal plru_victim : plru_out_t;
|
|
103
|
+
signal replace_way : way_t;
|
|
104
|
+
signal bus_sel : std_ulogic_vector(7 downto 0);
|
|
105
|
+
|
|
106
|
+
function get_index(addr : std_ulogic_vector(63 downto 0)) return index_t is
|
|
107
|
+
begin
|
|
108
|
+
return to_integer(unsigned(addr(63 - tag_bits downto line_off_bits)));
|
|
109
|
+
end function get_index;
|
|
110
|
+
|
|
111
|
+
function get_row(addr : std_ulogic_vector(63 downto 0)) return row_t is
|
|
112
|
+
begin
|
|
113
|
+
return to_integer(unsigned(addr(63 - tag_bits downto row_off_bits)));
|
|
114
|
+
end function get_row;
|
|
115
|
+
|
|
116
|
+
function is_last_row_addr(addr : wishbone_addr_type) return boolean is
|
|
117
|
+
constant ones : std_ulogic_vector(row_linebits - 1 downto 0) := (others => '1');
|
|
118
|
+
begin
|
|
119
|
+
return addr(line_off_bits - 1 downto row_off_bits) = ones;
|
|
120
|
+
end function is_last_row_addr;
|
|
121
|
+
|
|
122
|
+
function is_last_row(row : row_t) return boolean is
|
|
123
|
+
variable row_v : std_ulogic_vector(row_bits - 1 downto 0);
|
|
124
|
+
constant ones : std_ulogic_vector(row_linebits - 1 downto 0) := (others => '1');
|
|
125
|
+
begin
|
|
126
|
+
row_v := std_ulogic_vector(to_unsigned(row,row_bits));
|
|
127
|
+
return row_v(row_linebits - 1 downto 0) = ones;
|
|
128
|
+
end function is_last_row;
|
|
129
|
+
|
|
130
|
+
function next_row_addr(addr : wishbone_addr_type) return std_ulogic_vector is
|
|
131
|
+
variable row_idx : std_ulogic_vector(row_linebits - 1 downto 0);
|
|
132
|
+
variable result : wishbone_addr_type;
|
|
133
|
+
begin
|
|
134
|
+
row_idx := addr(line_off_bits - 1 downto row_off_bits);
|
|
135
|
+
row_idx := std_ulogic_vector(unsigned(row_idx) + 1);
|
|
136
|
+
result := addr;
|
|
137
|
+
result(line_off_bits - 1 downto row_off_bits) := row_idx;
|
|
138
|
+
return result;
|
|
139
|
+
end function next_row_addr;
|
|
140
|
+
|
|
141
|
+
function next_row(row : row_t) return row_t is
|
|
142
|
+
variable row_v : std_ulogic_vector(row_bits - 1 downto 0);
|
|
143
|
+
variable row_idx : std_ulogic_vector(row_linebits - 1 downto 0);
|
|
144
|
+
variable result : std_ulogic_vector(row_bits - 1 downto 0);
|
|
145
|
+
begin
|
|
146
|
+
row_v := std_ulogic_vector(to_unsigned(row,row_bits));
|
|
147
|
+
row_idx := row_v(row_linebits - 1 downto 0);
|
|
148
|
+
row_v(row_linebits - 1 downto 0) := std_ulogic_vector(unsigned(row_idx) + 1);
|
|
149
|
+
return to_integer(unsigned(row_v));
|
|
150
|
+
end function next_row;
|
|
151
|
+
|
|
152
|
+
function get_tag(addr : std_ulogic_vector(63 downto 0)) return cache_tag_t is
|
|
153
|
+
begin
|
|
154
|
+
return addr(63 downto 64 - tag_bits);
|
|
155
|
+
end function get_tag;
|
|
156
|
+
|
|
157
|
+
function read_tag(way : way_t;tagset : cache_tags_set_t) return cache_tag_t is
|
|
158
|
+
begin
|
|
159
|
+
return tagset((way + 1) * tag_bits - 1 downto way * tag_bits);
|
|
160
|
+
end function read_tag;
|
|
161
|
+
|
|
162
|
+
procedure write_tag(
|
|
163
|
+
way : in way_t;
|
|
164
|
+
tagset : inout cache_tags_set_t;
|
|
165
|
+
tag : cache_tag_t) is
|
|
166
|
+
begin
|
|
167
|
+
tagset((way + 1) * tag_bits - 1 downto way * tag_bits) := tag;
|
|
168
|
+
end write_tag;
|
|
169
|
+
begin
|
|
170
|
+
|
|
171
|
+
assert line_size mod row_size = 0
|
|
172
|
+
report "line_size not multiple of row_size" severity failure;
|
|
173
|
+
assert ispow2(line_size)
|
|
174
|
+
report "line_size not power of 2" severity failure;
|
|
175
|
+
assert ispow2(num_lines)
|
|
176
|
+
report "num_lines not power of 2" severity failure;
|
|
177
|
+
assert ispow2(row_per_line)
|
|
178
|
+
report "row_per_line not power of 2" severity failure;
|
|
179
|
+
assert (row_bits = index_bits + row_linebits)
|
|
180
|
+
report "geometry bits don't add up" severity failure;
|
|
181
|
+
assert (line_off_bits = row_off_bits + row_linebits)
|
|
182
|
+
report "geometry bits don't add up" severity failure;
|
|
183
|
+
assert (64 = tag_bits + index_bits + line_off_bits)
|
|
184
|
+
report "geometry bits don't add up" severity failure;
|
|
185
|
+
assert (64 = tag_bits + row_bits + row_off_bits)
|
|
186
|
+
report "geometry bits don't add up" severity failure;
|
|
187
|
+
assert (64 = wishbone_data_bits)
|
|
188
|
+
report "can't yet handle a wishbone width that isn't 64-bits" severity failure;
|
|
189
|
+
if num_ways > 1 generate
|
|
190
|
+
for i in 0 to num_lines - 1 generate
|
|
191
|
+
plru : entity work.plru
|
|
192
|
+
port map(
|
|
193
|
+
clk => clk,
|
|
194
|
+
rst => rst,
|
|
195
|
+
acc => plru_acc,
|
|
196
|
+
acc_en => plru_acc_en,
|
|
197
|
+
lru => plru_out);
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
process(req_index,req_op,req_hit_way,plru_out)
|
|
201
|
+
begin
|
|
202
|
+
if (req_op = op_load_hit or req_op = op_store_hit) and req_index = i then
|
|
203
|
+
plru_acc_en <= '1';
|
|
204
|
+
else
|
|
205
|
+
plru_acc_en <= '0';
|
|
206
|
+
end if;
|
|
207
|
+
plru_acc <= std_ulogic_vector(to_unsigned(req_hit_way,way_bits));
|
|
208
|
+
plru_victim(i) <= plru_out;
|
|
209
|
+
end process;
|
|
210
|
+
end generate;
|
|
211
|
+
end generate;
|
|
212
|
+
|
|
213
|
+
stage_0 : process(clk)
|
|
214
|
+
begin
|
|
215
|
+
if rising_edge(clk) then
|
|
216
|
+
if rst = '1' then
|
|
217
|
+
r0.valid <= '0';
|
|
218
|
+
elsif stall_out = '0' then
|
|
219
|
+
r0 <= d_in;
|
|
220
|
+
end if;
|
|
221
|
+
end if;
|
|
222
|
+
end process;
|
|
223
|
+
|
|
224
|
+
dcache_request : process(all)
|
|
225
|
+
variable is_hit : std_ulogic;
|
|
226
|
+
variable hit_way : way_t;
|
|
227
|
+
variable op : op_t;
|
|
228
|
+
variable tmp : std_ulogic_vector(63 downto 0);
|
|
229
|
+
variable data : std_ulogic_vector(63 downto 0);
|
|
230
|
+
variable opsel : std_ulogic_vector(3 downto 0);
|
|
231
|
+
variable go : std_ulogic;
|
|
232
|
+
begin
|
|
233
|
+
req_index <= get_index(r0.addr);
|
|
234
|
+
req_row <= get_row(r0.addr);
|
|
235
|
+
req_tag <= get_tag(r0.addr);
|
|
236
|
+
go := r0.valid and stall_out;
|
|
237
|
+
req_laddr <= r0.addr(63 downto line_off_bits) & (line_off_bits - 1 downto 0 => '0');
|
|
238
|
+
hit_way := 0;
|
|
239
|
+
is_hit := '0';
|
|
240
|
+
req_hit_way <= hit_way;
|
|
241
|
+
replace_way <= to_integer(unsigned(plru_victim(req_index)));
|
|
242
|
+
opsel := go & r0.load & r0.nc & is_hit;
|
|
243
|
+
case opsel is
|
|
244
|
+
when "1101" =>
|
|
245
|
+
op := op_load_hit;
|
|
246
|
+
when "1100" =>
|
|
247
|
+
op := op_load_miss;
|
|
248
|
+
when "1110" =>
|
|
249
|
+
op := op_load_nc;
|
|
250
|
+
when "1001" =>
|
|
251
|
+
op := op_store_hit;
|
|
252
|
+
when "1000" =>
|
|
253
|
+
op := op_store_miss;
|
|
254
|
+
when "1010" =>
|
|
255
|
+
op := op_store_miss;
|
|
256
|
+
when "1011" =>
|
|
257
|
+
op := op_bad;
|
|
258
|
+
when "1111" =>
|
|
259
|
+
op := op_bad;
|
|
260
|
+
when others =>
|
|
261
|
+
op := op_none;
|
|
262
|
+
end case;
|
|
263
|
+
req_op <= op;
|
|
264
|
+
if stall_out = '0' then
|
|
265
|
+
early_req_row <= get_row(d_in.addr);
|
|
266
|
+
else
|
|
267
|
+
early_req_row <= req_row;
|
|
268
|
+
end if;
|
|
269
|
+
end process;
|
|
270
|
+
wishbone_out <= r1.wb;
|
|
271
|
+
stall_out <= '1' when r1.state /= idle else '0';
|
|
272
|
+
|
|
273
|
+
reservation_comb : process(all)
|
|
274
|
+
begin
|
|
275
|
+
cancel_store <= '0';
|
|
276
|
+
set_rsrv <= '0';
|
|
277
|
+
clear_rsrv <= '0';
|
|
278
|
+
if stall_out = '0' and r0.valid = '1' and r0.reserve = '1' then
|
|
279
|
+
if r0.load = '1' then
|
|
280
|
+
set_rsrv <= '1';
|
|
281
|
+
else
|
|
282
|
+
clear_rsrv <= '1';
|
|
283
|
+
if reservation.valid = '0' or r0.addr(63 downto line_off_bits) /= reservation.addr then
|
|
284
|
+
cancel_store <= '1';
|
|
285
|
+
end if;
|
|
286
|
+
end if;
|
|
287
|
+
end if;
|
|
288
|
+
end process;
|
|
289
|
+
|
|
290
|
+
reservation_reg : process(clk)
|
|
291
|
+
begin
|
|
292
|
+
if rising_edge(clk) then
|
|
293
|
+
if rst = '1' or clear_rsrv = '1' then
|
|
294
|
+
reservation.valid <= '0';
|
|
295
|
+
elsif set_rsrv = '1' then
|
|
296
|
+
reservation.valid <= '1';
|
|
297
|
+
reservation.addr <= r0.addr(63 downto line_off_bits);
|
|
298
|
+
end if;
|
|
299
|
+
end if;
|
|
300
|
+
end process;
|
|
301
|
+
|
|
302
|
+
writeback_control : process(all)
|
|
303
|
+
begin
|
|
304
|
+
d_out.valid <= '0';
|
|
305
|
+
d_out.data <= cache_out(r1.hit_way);
|
|
306
|
+
d_out.store_done <= '0';
|
|
307
|
+
assert (r1.slow_valid and r1.stcx_fail) /= '1'
|
|
308
|
+
report "unexpected slow_valid collision with stcx_fail" severity failure;
|
|
309
|
+
assert ((r1.slow_valid or r1.stcx_fail) and r1.hit_load_valid) /= '1'
|
|
310
|
+
report "unexpected hit_load_delayed collision with slow_valid" severity failure;
|
|
311
|
+
if r1.hit_load_valid = '1' then
|
|
312
|
+
report "completing load hit";
|
|
313
|
+
d_out.valid <= '1';
|
|
314
|
+
end if;
|
|
315
|
+
if r1.slow_valid = '1' then
|
|
316
|
+
if r1.req.load then
|
|
317
|
+
d_out.data <= r1.slow_data;
|
|
318
|
+
end if;
|
|
319
|
+
d_out.store_done <= '1';
|
|
320
|
+
report "completing store or load miss";
|
|
321
|
+
d_out.valid <= '1';
|
|
322
|
+
end if;
|
|
323
|
+
if r1.stcx_fail = '1' then
|
|
324
|
+
d_out.store_done <= '0';
|
|
325
|
+
d_out.valid <= '1';
|
|
326
|
+
end if;
|
|
327
|
+
end process;
|
|
328
|
+
for i in 0 to num_ways - 1 generate
|
|
329
|
+
way : entity work.cache_ram
|
|
330
|
+
port map(
|
|
331
|
+
clk => clk,
|
|
332
|
+
rd_en => do_read,
|
|
333
|
+
rd_addr => rd_addr,
|
|
334
|
+
rd_data => dout,
|
|
335
|
+
wr_en => do_write,
|
|
336
|
+
wr_sel => wr_sel,
|
|
337
|
+
wr_addr => wr_addr,
|
|
338
|
+
wr_data => wr_data);
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
process(all)
|
|
342
|
+
variable tmp_adr : std_ulogic_vector(63 downto 0);
|
|
343
|
+
variable reloading : boolean;
|
|
344
|
+
begin
|
|
345
|
+
do_read <= '1';
|
|
346
|
+
rd_addr <= std_ulogic_vector(to_unsigned(early_req_row,row_bits));
|
|
347
|
+
cache_out(i) <= dout;
|
|
348
|
+
if r1.state = idle then
|
|
349
|
+
wr_addr <= std_ulogic_vector(to_unsigned(req_row,row_bits));
|
|
350
|
+
wr_data <= r0.data;
|
|
351
|
+
wr_sel <= r0.byte_sel;
|
|
352
|
+
else
|
|
353
|
+
wr_data <= wishbone_in.dat;
|
|
354
|
+
wr_sel <= (others => '1');
|
|
355
|
+
wr_addr <= std_ulogic_vector(to_unsigned(r1.store_row,row_bits));
|
|
356
|
+
end if;
|
|
357
|
+
do_write <= '0';
|
|
358
|
+
reloading := r1.state = reload_wait_ack;
|
|
359
|
+
if reloading and wishbone_in.ack = '1' and r1.store_way = i then
|
|
360
|
+
do_write <= '1';
|
|
361
|
+
end if;
|
|
362
|
+
if req_op = op_store_hit and req_hit_way = i and cancel_store = '0' then
|
|
363
|
+
assert reloading
|
|
364
|
+
report "store hit while in state:" & state_t'image(r1.state) severity failure;
|
|
365
|
+
do_write <= '1';
|
|
366
|
+
end if;
|
|
367
|
+
end process;
|
|
368
|
+
end generate;
|
|
369
|
+
|
|
370
|
+
dcache_fast_hit : process(clk)
|
|
371
|
+
begin
|
|
372
|
+
if rising_edge(clk) then
|
|
373
|
+
if req_op /= op_none and stall_out = '0' then
|
|
374
|
+
r1.req <= r0;
|
|
375
|
+
report "op:" & op_t'image(req_op) & " addr:" & to_hstring(r0.addr) & " nc:" & std_ulogic'image(r0.nc) & " idx:" & integer'image(req_index) & " tag:" & to_hstring(req_tag) & " way: " & integer'image(req_hit_way);
|
|
376
|
+
end if;
|
|
377
|
+
if req_op = op_load_hit then
|
|
378
|
+
r1.hit_way <= req_hit_way;
|
|
379
|
+
r1.hit_load_valid <= '1';
|
|
380
|
+
else
|
|
381
|
+
r1.hit_load_valid <= '0';
|
|
382
|
+
end if;
|
|
383
|
+
end if;
|
|
384
|
+
end process;
|
|
385
|
+
|
|
386
|
+
dcache_slow : process(clk)
|
|
387
|
+
variable tagset : cache_tags_set_t;
|
|
388
|
+
variable stbs_done : boolean;
|
|
389
|
+
begin
|
|
390
|
+
if rising_edge(clk) then
|
|
391
|
+
if rst = '1' then
|
|
392
|
+
;
|
|
393
|
+
r1.state <= idle;
|
|
394
|
+
r1.slow_valid <= '0';
|
|
395
|
+
r1.wb.cyc <= '0';
|
|
396
|
+
r1.wb.stb <= '0';
|
|
397
|
+
r1.wb.adr <= (others => '0');
|
|
398
|
+
else
|
|
399
|
+
r1.slow_valid <= '0';
|
|
400
|
+
r1.stcx_fail <= '0';
|
|
401
|
+
case r1.state is
|
|
402
|
+
when idle =>
|
|
403
|
+
case req_op is
|
|
404
|
+
when op_load_hit =>
|
|
405
|
+
when op_load_miss =>
|
|
406
|
+
report "cache miss addr:" & to_hstring(r0.addr) & " idx:" & integer'image(req_index) & " way:" & integer'image(replace_way) & " tag:" & to_hstring(req_tag);
|
|
407
|
+
cache_valids(req_index)(replace_way) <= '0';
|
|
408
|
+
r1.store_index <= req_index;
|
|
409
|
+
r1.store_way <= replace_way;
|
|
410
|
+
r1.store_row <= get_row(req_laddr);
|
|
411
|
+
r1.wb.adr <= req_laddr(r1.wb.adr'left downto 0);
|
|
412
|
+
r1.wb.sel <= (others => '1');
|
|
413
|
+
r1.wb.we <= '0';
|
|
414
|
+
r1.wb.cyc <= '1';
|
|
415
|
+
r1.wb.stb <= '1';
|
|
416
|
+
r1.state <= reload_wait_ack;
|
|
417
|
+
when op_load_nc =>
|
|
418
|
+
r1.wb.sel <= r0.byte_sel;
|
|
419
|
+
r1.wb.adr <= r0.addr(r1.wb.adr'left downto 3) & "000";
|
|
420
|
+
r1.wb.cyc <= '1';
|
|
421
|
+
r1.wb.stb <= '1';
|
|
422
|
+
r1.wb.we <= '0';
|
|
423
|
+
r1.state <= nc_load_wait_ack;
|
|
424
|
+
when op_store_hit | op_store_miss =>
|
|
425
|
+
r1.wb.sel <= r0.byte_sel;
|
|
426
|
+
r1.wb.adr <= r0.addr(r1.wb.adr'left downto 3) & "000";
|
|
427
|
+
r1.wb.dat <= r0.data;
|
|
428
|
+
if cancel_store = '0' then
|
|
429
|
+
r1.wb.cyc <= '1';
|
|
430
|
+
r1.wb.stb <= '1';
|
|
431
|
+
r1.wb.we <= '1';
|
|
432
|
+
r1.state <= store_wait_ack;
|
|
433
|
+
else
|
|
434
|
+
r1.stcx_fail <= '1';
|
|
435
|
+
r1.state <= idle;
|
|
436
|
+
end if;
|
|
437
|
+
when op_none =>
|
|
438
|
+
when op_bad =>
|
|
439
|
+
end case;
|
|
440
|
+
when reload_wait_ack =>
|
|
441
|
+
stbs_done := r1.wb.stb = '0';
|
|
442
|
+
if wishbone_in.stall = '0' and stbs_done then
|
|
443
|
+
if is_last_row_addr(r1.wb.adr) then
|
|
444
|
+
r1.wb.stb <= '0';
|
|
445
|
+
stbs_done := true;
|
|
446
|
+
end if;
|
|
447
|
+
r1.wb.adr <= next_row_addr(r1.wb.adr);
|
|
448
|
+
end if;
|
|
449
|
+
if wishbone_in.ack = '1' then
|
|
450
|
+
if r1.store_row = get_row(r1.req.addr) then
|
|
451
|
+
r1.slow_data <= wishbone_in.dat;
|
|
452
|
+
end if;
|
|
453
|
+
if stbs_done and is_last_row(r1.store_row) then
|
|
454
|
+
r1.wb.cyc <= '0';
|
|
455
|
+
cache_valids(r1.store_index)(r1.store_way) <= '1';
|
|
456
|
+
r1.state <= finish_ld_miss;
|
|
457
|
+
end if;
|
|
458
|
+
r1.store_row <= next_row(r1.store_row);
|
|
459
|
+
end if;
|
|
460
|
+
when finish_ld_miss =>
|
|
461
|
+
r1.slow_valid <= '1';
|
|
462
|
+
r1.state <= idle;
|
|
463
|
+
report "completing miss !";
|
|
464
|
+
when store_wait_ack | nc_load_wait_ack =>
|
|
465
|
+
if wishbone_in.stall = '0' then
|
|
466
|
+
r1.wb.stb <= '0';
|
|
467
|
+
end if;
|
|
468
|
+
if wishbone_in.ack = '1' then
|
|
469
|
+
if r1.state = nc_load_wait_ack then
|
|
470
|
+
r1.slow_data <= wishbone_in.dat;
|
|
471
|
+
end if;
|
|
472
|
+
r1.state <= idle;
|
|
473
|
+
r1.slow_valid <= '1';
|
|
474
|
+
r1.wb.cyc <= '0';
|
|
475
|
+
r1.wb.stb <= '0';
|
|
476
|
+
end if;
|
|
477
|
+
end case;
|
|
478
|
+
end if;
|
|
479
|
+
end if;
|
|
480
|
+
end process;
|
|
481
|
+
end rtl;
|