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

Subversion Repositories nanoblaze

[/] [nanoblaze/] [trunk/] [Circuit/] [controller.vhd] - Blame information for rev 9

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 9 fcorthay
--##############################################################################
2
--
3
--  controller
4
--      Main processor controller
5
--
6
--      Controls all other blocks: ALU, program counter, stack, …
7
--
8
--------------------------------------------------------------------------------
9
--
10
--  Versions / Authors
11
--      1.0 Francois Corthay    first implementation
12
--
13
--  Provided under GNU LGPL licence: <http://www.gnu.org/copyleft/lesser.html>
14
--
15
--  by the electronics group of "HES-SO//Valais Wallis", in Switzerland:
16
--  <http://www.hevs.ch/en/rad-instituts/institut-systemes-industriels/>.
17
--
18
--------------------------------------------------------------------------------
19
--
20
--  Hierarchy
21
--      Used by "nanoblaze/nanoProcessor".
22
--
23
--##############################################################################
24
 
25
LIBRARY ieee;
26
  USE ieee.std_logic_1164.all;
27
  USE ieee.numeric_std.all;
28
 
29
ENTITY controller IS
30
  GENERIC(
31
    intCodeBitNb    : positive := 5;
32
    branchCondBitNb : positive := 3;
33
    opCodeBitNb     : positive := 5
34
  );
35
  PORT(
36
    reset            : IN  std_ulogic;
37
    clock            : IN  std_ulogic;
38
    en               : IN  std_ulogic;
39
    opCode           : IN  std_ulogic_vector(opCodeBitNb-1 DOWNTO 0);
40
    twoRegInstr      : IN  std_ulogic;
41
    registerFileSel  : OUT std_ulogic;
42
    instrDataSel     : OUT std_ulogic;
43
    portInSel        : OUT std_ulogic;
44
    scratchpadSel    : OUT std_ulogic;
45
    regWrite         : OUT std_ulogic;
46
    readStrobe       : OUT std_ulogic;
47
    writeStrobe      : OUT std_uLogic;
48
    scratchpadWrite  : OUT std_ulogic;
49
    branchCond       : IN  std_ulogic_vector(branchCondBitNb-1 DOWNTO 0);
50
    cOut             : IN  std_ulogic;
51
    zero             : IN  std_ulogic;
52
    cIn              : OUT std_ulogic;
53
    incPC            : OUT std_ulogic;
54
    loadInstrAddress : OUT std_ulogic;
55
    loadStoredPC     : OUT std_ulogic;
56
    prevPC           : OUT std_ulogic;
57
    storePC          : OUT std_ulogic;
58
    intCode          : IN  std_ulogic_vector(intCodeBitNb-1 DOWNTO 0);
59
    int              : IN  std_ulogic;
60
    intAck           : OUT std_ulogic
61
  );
62
 
63
END controller ;
64
 
65
--==============================================================================
66
 
67
ARCHITECTURE RTL OF controller IS
68
 
69
  signal en1, enInt: std_ulogic;
70
 
71
  constant opCodeLength : integer := 5;
72
  subtype opCodeType is std_ulogic_vector(opCodeLength-1 downto 0);
73
  constant opLoad  : opCodeType := "00000";
74
  constant opInput : opCodeType := "00010";
75
  constant opFetch : opCodeType := "00011";
76
  constant opAnd   : opCodeType := "00101";
77
  constant opOr    : opCodeType := "00110";
78
  constant opXor   : opCodeType := "00111";
79
  constant opTest  : opCodeType := "01001";
80
  constant opComp  : opCodeType := "01010";
81
  constant opAdd   : opCodeType := "01100";
82
  constant opAddCy : opCodeType := "01101";
83
  constant opSub   : opCodeType := "01110";
84
  constant opSubCy : opCodeType := "01111";
85
  constant opShRot : opCodeType := "10000";
86
  constant opRet   : opCodeType := "10101";
87
  constant opOutput: opCodeType := "10110";
88
  constant opStore : opCodeType := "10111";
89
  constant opCall  : opCodeType := "11000";
90
  constant opJump  : opCodeType := "11010";
91
  constant opIntF  : opCodeType := "11110";
92
 
93
  constant branchConditionLength : integer := 3;
94
  subtype branchConditionType is std_ulogic_vector(branchConditionLength-1 downto 0);
95
  constant brAw  : branchConditionType := "000";
