OpenCores
URL https://opencores.org/ocsvn/potato/potato/trunk

Subversion Repositories potato

[/] [potato/] [trunk/] [src/] [pp_control_unit.vhd] - Blame information for rev 58

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 skordal
-- The Potato Processor - A simple processor for FPGAs
2
-- (c) Kristian Klomsten Skordal 2014 - 2015 <kristian.skordal@wafflemail.net>
3 3 skordal
-- Report bugs and issues on <http://opencores.org/project,potato,bugtracker>
4 2 skordal
 
5
library ieee;
6
use ieee.std_logic_1164.all;
7
 
8
use work.pp_constants.all;
9
use work.pp_csr.all;
10 14 skordal
use work.pp_types.all;
11
use work.pp_utilities.all;
12 2 skordal
 
13
--! @brief Unit decoding instructions and setting control signals apropriately.
14
entity pp_control_unit is
15
        port(
16
                -- Inputs, indices correspond to instruction word indices:
17
                opcode  : in std_logic_vector( 4 downto 0);
18
                funct3  : in std_logic_vector( 2 downto 0);
19
                funct7  : in std_logic_vector( 6 downto 0);
20
                funct12 : in std_logic_vectoR(11 downto 0);
21
 
22
                -- Control signals:
23
                rd_write            : out std_logic;
24
                branch              : out branch_type;
25
 
26
                -- Exception signals:
27
                decode_exception       : out std_logic;
28 58 skordal
                decode_exception_cause : out csr_exception_cause;
29 2 skordal
 
30
                -- Control register signals:
31
                csr_write : out csr_write_mode;
32
                csr_imm   : out std_logic; --! Indicating an immediate variant of the csrr* instructions.
33
 
34
                -- Sources of operands to the ALU:
35
                alu_x_src, alu_y_src : out alu_operand_source;
36
 
37
                -- ALU operation:
38
                alu_op : out alu_operation;
39
 
40
                -- Memory transaction parameters:
41
                mem_op   : out memory_operation_type;
42
                mem_size : out memory_operation_size
43
        );
44
end entity pp_control_unit;
45
 
46
architecture behaviour of pp_control_unit is
47 14 skordal
        signal exception       : std_logic;
48 58 skordal
        signal exception_cause : csr_exception_cause;
49 14 skordal
        signal alu_op_temp     : alu_operation;
50 2 skordal
begin
51
 
52
        csr_imm <= funct3(2);
53 14 skordal
        alu_op <= alu_op_temp;
54 2 skordal
 
55 14 skordal
        decode_exception <= exception or to_std_logic(alu_op_temp = ALU_INVALID);
56
        decode_exception_cause <= exception_cause when alu_op_temp /= ALU_INVALID
57
                else CSR_CAUSE_INVALID_INSTR;
58
 
59 2 skordal
        alu_control: entity work.pp_alu_control_unit
60
                port map(
61
                        opcode => opcode,
62
                        funct3 => funct3,
63
                        funct7 => funct7,
64
                        alu_x_src => alu_x_src,
65
                        alu_y_src => alu_y_src,
66 14 skordal
                        alu_op => alu_op_temp
67 2 skordal
                );
68
 
69
        decode_ctrl: process(opcode, funct3, funct12)
70
        begin
71
                case opcode is
72
                        when b"01101" => -- Load upper immediate
73
                                rd_write <= '1';
74 14 skordal
                                exception <= '0';
75
                                exception_cause <= CSR_CAUSE_NONE;
76 2 skordal
                                branch <= BRANCH_NONE;
77
                        when b"00101" => -- Add upper immediate to PC
78
                                rd_write <= '1';
79 14 skordal
                                exception <= '0';
80
                                exception_cause <= CSR_CAUSE_NONE;
81 2 skordal
                                branch <= BRANCH_NONE;
82
                        when b"11011" => -- Jump and link
83
                                rd_write <= '1';
84 14 skordal
                                exception <= '0';
85
                                exception_cause <= CSR_CAUSE_NONE;
86 2 skordal
                                branch <= BRANCH_JUMP;
87
                        when b"11001" => -- Jump and link register
88
                                rd_write <= '1';
89 14 skordal
                                exception <= '0';
90
                                exception_cause <= CSR_CAUSE_NONE;
91 2 skordal
                                branch <= BRANCH_JUMP_INDIRECT;
92
                        when b"11000" => -- Branch operations
93
                                rd_write <= '0';
94 14 skordal
                                exception <= '0';
95
                                exception_cause <= CSR_CAUSE_NONE;
96 2 skordal
                                branch <= BRANCH_CONDITIONAL;
97
                        when b"00000" => -- Load instructions
98
                                rd_write <= '1';
99 14 skordal
                                exception <= '0';
100
                                exception_cause <= CSR_CAUSE_NONE;
101 2 skordal
                                branch <= BRANCH_NONE;
102
                        when b"01000" => -- Store instructions
103
                                rd_write <= '0';
104 14 skordal
                                exception <= '0';
105
                                exception_cause <= CSR_CAUSE_NONE;
106 2 skordal
                                branch <= BRANCH_NONE;
107
                        when b"00100" => -- Register-immediate operations
108
                                rd_write <= '1';
109 14 skordal
                                exception <= '0';
110
                                exception_cause <= CSR_CAUSE_NONE;
111 2 skordal
                                branch <= BRANCH_NONE;
