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/dmi_dtm_xilinx.vhdl
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
-- generated by Vertigo VHDL tool
|
|
2
|
+
library ieee;
|
|
3
|
+
use ieee.std_logic_1164.all;
|
|
4
|
+
use ieee.math_real.all;
|
|
5
|
+
library work;
|
|
6
|
+
use work.wishbone_types.all;
|
|
7
|
+
library unisim;
|
|
8
|
+
use unisim.vcomponents.all;
|
|
9
|
+
|
|
10
|
+
entity dmi_dtm is
|
|
11
|
+
generic(
|
|
12
|
+
abits : integer8 := 8;
|
|
13
|
+
dbits : integer32 := 32);
|
|
14
|
+
port(
|
|
15
|
+
sys_clk : in std_ulogic;
|
|
16
|
+
sys_reset : in std_ulogic;
|
|
17
|
+
dmi_addr : out std_ulogic_vector(abits - 1 downto 0);
|
|
18
|
+
dmi_din : in std_ulogic_vector(dbits - 1 downto 0);
|
|
19
|
+
dmi_dout : out std_ulogic_vector(dbits - 1 downto 0);
|
|
20
|
+
dmi_req : out std_ulogic;
|
|
21
|
+
dmi_wr : out std_ulogic;
|
|
22
|
+
dmi_ack : in std_ulogic);
|
|
23
|
+
end entity dmi_dtm;
|
|
24
|
+
|
|
25
|
+
architecture behaviour of dmi_dtm is
|
|
26
|
+
signal jtag_reset : std_ulogic;
|
|
27
|
+
signal capture : std_ulogic;
|
|
28
|
+
signal update : std_ulogic;
|
|
29
|
+
signal drck : std_ulogic;
|
|
30
|
+
signal jtag_clk : std_ulogic;
|
|
31
|
+
signal sel : std_ulogic;
|
|
32
|
+
signal shift : std_ulogic;
|
|
33
|
+
signal tdi : std_ulogic;
|
|
34
|
+
signal tdo : std_ulogic;
|
|
35
|
+
signal tck : std_ulogic;
|
|
36
|
+
signal shiftr : std_ulogic_vector(abits + dbits + 1 downto 0);
|
|
37
|
+
signal request : std_ulogic_vector(abits + dbits + 1 downto 0);
|
|
38
|
+
signal jtag_req : std_ulogic;
|
|
39
|
+
signal dmi_ack_0 : std_ulogic;
|
|
40
|
+
signal dmi_ack_1 : std_ulogic;
|
|
41
|
+
signal jtag_req_0 : std_ulogic;
|
|
42
|
+
signal jtag_req_1 : std_ulogic;
|
|
43
|
+
signal jtag_bsy : std_ulogic;
|
|
44
|
+
signal op_valid : std_ulogic;
|
|
45
|
+
signal rsp_op : std_ulogic_vector(1 downto 0);
|
|
46
|
+
constant dmi_req_nop : std_ulogic_vector(1 downto 0) := "00";
|
|
47
|
+
constant dmi_req_rd : std_ulogic_vector(1 downto 0) := "01";
|
|
48
|
+
constant dmi_req_wr : std_ulogic_vector(1 downto 0) := "10";
|
|
49
|
+
constant dmi_rsp_ok : std_ulogic_vector(1 downto 0) := "00";
|
|
50
|
+
constant dmi_rsp_bsy : std_ulogic_vector(1 downto 0) := "11";
|
|
51
|
+
begin
|
|
52
|
+
|
|
53
|
+
bscan : component bscane2
|
|
54
|
+
generic map(
|
|
55
|
+
jtag_chain => 2);
|
|
56
|
+
port map(
|
|
57
|
+
capture => capture,
|
|
58
|
+
drck => drck,
|
|
59
|
+
reset => jtag_reset,
|
|
60
|
+
runtest => open,
|
|
61
|
+
sel => sel,
|
|
62
|
+
shift => shift,
|
|
63
|
+
tck => tck,
|
|
64
|
+
tdi => tdi,
|
|
65
|
+
tms => open,
|
|
66
|
+
update => update,
|
|
67
|
+
tdo => tdo);
|
|
68
|
+
|
|
69
|
+
clkbuf : component bufg
|
|
70
|
+
port map(
|
|
71
|
+
i => tck,
|
|
72
|
+
o => jtag_clk);
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
dmi_req_sync : process(sys_clk)
|
|
76
|
+
begin
|
|
77
|
+
if rising_edge(sys_clk) then
|
|
78
|
+
if (sys_reset = '1') then
|
|
79
|
+
jtag_req_0 <= '0';
|
|
80
|
+
jtag_req_1 <= '0';
|
|
81
|
+
else
|
|
82
|
+
jtag_req_0 <= jtag_req;
|
|
83
|
+
jtag_req_1 <= jtag_req_0;
|
|
84
|
+
end if;
|
|
85
|
+
end if;
|
|
86
|
+
end process;
|
|
87
|
+
dmi_req <= jtag_req_1;
|
|
88
|
+
|
|
89
|
+
dmi_ack_sync : process(jtag_clk,jtag_reset)
|
|
90
|
+
begin
|
|
91
|
+
if jtag_reset = '1' then
|
|
92
|
+
dmi_ack_0 <= '0';
|
|
93
|
+
dmi_ack_1 <= '0';
|
|
94
|
+
elsif rising_edge(jtag_clk) then
|
|
95
|
+
dmi_ack_0 <= dmi_ack;
|
|
96
|
+
dmi_ack_1 <= dmi_ack_0;
|
|
97
|
+
end if;
|
|
98
|
+
end process;
|
|
99
|
+
jtag_bsy <= jtag_req or dmi_ack_1;
|
|
100
|
+
with shiftr(1 downto 0) select op_valid <=
|
|
101
|
+
'1' when dmi_req_rd,
|
|
102
|
+
'1' when dmi_req_wr,
|
|
103
|
+
'0' when others,;
|
|
104
|
+
rsp_op <= dmi_rsp_bsy when jtag_bsy = '1' else dmi_rsp_ok;
|
|
105
|
+
dmi_addr <= request(abits + dbits + 1 downto dbits + 2);
|
|
106
|
+
dmi_dout <= request(dbits + 1 downto 2);
|
|
107
|
+
dmi_wr <= '1' when request(1 downto 0) = dmi_req_wr else '0';
|
|
108
|
+
tdo <= shiftr(0);
|
|
109
|
+
|
|
110
|
+
shifter : process(jtag_clk,jtag_reset)
|
|
111
|
+
begin
|
|
112
|
+
if jtag_reset = '1' then
|
|
113
|
+
shiftr <= (others => '0');
|
|
114
|
+
jtag_req <= '0';
|
|
115
|
+
elsif rising_edge(jtag_clk) then
|
|
116
|
+
if sel = '1' then
|
|
117
|
+
if shift = '1' then
|
|
118
|
+
shiftr <= tdi & shiftr(abits + dbits + 1 downto 1);
|
|
119
|
+
end if;
|
|
120
|
+
if update = '1' and op_valid = '1' then
|
|
121
|
+
if jtag_bsy = '0' then
|
|
122
|
+
request <= shiftr;
|
|
123
|
+
jtag_req <= '1';
|
|
124
|
+
end if;
|
|
125
|
+
shiftr(1 downto 0) <= dmi_rsp_bsy;
|
|
126
|
+
end if;
|
|
127
|
+
if jtag_req = '1' and dmi_ack_1 = '1' then
|
|
128
|
+
jtag_req <= '0';
|
|
129
|
+
if request(1 downto 0) = dmi_req_rd then
|
|
130
|
+
request(dbits + 1 downto 2) <= dmi_din;
|
|
131
|
+
end if;
|
|
132
|
+
end if;
|
|
133
|
+
if capture = '1' then
|
|
134
|
+
shiftr <= request(abits + dbits + 1 downto 2) & rsp_op;
|
|
135
|
+
end if;
|
|
136
|
+
end if;
|
|
137
|
+
end if;
|
|
138
|
+
end process;
|
|
139
|
+
end behaviour;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
../microwatt/execute1.vhdl
|
|
@@ -0,0 +1,689 @@
|
|
|
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.decode_types.all;
|
|
7
|
+
use work.common.all;
|
|
8
|
+
use work.helpers.all;
|
|
9
|
+
use work.crhelpers.all;
|
|
10
|
+
use work.insn_helpers.all;
|
|
11
|
+
use work.ppc_fx_insns.all;
|
|
12
|
+
|
|
13
|
+
entity execute1 is
|
|
14
|
+
generic(
|
|
15
|
+
ex1_bypass : booleantrue := true);
|
|
16
|
+
port(
|
|
17
|
+
clk : in std_ulogic;
|
|
18
|
+
rst : in std_ulogic;
|
|
19
|
+
flush_out : out std_ulogic;
|
|
20
|
+
stall_out : out std_ulogic;
|
|
21
|
+
e_in : in decode2toexecute1type;
|
|
22
|
+
l_out : out execute1toloadstore1type;
|
|
23
|
+
f_out : out execute1tofetch1type;
|
|
24
|
+
e_out : out execute1towritebacktype;
|
|
25
|
+
icache_inval : out std_ulogic;
|
|
26
|
+
terminate_out : out std_ulogic);
|
|
27
|
+
end entity execute1;
|
|
28
|
+
|
|
29
|
+
architecture behaviour of execute1 is
|
|
30
|
+
|
|
31
|
+
type reg_type is record
|
|
32
|
+
e : execute1towritebacktype;
|
|
33
|
+
lr_update : std_ulogic;
|
|
34
|
+
next_lr : std_ulogic_vector(63 downto 0);
|
|
35
|
+
mul_in_progress : std_ulogic;
|
|
36
|
+
div_in_progress : std_ulogic;
|
|
37
|
+
cntz_in_progress : std_ulogic;
|
|
38
|
+
slow_op_dest : gpr_index_t;
|
|
39
|
+
slow_op_rc : std_ulogic;
|
|
40
|
+
slow_op_oe : std_ulogic;
|
|
41
|
+
slow_op_xerc : xer_common_t;
|
|
42
|
+
end record;
|
|
43
|
+
signal r : reg_type;
|
|
44
|
+
signal rin : reg_type;
|
|
45
|
+
signal a_in : std_ulogic_vector(63 downto 0);
|
|
46
|
+
signal b_in : std_ulogic_vector(63 downto 0);
|
|
47
|
+
signal c_in : std_ulogic_vector(63 downto 0);
|
|
48
|
+
signal ctrl : ctrl_t := (irq_state => write_srr0,others => (others => '0'));
|
|
49
|
+
signal ctrl_tmp : ctrl_t := (irq_state => write_srr0,others => (others => '0'));
|
|
50
|
+
signal right_shift : std_ulogic;
|
|
51
|
+
signal rot_clear_left : std_ulogic;
|
|
52
|
+
signal rot_clear_right : std_ulogic;
|
|
53
|
+
signal rotator_result : std_ulogic_vector(63 downto 0);
|
|
54
|
+
signal rotator_carry : std_ulogic;
|
|
55
|
+
signal logical_result : std_ulogic_vector(63 downto 0);
|
|
56
|
+
signal countzero_result : std_ulogic_vector(63 downto 0);
|
|
57
|
+
signal popcnt_result : std_ulogic_vector(63 downto 0);
|
|
58
|
+
signal parity_result : std_ulogic_vector(63 downto 0);
|
|
59
|
+
signal x_to_multiply : execute1tomultiplytype;
|
|
60
|
+
signal multiply_to_x : multiplytoexecute1type;
|
|
61
|
+
signal x_to_divider : execute1todividertype;
|
|
62
|
+
signal divider_to_x : dividertoexecute1type;
|
|
63
|
+
|
|
64
|
+
procedure set_carry(
|
|
65
|
+
e : inout execute1towritebacktype;
|
|
66
|
+
carry32 : in std_ulogic;
|
|
67
|
+
carry : in std_ulogic) is
|
|
68
|
+
begin
|
|
69
|
+
e.xerc.ca32 := carry32;
|
|
70
|
+
e.xerc.ca := carry;
|
|
71
|
+
e.write_xerc_enable := '1';
|
|
72
|
+
end set_carry;
|
|
73
|
+
|
|
74
|
+
procedure set_ov(
|
|
75
|
+
e : inout execute1towritebacktype;
|
|
76
|
+
ov : in std_ulogic;
|
|
77
|
+
ov32 : in std_ulogic) is
|
|
78
|
+
begin
|
|
79
|
+
e.xerc.ov32 := ov32;
|
|
80
|
+
e.xerc.ov := ov;
|
|
81
|
+
if ov = '1' then
|
|
82
|
+
e.xerc.so := '1';
|
|
83
|
+
end if;
|
|
84
|
+
e.write_xerc_enable := '1';
|
|
85
|
+
end set_ov;
|
|
86
|
+
|
|
87
|
+
function calc_ov(msb_a : std_ulogic;msb_b : std_ulogic;ca : std_ulogic;msb_r : std_ulogic) return std_ulogic is
|
|
88
|
+
begin
|
|
89
|
+
return (ca xor msb_r) and (msb_a xor msb_b);
|
|
90
|
+
end function calc_ov;
|
|
91
|
+
|
|
92
|
+
function decode_input_carry(ic : carry_in_t;xerc : xer_common_t) return std_ulogic is
|
|
93
|
+
begin
|
|
94
|
+
case ic is
|
|
95
|
+
when zero =>
|
|
96
|
+
return '0';
|
|
97
|
+
when ca =>
|
|
98
|
+
return xerc.ca;
|
|
99
|
+
when one =>
|
|
100
|
+
return '1';
|
|
101
|
+
end case;
|
|
102
|
+
end function decode_input_carry;
|
|
103
|
+
|
|
104
|
+
function msr_copy(msr : std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
|
105
|
+
variable msr_out : std_ulogic_vector(63 downto 0);
|
|
106
|
+
begin
|
|
107
|
+
msr_out := (others => '0');
|
|
108
|
+
msr_out(32 downto 0) := msr(32 downto 0);
|
|
109
|
+
msr_out(41 downto 37) := msr(41 downto 37);
|
|
110
|
+
msr_out(63 downto 48) := msr(63 downto 48);
|
|
111
|
+
return msr_out;
|
|
112
|
+
end function msr_copy;
|
|
113
|
+
begin
|
|
114
|
+
|
|
115
|
+
rotator_0 : entity work.rotator
|
|
116
|
+
port map(
|
|
117
|
+
rs => c_in,
|
|
118
|
+
ra => a_in,
|
|
119
|
+
shift => b_in(6 downto 0),
|
|
120
|
+
insn => e_in.insn,
|
|
121
|
+
is_32bit => e_in.is_32bit,
|
|
122
|
+
right_shift => right_shift,
|
|
123
|
+
arith => e_in.is_signed,
|
|
124
|
+
clear_left => rot_clear_left,
|
|
125
|
+
clear_right => rot_clear_right,
|
|
126
|
+
result => rotator_result,
|
|
127
|
+
carry_out => rotator_carry);
|
|
128
|
+
|
|
129
|
+
logical_0 : entity work.logical
|
|
130
|
+
port map(
|
|
131
|
+
rs => c_in,
|
|
132
|
+
rb => b_in,
|
|
133
|
+
op => e_in.insn_type,
|
|
134
|
+
invert_in => e_in.invert_a,
|
|
135
|
+
invert_out => e_in.invert_out,
|
|
136
|
+
result => logical_result,
|
|
137
|
+
datalen => e_in.data_len,
|
|
138
|
+
popcnt => popcnt_result,
|
|
139
|
+
parity => parity_result);
|
|
140
|
+
|
|
141
|
+
countzero_0 : entity work.zero_counter
|
|
142
|
+
port map(
|
|
143
|
+
clk => clk,
|
|
144
|
+
rs => c_in,
|
|
145
|
+
count_right => e_in.insn(10),
|
|
146
|
+
is_32bit => e_in.is_32bit,
|
|
147
|
+
result => countzero_result);
|
|
148
|
+
|
|
149
|
+
multiply_0 : entity work.multiply
|
|
150
|
+
port map(
|
|
151
|
+
clk => clk,
|
|
152
|
+
m_in => x_to_multiply,
|
|
153
|
+
m_out => multiply_to_x);
|
|
154
|
+
|
|
155
|
+
divider_0 : entity work.divider
|
|
156
|
+
port map(
|
|
157
|
+
clk => clk,
|
|
158
|
+
rst => rst,
|
|
159
|
+
d_in => x_to_divider,
|
|
160
|
+
d_out => divider_to_x);
|
|
161
|
+
|
|
162
|
+
a_in <= r.e.write_data when ex1_bypass and e_in.bypass_data1 = '1' else e_in.read_data1;
|
|
163
|
+
b_in <= r.e.write_data when ex1_bypass and e_in.bypass_data2 = '1' else e_in.read_data2;
|
|
164
|
+
c_in <= r.e.write_data when ex1_bypass and e_in.bypass_data3 = '1' else e_in.read_data3;
|
|
165
|
+
|
|
166
|
+
execute1_0 : process(clk)
|
|
167
|
+
begin
|
|
168
|
+
if rising_edge(clk) then
|
|
169
|
+
r <= rin;
|
|
170
|
+
ctrl <= ctrl_tmp;
|
|
171
|
+
assert (r.lr_update = '1' and e_in.valid = '1')
|
|
172
|
+
report "lr update collision with valid in ex1" severity failure;
|
|
173
|
+
if r.lr_update = '1' then
|
|
174
|
+
report "lr update to " & to_hstring(r.next_lr);
|
|
175
|
+
end if;
|
|
176
|
+
end if;
|
|
177
|
+
end process;
|
|
178
|
+
|
|
179
|
+
execute1_1 : process(all)
|
|
180
|
+
variable v : reg_type;
|
|
181
|
+
variable a_inv : std_ulogic_vector(63 downto 0);
|
|
182
|
+
variable result : std_ulogic_vector(63 downto 0);
|
|
183
|
+
variable newcrf : std_ulogic_vector(3 downto 0);
|
|
184
|
+
variable result_with_carry : std_ulogic_vector(64 downto 0);
|
|
185
|
+
variable result_en : std_ulogic;
|
|
186
|
+
variable crnum : crnum_t;
|
|
187
|
+
variable crbit : integer range 0 to 31;
|
|
188
|
+
variable scrnum : crnum_t;
|
|
189
|
+
variable lo : integer;
|
|
190
|
+
variable hi : integer;
|
|
191
|
+
variable sh : std_ulogic_vector(5 downto 0);
|
|
192
|
+
variable mb : std_ulogic_vector(5 downto 0);
|
|
193
|
+
variable me : std_ulogic_vector(5 downto 0);
|
|
194
|
+
variable sh32 : std_ulogic_vector(4 downto 0);
|
|
195
|
+
variable mb32 : std_ulogic_vector(4 downto 0);
|
|
196
|
+
variable me32 : std_ulogic_vector(4 downto 0);
|
|
197
|
+
variable bo : std_ulogic_vector(4 downto 0);
|
|
198
|
+
variable bi : std_ulogic_vector(4 downto 0);
|
|
199
|
+
variable bf : std_ulogic_vector(2 downto 0);
|
|
200
|
+
variable bfa : std_ulogic_vector(2 downto 0);
|
|
201
|
+
variable cr_op : std_ulogic_vector(9 downto 0);
|
|
202
|
+
variable cr_operands : std_ulogic_vector(1 downto 0);
|
|
203
|
+
variable bt : std_ulogic_vector(4 downto 0);
|
|
204
|
+
variable ba : std_ulogic_vector(4 downto 0);
|
|
205
|
+
variable bb : std_ulogic_vector(4 downto 0);
|
|
206
|
+
variable btnum : integer range 0 to 31;
|
|
207
|
+
variable banum : integer range 0 to 31;
|
|
208
|
+
variable bbnum : integer range 0 to 31;
|
|
209
|
+
variable crresult : std_ulogic;
|
|
210
|
+
variable l : std_ulogic;
|
|
211
|
+
variable next_nia : std_ulogic_vector(63 downto 0);
|
|
212
|
+
variable carry_32 : std_ulogic;
|
|
213
|
+
variable carry_64 : std_ulogic;
|
|
214
|
+
variable sign1 : std_ulogic;
|
|
215
|
+
variable sign2 : std_ulogic;
|
|
216
|
+
variable abs1 : signed(63 downto 0);
|
|
217
|
+
variable abs2 : signed(63 downto 0);
|
|
218
|
+
variable overflow : std_ulogic;
|
|
219
|
+
variable negative : std_ulogic;
|
|
220
|
+
variable zerohi : std_ulogic;
|
|
221
|
+
variable zerolo : std_ulogic;
|
|
222
|
+
variable msb_a : std_ulogic;
|
|
223
|
+
variable msb_b : std_ulogic;
|
|
224
|
+
variable a_lt : std_ulogic;
|
|
225
|
+
variable lv : execute1toloadstore1type;
|
|
226
|
+
variable irq_valid : std_ulogic;
|
|
227
|
+
variable exception : std_ulogic;
|
|
228
|
+
begin
|
|
229
|
+
result := (others => '0');
|
|
230
|
+
result_with_carry := (others => '0');
|
|
231
|
+
result_en := '0';
|
|
232
|
+
newcrf := (others => '0');
|
|
233
|
+
v := r;
|
|
234
|
+
v.e := execute1towritebackinit;
|
|
235
|
+
if r.e.write_xerc_enable = '1' then
|
|
236
|
+
v.e.xerc := r.e.xerc;
|
|
237
|
+
else
|
|
238
|
+
v.e.xerc := e_in.xerc;
|
|
239
|
+
end if;
|
|
240
|
+
v.lr_update := '0';
|
|
241
|
+
v.mul_in_progress := '0';
|
|
242
|
+
v.div_in_progress := '0';
|
|
243
|
+
v.cntz_in_progress := '0';
|
|
244
|
+
x_to_multiply <= execute1tomultiplyinit;
|
|
245
|
+
x_to_multiply.insn_type <= e_in.insn_type;
|
|
246
|
+
x_to_multiply.is_32bit <= e_in.is_32bit;
|
|
247
|
+
if e_in.is_32bit = '1' then
|
|
248
|
+
if e_in.is_signed = '1' then
|
|
249
|
+
x_to_multiply.data1 <= (others => a_in(31));
|
|
250
|
+
x_to_multiply.data1(31 downto 0) <= a_in(31 downto 0);
|
|
251
|
+
x_to_multiply.data2 <= (others => b_in(31));
|
|
252
|
+
x_to_multiply.data2(31 downto 0) <= b_in(31 downto 0);
|
|
253
|
+
else
|
|
254
|
+
x_to_multiply.data1 <= '0' & x"00000000" & a_in(31 downto 0);
|
|
255
|
+
x_to_multiply.data2 <= '0' & x"00000000" & b_in(31 downto 0);
|
|
256
|
+
end if;
|
|
257
|
+
else
|
|
258
|
+
if e_in.is_signed = '1' then
|
|
259
|
+
x_to_multiply.data1 <= a_in(63) & a_in;
|
|
260
|
+
x_to_multiply.data2 <= b_in(63) & b_in;
|
|
261
|
+
else
|
|
262
|
+
x_to_multiply.data1 <= '0' & a_in;
|
|
263
|
+
x_to_multiply.data2 <= '0' & b_in;
|
|
264
|
+
end if;
|
|
265
|
+
end if;
|
|
266
|
+
sign1 := '0';
|
|
267
|
+
sign2 := '0';
|
|
268
|
+
if e_in.is_signed = '1' then
|
|
269
|
+
if e_in.is_32bit = '1' then
|
|
270
|
+
sign1 := a_in(31);
|
|
271
|
+
sign2 := b_in(31);
|
|
272
|
+
else
|
|
273
|
+
sign1 := a_in(63);
|
|
274
|
+
sign2 := b_in(63);
|
|
275
|
+
end if;
|
|
276
|
+
end if;
|
|
277
|
+
if sign1 = '0' then
|
|
278
|
+
abs1 := signed(a_in);
|
|
279
|
+
else
|
|
280
|
+
abs1 := signed(a_in);
|
|
281
|
+
end if;
|
|
282
|
+
if sign2 = '0' then
|
|
283
|
+
abs2 := signed(b_in);
|
|
284
|
+
else
|
|
285
|
+
abs2 := signed(b_in);
|
|
286
|
+
end if;
|
|
287
|
+
x_to_divider <= execute1todividerinit;
|
|
288
|
+
x_to_divider.is_signed <= e_in.is_signed;
|
|
289
|
+
x_to_divider.is_32bit <= e_in.is_32bit;
|
|
290
|
+
if e_in.insn_type = op_mod then
|
|
291
|
+
x_to_divider.is_modulus <= '1';
|
|
292
|
+
end if;
|
|
293
|
+
x_to_divider.neg_result <= sign1 xor (sign2 and x_to_divider.is_modulus);
|
|
294
|
+
if e_in.is_32bit = '0' then
|
|
295
|
+
if e_in.insn_type = op_dive then
|
|
296
|
+
x_to_divider.is_extended <= '1';
|
|
297
|
+
end if;
|
|
298
|
+
x_to_divider.dividend <= std_ulogic_vector(abs1);
|
|
299
|
+
x_to_divider.divisor <= std_ulogic_vector(abs2);
|
|
300
|
+
else
|
|
301
|
+
x_to_divider.is_extended <= '0';
|
|
302
|
+
if e_in.insn_type = op_dive then
|
|
303
|
+
x_to_divider.dividend <= std_ulogic_vector(abs1(31 downto 0)) & x"00000000";
|
|
304
|
+
else
|
|
305
|
+
x_to_divider.dividend <= x"00000000" & std_ulogic_vector(abs1(31 downto 0));
|
|
306
|
+
end if;
|
|
307
|
+
x_to_divider.divisor <= x"00000000" & std_ulogic_vector(abs2(31 downto 0));
|
|
308
|
+
end if;
|
|
309
|
+
ctrl_tmp <= ctrl;
|
|
310
|
+
ctrl_tmp.tb <= std_ulogic_vector(unsigned(ctrl.tb) + 1);
|
|
311
|
+
ctrl_tmp.dec <= std_ulogic_vector(unsigned(ctrl.dec) - 1);
|
|
312
|
+
irq_valid := '0';
|
|
313
|
+
if ctrl.msr(63 - 48) = '1' and ctrl.dec(63) = '1' then
|
|
314
|
+
report "irq valid";
|
|
315
|
+
irq_valid := '1';
|
|
316
|
+
end if;
|
|
317
|
+
terminate_out <= '0';
|
|
318
|
+
icache_inval <= '0';
|
|
319
|
+
stall_out <= '0';
|
|
320
|
+
f_out <= execute1tofetch1typeinit;
|
|
321
|
+
next_nia := std_ulogic_vector(unsigned(e_in.nia) + 4);
|
|
322
|
+
right_shift <= '1' when e_in.insn_type = op_shr else '0';
|
|
323
|
+
rot_clear_left <= '1' when e_in.insn_type = op_rlc or e_in.insn_type = op_rlcl else '0';
|
|
324
|
+
rot_clear_right <= '1' when e_in.insn_type = op_rlc or e_in.insn_type = op_rlcr else '0';
|
|
325
|
+
ctrl_tmp.irq_state <= write_srr0;
|
|
326
|
+
exception := '0';
|
|
327
|
+
if ctrl.irq_state = write_srr1 then
|
|
328
|
+
v.e.write_reg := fast_spr_num(spr_srr1);
|
|
329
|
+
result := ctrl.srr1;
|
|
330
|
+
result_en := '1';
|
|
331
|
+
ctrl_tmp.msr(63 - 48) <= '0';
|
|
332
|
+
f_out.redirect <= '1';
|
|
333
|
+
f_out.redirect_nia <= ctrl.irq_nia;
|
|
334
|
+
v.e.valid := '1';
|
|
335
|
+
report "writing srr1: " & to_hstring(ctrl.srr1);
|
|
336
|
+
elsif irq_valid = '1' then
|
|
337
|
+
exception := '1';
|
|
338
|
+
ctrl_tmp.irq_nia <= std_logic_vector(to_unsigned(16#900#,64));
|
|
339
|
+
ctrl_tmp.srr1 <= msr_copy(ctrl.msr);
|
|
340
|
+
result := e_in.nia;
|
|
341
|
+
elsif e_in.valid = '1' then
|
|
342
|
+
v.e.valid := '1';
|
|
343
|
+
v.e.write_reg := e_in.write_reg;
|
|
344
|
+
v.slow_op_dest := gspr_to_gpr(e_in.write_reg);
|
|
345
|
+
v.slow_op_rc := e_in.rc;
|
|
346
|
+
v.slow_op_oe := e_in.oe;
|
|
347
|
+
v.slow_op_xerc := v.e.xerc;
|
|
348
|
+
case e_in.insn_type is
|
|
349
|
+
when op_illegal =>
|
|
350
|
+
exception := '1';
|
|
351
|
+
ctrl_tmp.irq_nia <= std_logic_vector(to_unsigned(16#700#,64));
|
|
352
|
+
ctrl_tmp.srr1 <= msr_copy(ctrl.msr);
|
|
353
|
+
ctrl_tmp.srr1(63 - 44) <= '1';
|
|
354
|
+
result := e_in.nia;
|
|
355
|
+
report "illegal";
|
|
356
|
+
when op_sc =>
|
|
357
|
+
exception := '1';
|
|
358
|
+
ctrl_tmp.irq_nia <= std_logic_vector(to_unsigned(16#c00#,64));
|
|
359
|
+
ctrl_tmp.srr1 <= msr_copy(ctrl.msr);
|
|
360
|
+
result := std_logic_vector(unsigned(e_in.nia) + 4);
|
|
361
|
+
report "sc";
|
|
362
|
+
when op_attn =>
|
|
363
|
+
terminate_out <= '1';
|
|
364
|
+
report "attn";
|
|
365
|
+
when op_nop =>
|
|
366
|
+
when op_add | op_cmp =>
|
|
367
|
+
if e_in.invert_a = '0' then
|
|
368
|
+
a_inv := a_in;
|
|
369
|
+
else
|
|
370
|
+
a_inv := a_in;
|
|
371
|
+
end if;
|
|
372
|
+
result_with_carry := ppc_adde(a_inv,b_in,decode_input_carry(e_in.input_carry,v.e.xerc));
|
|
373
|
+
result := result_with_carry(63 downto 0);
|
|
374
|
+
carry_32 := result(32) xor a_inv(32) xor b_in(32);
|
|
375
|
+
carry_64 := result_with_carry(64);
|
|
376
|
+
if e_in.insn_type = op_add then
|
|
377
|
+
if e_in.output_carry = '1' then
|
|
378
|
+
()
|
|
379
|
+
end if;
|
|
380
|
+
if e_in.oe = '1' then
|
|
381
|
+
()
|
|
382
|
+
end if;
|
|
383
|
+
result_en := '1';
|
|
384
|
+
else
|
|
385
|
+
bf := insn_bf(e_in.insn);
|
|
386
|
+
l := insn_l(e_in.insn);
|
|
387
|
+
v.e.write_cr_enable := '1';
|
|
388
|
+
crnum := to_integer(unsigned(bf));
|
|
389
|
+
v.e.write_cr_mask := num_to_fxm(crnum);
|
|
390
|
+
zerolo := (or(a_in(31 downto 0) xor b_in(31 downto 0)));
|
|
391
|
+
zerohi := (or(a_in(63 downto 32) xor b_in(63 downto 32)));
|
|
392
|
+
if zerolo = '1' and (l = '0' or zerohi = '1') then
|
|
393
|
+
newcrf := "001" & v.e.xerc.so;
|
|
394
|
+
else
|
|
395
|
+
if l = '1' then
|
|
396
|
+
msb_a := a_in(63);
|
|
397
|
+
msb_b := b_in(63);
|
|
398
|
+
else
|
|
399
|
+
msb_a := a_in(31);
|
|
400
|
+
msb_b := b_in(31);
|
|
401
|
+
end if;
|
|
402
|
+
if msb_a /= msb_b then
|
|
403
|
+
a_lt := msb_a xnor e_in.is_signed;
|
|
404
|
+
else
|
|
405
|
+
a_lt := (l and carry_32) or (l and carry_64);
|
|
406
|
+
end if;
|
|
407
|
+
newcrf := a_lt & a_lt & '0' & v.e.xerc.so;
|
|
408
|
+
end if;
|
|
409
|
+
end if;
|
|
410
|
+
when op_and | op_or | op_xor =>
|
|
411
|
+
result := logical_result;
|
|
412
|
+
result_en := '1';
|
|
413
|
+
when op_b =>
|
|
414
|
+
f_out.redirect <= '1';
|
|
415
|
+
if (insn_aa(e_in.insn)) then
|
|
416
|
+
f_out.redirect_nia <= std_ulogic_vector(signed(b_in));
|
|
417
|
+
else
|
|
418
|
+
f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(b_in));
|
|
419
|
+
end if;
|
|
420
|
+
when op_bc =>
|
|
421
|
+
bo := insn_bo(e_in.insn);
|
|
422
|
+
bi := insn_bi(e_in.insn);
|
|
423
|
+
if bo(4 - 2) = '0' then
|
|
424
|
+
result := std_ulogic_vector(unsigned(a_in) - 1);
|
|
425
|
+
result_en := '1';
|
|
426
|
+
v.e.write_reg := fast_spr_num(spr_ctr);
|
|
427
|
+
end if;
|
|
428
|
+
if ppc_bc_taken(bo,bi,e_in.cr,a_in) = 1 then
|
|
429
|
+
f_out.redirect <= '1';
|
|
430
|
+
if (insn_aa(e_in.insn)) then
|
|
431
|
+
f_out.redirect_nia <= std_ulogic_vector(signed(b_in));
|
|
432
|
+
else
|
|
433
|
+
f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(b_in));
|
|
434
|
+
end if;
|
|
435
|
+
end if;
|
|
436
|
+
when op_bcreg =>
|
|
437
|
+
bo := insn_bo(e_in.insn);
|
|
438
|
+
bi := insn_bi(e_in.insn);
|
|
439
|
+
if bo(4 - 2) = '0' and e_in.insn(10) = '0' then
|
|
440
|
+
result := std_ulogic_vector(unsigned(a_in) - 1);
|
|
441
|
+
result_en := '1';
|
|
442
|
+
v.e.write_reg := fast_spr_num(spr_ctr);
|
|
443
|
+
end if;
|
|
444
|
+
if ppc_bc_taken(bo,bi,e_in.cr,a_in) = 1 then
|
|
445
|
+
f_out.redirect <= '1';
|
|
446
|
+
f_out.redirect_nia <= b_in(63 downto 2) & "00";
|
|
447
|
+
end if;
|
|
448
|
+
when op_rfid =>
|
|
449
|
+
f_out.redirect <= '1';
|
|
450
|
+
f_out.redirect_nia <= a_in(63 downto 2) & "00";
|
|
451
|
+
ctrl_tmp.msr <= msr_copy(std_ulogic_vector(signed(b_in)));
|
|
452
|
+
when op_cmpb =>
|
|
453
|
+
result := ppc_cmpb(c_in,b_in);
|
|
454
|
+
result_en := '1';
|
|
455
|
+
when op_cntz =>
|
|
456
|
+
v.e.valid := '0';
|
|
457
|
+
v.cntz_in_progress := '1';
|
|
458
|
+
stall_out <= '1';
|
|
459
|
+
when op_exts =>
|
|
460
|
+
negative := (e_in.data_len(0) and c_in(7)) or (e_in.data_len(1) and c_in(15)) or (e_in.data_len(2) and c_in(31));
|
|
461
|
+
result := (others => negative);
|
|
462
|
+
if e_in.data_len(2) = '1' then
|
|
463
|
+
result(31 downto 16) := c_in(31 downto 16);
|
|
464
|
+
end if;
|
|
465
|
+
if e_in.data_len(2) = '1' or e_in.data_len(1) = '1' then
|
|
466
|
+
result(15 downto 8) := c_in(15 downto 8);
|
|
467
|
+
end if;
|
|
468
|
+
result(7 downto 0) := c_in(7 downto 0);
|
|
469
|
+
result_en := '1';
|
|
470
|
+
when op_isel =>
|
|
471
|
+
crbit := to_integer(unsigned(insn_bc(e_in.insn)));
|
|
472
|
+
if e_in.cr(31 - crbit) = '1' then
|
|
473
|
+
result := a_in;
|
|
474
|
+
else
|
|
475
|
+
result := b_in;
|
|
476
|
+
end if;
|
|
477
|
+
result_en := '1';
|
|
478
|
+
when op_mcrf =>
|
|
479
|
+
cr_op := insn_cr(e_in.insn);
|
|
480
|
+
report "cr op " & to_hstring(cr_op);
|
|
481
|
+
if cr_op(0) = '0' then
|
|
482
|
+
bf := insn_bf(e_in.insn);
|
|
483
|
+
bfa := insn_bfa(e_in.insn);
|
|
484
|
+
v.e.write_cr_enable := '1';
|
|
485
|
+
crnum := to_integer(unsigned(bf));
|
|
486
|
+
scrnum := to_integer(unsigned(bfa));
|
|
487
|
+
v.e.write_cr_mask := num_to_fxm(crnum);
|
|
488
|
+
;
|
|
489
|
+
else
|
|
490
|
+
v.e.write_cr_enable := '1';
|
|
491
|
+
bt := insn_bt(e_in.insn);
|
|
492
|
+
ba := insn_ba(e_in.insn);
|
|
493
|
+
bb := insn_bb(e_in.insn);
|
|
494
|
+
btnum := 31 - to_integer(unsigned(bt));
|
|
495
|
+
banum := 31 - to_integer(unsigned(ba));
|
|
496
|
+
bbnum := 31 - to_integer(unsigned(bb));
|
|
497
|
+
cr_operands := e_in.cr(banum) & e_in.cr(bbnum);
|
|
498
|
+
crresult := cr_op(5 + to_integer(unsigned(cr_operands)));
|
|
499
|
+
v.e.write_cr_mask := num_to_fxm((31 - btnum) / 4);
|
|
500
|
+
end if;
|
|
501
|
+
when op_mfmsr =>
|
|
502
|
+
result := msr_copy(ctrl.msr);
|
|
503
|
+
result_en := '1';
|
|
504
|
+
when op_mfspr =>
|
|
505
|
+
report "mfspr to spr " & integer'image(decode_spr_num(e_in.insn)) & "=" & to_hstring(a_in);
|
|
506
|
+
if is_fast_spr(e_in.read_reg1) then
|
|
507
|
+
result := a_in;
|
|
508
|
+
if decode_spr_num(e_in.insn) = spr_xer then
|
|
509
|
+
result(63 downto 32) := (others => '0');
|
|
510
|
+
result(63 - 32) := v.e.xerc.so;
|
|
511
|
+
result(63 - 33) := v.e.xerc.ov;
|
|
512
|
+
result(63 - 34) := v.e.xerc.ca;
|
|
513
|
+
result(63 - 35 downto 63 - 43) := "000000000";
|
|
514
|
+
result(63 - 44) := v.e.xerc.ov32;
|
|
515
|
+
result(63 - 45) := v.e.xerc.ca32;
|
|
516
|
+
end if;
|
|
517
|
+
else
|
|
518
|
+
case decode_spr_num(e_in.insn) is
|
|
519
|
+
when spr_tb =>
|
|
520
|
+
result := ctrl.tb;
|
|
521
|
+
when spr_dec =>
|
|
522
|
+
result := ctrl.dec;
|
|
523
|
+
when others =>
|
|
524
|
+
result := (others => '0');
|
|
525
|
+
end case;
|
|
526
|
+
end if;
|
|
527
|
+
result_en := '1';
|
|
528
|
+
when op_mfcr =>
|
|
529
|
+
if e_in.insn(20) = '0' then
|
|
530
|
+
result := x"00000000" & e_in.cr;
|
|
531
|
+
else
|
|
532
|
+
crnum := fxm_to_num(insn_fxm(e_in.insn));
|
|
533
|
+
result := (others => '0');
|
|
534
|
+
end if;
|
|
535
|
+
result_en := '1';
|
|
536
|
+
when op_mtcrf =>
|
|
537
|
+
v.e.write_cr_enable := '1';
|
|
538
|
+
if e_in.insn(20) = '0' then
|
|
539
|
+
v.e.write_cr_mask := insn_fxm(e_in.insn);
|
|
540
|
+
else
|
|
541
|
+
crnum := fxm_to_num(insn_fxm(e_in.insn));
|
|
542
|
+
v.e.write_cr_mask := num_to_fxm(crnum);
|
|
543
|
+
end if;
|
|
544
|
+
v.e.write_cr_data := c_in(31 downto 0);
|
|
545
|
+
when op_mtmsrd =>
|
|
546
|
+
ctrl_tmp.msr <= msr_copy(c_in);
|
|
547
|
+
when op_mtspr =>
|
|
548
|
+
report "mtspr to spr " & integer'image(decode_spr_num(e_in.insn)) & "=" & to_hstring(c_in);
|
|
549
|
+
if is_fast_spr(e_in.write_reg) then
|
|
550
|
+
result := c_in;
|
|
551
|
+
result_en := '1';
|
|
552
|
+
if decode_spr_num(e_in.insn) = spr_xer then
|
|
553
|
+
v.e.xerc.so := c_in(63 - 32);
|
|
554
|
+
v.e.xerc.ov := c_in(63 - 33);
|
|
555
|
+
v.e.xerc.ca := c_in(63 - 34);
|
|
556
|
+
v.e.xerc.ov32 := c_in(63 - 44);
|
|
557
|
+
v.e.xerc.ca32 := c_in(63 - 45);
|
|
558
|
+
v.e.write_xerc_enable := '1';
|
|
559
|
+
end if;
|
|
560
|
+
else
|
|
561
|
+
case decode_spr_num(e_in.insn) is
|
|
562
|
+
when spr_dec =>
|
|
563
|
+
ctrl_tmp.dec <= c_in;
|
|
564
|
+
when others =>
|
|
565
|
+
end case;
|
|
566
|
+
end if;
|
|
567
|
+
when op_popcnt =>
|
|
568
|
+
result := popcnt_result;
|
|
569
|
+
result_en := '1';
|
|
570
|
+
when op_prty =>
|
|
571
|
+
result := parity_result;
|
|
572
|
+
result_en := '1';
|
|
573
|
+
when op_rlc | op_rlcl | op_rlcr | op_shl | op_shr =>
|
|
574
|
+
result := rotator_result;
|
|
575
|
+
if e_in.output_carry = '1' then
|
|
576
|
+
()
|
|
577
|
+
end if;
|
|
578
|
+
result_en := '1';
|
|
579
|
+
when op_sim_config =>
|
|
580
|
+
result := x"0000000000000000";
|
|
581
|
+
result_en := '1';
|
|
582
|
+
when op_tdi =>
|
|
583
|
+
report "op_tdi fixme";
|
|
584
|
+
when op_isync =>
|
|
585
|
+
f_out.redirect <= '1';
|
|
586
|
+
f_out.redirect_nia <= next_nia;
|
|
587
|
+
when op_icbi =>
|
|
588
|
+
icache_inval <= '1';
|
|
589
|
+
when op_mul_l64 | op_mul_h64 | op_mul_h32 =>
|
|
590
|
+
v.e.valid := '0';
|
|
591
|
+
v.mul_in_progress := '1';
|
|
592
|
+
stall_out <= '1';
|
|
593
|
+
x_to_multiply.valid <= '1';
|
|
594
|
+
when op_div | op_dive | op_mod =>
|
|
595
|
+
v.e.valid := '0';
|
|
596
|
+
v.div_in_progress := '1';
|
|
597
|
+
stall_out <= '1';
|
|
598
|
+
x_to_divider.valid <= '1';
|
|
599
|
+
when op_load | op_store =>
|
|
600
|
+
v.e.valid := '0';
|
|
601
|
+
when others =>
|
|
602
|
+
terminate_out <= '1';
|
|
603
|
+
report "illegal";
|
|
604
|
+
end case;
|
|
605
|
+
v.e.rc := e_in.rc and e_in.valid;
|
|
606
|
+
if e_in.lr = '1' then
|
|
607
|
+
v.lr_update := '1';
|
|
608
|
+
v.next_lr := next_nia;
|
|
609
|
+
v.e.valid := '0';
|
|
610
|
+
report "delayed lr update to " & to_hstring(next_nia);
|
|
611
|
+
stall_out <= '1';
|
|
612
|
+
end if;
|
|
613
|
+
elsif r.lr_update = '1' then
|
|
614
|
+
result_en := '1';
|
|
615
|
+
result := r.next_lr;
|
|
616
|
+
v.e.write_reg := fast_spr_num(spr_lr);
|
|
617
|
+
v.e.valid := '1';
|
|
618
|
+
elsif r.cntz_in_progress = '1' then
|
|
619
|
+
result := countzero_result;
|
|
620
|
+
result_en := '1';
|
|
621
|
+
v.e.write_reg := gpr_to_gspr(v.slow_op_dest);
|
|
622
|
+
v.e.rc := v.slow_op_rc;
|
|
623
|
+
v.e.xerc := v.slow_op_xerc;
|
|
624
|
+
v.e.valid := '1';
|
|
625
|
+
elsif r.mul_in_progress = '1' or r.div_in_progress = '1' then
|
|
626
|
+
if (r.mul_in_progress = '1' and multiply_to_x.valid = '1') or (r.div_in_progress = '1' and divider_to_x.valid = '1') then
|
|
627
|
+
if r.mul_in_progress = '1' then
|
|
628
|
+
result := multiply_to_x.write_reg_data;
|
|
629
|
+
overflow := multiply_to_x.overflow;
|
|
630
|
+
else
|
|
631
|
+
result := divider_to_x.write_reg_data;
|
|
632
|
+
overflow := divider_to_x.overflow;
|
|
633
|
+
end if;
|
|
634
|
+
result_en := '1';
|
|
635
|
+
v.e.write_reg := gpr_to_gspr(v.slow_op_dest);
|
|
636
|
+
v.e.rc := v.slow_op_rc;
|
|
637
|
+
v.e.xerc := v.slow_op_xerc;
|
|
638
|
+
v.e.write_xerc_enable := v.slow_op_oe;
|
|
639
|
+
if v.slow_op_oe = '1' then
|
|
640
|
+
v.e.xerc.ov := overflow;
|
|
641
|
+
v.e.xerc.ov32 := overflow;
|
|
642
|
+
v.e.xerc.so := v.slow_op_xerc.so or overflow;
|
|
643
|
+
end if;
|
|
644
|
+
v.e.valid := '1';
|
|
645
|
+
else
|
|
646
|
+
stall_out <= '1';
|
|
647
|
+
v.mul_in_progress := r.mul_in_progress;
|
|
648
|
+
v.div_in_progress := r.div_in_progress;
|
|
649
|
+
end if;
|
|
650
|
+
end if;
|
|
651
|
+
if exception = '1' then
|
|
652
|
+
v.e.write_reg := fast_spr_num(spr_srr0);
|
|
653
|
+
if e_in.valid = '1' then
|
|
654
|
+
result_en := '1';
|
|
655
|
+
ctrl_tmp.irq_state <= write_srr1;
|
|
656
|
+
stall_out <= '1';
|
|
657
|
+
v.e.valid := '0';
|
|
658
|
+
end if;
|
|
659
|
+
end if;
|
|
660
|
+
v.e.write_data := result;
|
|
661
|
+
v.e.write_enable := result_en;
|
|
662
|
+
lv := execute1toloadstore1init;
|
|
663
|
+
if e_in.valid = '1' and (e_in.insn_type = op_load or e_in.insn_type = op_store) then
|
|
664
|
+
lv.valid := '1';
|
|
665
|
+
end if;
|
|
666
|
+
if e_in.insn_type = op_load then
|
|
667
|
+
lv.load := '1';
|
|
668
|
+
end if;
|
|
669
|
+
lv.addr1 := a_in;
|
|
670
|
+
lv.addr2 := b_in;
|
|
671
|
+
lv.data := c_in;
|
|
672
|
+
lv.write_reg := gspr_to_gpr(e_in.write_reg);
|
|
673
|
+
lv.length := e_in.data_len;
|
|
674
|
+
lv.byte_reverse := e_in.byte_reverse;
|
|
675
|
+
lv.sign_extend := e_in.sign_extend;
|
|
676
|
+
lv.update := e_in.update;
|
|
677
|
+
lv.update_reg := gspr_to_gpr(e_in.read_reg1);
|
|
678
|
+
lv.xerc := v.e.xerc;
|
|
679
|
+
lv.reserve := e_in.reserve;
|
|
680
|
+
lv.rc := e_in.rc;
|
|
681
|
+
if e_in.insn(31 downto 26) = "011111" and e_in.insn(10 downto 9) = "11" and e_in.insn(5 downto 1) = "10101" then
|
|
682
|
+
lv.ci := '1';
|
|
683
|
+
end if;
|
|
684
|
+
rin <= v;
|
|
685
|
+
l_out <= lv;
|
|
686
|
+
e_out <= r.e;
|
|
687
|
+
flush_out <= f_out.redirect;
|
|
688
|
+
end process;
|
|
689
|
+
end behaviour;
|