96
  constant brZ   : branchConditionType := "100";
97
  constant brNZ  : branchConditionType := "101";
98
  constant brC   : branchConditionType := "110";
99
  constant brNC  : branchConditionType := "111";
100
 
101
  signal aluOpSel: std_ulogic;
102
  signal regWriteEn: std_ulogic;
103
 
104
  signal flagsEn, flagsEnable: std_ulogic;
105
  signal carrySaved: std_ulogic;
106
  signal zeroSaved: std_ulogic;
107
 
108
  signal branchEnable1, branchEnable: std_ulogic;
109
  signal discardOpCode: std_ulogic;
110
 
111
  signal updateIntFlag: std_ulogic;
112
 
113
BEGIN
114
  ------------------------------------------------------------------------------
115
                                                                -- Enable signal
116
  buildEnable: process(reset, clock)
117
  begin
118
    if reset = '1' then
119
      en1 <= '0';
120
    elsif rising_edge(clock) then
121
      en1 <= '1';
122
    end if;
123
  end process buildEnable;
124
 
125
  enInt <= en1 and en;  -- don't enable very first instruction twice
126
 
127
  ------------------------------------------------------------------------------
128
                                                                 -- ALU controls
129
  selectdataSource: process(opCode)
130
  begin
131
    aluOpSel      <= '0';
132
    portInSel     <= '0';
133
    scratchpadSel <= '0';
134
    case opCode(opCodeLength-1 downto 0) is
135
      when opLoad  => aluOpSel      <= '1';
136
      when opInput => portInSel     <= '1';
137
      when opFetch => scratchpadSel <= '1';
138
      when opAnd   => aluOpSel      <= '1';
139
      when opOr    => aluOpSel      <= '1';
140
      when opXor   => aluOpSel      <= '1';
141
      when opTest  => aluOpSel      <= '1';
142
      when opComp  => aluOpSel      <= '1';
143
      when opAdd   => aluOpSel      <= '1';
144
      when opAddCy => aluOpSel      <= '1';
145
      when opSub   => aluOpSel      <= '1';
146
      when opSubCy => aluOpSel      <= '1';
147
      when opShRot => aluOpSel      <= '1';
148
      when others  => aluOpSel      <= '-';
149
                      portInSel     <= '-';
150
                      scratchpadSel <= '-';
151
    end case;
152
  end process selectdataSource;
153
 
154
  registerFileSel <= aluOpSel and      twoRegInstr;
155
  instrDataSel    <= aluOpSel and (not twoRegInstr);
156
 
157
  regWriteEn <= enInt and (not discardOpCode);
158
 
159
  regWriteTable: process(opCode, regWriteEn)
160
  begin
161
    case opCode(opCodeLength-1 downto 0) is
162
      when opLoad  => regWrite <= regWriteEn;
163
      when opInput => regWrite <= regWriteEn;
164
      when opFetch => regWrite <= regWriteEn;
165
      when opAnd   => regWrite <= regWriteEn;
166
      when opOr    => regWrite <= regWriteEn;
167
      when opXor   => regWrite <= regWriteEn;
168
      when opAdd   => regWrite <= regWriteEn;
169
      when opAddCy => regWrite <= regWriteEn;
170
      when opSub   => regWrite <= regWriteEn;
171
      when opSubCy => regWrite <= regWriteEn;
172
      when opShRot => regWrite <= regWriteEn;
173
      when others  => regWrite <= '0';
174
    end case;
175
  end process regWriteTable;
176
 
177
  ------------------------------------------------------------------------------
178
                                                                 -- I/O controls
179
  readStrobe  <= enInt when (opCode = opInput) and (discardOpCode = '0')
180
    else '0';
181
  writeStrobe <= enInt when (opCode = opOutput) and (discardOpCode = '0')
182
    else '0';
183
 
184
  ------------------------------------------------------------------------------
185
                                                          -- scratchpad controls
186
  scratchpadWrite <= '1' when opCode = opStore else '0';
187
 
188
  ------------------------------------------------------------------------------
189
                                                                  -- Carry logic
190
  flagsEn <= enInt and (not branchEnable);
191
 
192
  flagsEnableTable: process(opCode, flagsEn)
193
  begin
194
    case opCode(opCodeLength-1 downto 0) is
195
      when opAnd   => flagsEnable <= flagsEn;
196
      when opOr    => flagsEnable <= flagsEn;