112
                        when b"01100" => -- Register-register operations
113
                                rd_write <= '1';
114 14 skordal
                                exception <= '0';
115
                                exception_cause <= CSR_CAUSE_NONE;
116 2 skordal
                                branch <= BRANCH_NONE;
117
                        when b"00011" => -- Fence instructions, ignored
118
                                rd_write <= '0';
119 14 skordal
                                exception <= '0';
120
                                exception_cause <= CSR_CAUSE_NONE;
121 2 skordal
                                branch <= BRANCH_NONE;
122
                        when b"11100" => -- System instructions
123
                                if funct3 = b"000" then
124
                                        rd_write <= '0';
125
 
126
                                        if funct12 = x"000" then
127 14 skordal
                                                exception <= '1';
128 58 skordal
                                                exception_cause <= CSR_CAUSE_ECALL;
129 2 skordal
                                                branch <= BRANCH_NONE;
130
                                        elsif funct12 = x"001" then
131 14 skordal
                                                exception <= '1';
132
                                                exception_cause <= CSR_CAUSE_BREAKPOINT;
133 2 skordal
                                                branch <= BRANCH_NONE;
134 58 skordal
                                        elsif funct12 = CSR_EPC_ERET then
135 14 skordal
                                                exception <= '0';
136
                                                exception_cause <= CSR_CAUSE_NONE;
137 2 skordal
                                                branch <= BRANCH_SRET;
138
                                        else
139 14 skordal
                                                exception <= '1';
140
                                                exception_cause <= CSR_CAUSE_INVALID_INSTR;
141 2 skordal
                                                branch <= BRANCH_NONE;
142
                                        end if;
143
                                else
144
                                        rd_write <= '1';
145 14 skordal
                                        exception <= '0';
146
                                        exception_cause <= CSR_CAUSE_NONE;
147 2 skordal
                                        branch <= BRANCH_NONE;
148
                                end if;
149
                        when others =>
150
                                rd_write <= '0';
151 14 skordal
                                exception <= '1';
152
                                exception_cause <= CSR_CAUSE_INVALID_INSTR;
153 2 skordal
                                branch <= BRANCH_NONE;
154
                end case;
155
        end process decode_ctrl;
156
 
157
        decode_csr: process(opcode, funct3)
158
        begin
159
                if opcode = b"11100" then
160
                        case funct3 is
161
                                when b"001" | b"101" => -- csrrw/i
162
                                        csr_write <= CSR_WRITE_REPLACE;
163
                                when b"010" | b"110" => -- csrrs/i
164
                                        csr_write <= CSR_WRITE_SET;
165
                                when b"011" | b"111" => -- csrrc/i
166
                                        csr_write <= CSR_WRITE_CLEAR;
167
                                when others =>
168
                                        csr_write <= CSR_WRITE_NONE;
169
                        end case;
170
                else
171
                        csr_write <= CSR_WRITE_NONE;
172
                end if;
173
        end process decode_csr;
174
 
175
        decode_mem: process(opcode, funct3)
176
        begin
177
                case opcode is
178
                        when b"00000" => -- Load instructions
179
                                case funct3 is
180
                                        when b"000" => -- lw
181
                                                mem_size <= MEMOP_SIZE_BYTE;
182
                                                mem_op <= MEMOP_TYPE_LOAD;
183
                                        when b"001" => -- lh
184
                                                mem_size <= MEMOP_SIZE_HALFWORD;
185
                                                mem_op <= MEMOP_TYPE_LOAD;
186
                                        when b"010" | b"110" => -- lw
187
                                                mem_size <= MEMOP_SIZE_WORD;
188
                                                mem_op <= MEMOP_TYPE_LOAD;
189
                                        when b"100" => -- lbu
190
                                                mem_size <= MEMOP_SIZE_BYTE;
191
                                                mem_op <= MEMOP_TYPE_LOAD_UNSIGNED;
192
                                        when b"101" => -- lhu
193
                                                mem_size <= MEMOP_SIZE_HALFWORD;
194
                                                mem_op <= MEMOP_TYPE_LOAD_UNSIGNED;
195
                                        when others => -- FIXME: Treat others as lw.
196
                                                mem_size <= MEMOP_SIZE_WORD;
197
                                                mem_op <= MEMOP_TYPE_INVALID;
198
                                end case;
199
                        when b"01000" => -- Store instructions
200
                                case funct3 is
201
                                        when b"000" =>
202
                                                mem_op <= MEMOP_TYPE_STORE;
203
                                                mem_size <= MEMOP_SIZE_BYTE;
204
                                        when b"001" =>
205
                                                mem_op <= MEMOP_TYPE_STORE;
206
                                                mem_size <= MEMOP_SIZE_HALFWORD;
207
                                        when b"010" =>
208
                                                mem_op <= MEMOP_TYPE_STORE;
209
                                                mem_size <= MEMOP_SIZE_WORD;
210
                                        when others =>
211
                                                mem_op <= MEMOP_TYPE_INVALID;
212
                                                mem_size <= MEMOP_SIZE_WORD;
213
                                end case;
214
                        when others =>
215
                                mem_op <= MEMOP_TYPE_NONE;
216
                                mem_size <= MEMOP_SIZE_WORD;
217
                end case;
218
        end process decode_mem;
219
 
220
end architecture behaviour;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.