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

Subversion Repositories nanoblaze

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

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
END controller ;
63
 
64
--==============================================================================
65
 
66
ARCHITECTURE RTL OF controller IS
67
 
68
  signal en1, enInt: std_ulogic;
69
 
70
  constant opCodeLength : integer := 5;
71
  subtype opCodeType is std_ulogic_vector(opCodeLength-1 downto 0);
72
  constant opLoad  : opCodeType := "00000";
73
  constant opInput : opCodeType := "00010";
74
  constant opFetch : opCodeType := "00011";
75
  constant opAnd   : opCodeType := "00101";
76
  constant opOr    : opCodeType := "00110";
77
  constant opXor   : opCodeType := "00111";
78
  constant opTest  : opCodeType := "01001";
79
  constant opComp  : opCodeType := "01010";
80
  constant opAdd   : opCodeType := "01100";
81
  constant opAddCy : opCodeType := "01101";
82
  constant opSub   : opCodeType := "01110";
83
  constant opSubCy : opCodeType := "01111";
84
  constant opShRot : opCodeType := "10000";
85
  constant opRet   : opCodeType := "10101";
86
  constant opOutput: opCodeType := "10110";
87
  constant opStore : opCodeType := "10111";
88
  constant opCall  : opCodeType := "11000";
89
  constant opJump  : opCodeType := "11010";
90
  constant opIntF  : opCodeType := "11110";
91
 
92
  constant branchConditionLength : integer := 3;
93
  subtype branchConditionType is std_ulogic_vector(branchConditionLength-1 downto 0);
94
  constant brAw  : branchConditionType := "000";
95
  constant brZ   : branchConditionType := "100";
96
  constant brNZ  : branchConditionType := "101";
97
  constant brC   : branchConditionType := "110";
98
  constant brNC  : branchConditionType := "111";
99
 
100
  signal aluOpSel: std_ulogic;
101
  signal regWriteEn: std_ulogic;
102
 
103
  signal flagsEn, flagsEnable: std_ulogic;
104
  signal carrySaved: std_ulogic;
105
  signal zeroSaved: std_ulogic;
106
 
107
  signal branchEnable1, branchEnable: std_ulogic;
108
  signal discardOpCode: std_ulogic;
109
 
110
  signal updateIntFlag: std_ulogic;
111
 
112
BEGIN
113
  ------------------------------------------------------------------------------
114
                                                                -- Enable signal
115
  buildEnable: process(reset, clock)
116
  begin
117
    if reset = '1' then
118
      en1 <= '0';
119
    elsif rising_edge(clock) then
120
      en1 <= '1';
121
    end if;
122
  end process buildEnable;
123
 
124
  enInt <= en1 and en;  -- don't enable very first instruction twice
125
 
126
  ------------------------------------------------------------------------------
127
                                                                 -- ALU controls
128
  selectdataSource: process(opCode)
129
  begin
130
    aluOpSel      <= '0';
131
    portInSel     <= '0';
132
    scratchpadSel <= '0';
133
    case opCode(opCodeLength-1 downto 0) is
134
      when opLoad  => aluOpSel      <= '1';
135
      when opInput => portInSel     <= '1';
136
      when opFetch => scratchpadSel <= '1';
137
      when opAnd   => aluOpSel      <= '1';
138
      when opOr    => aluOpSel      <= '1';
139
      when opXor   => aluOpSel      <= '1';
140
      when opTest  => aluOpSel      <= '1';
141
      when opComp  => aluOpSel      <= '1';
142
      when opAdd   => aluOpSel      <= '1';
143
      when opAddCy => aluOpSel      <= '1';
144
      when opSub   => aluOpSel      <= '1';
145
      when opSubCy => aluOpSel      <= '1';
146
      when opShRot => aluOpSel      <= '1';
147
      when others  => aluOpSel      <= '-';
148
                      portInSel     <= '-';
149
                      scratchpadSel <= '-';
150
    end case;
151
  end process selectdataSource;
152
 
153
  registerFileSel <= aluOpSel and      twoRegInstr;
154
  instrDataSel    <= aluOpSel and (not twoRegInstr);
155
 
156
  regWriteEn <= enInt and (not discardOpCode);
157
 
158
  regWriteTable: process(opCode, regWriteEn)
159
  begin
160
    case opCode(opCodeLength-1 downto 0) is
161
      when opLoad  => regWrite <= regWriteEn;
162
      when opInput => regWrite <= regWriteEn;
163
      when opFetch => regWrite <= regWriteEn;
164
      when opAnd   => regWrite <= regWriteEn;
165
      when opOr    => regWrite <= regWriteEn;
166
      when opXor   => regWrite <= regWriteEn;
167
      when opAdd   => regWrite <= regWriteEn;
168
      when opAddCy => regWrite <= regWriteEn;
169
      when opSub   => regWrite <= regWriteEn;
170
      when opSubCy => regWrite <= regWriteEn;
171
      when opShRot => regWrite <= regWriteEn;
172
      when others  => regWrite <= '0';
173
    end case;
174
  end process regWriteTable;
175
 
176
  ------------------------------------------------------------------------------
177
                                                                 -- I/O controls
