-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrv32.vhd
132 lines (120 loc) · 4.52 KB
/
rv32.vhd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
entity RV32 is
port (
clk_i : in std_logic; -- Clock input
rst_i : in std_logic; -- Active-high reset input
instr_addr_o : out std_logic_vector(31 downto 0); -- 32-bit instruction address
instr_data_i : in std_logic_vector(31 downto 0); -- 32-bit instruction data
mem_we_o : out std_logic; -- Active-high memory write strobe
mem_addr_o : out std_logic_vector(31 downto 0); -- 32-bit memory address
mem_data_i : in std_logic_vector(31 downto 0); -- 32-bit read memory data
mem_data_o : out std_logic_vector(31 downto 0) -- 32-bit write memory data
);
end;
architecture core of RV32 is
function ToInt(v : std_logic_vector) return integer is
begin
return to_integer(unsigned(v));
end function;
signal instr_addr_buf : std_logic_vector(31 downto 0) := X"00000000";
signal reg_deb : std_logic_vector(31 downto 0) := X"00000000";
-- signal reg_x1 : std_logic_vector(31 downto 0);
-- signal reg_x2 : std_logic_vector(31 downto 0);
-- signal reg_x3 : std_logic_vector(31 downto 0);
constant REGNUMBER : integer := 4;
type registr_type is array (0 to REGNUMBER-1) of std_logic_vector(31 downto 0);
signal rex_x : registr_type :=(
0 => X"00000000",
1 => X"00000000",
2 => X"00000000",
3 => X"00000000"
);
signal debug : integer := 0;
begin
process(clk_i)
begin
if rising_edge(clk_i) then
if rst_i = '0' then -- rst 0 chek
if instr_data_i(1 downto 0) = "11" then -- if it is a command
case instr_data_i(6 downto 2) is
when "00100" => -- I-type
case instr_data_i(14 downto 12) is
when "000" => -- addi
reg_deb <=
rex_x(ToInt(instr_data_i(19 downto 15)))
+ instr_data_i(31 downto 20);
rex_x(ToInt(instr_data_i(11 downto 7))) <=
rex_x(ToInt(instr_data_i(19 downto 15)))
+ instr_data_i(31 downto 20);
when "111" => -- andi
rex_x(ToInt(instr_data_i(11 downto 7))) <=
rex_x(ToInt(instr_data_i(19 downto 15)))
and (instr_data_i(31 downto 20) + X"00000000");
reg_deb <=
rex_x(ToInt(instr_data_i(19 downto 15)))
and (instr_data_i(31 downto 20) + X"00000000");
when others =>
null;
end case;
when "01000" => -- S-type, memory
case instr_data_i(14 downto 12) is
when "010" => -- sw
-- if clk_i = '0' then
-- mem_we_o <= '0';
-- else
mem_we_o <= '1';
mem_addr_o <=
rex_x(ToInt(instr_data_i(19 downto 15)))
+ (instr_data_i(31 downto 25)*"100000" + instr_data_i(11 downto 7));
mem_data_o <=
rex_x(ToInt(instr_data_i(24 downto 20)));
when others =>
null;
end case;
when "00000" => -- I-type, memory
case instr_data_i(14 downto 12) is
when "010" => -- lw
mem_we_o <= '0';
mem_addr_o <=
rex_x(ToInt(instr_data_i(19 downto 15)))
+ instr_data_i(31 downto 20);
reg_deb <=
mem_data_i;
rex_x(ToInt(instr_data_i(11 downto 7))) <=
mem_data_i;
when others =>
null;
end case;
when others =>
null;
end case;
end if;
if not(instr_data_i(1 downto 0) = "11" and
instr_data_i(6 downto 2) = "01000" and
instr_data_i(14 downto 12) = "010") then
mem_we_o <= '0';
end if;
instr_addr_o <= instr_addr_buf;
instr_addr_buf <= instr_addr_buf + 4;
else
instr_addr_o <= X"00000000";
mem_addr_o <= X"00000000";
mem_data_o <= X"00000000";
mem_we_o <= '0';
for i in 0 to REGNUMBER-1 loop
rex_x(i) <= X"00000000";
end loop;
end if;-- rst 0 chek
end if;
-- if falling_edge(clk_i) then
-- if rst_i = '0' then -- rst 0 chek
-- instr_addr_o <= instr_addr_buf;
-- instr_addr_buf <= instr_addr_buf + 4;
-- end if;
-- mem_we_o <= '0';
-- end if;
end process;
end core;