197
      when opXor   => flagsEnable <= flagsEn;
198
      when opTest  => flagsEnable <= flagsEn;
199
      when opComp  => flagsEnable <= flagsEn;
200
      when opAdd   => flagsEnable <= flagsEn;
201
      when opAddCy => flagsEnable <= flagsEn;
202
      when opSub   => flagsEnable <= flagsEn;
203
      when opSubCy => flagsEnable <= flagsEn;
204
      when opShRot => flagsEnable <= flagsEn;
205
      when others  => flagsEnable <= '0';
206
    end case;
207
  end process flagsEnableTable;
208
 
209
  saveCarries: process(reset, clock)
210
  begin
211
    if reset = '1' then
212
      carrySaved <= '0';
213
      zeroSaved <= '0';
214
    elsif rising_edge(clock) then
215
      if flagsEnable = '1' then
216
        carrySaved <= cOut;
217
        zeroSaved <= zero;
218
      end if;
219
    end if;
220
  end process saveCarries;
221
 
222
  cIn <= carrySaved;
223
 
224
  ------------------------------------------------------------------------------
225
                                                     -- Program counter controls
226
  checkBranchCondition: process(branchCond, zeroSaved, carrySaved)
227
  begin
228
    case branchCond(branchConditionLength-1 downto 0) is
229
      when brAw => branchEnable1 <= '1';
230
      when brZ  => branchEnable1 <= zeroSaved;
231
      when brNZ => branchEnable1 <= not zeroSaved;
232
      when brC  => branchEnable1 <= carrySaved;
233
      when brNC => branchEnable1 <= not carrySaved;
234
      when others => branchEnable1 <= '-';
235
    end case;
236
  end process checkBranchCondition;
237
 
238
  branchEnableTable: process(opCode, branchEnable1, discardOpCode)
239
  begin
240
    if discardOpCode = '0' then
241
      case opCode(opCodeLength-1 downto 0) is
242
        when opRet  => branchEnable <= branchEnable1;
243
        when opCall => branchEnable <= branchEnable1;
244
        when opJump => branchEnable <= branchEnable1;
245
        when others  => branchEnable <= '0';
246
      end case;
247
    else
248
      branchEnable <= '0';
249
    end if;
250
  end process branchEnableTable;
251
 
252
  progCounterControlTable: process(opCode, enInt, branchEnable)
253
  begin
254
    incPC <= enInt;
255
    loadInstrAddress <= '0';
256
    loadStoredPC     <= '0';
257
    case opCode(opCodeLength-1 downto 0) is
258
      when opRet  => incPC <= not branchEnable;
259
                     loadStoredPC <= enInt and branchEnable;
260
      when opCall => incPC <= not branchEnable;
261
                     loadInstrAddress <= enInt and branchEnable;
262
      when opJump => incPC <= not branchEnable;
263
                     loadInstrAddress <= enInt and branchEnable;
264
      when others => null;
265
    end case;
266
  end process progCounterControlTable;
267
 
268
  -- If a branch condition is met, the next operation has to be discarded.
269
  -- This is due to the synchronous operation of the program ROM: the
270
  -- instructions are provided one clock period after the program counter.
271
  -- so while the branch operation is processed, the next instruction is
272
  -- already being fetched.
273
  delayBranchEnable: process(reset, clock)
274
  begin
275
    if reset = '1' then
276
      discardOpCode <= '0';
277
    elsif rising_edge(clock) then
278
      discardOpCode <= branchEnable;
279
    end if;
280
  end process delayBranchEnable;
281
 
282
  ------------------------------------------------------------------------------
283
                                                       -- Stack pointer controls
284
  pcStackControlTable: process(discardOpCode, opCode, enInt)
285
  begin
286
    storePC <= '0';
287
    prevPC  <= '0';
288
    if discardOpCode = '0' then
289
      case opCode(opCodeLength-1 downto 0) is
290
        when opRet  => prevPC <= enInt;
291
        when opCall => storePC <= enInt;
292
        when others  => null;
293
      end case;
294
    end if;
295
  end process pcStackControlTable;
296
 
297
 
298
  ------------------------------------------------------------------------------
299
                                                            -- interrupt control
300
  updateIntFlag <= '1' when opCode = opIntF else '0';
301
 
302
END ARCHITECTURE RTL;

powered by: WebSVN 2.1.0

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