/
reg_index.vhd
129 lines (111 loc) · 3.35 KB
/
reg_index.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
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 09:27:29 10/21/2023
-- Design Name:
-- Module Name: indexreg - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
use work.sifp_package.all;
use work.monitor_code.all;
entity reg_index is
Port ( clk : in STD_LOGIC;
reset : in STD_LOGIC;
operation : in STD_LOGIC_VECTOR(2 downto 0);
din : in STD_LOGIC_VECTOR(15 downto 0);
zi : in STD_LOGIC;
ci : in STD_LOGIC;
reg : out STD_LOGIC_VECTOR(15 downto 0);
zo : out STD_LOGIC;
co : out STD_LOGIC;
reg_d : out STD_LOGIC;
reg_a : out STD_LOGIC;
active: out STD_LOGIC);
end reg_index;
architecture Behavioral of reg_index is
-- actual register value
signal r: std_logic_vector(15 downto 0);
-- helpers
signal y: std_logic_vector(17 downto 0);
signal y_z: std_logic;
begin
on_clk: process(clk, reset)
begin
if (reset = '1') then
r <= X"BEEF";
else
if (rising_edge(clk)) then
case operation is
when r_x_INX | r_x_DEX | r_x_LDX | r_x_ADX =>
r <= y(16 downto 1);
when others =>
null;
end case;
end if;
end if;
end process;
-- ALU is adder generating carry_out and zero flags
with operation select y <=
std_logic_vector(unsigned('0' & r & '1') + unsigned('0' & (din xor X"FFFF") & '1')) when r_x_CPX,
std_logic_vector(unsigned('0' & r & '1') + unsigned('0' & (din and X"0000") & '1')) when r_x_INX,
std_logic_vector(unsigned('0' & r & '0') + unsigned('0' & (din or X"FFFF") & '0')) when r_x_DEX,
'0' & din & '0' when r_x_LDX,
std_logic_vector(unsigned('0' & r & '0') + unsigned('0' & din & '0')) when r_x_ADX,
'0' & r & '0' when others;
y_z <= '1' when (y(16 downto 1) = X"0000") else '0';
-- zero flag output
with operation select zo <=
y_z when r_x_CPX,
y_z when r_x_INX,
y_z when r_x_DEX,
y_z when r_x_LDX,
y_z when r_x_ADX,
zi when others;
-- carry flag output
with operation select co <=
y(17) when r_x_CPX,
y(17) when r_x_INX,
y(17) when r_x_DEX,
y(17) when r_x_ADX,
ci when others;
-- value
reg <= r;
-- projecting as data
reg_d <= '1' when (operation = r_x_STX) else '0';
-- projecting as address
reg_a <= '1' when (operation = r_x_M_X) else '0';
-- active when the operation is anything except NOX/NOY
active <= '0' when (operation = r_x_NOX) else '1';
---- Start boilerplate code (use with utmost caution!)
-- with cpu_r_x select r_x <=
-- NOX when r_x_NOX, -- default value
-- CPX when r_x_CPX,
-- INX when r_x_INX,
-- DEX when r_x_DEX,
-- LDX when r_x_LDX,
-- ADX when r_x_ADX,
-- M[X] when r_x_M[X],
-- STX when r_x_STX;
-- STX when r_x_X;
---- End boilerplate code
end Behavioral;