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.
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/icache.vhdl
@@ -0,0 +1,337 @@
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.wishbone_types.all;
9
+
10
+ entity icache is
11
+ generic(
12
+ sim : booleanfalse := false;
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
+ i_in : in fetch1toicachetype;
20
+ i_out : out icachetofetch2type;
21
+ stall_out : out std_ulogic;
22
+ flush_in : in std_ulogic;
23
+ wishbone_out : out wishbone_master_out;
24
+ wishbone_in : in wishbone_slave_out);
25
+ end entity icache;
26
+
27
+ architecture rtl of icache is
28
+ constant row_size : natural := wishbone_data_bits / 8;
29
+ constant row_per_line : natural := line_size / row_size;
30
+ constant bram_rows : natural := num_lines * row_per_line;
31
+ constant insn_per_row : natural := wishbone_data_bits / 32;
32
+ constant insn_bits : natural := log2(insn_per_row);
33
+ constant row_bits : natural := log2(bram_rows);
34
+ constant row_linebits : natural := log2(row_per_line);
35
+ constant line_off_bits : natural := log2(line_size);
36
+ constant row_off_bits : natural := log2(row_size);
37
+ constant index_bits : natural := log2(num_lines);
38
+ constant tag_bits : natural := 64 - line_off_bits - index_bits;
39
+ constant way_bits : natural := log2(num_ways);
40
+
41
+ subtype row_t is integer range 0 to bram_rows - 1;
42
+
43
+ subtype index_t is integer range 0 to num_lines - 1;
44
+
45
+ subtype way_t is integer range 0 to num_ways - 1;
46
+
47
+ subtype cache_row_t is std_ulogic_vector(wishbone_data_bits - 1 downto 0);
48
+
49
+ subtype cache_tag_t is std_logic_vector(tag_bits - 1 downto 0);
50
+ constant tag_ram_width : natural := tag_bits * num_ways;
51
+
52
+ subtype cache_tags_set_t is std_logic_vector(tag_ram_width - 1 downto 0);
53
+
54
+ type cache_tags_array_t is array(range index_t) of cache_tags_set_t;
55
+
56
+ subtype cache_way_valids_t is std_ulogic_vector(num_ways - 1 downto 0);
57
+
58
+ type cache_valids_t is array(range index_t) of cache_way_valids_t;
59
+ signal cache_tags : cache_tags_array_t;
60
+ signal cache_valids : cache_valids_t;
61
+ attribute ram_style : string;
62
+ attribute ram_style of cache_tags : signal is "distributed";
63
+
64
+ type state_t is (idle,wait_ack);
65
+
66
+ type reg_internal_t is record
67
+ hit_way : way_t;
68
+ hit_nia : std_ulogic_vector(63 downto 0);
69
+ hit_smark : std_ulogic;
70
+ hit_valid : std_ulogic;
71
+ state : state_t;
72
+ wb : wishbone_master_out;
73
+ store_way : way_t;
74
+ store_index : index_t;
75
+ store_row : row_t;
76
+ end record;
77
+ signal r : reg_internal_t;
78
+ signal req_index : index_t;
79
+ signal req_row : row_t;
80
+ signal req_hit_way : way_t;
81
+ signal req_tag : cache_tag_t;
82
+ signal req_is_hit : std_ulogic;
83
+ signal req_is_miss : std_ulogic;
84
+ signal req_laddr : std_ulogic_vector(63 downto 0);
85
+
86
+ type cache_ram_out_t is array(range way_t) of cache_row_t;
87
+ signal cache_out : cache_ram_out_t;
88
+
89
+ type plru_out_t is array(range index_t) of std_ulogic_vector(way_bits - 1 downto 0);
90
+ signal plru_victim : plru_out_t;
91
+ signal replace_way : way_t;
92
+
93
+ function get_index(addr : std_ulogic_vector(63 downto 0)) return index_t is
94
+ begin
95
+ return to_integer(unsigned(addr(63 - tag_bits downto line_off_bits)));
96
+ end function get_index;
97
+
98
+ function get_row(addr : std_ulogic_vector(63 downto 0)) return row_t is
99
+ begin
100
+ return to_integer(unsigned(addr(63 - tag_bits downto row_off_bits)));
101
+ end function get_row;
102
+
103
+ function is_last_row_addr(addr : wishbone_addr_type) return boolean is
104
+ constant ones : std_ulogic_vector(row_linebits - 1 downto 0) := (others => '1');
105
+ begin
106
+ return addr(line_off_bits - 1 downto row_off_bits) = ones;
107
+ end function is_last_row_addr;
108
+
109
+ function is_last_row(row : row_t) return boolean is
110
+ variable row_v : std_ulogic_vector(row_bits - 1 downto 0);
111
+ constant ones : std_ulogic_vector(row_linebits - 1 downto 0) := (others => '1');
112
+ begin
113
+ row_v := std_ulogic_vector(to_unsigned(row,row_bits));
114
+ return row_v(row_linebits - 1 downto 0) = ones;
115
+ end function is_last_row;
116
+
117
+ function next_row_addr(addr : wishbone_addr_type) return std_ulogic_vector is
118
+ variable row_idx : std_ulogic_vector(row_linebits - 1 downto 0);
119
+ variable result : wishbone_addr_type;
120
+ begin
121
+ row_idx := addr(line_off_bits - 1 downto row_off_bits);
122
+ row_idx := std_ulogic_vector(unsigned(row_idx) + 1);
123
+ result := addr;
124
+ result(line_off_bits - 1 downto row_off_bits) := row_idx;
125
+ return result;
126
+ end function next_row_addr;
127
+
128
+ function next_row(row : row_t) return row_t is
129
+ variable row_v : std_ulogic_vector(row_bits - 1 downto 0);
130
+ variable row_idx : std_ulogic_vector(row_linebits - 1 downto 0);
131
+ variable result : std_ulogic_vector(row_bits - 1 downto 0);
132
+ begin
133
+ row_v := std_ulogic_vector(to_unsigned(row,row_bits));
134
+ row_idx := row_v(row_linebits - 1 downto 0);
135
+ row_v(row_linebits - 1 downto 0) := std_ulogic_vector(unsigned(row_idx) + 1);
136
+ return to_integer(unsigned(row_v));
137
+ end function next_row;
138
+
139
+ function read_insn_word(addr : std_ulogic_vector(63 downto 0);data : cache_row_t) return std_ulogic_vector is
140
+ variable word : integer range 0 to insn_per_row - 1;
141
+ begin
142
+ word := to_integer(unsigned(addr(insn_bits + 2 - 1 downto 2)));
143
+ return data(31 + word * 32 downto word * 32);
144
+ end function read_insn_word;
145
+
146
+ function get_tag(addr : std_ulogic_vector(63 downto 0)) return cache_tag_t is
147
+ begin
148
+ return addr(63 downto 64 - tag_bits);
149
+ end function get_tag;
150
+
151
+ function read_tag(way : way_t;tagset : cache_tags_set_t) return cache_tag_t is
152
+ begin
153
+ return tagset((way + 1) * tag_bits - 1 downto way * tag_bits);
154
+ end function read_tag;
155
+
156
+ procedure write_tag(
157
+ way : in way_t;
158
+ tagset : inout cache_tags_set_t;
159
+ tag : cache_tag_t) is
160
+ begin
161
+ tagset((way + 1) * tag_bits - 1 downto way * tag_bits) := tag;
162
+ end write_tag;
163
+ begin
164
+
165
+ assert line_size mod row_size = 0;
166
+ assert ispow2(line_size)
167
+ report "line_size not power of 2" severity failure;
168
+ assert ispow2(num_lines)
169
+ report "num_lines not power of 2" severity failure;
170
+ assert ispow2(row_per_line)
171
+ report "row_per_line not power of 2" severity failure;
172
+ assert ispow2(insn_per_row)
173
+ report "insn_per_row not power of 2" severity failure;
174
+ assert (row_bits = index_bits + row_linebits)
175
+ report "geometry bits don't add up" severity failure;
176
+ assert (line_off_bits = row_off_bits + row_linebits)
177
+ report "geometry bits don't add up" severity failure;
178
+ assert (64 = tag_bits + index_bits + line_off_bits)
179
+ report "geometry bits don't add up" severity failure;
180
+ assert (64 = tag_bits + row_bits + row_off_bits)
181
+ report "geometry bits don't add up" severity failure;
182
+ if sim generate
183
+
184
+ debug : process
185
+ begin
186
+ report "row_size = " & natural'image(row_size);
187
+ report "row_per_line = " & natural'image(row_per_line);
188
+ report "bram_rows = " & natural'image(bram_rows);
189
+ report "insn_per_row = " & natural'image(insn_per_row);
190
+ report "insn_bits = " & natural'image(insn_bits);
191
+ report "row_bits = " & natural'image(row_bits);
192
+ report "row_linebits = " & natural'image(row_linebits);
193
+ report "line_off_bits = " & natural'image(line_off_bits);
194
+ report "row_off_bits = " & natural'image(row_off_bits);
195
+ report "index_bits = " & natural'image(index_bits);
196
+ report "tag_bits = " & natural'image(tag_bits);
197
+ report "way_bits = " & natural'image(way_bits);
198
+ wait ;
199
+ end process;
200
+ end generate;
201
+ for i in 0 to num_ways - 1 generate
202
+ way : entity work.cache_ram
203
+ port map(
204
+ clk => clk,
205
+ rd_en => do_read,
206
+ rd_addr => rd_addr,
207
+ rd_data => dout,
208
+ wr_en => do_write,
209
+ wr_sel => (others => '1'),
210
+ wr_addr => wr_addr,
211
+ wr_data => wishbone_in.dat);
212
+
213
+
214
+ process(all)
215
+ begin
216
+ do_read <= '1';
217
+ do_write <= '0';
218
+ if wishbone_in.ack = '1' and r.store_way = i then
219
+ do_write <= '1';
220
+ end if;
221
+ cache_out(i) <= dout;
222
+ rd_addr <= std_ulogic_vector(to_unsigned(req_row,row_bits));
223
+ wr_addr <= std_ulogic_vector(to_unsigned(r.store_row,row_bits));
224
+ end process;
225
+ end generate;
226
+ if num_ways > 1 generate
227
+ for i in 0 to num_lines - 1 generate
228
+ plru : entity work.plru
229
+ port map(
230
+ clk => clk,
231
+ rst => rst,
232
+ acc => plru_acc,
233
+ acc_en => plru_acc_en,
234
+ lru => plru_out);
235
+
236
+
237
+ process(req_index,req_is_hit,req_hit_way,req_is_hit,plru_out)
238
+ begin
239
+ if req_is_hit = '1' and req_index = i then
240
+ plru_acc_en <= req_is_hit;
241
+ else
242
+ plru_acc_en <= '0';
243
+ end if;
244
+ plru_acc <= std_ulogic_vector(to_unsigned(req_hit_way,way_bits));
245
+ plru_victim(i) <= plru_out;
246
+ end process;
247
+ end generate;
248
+ end generate;
249
+
250
+ icache_comb : process(all)
251
+ variable is_hit : std_ulogic;
252
+ variable hit_way : way_t;
253
+ begin
254
+ req_index <= get_index(i_in.nia);
255
+ req_row <= get_row(i_in.nia);
256
+ req_tag <= get_tag(i_in.nia);
257
+ req_laddr <= i_in.nia(63 downto line_off_bits) & (line_off_bits - 1 downto 0 => '0');
258
+ hit_way := 0;
259
+ is_hit := '0';
260
+ req_is_hit <= i_in.req and is_hit and flush_in;
261
+ req_is_miss <= i_in.req and is_hit and flush_in;
262
+ req_hit_way <= hit_way;
263
+ replace_way <= to_integer(unsigned(plru_victim(req_index)));
264
+ i_out.insn <= read_insn_word(r.hit_nia,cache_out(r.hit_way));
265
+ i_out.valid <= r.hit_valid;
266
+ i_out.nia <= r.hit_nia;
267
+ i_out.stop_mark <= r.hit_smark;
268
+ stall_out <= is_hit;
269
+ wishbone_out <= r.wb;
270
+ end process;
271
+
272
+ icache_hit : process(clk)
273
+ begin
274
+ if rising_edge(clk) then
275
+ if req_is_hit = '1' then
276
+ r.hit_way <= req_hit_way;
277
+ r.hit_nia <= i_in.nia;
278
+ r.hit_smark <= i_in.stop_mark;
279
+ r.hit_valid <= '1';
280
+ report "cache hit nia:" & to_hstring(i_in.nia) & " sm:" & std_ulogic'image(i_in.stop_mark) & " idx:" & integer'image(req_index) & " tag:" & to_hstring(req_tag) & " way: " & integer'image(req_hit_way);
281
+ else
282
+ r.hit_valid <= '0';
283
+ r.hit_smark <= i_in.stop_mark;
284
+ end if;
285
+ end if;
286
+ end process;
287
+
288
+ icache_miss : process(clk)
289
+ variable tagset : cache_tags_set_t;
290
+ variable stbs_done : boolean;
291
+ begin
292
+ if rising_edge(clk) then
293
+ if rst = '1' then
294
+ ;
295
+ r.state <= idle;
296
+ r.wb.cyc <= '0';
297
+ r.wb.stb <= '0';
298
+ r.wb.dat <= (others => '0');
299
+ r.wb.sel <= "11111111";
300
+ r.wb.we <= '0';
301
+ r.wb.adr <= (others => '0');
302
+ else
303
+ case r.state is
304
+ when idle =>
305
+ if req_is_miss = '1' then
306
+ report "cache miss nia:" & to_hstring(i_in.nia) & " sm:" & std_ulogic'image(i_in.stop_mark) & " idx:" & integer'image(req_index) & " way:" & integer'image(replace_way) & " tag:" & to_hstring(req_tag);
307
+ cache_valids(req_index)(replace_way) <= '0';
308
+ r.store_index <= req_index;
309
+ r.store_way <= replace_way;
310
+ r.store_row <= get_row(req_laddr);
311
+ r.wb.adr <= req_laddr(r.wb.adr'left downto 0);
312
+ r.wb.cyc <= '1';
313
+ r.wb.stb <= '1';
314
+ r.state <= wait_ack;
315
+ end if;
316
+ when wait_ack =>
317
+ stbs_done := r.wb.stb = '0';
318
+ if wishbone_in.stall = '0' and stbs_done then
319
+ if is_last_row_addr(r.wb.adr) then
320
+ r.wb.stb <= '0';
321
+ stbs_done := true;
322
+ end if;
323
+ r.wb.adr <= next_row_addr(r.wb.adr);
324
+ end if;
325
+ if wishbone_in.ack = '1' then
326
+ if stbs_done and is_last_row(r.store_row) then
327
+ r.wb.cyc <= '0';
328
+ cache_valids(r.store_index)(r.store_way) <= '1';
329
+ r.state <= idle;
330
+ end if;
331
+ r.store_row <= next_row(r.store_row);
332
+ end if;
333
+ end case;
334
+ end if;
335
+ end if;
336
+ end process;
337
+ end rtl;
@@ -0,0 +1 @@
1
+ ../microwatt/icache_tb.vhdl
@@ -0,0 +1,104 @@
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
+ use work.wishbone_types.all;
7
+
8
+ entity icache_tb is
9
+ end entity icache_tb;
10
+
11
+ architecture behave of icache_tb is
12
+ signal clk : std_ulogic;
13
+ signal rst : std_ulogic;
14
+ signal i_out : fetch1toicachetype;
15
+ signal i_in : icachetofetch2type;
16
+ signal wb_bram_in : wishbone_master_out;
17
+ signal wb_bram_out : wishbone_slave_out;
18
+ constant clk_period : time := 10 ns;
19
+ begin
20
+
21
+ icache0 : entity work.icache
22
+ port map(
23
+ clk => clk,
24
+ rst => rst,
25
+ i_in => i_out,
26
+ i_out => i_in,
27
+ flush_in => '0',
28
+ wishbone_out => wb_bram_in,
29
+ wishbone_in => wb_bram_out);
30
+
31
+ bram0 : entity work.wishbone_bram_wrapper
32
+ port map(
33
+ clk => clk,
34
+ rst => rst,
35
+ wishbone_in => wb_bram_in,
36
+ wishbone_out => wb_bram_out);
37
+
38
+
39
+ clk_process : process
40
+ begin
41
+ clk <= '0';
42
+ wait clk_period / 2;
43
+ clk <= '1';
44
+ wait clk_period / 2;
45
+ end process;
46
+
47
+ rst_process : process
48
+ begin
49
+ rst <= '1';
50
+ wait 2 * clk_period;
51
+ rst <= '0';
52
+ wait ;
53
+ end process;
54
+
55
+ stim : process
56
+ begin
57
+ i_out.req <= '0';
58
+ i_out.nia <= (others => '0');
59
+ i_out.stop_mark <= '0';
60
+ wait rising_edge(clk);
61
+ wait rising_edge(clk);
62
+ wait rising_edge(clk);
63
+ wait rising_edge(clk);
64
+ i_out.req <= '1';
65
+ i_out.nia <= x"0000000000000004";
66
+ wait 30 * clk_period;
67
+ wait rising_edge(clk);
68
+ assert i_in.valid = '1';
69
+ assert i_in.insn = x"00000001"
70
+ report "insn @" & to_hstring(i_out.nia) & "=" & to_hstring(i_in.insn) & " expected 00000001" severity failure;
71
+ i_out.req <= '0';
72
+ wait rising_edge(clk);
73
+ i_out.req <= '1';
74
+ i_out.nia <= x"0000000000000008";
75
+ wait rising_edge(clk);
76
+ wait rising_edge(clk);
77
+ assert i_in.valid = '1';
78
+ assert i_in.insn = x"00000002"
79
+ report "insn @" & to_hstring(i_out.nia) & "=" & to_hstring(i_in.insn) & " expected 00000002" severity failure;
80
+ wait rising_edge(clk);
81
+ i_out.req <= '1';
82
+ i_out.nia <= x"0000000000000040";
83
+ wait 30 * clk_period;
84
+ wait rising_edge(clk);
85
+ assert i_in.valid = '1';
86
+ assert i_in.insn = x"00000010"
87
+ report "insn @" & to_hstring(i_out.nia) & "=" & to_hstring(i_in.insn) & " expected 00000010" severity failure;
88
+ i_out.req <= '1';
89
+ i_out.nia <= x"0000000000000100";
90
+ wait rising_edge(clk);
91
+ wait rising_edge(clk);
92
+ assert i_in.valid = '0';
93
+ wait rising_edge(clk);
94
+ wait 30 * clk_period;
95
+ wait rising_edge(clk);
96
+ assert i_in.valid = '1';
97
+ assert i_in.insn = x"00000040"
98
+ report "insn @" & to_hstring(i_out.nia) & "=" & to_hstring(i_in.insn) & " expected 00000040" severity failure;
99
+ i_out.req <= '0';
100
+ assert false
101
+ report "end of test" severity failure;
102
+ wait ;
103
+ end process;
104
+ end behave;
@@ -0,0 +1 @@
1
+ ../microwatt/insn_helpers.vhdl