5
5
-- ==============================================================================
6
6
-- Description:
7
7
-- Main module of the design. It contains the processor implementation.
8
+ -- Based on http://fpgacpu.org/papers/xsoc-series-drafts.pdf
8
9
--
9
10
-- Instruction formats:
10
11
--
11
- -- |<------ 8 ------>|<-- 4 -->|<-- 4 -->|<-------------- 16 --------------->|
12
-
13
- -- | 31 24 | 23 20 | 19 16 | 15 0 |
14
- -- |-------------------------------------------------------------------------|
15
- -- | opcode | op1 | op2 | not used |
16
- -- |-------------------------------------------------------------------------|
17
- -- | opcode | op1 | - | constant |
18
- -- |-------------------------------------------------------------------------|
19
- -- | opcode | op1 | addr |
20
- -- |-------------------------------------------------------------------------|
21
- -- | opcode | - | addr |
22
- -- ---------------------------------------------------------------------------
12
+ -- 15 12 11 8 7 4 3 0
13
+ -- |-------------------------------------------|
14
+ -- | opcode | rd | ra | rb | rrr
15
+ -- |-------------------------------------------|
16
+ -- | opcode | rd | ra | im | rri
17
+ -- |-------------------------------------------|
18
+ -- | opcode | rd | fn | rb | rr
19
+ -- |-------------------------------------------|
20
+ -- | opcode | rd | fn | im | ri
21
+ -- |-------------------------------------------|
22
+ -- | opcode | im | i12
23
+ -- |-------------------------------------------|
24
+ -- | opcode | cond | displ | br
25
+ -- |-------------------------------------------|
23
26
--
24
- -- ==================================================
25
- -- | Instruction set |
26
- -- ==================================================
27
- -- | opcode | op1 | op2 | operation |
28
- -- --------------------------------------------------
29
- -- | 00000000 | - | - | HLT |
30
- -- | | | | |
31
- -- ==================================================
27
+ -- ====================================
28
+ -- | Instruction set |
29
+ -- ====================================
30
+ -- | format | operation |
31
+ -- ------------------------------------
32
+ -- | 0dab | rd = ra + rb |
33
+ -- | 1dab | rd = ra - rb |
34
+ -- | 2dai | rd = ra + im |
35
+ -- | 3d*b | rd = rd * rb |
36
+ -- ====================================
32
37
--
33
38
-- ==============================================================================
34
39
@@ -38,13 +43,13 @@ use ieee.numeric_std.all;
38
43
39
44
entity processor is
40
45
generic (
41
- N : integer := 20 ; -- Address width
42
- B : integer := 32 ; -- Data bus width
46
+ N : integer := 16 ; -- Address width
47
+ B : integer := 16 ; -- Data bus width
43
48
R : integer := 4 -- 2**R registers
44
49
);
45
50
port (
46
51
clk : in std_logic ; -- Clock
47
- arst : in std_logic ; -- Asynch reset
52
+ rst : in std_logic ; -- Synchronous reset
48
53
r_data : in std_logic_vector (B- 1 downto 0 ); -- Data in
49
54
rw_l : out std_logic ; -- Read/write
50
55
sel_l : out std_logic ; -- Memory select
@@ -57,7 +62,13 @@ architecture RTL of processor is
57
62
-- ==============
58
63
-- | FSM states |
59
64
-- ==============
60
- type state_t is (fetch0, fetch1, decode, read , execute, write , halt);
65
+ type state_t is (fetch_0, fetch_1,
66
+ decode, decode_rrr_0,
67
+ read ,
68
+ execute_0, execute_1,
69
+ write_r,
70
+ halt
71
+ );
61
72
62
73
signal state_q : state_t; -- Current state
63
74
signal state_n : state_t; -- Next state
@@ -67,9 +78,11 @@ architecture RTL of processor is
67
78
-- =============
68
79
type reg_t is array (2 ** R - 1 downto 0 ) of std_logic_vector (B- 1 downto 0 );
69
80
70
- signal regs_q : reg_t; -- General register file
71
- signal src_reg_i : std_logic_vector (R- 1 downto 0 ); -- Source register index
72
- signal dst_reg_i : std_logic_vector (R- 1 downto 0 ); -- Destination register index
81
+ signal regs_q, regs_n : reg_t; -- General register file
82
+ signal reg_d_q, reg_d_n : std_logic_vector (R- 1 downto 0 ); -- Destination register index
83
+
84
+ signal op_a_q, op_a_n : std_logic_vector (B- 1 downto 0 ); -- Operand A
85
+ signal op_b_q, op_b_n : std_logic_vector (B- 1 downto 0 ); -- Operand B
73
86
74
87
signal pc_q, pc_n : std_logic_vector (N- 1 downto 0 ); -- Program counter
75
88
signal ir_q, ir_n : std_logic_vector (B- 1 downto 0 ); -- Instruction register
@@ -80,43 +93,81 @@ architecture RTL of processor is
80
93
81
94
signal rw_q, rw_n : std_logic ; -- Memory read/write output reg.
82
95
signal sel_q, sel_n : std_logic ; -- Memory selection output reg.
96
+
97
+ signal alu_sel_i : std_logic_vector (2 downto 0 ); -- ALU operation selector
98
+ signal alu_out_i : std_logic_vector (B- 1 downto 0 ); -- ALU output
83
99
begin
84
100
101
+ -- ==================
102
+ -- | Instantiations |
103
+ -- ==================
104
+ alu_inst : entity work .alu
105
+ generic map (W => B)
106
+ port map (sel => alu_sel_i,
107
+ a => op_a_q,
108
+ b => op_b_q,
109
+ cf => open ,
110
+ zf => open ,
111
+ ov => open ,
112
+ sf => open ,
113
+ y => alu_out_i);
114
+
85
115
-- =========================
86
116
-- | Register update logic |
87
117
-- =========================
88
- clk_re : process (clk, arst ) is
118
+ clk_re : process (clk) is
89
119
begin
90
- if arst = '1' then
91
- state_q <= fetch0;
92
- regs_q <= (others => (others => '0' ));
93
- pc_q <= (others => '0' );
94
- ir_q <= (others => '0' );
95
- mar_q <= (others => '0' );
96
- mdo_q <= (others => '0' );
97
- sp_q <= (others => '0' );
98
- st_q <= (others => '0' );
99
- rw_q <= '1' ;
100
- sel_q <= '1' ;
101
- elsif rising_edge (clk) then
102
- state_q <= state_n;
103
- pc_q <= pc_n;
104
- ir_q <= ir_n;
105
- mar_q <= mar_n;
106
- mdo_q <= mdo_n;
107
- sp_q <= sp_n;
108
- st_q <= st_n;
109
- rw_q <= rw_n;
110
- sel_q <= sel_n;
120
+ if rising_edge (clk) then
121
+ if rst = '1' then
122
+ state_q <= fetch_0;
123
+ regs_q <= (others => (others => '0' ));
124
+ reg_d_q <= (others => '0' );
125
+ op_a_q <= (others => '0' );
126
+ op_b_q <= (others => '0' );
127
+ pc_q <= (others => '0' );
128
+ ir_q <= (others => '0' );
129
+ mar_q <= (others => '0' );
130
+ mdo_q <= (others => '0' );
131
+ sp_q <= (others => '0' );
132
+ st_q <= (others => '0' );
133
+ rw_q <= '1' ;
134
+ sel_q <= '1' ;
135
+
136
+ -- Debug values for the registers
137
+ regs_q(2 ) <= X"0001" ; -- R2
138
+ regs_q(3 ) <= X"0002" ; -- R3
139
+
140
+ else
141
+ regs_q <= regs_n;
142
+ state_q <= state_n;
143
+ reg_d_q <= reg_d_n;
144
+ op_a_q <= op_a_n;
145
+ op_b_q <= op_b_n;
146
+ pc_q <= pc_n;
147
+ ir_q <= ir_n;
148
+ mar_q <= mar_n;
149
+ mdo_q <= mdo_n;
150
+ sp_q <= sp_n;
151
+ st_q <= st_n;
152
+ rw_q <= rw_n;
153
+ sel_q <= sel_n;
154
+ end if ;
111
155
end if ;
112
156
end process clk_re ;
113
157
114
158
-- =====================
115
159
-- | FSM control logic |
116
160
-- =====================
117
- fsm : process (ir_q, mar_q, mdo_q, pc_q, rw_q, sel_q, sp_q, st_q, state_q) is
161
+ fsm : process (ir_q, mar_q, mdo_q, pc_q, rw_q, sel_q, sp_q, st_q, state_q, r_data, alu_out_i, reg_d_q, regs_q, op_a_q, op_b_q ) is
118
162
begin
163
+ -- =======================
164
+ -- | Next-value defaults |
165
+ -- =======================
119
166
state_n <= state_q;
167
+ regs_n <= regs_q;
168
+ reg_d_n <= reg_d_q;
169
+ op_a_n <= op_a_q;
170
+ op_b_n <= op_b_q;
120
171
pc_n <= pc_q;
121
172
ir_n <= ir_q;
122
173
mar_n <= mar_q;
@@ -126,25 +177,79 @@ begin
126
177
rw_n <= rw_q;
127
178
sel_n <= sel_q;
128
179
180
+ -- =======
181
+ -- | FSM |
182
+ -- =======
129
183
case state_q is
130
- when fetch0 =>
184
+ -- Initiate read and increment program counter
185
+ when fetch_0 =>
131
186
pc_n <= std_logic_vector (unsigned (pc_q) + 1 );
132
187
mar_n <= pc_q;
133
188
sel_n <= '0' ;
134
189
rw_n <= '1' ;
135
- state_n <= fetch1;
136
- when fetch1 =>
190
+ state_n <= fetch_1;
191
+
192
+ -- Wait state for synchronous memory read
193
+ when fetch_1 =>
137
194
state_n <= decode;
195
+
196
+ -- Save instruction in IR and start decoding
138
197
when decode =>
139
- null ;
198
+ sel_n <= '1' ;
199
+ ir_n <= r_data;
200
+
201
+ case r_data(15 downto 12 ) is
202
+ -- RRR instruction
203
+ when X"0" | X"1" =>
204
+ state_n <= decode_rrr_0;
205
+
206
+ -- ERROR!
207
+ when others =>
208
+ state_n <= halt;
209
+ end case ;
210
+
211
+ -- Move operands from registers to OP_A and OP_B, and execute
212
+ when decode_rrr_0 =>
213
+ reg_d_n <= ir_q(11 downto 8 );
214
+
215
+ op_a_n <= regs_q(to_integer (unsigned (ir_q(7 downto 4 ))));
216
+ op_b_n <= regs_q(to_integer (unsigned (ir_q(3 downto 0 ))));
217
+
218
+ -- Execute based on OPCODE
219
+ case ir_q(15 downto 12 ) is
220
+ -- Addition
221
+ when X"0" =>
222
+ state_n <= execute_0;
223
+
224
+ -- Subtraction
225
+ when X"1" =>
226
+ state_n <= execute_1;
227
+
228
+ -- ERROR!
229
+ when others =>
230
+ state_n <= halt;
231
+ end case ;
232
+
140
233
when read =>
141
234
null ;
142
- when execute =>
143
- null ;
144
- when write =>
145
- null ;
235
+
236
+ -- ADD Rd, Ra, Rb
237
+ when execute_0 =>
238
+ alu_sel_i <= "010" ;
239
+ state_n <= write_r;
240
+
241
+ -- SUB Rd, Ra, Rb
242
+ when execute_1 =>
243
+ alu_sel_i <= "011" ;
244
+ state_n <= write_r;
245
+
246
+ -- Write result to register
247
+ when write_r =>
248
+ regs_n(to_integer (unsigned (reg_d_q))) <= alu_out_i;
249
+ state_n <= fetch_0;
250
+
146
251
when halt =>
147
- null ;
252
+ state_n <= halt ;
148
253
end case ;
149
254
end process fsm ;
150
255
0 commit comments