Skip to content

Commit 1c4c67e

Browse files
committed
Major changes in the design
- Changed the design to mirror existing RISC-16 architecture linked in the processor's description: * 16-bit wide instructions * 16-bit registers - Changed reset to synchronous - Added ALU block to the CPU - Added internal signals to support register file and operands - Implemented and tested ADD and SUB instructions
1 parent 2052ea1 commit 1c4c67e

File tree

5 files changed

+178
-67
lines changed

5 files changed

+178
-67
lines changed

Diff for: .gitignore

+4-1
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,7 @@ tb/work/_lib1_0.qdb
66
tb/work/_lib1_0.qtl
77
tb/work/_vmake
88
tb/computer.cr.mti
9-
tb/vsim.wlf
9+
tb/vsim.wlf
10+
*.qpg
11+
*.qtl
12+
*.qdb

Diff for: src/computer.vhd

+6-4
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ entity computer is
99
end entity computer;
1010

1111
architecture struct of computer is
12-
constant N : integer := 20;
13-
constant B : integer := 32;
12+
constant N : integer := 16;
13+
constant B : integer := 16;
14+
constant R : integer := 4;
1415

1516
-- Internal signals for block interconnections
1617
signal rw_l_i : std_logic;
@@ -22,9 +23,10 @@ begin
2223

2324
proc_0 : entity work.processor(RTL)
2425
generic map(N => N,
25-
B => B)
26+
B => B,
27+
R => R)
2628
port map(clk => clk,
27-
arst => arst,
29+
rst => arst,
2830
r_data => data_m2p_i,
2931
rw_l => rw_l_i,
3032
sel_l => sel_l_i,

Diff for: src/memory.vhd

+3-2
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,9 @@ begin
5858
mem_i <= (others => (others => '0'));
5959
r_data_q <= (others => '0');
6060

61-
-- Debug commands
62-
mem_i(0) <= (others => '1'); -- First memory location filled with ONEs
61+
-- Debug instructions
62+
mem_i(0) <= X"0123"; -- ADD R1, R2, R3
63+
mem_i(1) <= X"1123"; -- SUB R1, R2, R3
6364

6465
elsif rising_edge(clk) then
6566
if (sel_l = '1') then

Diff for: src/processor.vhd

+164-59
Original file line numberDiff line numberDiff line change
@@ -5,30 +5,35 @@
55
--==============================================================================
66
-- Description:
77
-- Main module of the design. It contains the processor implementation.
8+
-- Based on http://fpgacpu.org/papers/xsoc-series-drafts.pdf
89
--
910
-- Instruction formats:
1011
--
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+
-- |-------------------------------------------|
2326
--
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+
-- ====================================
3237
--
3338
--==============================================================================
3439

@@ -38,13 +43,13 @@ use ieee.numeric_std.all;
3843

3944
entity processor is
4045
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
4348
R : integer := 4 -- 2**R registers
4449
);
4550
port (
4651
clk : in std_logic; -- Clock
47-
arst : in std_logic; -- Asynch reset
52+
rst : in std_logic; -- Synchronous reset
4853
r_data : in std_logic_vector(B-1 downto 0); -- Data in
4954
rw_l : out std_logic; -- Read/write
5055
sel_l : out std_logic; -- Memory select
@@ -57,7 +62,13 @@ architecture RTL of processor is
5762
-- ==============
5863
-- | FSM states |
5964
-- ==============
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+
);
6172

6273
signal state_q : state_t; -- Current state
6374
signal state_n : state_t; -- Next state
@@ -67,9 +78,11 @@ architecture RTL of processor is
6778
-- =============
6879
type reg_t is array(2**R - 1 downto 0) of std_logic_vector(B-1 downto 0);
6980

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
7386

7487
signal pc_q, pc_n : std_logic_vector(N-1 downto 0); -- Program counter
7588
signal ir_q, ir_n : std_logic_vector(B-1 downto 0); -- Instruction register
@@ -80,43 +93,81 @@ architecture RTL of processor is
8093

8194
signal rw_q, rw_n : std_logic; -- Memory read/write output reg.
8295
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
8399
begin
84100

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+
85115
-- =========================
86116
-- | Register update logic |
87117
-- =========================
88-
clk_re : process(clk, arst) is
118+
clk_re : process(clk) is
89119
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;
111155
end if;
112156
end process clk_re;
113157

114158
-- =====================
115159
-- | FSM control logic |
116160
-- =====================
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
118162
begin
163+
-- =======================
164+
-- | Next-value defaults |
165+
-- =======================
119166
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;
120171
pc_n <= pc_q;
121172
ir_n <= ir_q;
122173
mar_n <= mar_q;
@@ -126,25 +177,79 @@ begin
126177
rw_n <= rw_q;
127178
sel_n <= sel_q;
128179

180+
-- =======
181+
-- | FSM |
182+
-- =======
129183
case state_q is
130-
when fetch0 =>
184+
-- Initiate read and increment program counter
185+
when fetch_0 =>
131186
pc_n <= std_logic_vector(unsigned(pc_q) + 1);
132187
mar_n <= pc_q;
133188
sel_n <= '0';
134189
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 =>
137194
state_n <= decode;
195+
196+
-- Save instruction in IR and start decoding
138197
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+
140233
when read =>
141234
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+
146251
when halt =>
147-
null;
252+
state_n <= halt;
148253
end case;
149254
end process fsm;
150255

Diff for: tb/computer_tb.vhd

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,6 @@ begin
2222
wait for T/2;
2323
end process clk_gen;
2424

25-
arst <= '1', '0' after T/4;
25+
arst <= '1', '0' after 3*T/4;
2626

2727
end architecture tb_arch;

0 commit comments

Comments
 (0)