178
  readStrobe  <= enInt when (opCode = opInput) and (discardOpCode = '0')
179
    else '0';
180
  writeStrobe <= enInt when (opCode = opOutput) and (discardOpCode = '0')
181
    else '0';
182
 
183
  ------------------------------------------------------------------------------
184
                                                          -- scratchpad controls
185
  scratchpadWrite <= '1' when opCode = opStore else '0';
186
 
187
  ------------------------------------------------------------------------------
188
                                                                  -- Carry logic
189
  flagsEn <= enInt and (not branchEnable);
190
 
191
  flagsEnableTable: process(opCode, flagsEn)
192
  begin
193
    case opCode(opCodeLength-1 downto 0) is
194
      when opAnd   => flagsEnable <= flagsEn;
195
      when opOr    => flagsEnable <= flagsEn;
196
      when opXor   => flagsEnable <= flagsEn;
197
      when opTest  => flagsEnable <= flagsEn;
198
      when opComp  => flagsEnable <= flagsEn;
199
      when opAdd   => flagsEnable <= flagsEn;
200
      when opAddCy => flagsEnable <= flagsEn;
201
      when opSub   => flagsEnable <= flagsEn;
202
      when opSubCy => flagsEnable <= flagsEn;
203
      when opShRot => flagsEnable <= flagsEn;
204
      when others  => flagsEnable <= '0';
205
    end case;
206
  end process flagsEnableTable;
207
 
208
  saveCarries: process(reset, clock)
209
  begin
210
    if reset = '1' then
211
      carrySaved <= '0';
212
      zeroSaved <= '0';
213
    elsif rising_edge(clock) then
214
      if flagsEnable = '1' then
215
        carrySaved <= cOut;
216
        zeroSaved <= zero;
217
      end if;
218
    end if;
219
  end process saveCarries;
220
 
221
  cIn <= carrySaved;
222
 
223
  ------------------------------------------------------------------------------
224
                                                     -- Program counter controls
225
  checkBranchCondition: process(branchCond, zeroSaved, carrySaved)
226
  begin
227
    case branchCond(branchConditionLength-1 downto 0) is
228
      when brAw => branchEnable1 <= '1';
229
      when brZ  => branchEnable1 <= zeroSaved;
230
      when brNZ => branchEnable1 <= not zeroSaved;
231
      when brC  => branchEnable1 <= carrySaved;
232
      when brNC => branchEnable1 <= not carrySaved;
233
      when others => branchEnable1 <= '-';
234
    end case;
235
  end process checkBranchCondition;
236
 
237
  branchEnableTable: process(opCode, branchEnable1, discardOpCode)
238
  begin
239
    if discardOpCode = '0' then
240
      case opCode(opCodeLength-1 downto 0) is
241
        when opRet  => branchEnable <= branchEnable1;
242
        when opCall => branchEnable <= branchEnable1;
243
        when opJump => branchEnable <= branchEnable1;
244
        when others  => branchEnable <= '0';
245
      end case;
246
    else
247
      branchEnable <= '0';
248
    end if;
249
  end process branchEnableTable;
250
 
251
  progCounterControlTable: process(opCode, enInt, branchEnable)
252
  begin
253
    incPC <= enInt;
254
    loadInstrAddress <= '0';
255
    loadStoredPC     <= '0';
256
    case opCode(opCodeLength-1 downto 0) is
257
      when opRet  => incPC <= not branchEnable;
258
                     loadStoredPC <= enInt and branchEnable;
259
      when opCall => incPC <= not branchEnable;
260
                     loadInstrAddress <= enInt and branchEnable;
261
      when opJump => incPC <= not branchEnable;
262
                     loadInstrAddress <= enInt and branchEnable;
263
      when others => null;
264
    end case;
265
  end process progCounterControlTable;
266
 
267
  -- If a branch condition is met, the next operation has to be discarded.
268
  -- This is due to the synchronous operation of the program ROM: the
269
  -- instructions are provided one clock period after the program counter.
270
  -- so while the branch operation is processed, the next instruction is
271
  -- already being fetched.
272
  delayBranchEnable: process(reset, clock)
273
  begin
274
    if reset = '1' then
275
      discardOpCode <= '0';
276
    elsif rising_edge(clock) then
277
      discardOpCode <= branchEnable;
278
    end if;
279
  end process delayBranchEnable;
280
 
281
  ------------------------------------------------------------------------------
282
                                                       -- Stack pointer controls
283
  pcStackControlTable: process(discardOpCode, opCode, enInt)
284
  begin
285
    storePC <= '0';
286
    prevPC  <= '0';
287
    if discardOpCode = '0' then
288
      case opCode(opCodeLength-1 downto 0) is
289
        when opRet  => prevPC <= enInt;
290
        when opCall => storePC <= enInt;
291
        when others  => null;
292
      end case;
293
    end if;
294
  end process pcStackControlTable;
295
 
296
 
297
  ------------------------------------------------------------------------------
298
                                                            -- interrupt control
299
  updateIntFlag <= '1' when opCode = opIntF else '0';
300
 
301
END ARCHITECTURE RTL;

powered by: WebSVN 2.1.0

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