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/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
|