vertigo_vhdl 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (183) hide show
  1. checksums.yaml +7 -0
  2. data/bin/vertigo +7 -0
  3. data/lib/vertigo.rb +4 -0
  4. data/lib/vertigo/ast.rb +87 -0
  5. data/lib/vertigo/ast_vertigo_rkgen.rb +607 -0
  6. data/lib/vertigo/code.rb +57 -0
  7. data/lib/vertigo/compiler.rb +61 -0
  8. data/lib/vertigo/generic_lexer.rb +61 -0
  9. data/lib/vertigo/generic_parser.rb +44 -0
  10. data/lib/vertigo/indent.rb +20 -0
  11. data/lib/vertigo/lexer.rb +172 -0
  12. data/lib/vertigo/parser.rb +1458 -0
  13. data/lib/vertigo/pretty_printer.rb +749 -0
  14. data/lib/vertigo/runner.rb +115 -0
  15. data/lib/vertigo/tb_generator.rb +81 -0
  16. data/lib/vertigo/template.tb.vhd +72 -0
  17. data/lib/vertigo/token.rb +67 -0
  18. data/lib/vertigo/version.rb +3 -0
  19. data/lib/vertigo/vertigo.rkg +354 -0
  20. data/lib/vertigo/visitor_vertigo_rkgen.rb +447 -0
  21. data/tests/ghdl_tests/fsm.vhd +98 -0
  22. data/tests/ghdl_tests/fsm_synth.vhd +248 -0
  23. data/tests/ghdl_tests/test_fsm.vhd +162 -0
  24. data/tests/parser_tests/else.vhd +64 -0
  25. data/tests/parser_tests/test_MUST_fail.vhd +1 -0
  26. data/tests/parser_tests/test_accelerator.vhd +160 -0
  27. data/tests/parser_tests/test_accelerator_pp.vhd +144 -0
  28. data/tests/parser_tests/test_aggregate.vhd +17 -0
  29. data/tests/parser_tests/test_aggregate_pp.vhd +15 -0
  30. data/tests/parser_tests/test_archi_1.vhd +45 -0
  31. data/tests/parser_tests/test_archi_1_pp.vhd +41 -0
  32. data/tests/parser_tests/test_array_array_00.vhd +25 -0
  33. data/tests/parser_tests/test_array_array_00_pp.vhd +25 -0
  34. data/tests/parser_tests/test_array_urange.vhd +25 -0
  35. data/tests/parser_tests/test_array_urange_pp.vhd +25 -0
  36. data/tests/parser_tests/test_chu-1.vhd +80 -0
  37. data/tests/parser_tests/test_chu-1_pp.vhd +104 -0
  38. data/tests/parser_tests/test_concat.vhd +11 -0
  39. data/tests/parser_tests/test_concat_pp.vhd +14 -0
  40. data/tests/parser_tests/test_counter.vhd +35 -0
  41. data/tests/parser_tests/test_counter_pp.vhd +35 -0
  42. data/tests/parser_tests/test_de2.vhd +358 -0
  43. data/tests/parser_tests/test_de2_pp.vhd +274 -0
  44. data/tests/parser_tests/test_encode.vhd +2679 -0
  45. data/tests/parser_tests/test_encode_pp.vhd +2549 -0
  46. data/tests/parser_tests/test_fsm.vhd +162 -0
  47. data/tests/parser_tests/test_fsm_pp.vhd +125 -0
  48. data/tests/parser_tests/test_fsm_synth.vhd +248 -0
  49. data/tests/parser_tests/test_fsm_synth_pp.vhd +197 -0
  50. data/tests/parser_tests/test_function-01.vhd +33 -0
  51. data/tests/parser_tests/test_function-01_pp.vhd +18 -0
  52. data/tests/parser_tests/test_lfsr.vhd +75 -0
  53. data/tests/parser_tests/test_lfsr_pp.vhd +44 -0
  54. data/tests/parser_tests/test_microwatt_cache_ram.vhd +1 -0
  55. data/tests/parser_tests/test_microwatt_cache_ram_pp.vhd +68 -0
  56. data/tests/parser_tests/test_microwatt_common.vhd +1 -0
  57. data/tests/parser_tests/test_microwatt_common_pp.vhd +336 -0
  58. data/tests/parser_tests/test_microwatt_control.vhd +1 -0
  59. data/tests/parser_tests/test_microwatt_control_pp.vhd +187 -0
  60. data/tests/parser_tests/test_microwatt_core.vhd +1 -0
  61. data/tests/parser_tests/test_microwatt_core_debug.vhd +1 -0
  62. data/tests/parser_tests/test_microwatt_core_debug_pp.vhd +104 -0
  63. data/tests/parser_tests/test_microwatt_core_pp.vhd +231 -0
  64. data/tests/parser_tests/test_microwatt_core_tb.vhd +1 -0
  65. data/tests/parser_tests/test_microwatt_core_tb_pp.vhd +43 -0
  66. data/tests/parser_tests/test_microwatt_countzero.vhd +1 -0
  67. data/tests/parser_tests/test_microwatt_countzero_pp.vhd +120 -0
  68. data/tests/parser_tests/test_microwatt_countzero_tb.vhd +1 -0
  69. data/tests/parser_tests/test_microwatt_countzero_tb_pp.vhd +70 -0
  70. data/tests/parser_tests/test_microwatt_cr_file.vhd +1 -0
  71. data/tests/parser_tests/test_microwatt_cr_file_pp.vhd +74 -0
  72. data/tests/parser_tests/test_microwatt_cr_hazard.vhd +1 -0
  73. data/tests/parser_tests/test_microwatt_cr_hazard_pp.vhd +51 -0
  74. data/tests/parser_tests/test_microwatt_crhelpers.vhd +1 -0
  75. data/tests/parser_tests/test_microwatt_crhelpers_pp.vhd +48 -0
  76. data/tests/parser_tests/test_microwatt_dcache.vhd +1 -0
  77. data/tests/parser_tests/test_microwatt_dcache_pp.vhd +481 -0
  78. data/tests/parser_tests/test_microwatt_dcache_tb.vhd +1 -0
  79. data/tests/parser_tests/test_microwatt_dcache_tb_pp.vhd +98 -0
  80. data/tests/parser_tests/test_microwatt_decode1.vhd +1 -0
  81. data/tests/parser_tests/test_microwatt_decode1_pp.vhd +138 -0
  82. data/tests/parser_tests/test_microwatt_decode2.vhd +1 -0
  83. data/tests/parser_tests/test_microwatt_decode2_pp.vhd +300 -0
  84. data/tests/parser_tests/test_microwatt_decode_types.vhd +1 -0
  85. data/tests/parser_tests/test_microwatt_decode_types_pp.vhd +67 -0
  86. data/tests/parser_tests/test_microwatt_divider.vhd +1 -0
  87. data/tests/parser_tests/test_microwatt_divider_pp.vhd +132 -0
  88. data/tests/parser_tests/test_microwatt_divider_tb.vhd +1 -0
  89. data/tests/parser_tests/test_microwatt_divider_tb_pp.vhd +95 -0
  90. data/tests/parser_tests/test_microwatt_dmi_dtm_dummy.vhd +1 -0
  91. data/tests/parser_tests/test_microwatt_dmi_dtm_dummy_pp.vhd +29 -0
  92. data/tests/parser_tests/test_microwatt_dmi_dtm_tb.vhd +1 -0
  93. data/tests/parser_tests/test_microwatt_dmi_dtm_tb_pp.vhd +197 -0
  94. data/tests/parser_tests/test_microwatt_dmi_dtm_xilinx.vhd +1 -0
  95. data/tests/parser_tests/test_microwatt_dmi_dtm_xilinx_pp.vhd +139 -0
  96. data/tests/parser_tests/test_microwatt_execute1.vhd +1 -0
  97. data/tests/parser_tests/test_microwatt_execute1_pp.vhd +689 -0
  98. data/tests/parser_tests/test_microwatt_fetch1.vhd +1 -0
  99. data/tests/parser_tests/test_microwatt_fetch1_pp.vhd +88 -0
  100. data/tests/parser_tests/test_microwatt_fetch2.vhd +1 -0
  101. data/tests/parser_tests/test_microwatt_fetch2_pp.vhd +79 -0
  102. data/tests/parser_tests/test_microwatt_glibc_random.vhd +1 -0
  103. data/tests/parser_tests/test_microwatt_glibc_random_helpers.vhd +1 -0
  104. data/tests/parser_tests/test_microwatt_glibc_random_helpers_pp.vhd +25 -0
  105. data/tests/parser_tests/test_microwatt_glibc_random_pp.vhd +41 -0
  106. data/tests/parser_tests/test_microwatt_gpr_hazard.vhd +1 -0
  107. data/tests/parser_tests/test_microwatt_gpr_hazard_pp.vhd +68 -0
  108. data/tests/parser_tests/test_microwatt_helpers.vhd +1 -0
  109. data/tests/parser_tests/test_microwatt_helpers_pp.vhd +153 -0
  110. data/tests/parser_tests/test_microwatt_icache.vhd +1 -0
  111. data/tests/parser_tests/test_microwatt_icache_pp.vhd +337 -0
  112. data/tests/parser_tests/test_microwatt_icache_tb.vhd +1 -0
  113. data/tests/parser_tests/test_microwatt_icache_tb_pp.vhd +104 -0
  114. data/tests/parser_tests/test_microwatt_insn_helpers.vhd +1 -0
  115. data/tests/parser_tests/test_microwatt_insn_helpers_pp.vhd +208 -0
  116. data/tests/parser_tests/test_microwatt_loadstore1.vhd +1 -0
  117. data/tests/parser_tests/test_microwatt_loadstore1_pp.vhd +222 -0
  118. data/tests/parser_tests/test_microwatt_logical.vhd +1 -0
  119. data/tests/parser_tests/test_microwatt_logical_pp.vhd +87 -0
  120. data/tests/parser_tests/test_microwatt_multiply.vhd +1 -0
  121. data/tests/parser_tests/test_microwatt_multiply_pp.vhd +84 -0
  122. data/tests/parser_tests/test_microwatt_multiply_tb.vhd +1 -0
  123. data/tests/parser_tests/test_microwatt_multiply_tb_pp.vhd +75 -0
  124. data/tests/parser_tests/test_microwatt_plru.vhd +1 -0
  125. data/tests/parser_tests/test_microwatt_plru_pp.vhd +46 -0
  126. data/tests/parser_tests/test_microwatt_plru_tb.vhd +1 -0
  127. data/tests/parser_tests/test_microwatt_plru_tb_pp.vhd +93 -0
  128. data/tests/parser_tests/test_microwatt_ppc_fx_insns.vhd +1 -0
  129. data/tests/parser_tests/test_microwatt_ppc_fx_insns_pp.vhd +665 -0
  130. data/tests/parser_tests/test_microwatt_register_file.vhd +1 -0
  131. data/tests/parser_tests/test_microwatt_register_file_pp.vhd +86 -0
  132. data/tests/parser_tests/test_microwatt_rotator.vhd +1 -0
  133. data/tests/parser_tests/test_microwatt_rotator_pp.vhd +149 -0
  134. data/tests/parser_tests/test_microwatt_rotator_tb.vhd +1 -0
  135. data/tests/parser_tests/test_microwatt_rotator_tb_pp.vhd +134 -0
  136. data/tests/parser_tests/test_microwatt_sim_bram.vhd +1 -0
  137. data/tests/parser_tests/test_microwatt_sim_bram_helpers.vhd +1 -0
  138. data/tests/parser_tests/test_microwatt_sim_bram_helpers_pp.vhd +52 -0
  139. data/tests/parser_tests/test_microwatt_sim_bram_pp.vhd +53 -0
  140. data/tests/parser_tests/test_microwatt_sim_console.vhd +1 -0
  141. data/tests/parser_tests/test_microwatt_sim_console_pp.vhd +43 -0
  142. data/tests/parser_tests/test_microwatt_sim_jtag.vhd +1 -0
  143. data/tests/parser_tests/test_microwatt_sim_jtag_pp.vhd +64 -0
  144. data/tests/parser_tests/test_microwatt_sim_jtag_socket.vhd +1 -0
  145. data/tests/parser_tests/test_microwatt_sim_jtag_socket_pp.vhd +36 -0
  146. data/tests/parser_tests/test_microwatt_sim_uart.vhd +1 -0
  147. data/tests/parser_tests/test_microwatt_sim_uart_pp.vhd +90 -0
  148. data/tests/parser_tests/test_microwatt_soc.vhd +1 -0
  149. data/tests/parser_tests/test_microwatt_soc_pp.vhd +195 -0
  150. data/tests/parser_tests/test_microwatt_utils.vhd +1 -0
  151. data/tests/parser_tests/test_microwatt_utils_pp.vhd +39 -0
  152. data/tests/parser_tests/test_microwatt_wishbone_arbiter.vhd +1 -0
  153. data/tests/parser_tests/test_microwatt_wishbone_arbiter_pp.vhd +54 -0
  154. data/tests/parser_tests/test_microwatt_wishbone_bram_tb.vhd +1 -0
  155. data/tests/parser_tests/test_microwatt_wishbone_bram_tb_pp.vhd +157 -0
  156. data/tests/parser_tests/test_microwatt_wishbone_bram_wrapper.vhd +1 -0
  157. data/tests/parser_tests/test_microwatt_wishbone_bram_wrapper_pp.vhd +62 -0
  158. data/tests/parser_tests/test_microwatt_wishbone_debug_master.vhd +1 -0
  159. data/tests/parser_tests/test_microwatt_wishbone_debug_master_pp.vhd +124 -0
  160. data/tests/parser_tests/test_microwatt_wishbone_types.vhd +1 -0
  161. data/tests/parser_tests/test_microwatt_wishbone_types_pp.vhd +38 -0
  162. data/tests/parser_tests/test_microwatt_writeback.vhd +1 -0
  163. data/tests/parser_tests/test_microwatt_writeback_pp.vhd +87 -0
  164. data/tests/parser_tests/test_package-1.vhd +68 -0
  165. data/tests/parser_tests/test_package-1_pp.vhd +53 -0
  166. data/tests/parser_tests/test_precedence.vhd +13 -0
  167. data/tests/parser_tests/test_precedence_pp.vhd +16 -0
  168. data/tests/parser_tests/test_selected_sig.vhd +14 -0
  169. data/tests/parser_tests/test_selected_sig_pp.vhd +10 -0
  170. data/tests/parser_tests/test_slice.vhd +15 -0
  171. data/tests/parser_tests/test_slice_pp.vhd +16 -0
  172. data/tests/parser_tests/test_tb-00.vhd +94 -0
  173. data/tests/parser_tests/test_tb-00_pp.vhd +71 -0
  174. data/tests/parser_tests/test_type_decl_02.vhd +9 -0
  175. data/tests/parser_tests/test_type_decl_02_pp.vhd +11 -0
  176. data/tests/parser_tests/test_use.vhd +7 -0
  177. data/tests/parser_tests/test_use_pp.vhd +10 -0
  178. data/tests/parser_tests/test_while_1.vhd +38 -0
  179. data/tests/parser_tests/test_while_1_pp.vhd +26 -0
  180. data/tests/parser_tests/test_with-00.vhd +21 -0
  181. data/tests/parser_tests/test_with-00_pp.vhd +12 -0
  182. data/tests/tb_gen_tests/test_accelerator.vhd +160 -0
  183. 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;