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

Subversion Repositories riscompatible

[/] [riscompatible/] [trunk/] [rtl/] [select_and_control.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 borin
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4
use work.riscompatible_package.all;
5
-------------------------------------------------------------------------------------------------------------------
6
entity select_and_control is
7
    generic
8
    (
9
        NumBitsProgramMemory : natural:=5;
10
        NumBitsDataMemory    : natural:=5;
11
        NumBitsRegBank       : natural:=5
12
    );
13
    port
14
    (
15
        Clk_I                    : in std_logic;
16
        Reset_I                  : in std_logic;
17
        PMem_Enable_O            : out std_logic;
18
        PMem_Address_O           : out std_logic_vector(NumBitsProgramMemory-1 downto 0);
19
        PMem_Write_O             : out std_logic;
20
        PMem_OutputData_I        : in TRiscoWord;
21
        DMem_Enable_O            : out std_logic;
22
        DMem_Write_O             : out std_logic;
23
        DMem_Address_O           : out std_logic_vector(NumBitsDataMemory-1 downto 0);
24
        DMem_InputData_O         : out TRiscoWord;
25
        DMem_OutputData_I        : in TRiscoWord;
26
        RegBnk_Register1_O       : out std_logic_vector(NumBitsRegBank - 1 downto 0);
27
        RegBnk_Register2_O       : out std_logic_vector(NumBitsRegBank - 1 downto 0);
28
        RegBnk_RegisterW_O       : out std_logic_vector(NumBitsRegBank - 1 downto 0);
29
        RegBnk_Write_O           : out std_logic;
30
        RegBnk_InputData_O       : out TRiscoWord;
31
        RegBnk_FT1_OutputData_I  : in TRiscoWord;
32
        RegBnk_FT2_OutputData_I  : in TRiscoWord;
33
        ULA_Function_O           : out std_logic_vector(4 downto 0);
34
        ULA_Output_I             : in TRiscoWord;
35
        ULA_Ng_O_I               : in std_logic; -- Negative
36
        ULA_Cy_O_I               : in std_logic; -- Carry
37
        ULA_Ov_O_I               : in std_logic; -- Overflow
38
        ULA_Zr_O_I               : in std_logic; -- Zero
39
        UD_Function_O            : out std_logic_vector(4 downto 0);
40
        UD_OutputData_I          : in TRiscoWord;
41
        UD_Cy_O_I                : in std_logic;
42
        RUA_Clr_O                : out std_logic;
43
        RUB_Clr_O                : out std_logic;
44
        RDA_Clr_O                : out std_logic;
45
        RDB_Clr_O                : out std_logic;
46
        RUA_Wen_O                : out std_logic;
47
        RUB_Wen_O                : out std_logic;
48
        RDA_Wen_O                : out std_logic;
49
        RDB_Wen_O                : out std_logic;
50
        RUA_Data_O               : out std_logic_vector(C_NumBitsWord-1 downto 0);
51
        RUB_Data_O               : out std_logic_vector(C_NumBitsWord-1 downto 0);
52
        RDA_Data_O               : out std_logic_vector(C_NumBitsWord-1 downto 0);
53
        RDB_Data_O               : out std_logic_vector(C_NumBitsWord-1 downto 0);
54
        PC_Clr_O                 : out std_logic;
55
        PC_Wen_O                 : out std_logic;
56
        PC_Data_I                : in std_logic_vector(C_NumBitsWord-1 downto 0);
57
        PC_Data_O                : out std_logic_vector(C_NumBitsWord-1 downto 0);
58
        PSW_Clr_O                : out std_logic;
59
        PSW_Wen_O                : out std_logic;
60
        PSW_Data_I               : in std_logic_vector(C_NumBitsWord-1 downto 0);
61
        PSW_Data_O               : out std_logic_vector(C_NumBitsWord-1 downto 0);
62
        Int_I                    : in std_logic;
63
        IntAck_O                 : out std_logic
64
    );
65
end select_and_control;
66
-------------------------------------------------------------------------------------------------------------------
67
architecture Ark1 of select_and_control is
68
    ---------------------------------------------
69
    -- Special Registers
70
    ---------------------------------------------
71
    constant C_R00      : integer range 0 to 31:=0;
72
    constant C_PSW      : integer range 0 to 31:=1;
73
    constant C_PC       : integer range 0 to 31:=2**NumBitsRegBank - 1;
74
    constant C_SPISR    : integer range 0 to 31:=C_PC - 1; -- SP of the Interrupt Service Routine
75
    ---------------------------------------------
76
    alias InterruptEnable_w : std_logic is PSW_Data_I(8);
77
    ---------------------------------------------
78
    signal DMem_Address_W : std_logic_vector(NumBitsDataMemory-1 downto 0);
79
    ---------------------------------------------
80
    procedure p_DecomposeInstructionIntoFields
81
    (
82
        PMemOutputData_I  : in TRiscoWord;
83
        T1_T0_O           : out std_logic_vector(1 downto 0);
84
        C4_C0_O           : out std_logic_vector(4 downto 0);
85
        F1_F0_SS2_O       : out std_logic_vector(2 downto 0);
86
        APS_O             : out std_logic;
87
        DST_O             : out std_logic_vector(4 downto 0);
88
        FT1_O             : out std_logic_vector(4 downto 0);
89
        FT2_O             : out std_logic_vector(4 downto 0);
90
        Kp_O              : out std_logic_vector(10 downto 0);
91
        Kg_O              : out std_logic_vector(16 downto 0)
92
    ) is
93
    begin
94
        T1_T0_O := PMemOutputData_I(31 downto 30);
95
        C4_C0_O := PMemOutputData_I(29 downto 25);
96
        APS_O := PMemOutputData_I(24);
97
        F1_F0_SS2_O := PMemOutputData_I(23 downto 22)&PMemOutputData_I(11);
98
        DST_O := PMemOutputData_I(21 downto 17);
99
        FT1_O := PMemOutputData_I(16 downto 12);
100
        FT2_O := PMemOutputData_I(10 downto 6);
101
        Kg_O := PMemOutputData_I(16 downto 0);
102
        Kp_O := PMemOutputData_I(10 downto 0);
103
    end procedure p_DecomposeInstructionIntoFields;
104
    ---------------------------------------------
105
    function f_SelectRegOutput
106
    (
107
        FTx_I               : in std_logic_vector(NumBitsRegBank - 1 downto 0);
108
        PSW_I               : in TRiscoWord;
109
        PC_I                : in TRiscoWord;
110
        RegBnk_OutputData_I : in TRiscoWord
111
    ) return TRiscoWord is
112
        variable FTxi : integer;
113
    begin
114
        FTXi := to_integer(unsigned(FTx_I));
115
        case FTxi is
116
            when C_R00 =>
117
                return (others => '0');
118
            when C_PSW =>
119
                return PSW_I;
120
            when C_PC =>
121
                return PC_I;
122
            when others =>
123
                return RegBnk_OutputData_I;             -- Source 1 and Source 2
124
        end case;
125
    end function f_SelectRegOutput;
126
    ---------------------------------------------
127
    procedure p_SelectRegInput1
128
    (
129
        F1_F0_SS2_I               : in std_logic_vector(2 downto 0);
130
        DST_I                     : in std_logic_vector(4 downto 0);
131
        FT1_I                     : in std_logic_vector(4 downto 0);
132
        FT2_I                     : in std_logic_vector(4 downto 0);
133
        signal RegBnk_Register1_O : out std_logic_vector(NumBitsRegBank - 1 downto 0)
134
    ) is
135
        variable F1_F0_SS2_v : std_logic_vector(2 downto 0);
136
    begin
137
        if F1_F0_SS2_I(2 downto 1) /= "00" then
138
            F1_F0_SS2_v(0) := '0'; -- Remove X
139
        else
140
            F1_F0_SS2_v(0) := F1_F0_SS2_I(0);
141
        end if;
142
        F1_F0_SS2_v(2 downto 1) := F1_F0_SS2_I(2 downto 1);
143
        case F1_F0_SS2_v is
144
            when FFS_DST_DST_Kgh | FFS_DST_DST_Kgl =>
145
                RegBnk_Register1_O <= DST_I(NumBitsRegBank - 1 downto 0);
146
            when FFS_DST_FT1_FT2 | FFS_DST_FT1_Kp =>
147
                RegBnk_Register1_O <= FT1_I(NumBitsRegBank - 1 downto 0);
148
            when others =>
149
                RegBnk_Register1_O <= (others=>'0');
150
        end case;
151
    end procedure p_SelectRegInput1;
152
    ---------------------------------------------    
153
    procedure p_SelectRegInput2
154
    (
155
        F1_F0_SS2_I               : in std_logic_vector(2 downto 0);
156
        DST_I                     : in std_logic_vector(4 downto 0);
157
        FT1_I                     : in std_logic_vector(4 downto 0);
158
        FT2_I                     : in std_logic_vector(4 downto 0);
159
        signal RegBnk_Register2_O : out std_logic_vector(NumBitsRegBank - 1 downto 0)
160
    ) is
161
        variable F1_F0_SS2_v : std_logic_vector(2 downto 0);
162
    begin
163
        if F1_F0_SS2_I(2 downto 1) /= "00" then
164
            F1_F0_SS2_v(0) := '0'; -- Remove X
165
        else
166
            F1_F0_SS2_v(0) := F1_F0_SS2_I(0);
167
        end if;
168
        F1_F0_SS2_v(2 downto 1) := F1_F0_SS2_I(2 downto 1);
169
        case F1_F0_SS2_v is
170
            when FFS_DST_FT1_FT2 =>
171
                RegBnk_Register2_O <= FT2_I(NumBitsRegBank - 1 downto 0);
172
            when others =>
173
                RegBnk_Register2_O <= (others=>'0');
174
        end case;
175
    end procedure p_SelectRegInput2;
176
    ---------------------------------------------    
177
begin
178
 
179
    p_select_and_control: process(Reset_I,Clk_I,PMem_OutputData_I,DMem_OutputData_I,RegBnk_FT1_OutputData_I,RegBnk_FT2_OutputData_I,ULA_Output_I,ULA_Ng_O_I,ULA_Cy_O_I,ULA_Ov_O_I,ULA_Zr_O_I,UD_OutputData_I,UD_Cy_O_I,PC_Data_I,DMem_Address_W,PSW_Data_I,PSW_Data_I)
180
        type TPhase is (RESET,IFETCH,IDECODE,OFETCH,IEXEC1,IEXEC2,IEXEC3);
181
        variable Phase_v            : TPhase;                        -- Phase of the Machine Cycle
182
        variable NextPhase_v        : TPhase;
183
        variable T1_T0_v            : std_logic_vector(1 downto 0);  -- Instruction Type
184
        variable C4_C0_v            : std_logic_vector(4 downto 0);  -- Instruction inside its type
185
        variable F1_F0_SS2_v        : std_logic_vector(2 downto 0);  -- Format of operands
186
        variable APS_v              : std_logic;                     -- Update or not Status Word
187
        variable DST_v              : std_logic_vector(4 downto 0);  -- Index of Destination
188
        variable FT1_v              : std_logic_vector(4 downto 0);  -- Index of Source 1
189
        variable FT2_v              : std_logic_vector(4 downto 0);  -- Index of Source 2
190
        variable Kp_v               : std_logic_vector(10 downto 0); -- Small Constant (Used to determine Constext)
191
        variable Kg_v               : std_logic_vector(16 downto 0); -- Large Constant (Used to determine Constext)
192
        variable Condition_v        : std_logic;                     -- Evaluate Condition
193
        variable IntAck_v           : std_logic;                     -- Interrupt Acknowledge
194
        variable IntMask_v          : std_logic;                     -- Masks interruption during first instruction of the ISR
195
    begin
196
        if rising_edge(Clk_I) then
197
            -------
198
            -- FSM
199
            -------
200
            Phase_v := NextPhase_v;
201
            if Reset_I ='1' then
202
                NextPhase_v := RESET;
203
                Phase_v := RESET;
204
                IntAck_v := '0';
205
                IntMask_v := '0';
206
 
207
            elsif Phase_v = RESET then
208
                NextPhase_v := IFETCH;
209
 
210
            elsif Phase_v = IFETCH then
211
                NextPhase_v := IDECODE;
212
                if Int_I = '0' then
213
                    IntAck_v := '0';
214
                end if;
215
 
216
            elsif Phase_v = IDECODE then
217
                --
218
                NextPhase_v := OFETCH;
219
 
220
            elsif Phase_v = OFETCH then
221
                if Int_I = '0' or IntMask_v = '1' or InterruptEnable_w = '0' then -- without reentrant interrupts...
222
                    p_DecomposeInstructionIntoFields(PMem_OutputData_I,T1_T0_v,C4_C0_v,F1_F0_SS2_v,APS_v,DST_v,FT1_v,FT2_v,Kp_v,Kg_v);
223
                    IntMask_v := '0';
224
                else -- Interrupt = inst sub; SPISR = R30 (original); SPISR = SPISR - 1; M[R30] = PC; PC = R00 + Kpe(0400h)
225
                    T1_T0_v := INST_SUB;
226
                    C4_C0_v := C_TR;
227
                    F1_F0_SS2_v := FFS_DST_FT1_Kp;
228
                    APS_v := '0';
229
                    DST_v := std_logic_vector(to_unsigned(C_SPISR,DST_v'high+1)); -- beware with the register used to recover the PC with smaller sizes of RegBank...
230
                    FT1_v := std_logic_vector(to_unsigned(C_R00,FT1_v'high+1));
231
                    Kp_v := "10000000000"; -- 400h -> address FFFFFC00
232
                    IntAck_v := '1';
233
                    IntMask_v := '1';
234
                end if;
235
                NextPhase_v := IEXEC1;
236
 
237
            elsif Phase_v = IEXEC1 then
238
                IntAck_v := '0';
239
                if T1_T0_v = INST_ULA then
240
                   NextPhase_v := IFETCH;
241
                elsif T1_T0_v = INST_MEM and C4_C0_v = C_ST then
242
                   NextPhase_v := IFETCH;
243
                else
244
                   NextPhase_v := IEXEC2;
245
                end if;
246
 
247
            elsif Phase_v = IEXEC2 then
248
                if (T1_T0_v = INST_MEM and (C4_C0_v = C_LDPOI or C4_C0_v = C_LDPOD or C4_C0_v = C_LDPRI)) or (T1_T0_v = INST_SUB) then
249
                   NextPhase_v := IEXEC3;
250
                else
251
                   NextPhase_v := IFETCH;
252
                end if;
253
 
254
            elsif Phase_v = IEXEC3 then
255
                NextPhase_v := IFETCH;
256
 
257
            end if;
258
        end if;
259
        -------------------------
260
        -- Selectors and Outputs
261
        -------------------------
262
 
263
        if Reset_I = '1' then
264
            IntAck_O <= '0';
265
            IntAck_v := '0';
266
        else
267
            IntAck_O <= IntAck_v;
268
        end if;
269
 
270
        if Reset_I = '1' then
271
            PMem_Enable_O <= '0';
272
            DMem_Enable_O <= '0';
273
        else
274
            PMem_Enable_O <= '1';
275
            DMem_Enable_O <= '1';
276
        end if;
277
 
278
        -- Condition
279
        Condition_v := '0';
280
        if Phase_v = OFETCH then
281
            case C4_C0_v is
282
                when C_TR  => Condition_v := '1';
283
                when C_NS  => Condition_v := ULA_Ng_O_I;
284
                when C_CS  => Condition_v := ULA_Cy_O_I;
285
                when C_OS  => Condition_v := ULA_Ov_O_I;
286
                when C_ZS  => Condition_v := ULA_Zr_O_I;
287
                when C_GE  => Condition_v := (not ULA_Ng_O_I);
288
                when C_GT  => Condition_v := (not ULA_Ng_O_I) and (not ULA_Zr_O_I);
289
                when C_EQ  => Condition_v := ULA_Zr_O_I;
290
                when C_FL  => Condition_v := '0';
291
                when C_NN  => Condition_v := not ULA_Ng_O_I;
292
                when C_NC  => Condition_v := not ULA_Cy_O_I;
293
                when C_NO  => Condition_v := not ULA_Ov_O_I;
294
                when C_NZ  => Condition_v := not ULA_Zr_O_I;
295
                when C_LT  => Condition_v := ULA_Ng_O_I;
296
                when C_LE  => Condition_v := ULA_Ng_O_I or ULA_Zr_O_I;
297
                when C_NE  => Condition_v := not ULA_Zr_O_I;
298
                when others => Condition_v := '0';
299
            end case;
300
        end if;
301
 
302
        -- Data Memory
303
        DMem_Address_W <= (others => '0');-- Default
304
        DMem_InputData_O <= (others => '0');
305
        DMem_Write_O <= '0';
306
        case Phase_v is
307
            when IEXEC1 =>
308
                if T1_T0_v = INST_MEM and (C4_C0_v = C_ST or C4_C0_v = C_STPOI or C4_C0_v = C_STPOD) then
309
                    DMem_Address_W <= ULA_Output_I(DMem_Address_W'range);
310
                    DMem_InputData_O <= RegBnk_FT1_OutputData_I;
311
                    DMem_Write_O <= '1';
312
                elsif T1_T0_v = INST_MEM and (C4_C0_v = C_LD or C4_C0_v = C_LDPOI or C4_C0_v = C_LDPOD) then
313
                    DMem_Address_W <= ULA_Output_I(DMem_Address_W'range);
314
                elsif T1_T0_v = INST_SUB and Condition_v = '1' then
315
                    DMem_Address_W <= ULA_Output_I(DMem_Address_W'range);
316
                    DMem_InputData_O <= PC_Data_I;
317
                    DMem_Write_O <= '1';
318
                end if;
319
            when IEXEC2 =>
320
                if T1_T0_v = INST_MEM and C4_C0_v = C_STPRI then
321
                    DMem_Address_W <= ULA_Output_I(DMem_Address_W'range);
322
                    DMem_InputData_O <= RegBnk_FT1_OutputData_I;
323
                    DMem_Write_O <= '1';
324
                elsif T1_T0_v = INST_MEM and C4_C0_v = C_LDPRI then
325
                    DMem_Address_W <= ULA_Output_I(DMem_Address_W'range);
326
                    DMem_InputData_O <= RegBnk_FT1_OutputData_I;
327
                end if;
328
            when others =>
329
                DMem_Address_W <= (others => '0');
330
                DMem_InputData_O <= (others => '0');
331
                DMem_Write_O <= '0';
332
        end case;
333
 
334
        -- Register Bank
335
        RegBnk_Register1_O <= (others=>'0');-- Default
336
        RegBnk_Register2_O <= (others=>'0');
337
        RegBnk_RegisterW_O <= (others=>'0');
338
        RegBnk_Write_O <= '0';
339
        RegBnk_InputData_O <= (others => '0');
340
        case Phase_v is
341
            when OFETCH =>
342
                -- Type of operands
343
                if T1_T0_v = INST_ULA then
344
                    p_SelectRegInput1(F1_F0_SS2_v,DST_v,FT1_v,FT2_v,RegBnk_Register1_O);
345
                    p_SelectRegInput2(F1_F0_SS2_v,DST_v,FT1_v,FT2_v,RegBnk_Register2_O);
346
                elsif T1_T0_v = INST_MEM or T1_T0_v = INST_JMP then
347
                    p_SelectRegInput1(F1_F0_SS2_v,DST_v,FT1_v,FT2_v,RegBnk_Register1_O);
348
                    p_SelectRegInput2(F1_F0_SS2_v,DST_v,FT1_v,FT2_v,RegBnk_Register2_O);
349
                    RegBnk_RegisterW_O <= DST_v(NumBitsRegBank - 1 downto 0);
350
                elsif T1_T0_v = INST_SUB then
351
                    RegBnk_Register1_O <= DST_v(NumBitsRegBank - 1 downto 0);
352
                end if;
353
            when IEXEC1 =>
354
                -- Execute
355
                if T1_T0_v = INST_ULA and DST_v(NumBitsRegBank - 1 downto 0) /= std_logic_vector(to_unsigned(C_PC,RegBnk_Register1_O'high+1)) then --If DST=PC, write to PC
356
                    RegBnk_RegisterW_O <= DST_v(NumBitsRegBank - 1 downto 0);
357
                    RegBnk_Write_O <= '1';
358
                    case C4_C0_v is -- Choose between ULA and UD result
359
                        -- ULA
360
                        when C_ADD | C_ADDC  | C_SUB | C_SUBC | C_SUBR | C_SUBRC | C_AND | C_OR | C_XOR =>
361
                            RegBnk_InputData_O <= ULA_Output_I;
362
                        -- Shifter 
363
                        when C_SRL | C_SLL | C_SRA | C_SLA | C_RRL | C_RLL | C_RRA | C_RLA =>
364
                            RegBnk_InputData_O <= UD_OutputData_I;
365
                        when C_SRLC | C_SLLC | C_SRAC | C_SLAC | C_RRLC | C_RLLC | C_RRAC | C_RLAC =>
366
                            RegBnk_InputData_O <= UD_OutputData_I;
367
                        when others  =>
368
                            RegBnk_InputData_O <= (others => '0');
369
                    end case;
370
                elsif T1_T0_v = INST_MEM and (C4_C0_v = C_ST or C4_C0_v = C_STPOI or C4_C0_v = C_STPOD) then
371
                    RegBnk_Register1_O <= DST_v(NumBitsRegBank - 1 downto 0);
372
                elsif T1_T0_v = INST_MEM and (C4_C0_v = C_STPRI or C4_C0_v = C_LDPRI) then
373
                    RegBnk_RegisterW_O <= FT2_v(NumBitsRegBank - 1 downto 0);
374
                    RegBnk_Write_O <= '1';
375
                    RegBnk_InputData_O <= ULA_Output_I;
376
                    p_SelectRegInput1(F1_F0_SS2_v,DST_v,FT1_v,FT2_v,RegBnk_Register1_O);
377
                elsif T1_T0_v = INST_SUB and Condition_v = '1' then
378
                    RegBnk_RegisterW_O <= DST_v(NumBitsRegBank - 1 downto 0);
379
                    RegBnk_Write_O <= '1';
380
                    RegBnk_InputData_O <= ULA_Output_I;
381
                    p_SelectRegInput1(F1_F0_SS2_v,DST_v,FT1_v,FT2_v,RegBnk_Register1_O);
382
                    p_SelectRegInput2(F1_F0_SS2_v,DST_v,FT1_v,FT2_v,RegBnk_Register2_O);
383
                end if;
384
            when IEXEC2 =>
385
                if T1_T0_v = INST_MEM and (C4_C0_v = C_LD or C4_C0_v = C_LDPOI or C4_C0_v = C_LDPOD) then
386
                    RegBnk_RegisterW_O <= DST_v(NumBitsRegBank - 1 downto 0);
387
                    RegBnk_Write_O <= '1';
388
                    RegBnk_InputData_O <= DMem_OutputData_I;
389
                elsif T1_T0_v = INST_MEM and (C4_C0_v = C_STPOI or C4_C0_v = C_STPOD) then
390
                    RegBnk_RegisterW_O <= FT2_v(NumBitsRegBank - 1 downto 0);
391
                    RegBnk_Write_O <= '1';
392
                    RegBnk_InputData_O <= ULA_Output_I;
393
                elsif T1_T0_v = INST_MEM and C4_C0_v = C_STPRI then
394
                    RegBnk_Register1_O <= DST_v(NumBitsRegBank - 1 downto 0);
395
                end if;
396
            when IEXEC3 =>
397
                if T1_T0_v = INST_MEM and C4_C0_v = C_LDPRI then
398
                    RegBnk_RegisterW_O <= DST_v(NumBitsRegBank - 1 downto 0);
399
                    RegBnk_Write_O <= '1';
400
                    RegBnk_InputData_O <= DMem_OutputData_I;
401
                elsif T1_T0_v = INST_MEM and (C4_C0_v = C_LDPOI or C4_C0_v = C_LDPOD) then
402
                    RegBnk_RegisterW_O <= FT2_v(NumBitsRegBank - 1 downto 0);
403
                    RegBnk_Write_O <= '1';
404
                    RegBnk_InputData_O <= ULA_Output_I;
405
                end if;
406
            when others =>
407
                RegBnk_Register1_O <= (others => '0');
408
                RegBnk_Register2_O <= (others => '0');
409
                RegBnk_Write_O <= '0';
410
                RegBnk_InputData_O <= (others => '0');
411
        end case;
412
 
413
        -- PSW
414
        -- When APS = 1, update flags for ULA/UD operations with flags values
415
        -- When APS = 0, update flags only via store operation on PSW (R01)
416
        PSW_Data_O <= (others => '0');
417
        PSW_Wen_O <= '0';
418
        case Phase_v is
419
            when IEXEC1 =>
420
                if T1_T0_v = INST_ULA then
421
                   case C4_C0_v is -- Choose between ULA and UD result
422
                        -- ULA
423
                        when C_ADD | C_ADDC  | C_SUB | C_SUBC | C_SUBR | C_SUBRC | C_AND | C_OR | C_XOR =>
424
                            if DST_v(NumBitsRegBank - 1 downto 0) = std_logic_vector(to_unsigned(C_PSW,RegBnk_Register1_O'high+1)) then
425
                                PSW_Data_O <= ULA_Output_I;
426
                            else
427
                                PSW_Data_O <= PSW_Data_I;
428
                            end if;
429
                            if APS_v = '1' then
430
                                PSW_Data_O(7 downto 4) <= ULA_Ng_O_I & ULA_Ov_O_I & ULA_Zr_O_I & ULA_Cy_O_I;
431
                            end if;
432
                        -- Shifter 
433
                        when C_SRL | C_SLL | C_SRA | C_SLA | C_RRL | C_RLL | C_RRA | C_RLA =>
434
                            if DST_v(NumBitsRegBank - 1 downto 0) = std_logic_vector(to_unsigned(C_PSW,RegBnk_Register1_O'high+1)) then
435
                                PSW_Data_O <= UD_OutputData_I;
436
                            else
437
                                PSW_Data_O <= PSW_Data_I;
438
                            end if;
439
 
440
                        when C_SRLC | C_SLLC | C_SRAC | C_SLAC | C_RRLC | C_RLLC | C_RRAC | C_RLAC =>
441
                            if DST_v(NumBitsRegBank - 1 downto 0) = std_logic_vector(to_unsigned(C_PSW,RegBnk_Register1_O'high+1)) then
442
                                PSW_Data_O <= UD_OutputData_I;
443
                            else
444
                                PSW_Data_O <= PSW_Data_I;
445
                            end if;
446
                            if APS_v = '1' then
447
                                PSW_Data_O(4) <= UD_Cy_O_I;
448
                            end if;
449
                        when others  =>
450
                            PSW_Data_O <= (others => '0');
451
                    end case;
452
                    PSW_Wen_O <= '1';
453
                elsif T1_T0_v = INST_MEM and (C4_C0_v = C_STPRI or C4_C0_v = C_LDPRI) and FT2_v(NumBitsRegBank - 1 downto 0) = std_logic_vector(to_unsigned(C_PSW,RegBnk_Register1_O'high+1)) then
454
                    PSW_Data_O <= ULA_Output_I;
455
                    PSW_Wen_O <= '1';
456
                elsif T1_T0_v = INST_SUB and Condition_v = '1' and DST_v(NumBitsRegBank - 1 downto 0) = std_logic_vector(to_unsigned(C_PSW,RegBnk_Register1_O'high+1)) then
457
                    PSW_Data_O <= ULA_Output_I;
458
                    PSW_Wen_O <= '1';
459
                end if;
460
            when IEXEC2 =>
461
                if T1_T0_v = INST_MEM and (C4_C0_v = C_LD or C4_C0_v = C_LDPOI or C4_C0_v = C_LDPOD) and DST_v(NumBitsRegBank - 1 downto 0) = std_logic_vector(to_unsigned(C_PSW,RegBnk_Register1_O'high+1)) then
462
                    PSW_Data_O <= DMem_OutputData_I;
463
                    PSW_Wen_O <= '1';
464
                elsif T1_T0_v = INST_MEM and (C4_C0_v = C_STPOI or C4_C0_v = C_STPOD) and FT2_v(NumBitsRegBank - 1 downto 0) = std_logic_vector(to_unsigned(C_PSW,RegBnk_Register1_O'high+1)) then
465
                    PSW_Data_O <= ULA_Output_I;
466
                    PSW_Wen_O <= '1';
467
                end if;
468
            when IEXEC3 =>
469
                if T1_T0_v = INST_MEM and C4_C0_v = C_LDPRI and DST_v(NumBitsRegBank - 1 downto 0) = std_logic_vector(to_unsigned(C_PSW,RegBnk_Register1_O'high+1)) then
470
                    PSW_Data_O <= DMem_OutputData_I;
471
                    PSW_Wen_O <= '1';
472
                elsif T1_T0_v = INST_MEM and (C4_C0_v = C_LDPOI or C4_C0_v = C_LDPOD) and FT2_v(NumBitsRegBank - 1 downto 0) = std_logic_vector(to_unsigned(C_PSW,RegBnk_Register1_O'high+1)) then
473
                    PSW_Data_O <= ULA_Output_I;
474
                    PSW_Wen_O <= '1';
475
                end if;
476
            when others =>
477
                PSW_Data_O <= (others => '0');
478
                PSW_Wen_O <= '0';
479
        end case;
480
 
481
        -- PC
482
        PC_Wen_O <= '0';
483
        PC_Data_O <= (others => '0');
484
        case Phase_v is
485
            when IEXEC1 =>
486
                if (T1_T0_v = INST_ULA and DST_v(NumBitsRegBank - 1 downto 0) = std_logic_vector(to_unsigned(C_PC,RegBnk_Register1_O'high+1))) then -- PC=R31
487
                    PC_Wen_O <= '1';
488
                    PC_Data_O <= ULA_Output_I;
489
                elsif (T1_T0_v = INST_JMP and Condition_v = '1' and DST_v(NumBitsRegBank - 1 downto 0) = std_logic_vector(to_unsigned(C_PC,RegBnk_Register1_O'high + 1))) then
490
                    PC_Wen_O <= '1';
491
                    PC_Data_O <= ULA_Output_I;
492
                else
493
                    PC_Wen_O <= '1';
494
                    PC_Data_O <= std_logic_vector(unsigned(PC_Data_I) + 1);
495
                end if;
496
            when IEXEC2 =>
497
                if T1_T0_v = INST_SUB and Condition_v = '1' then
498
                    PC_Wen_O <= '1';
499
                    PC_Data_O <= ULA_Output_I;
500
                elsif T1_T0_v = INST_MEM and C4_C0_v = C_LDPOI and DST_v(NumBitsRegBank - 1 downto 0) = std_logic_vector(to_unsigned(C_PC,RegBnk_Register1_O'high + 1)) then
501
                    PC_Wen_O <= '1';
502
                    PC_Data_O <= DMem_OutputData_I;
503
                end if;
504
            when others =>
505
                PC_Wen_O <= '0';
506
                PC_Data_O <= (others => '0');
507
        end case;
508
 
509
        -- ULA,UD
510
        ULA_Function_O <= (others=>'0');-- default
511
        UD_Function_O <= (others=>'0');
512
        case Phase_v is
513
            when IEXEC1 =>
514
                -- ULA/UD Function
515
                if T1_T0_v = INST_ULA then
516
                    ULA_Function_O <= C4_C0_v;
517
                    UD_Function_O <= C4_C0_v;
518
                elsif T1_T0_v = INST_MEM and C4_C0_v = C_ST then
519
                    ULA_Function_O <= C_ADD;
520
                elsif T1_T0_v = INST_MEM and C4_C0_v = C_LD then
521
                    ULA_Function_O <= C_ADD;
522
                elsif T1_T0_v = INST_JMP then
523
                    ULA_Function_O <= C_ADD;
524
                elsif T1_T0_v = INST_SUB then
525
                    ULA_Function_O <= C_SUB;
526
                end if;
527
            when IEXEC2 =>
528
                case T1_T0_v is   -- ULA and UD function based on instruction type
529
                    when INST_MEM =>
530
                        if C4_C0_v = C_STPOI or C4_C0_v = C_STPOD then
531
                            ULA_Function_O <= C_ADD;
532
                        end if;
533
                    when INST_SUB =>
534
                        if Condition_v = '1' then
535
                            ULA_Function_O <= C_ADD;
536
                        end if;
537
                    when others   =>
538
                        ULA_Function_O <= (others=>'0');
539
                        UD_Function_O <= (others=>'0');
540
                end case;
541
            when IEXEC3 =>
542
                if T1_T0_v = INST_MEM and (C4_C0_v = C_LDPOI or C4_C0_v = C_LDPOD) then
543
                    ULA_Function_O <= C_ADD;
544
                end if;
545
            when others =>
546
                ULA_Function_O <= (others=>'0');
547
                UD_Function_O <= (others=>'0');
548
        end case;
549
 
550
        -- RUA,RUB,RDA,RDB
551
        RUA_Wen_O <= '0'; RUB_Wen_O <= '0'; RDA_Wen_O <= '0'; RDB_Wen_O <= '0';
552
        RUA_Data_O <= (others=>'0');        RUB_Data_O <= (others=>'0');
553
        RDA_Data_O <= (others=>'0');        RDB_Data_O <= (others=>'0');
554
        case Phase_v is
555
            when OFETCH =>
556
                RUA_Wen_O <= '1'; RUB_Wen_O <= '1'; RDA_Wen_O <= '1'; RDB_Wen_O <= '1';
557
                if T1_T0_v = INST_MEM and (C4_C0_v = C_STPRI or C4_C0_v = C_LDPRI) then
558
                    RUA_Data_O <= std_logic_vector(to_unsigned(1,RUA_Data_O'high+1));
559
                    case (F1_F0_SS2_v) is
560
                        when FFS_DST_FT1_FT2 => RUB_Data_O <= f_SelectRegOutput(FT2_v(NumBitsRegBank - 1 downto 0),PSW_Data_I,PC_Data_I,RegBnk_FT2_OutputData_I);
561
                        when FFS_DST_FT1_Kp  => RUB_Data_O <= Kpe_F(Kp_v);             -- Source 1 and Kp
562
                        when FFS_DST_R00_Kgl => RUB_Data_O <= Kgl_F(Kg_v);             -- R00 and Kgl
563
                        when FFS_DST_DST_Kgl => RUB_Data_O <= Kgl_F(Kg_v);             -- DST and Kgl 
564
                        when others          => RUB_Data_O <= (others=>'0');           -- Not Specified
565
                    end case;
566
                elsif T1_T0_v = INST_SUB then
567
                    RUA_Data_O <= f_SelectRegOutput(DST_v(NumBitsRegBank - 1 downto 0),PSW_Data_I,PC_Data_I,RegBnk_FT1_OutputData_I); --RegBnk_FT1_OutputData_I;
568
                    RUB_Data_O <= std_logic_vector(to_unsigned(1,RUA_Data_O'high+1));
569
                else
570
                    -- Operand fetch for ULA and UD
571
                    case (F1_F0_SS2_v) is
572
                        when FFS_DST_FT1_FT2 => RUA_Data_O <= f_SelectRegOutput(FT1_v(NumBitsRegBank - 1 downto 0),PSW_Data_I,PC_Data_I,RegBnk_FT1_OutputData_I); --RegBnk_FT1_OutputData_I; -- Source 1 and Source 2  
573
                                                RUB_Data_O <= f_SelectRegOutput(FT2_v(NumBitsRegBank - 1 downto 0),PSW_Data_I,PC_Data_I,RegBnk_FT2_OutputData_I); --RegBnk_FT2_OutputData_I; 
574
                                                RDA_Data_O <= f_SelectRegOutput(FT1_v(NumBitsRegBank - 1 downto 0),PSW_Data_I,PC_Data_I,RegBnk_FT1_OutputData_I); --RegBnk_FT1_OutputData_I;   
575
                                                RDB_Data_O <= f_SelectRegOutput(FT2_v(NumBitsRegBank - 1 downto 0),PSW_Data_I,PC_Data_I,RegBnk_FT2_OutputData_I); --RegBnk_FT2_OutputData_I;
576
                        when FFS_DST_FT1_Kp  => RUA_Data_O <= f_SelectRegOutput(FT1_v(NumBitsRegBank - 1 downto 0),PSW_Data_I,PC_Data_I,RegBnk_FT1_OutputData_I); --RegBnk_FT1_OutputData_I; -- Source 1 and Kp  
577
                                                RUB_Data_O <= Kpe_F(Kp_v);
578
                                                RDA_Data_O <= f_SelectRegOutput(FT1_v(NumBitsRegBank - 1 downto 0),PSW_Data_I,PC_Data_I,RegBnk_FT1_OutputData_I); --RegBnk_FT1_OutputData_I;   
579
                                                RDB_Data_O <= Kpe_F(Kp_v);
580
                        when FFS_DST_R00_Kgl => RUA_Data_O <= (others => '0');         -- R00 and Kgl            
581
                                                RUB_Data_O <= Kgl_F(Kg_v);
582
                                                RDA_Data_O <= (others => '0');
583
                                                RDB_Data_O <= Kgl_F(Kg_v);
584
                        when FFS_DST_DST_Kgl => RUA_Data_O <= f_SelectRegOutput(FT1_v(NumBitsRegBank - 1 downto 0),PSW_Data_I,PC_Data_I,RegBnk_FT1_OutputData_I); --RegBnk_FT1_OutputData_I; -- DST and Kgl  
585
                                                RUB_Data_O <= Kgl_F(Kg_v);
586
                                                RDA_Data_O <= f_SelectRegOutput(FT1_v(NumBitsRegBank - 1 downto 0),PSW_Data_I,PC_Data_I,RegBnk_FT1_OutputData_I); --RegBnk_FT1_OutputData_I;   
587
                                                RDB_Data_O <= Kgl_F(Kg_v);
588
                        when others          => RUA_Data_O <= (others=>'0');           -- Not Specified  
589
                                                RUB_Data_O <= (others=>'0');
590
                                                RDA_Data_O <= (others=>'0');
591
                                                RDB_Data_O <= (others=>'0');
592
                    end case;
593
                end if;
594
            when IEXEC1 =>
595
                if T1_T0_v = INST_MEM and (C4_C0_v = C_STPOI or C4_C0_v = C_LDPOI) then
596
                    RUA_Data_O <= std_logic_vector(to_unsigned(1,RUA_Data_O'high+1));
597
                    RUA_Wen_O <= '1';
598
                elsif T1_T0_v = INST_MEM and (C4_C0_v = C_STPOD or C4_C0_v = C_LDPOD) then
599
                    RUA_Data_O <= std_logic_vector(to_signed(-1,RUA_Data_O'high+1));
600
                    RUA_Wen_O <= '1';
601
                elsif T1_T0_v = INST_MEM and (C4_C0_v = C_STPRI or C4_C0_v = C_LDPRI) then
602
                    case (F1_F0_SS2_v) is
603
                        when FFS_DST_FT1_FT2 => RUA_Data_O <= f_SelectRegOutput(FT1_v(NumBitsRegBank - 1 downto 0),PSW_Data_I,PC_Data_I,RegBnk_FT1_OutputData_I); --RegBnk_FT1_OutputData_I;
604
                        when FFS_DST_FT1_Kp  => RUA_Data_O <= f_SelectRegOutput(FT1_v(NumBitsRegBank - 1 downto 0),PSW_Data_I,PC_Data_I,RegBnk_FT1_OutputData_I); --RegBnk_FT1_OutputData_I;
605
                        when FFS_DST_R00_Kgl => RUA_Data_O <= (others => '0');
606
                        when FFS_DST_DST_Kgl => RUA_Data_O <= f_SelectRegOutput(FT1_v(NumBitsRegBank - 1 downto 0),PSW_Data_I,PC_Data_I,RegBnk_FT1_OutputData_I); --RegBnk_FT1_OutputData_I;
607
                        when others          => RUA_Data_O <= (others=>'0');
608
                    end case;
609
                    RUA_Wen_O <= '1';
610
                    RUB_Data_O <= ULA_Output_I;
611
                    RUB_Wen_O <= '1';
612
                elsif T1_T0_v = INST_SUB and Condition_v = '1' then
613
                    case (F1_F0_SS2_v) is
614
                        when FFS_DST_FT1_FT2 =>
615
                            RUA_Data_O <= f_SelectRegOutput(FT1_v(NumBitsRegBank - 1 downto 0),PSW_Data_I,PC_Data_I,RegBnk_FT1_OutputData_I); --RegBnk_FT1_OutputData_I; -- Source 1 and Source   
616
                            RUB_Data_O <= f_SelectRegOutput(FT2_v(NumBitsRegBank - 1 downto 0),PSW_Data_I,PC_Data_I,RegBnk_FT2_OutputData_I); --RegBnk_FT2_OutputData_I; 
617
                        when FFS_DST_FT1_Kp  =>
618
                            RUA_Data_O <= f_SelectRegOutput(FT1_v(NumBitsRegBank - 1 downto 0),PSW_Data_I,PC_Data_I,RegBnk_FT1_OutputData_I); --RegBnk_FT1_OutputData_I; -- Source 1 and K  
619
                            RUB_Data_O <= Kpe_F(Kp_v);
620
                        when FFS_DST_R00_Kgl =>
621
                            RUA_Data_O <= (others => '0');         -- R00 and Kgl            
622
                            RUB_Data_O <= Kgl_F(Kg_v);
623
                        when FFS_DST_DST_Kgl =>
624
                            RUA_Data_O <= f_SelectRegOutput(FT1_v(NumBitsRegBank - 1 downto 0),PSW_Data_I,PC_Data_I,RegBnk_FT1_OutputData_I); --RegBnk_FT1_OutputData_I; -- DST and Kgl  
625
                            RUB_Data_O <= Kgl_F(Kg_v);
626
                        when others          =>
627
                        RUA_Data_O <= (others=>'0');               -- Not Specified
628
                        RUB_Data_O <= (others=>'0');
629
                    end case;
630
                    RUA_Wen_O <= '1';
631
                    RUB_Wen_O <= '1';
632
                end if;
633
            when others =>
634
                RUA_Wen_O <= '0'; RUB_Wen_O <= '0'; RDA_Wen_O <= '0'; RDB_Wen_O <= '0';
635
                RUA_Data_O <= (others=>'0');        RUB_Data_O <= (others=>'0');
636
                RDA_Data_O <= (others=>'0');        RDB_Data_O <= (others=>'0');
637
        end case;
638
 
639
        -- RUA_Clr_O, RUB_Clr_O, RDA_Clr_O, RDB_Clr_O, PSW_Clr_O
640
        case Phase_v is
641
            when RESET =>
642
                RUA_Clr_O <= '1'; RUB_Clr_O <= '1'; RDA_Clr_O <= '1'; RDB_Clr_O <= '1'; PC_Clr_O <= '1'; PSW_Clr_O <= '1';
643
            when others =>
644
                RUA_Clr_O <= '0'; RUB_Clr_O <= '0'; RDA_Clr_O <= '0'; RDB_Clr_O <= '0'; PC_Clr_O <= '0'; PSW_Clr_O <= '0';
645
        end case;
646
 
647
    end process;
648
 
649
PMem_Write_O <= '0';                                                      -- Program Memory Read
650
PMem_Address_O <= PC_Data_I(PMem_Address_O'range) when Reset_I = '0' else -- Set memory address
651
                  (others => '0');
652
 
653
DMem_Address_O <= DMem_Address_W when Reset_I = '0' else -- Set memory address
654
                  (others => '0');
655
 
656
end Ark1;

powered by: WebSVN 2.1.0

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