]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/tumbl.git/blob - hw/mbl_Pkg.vhd
26acc724ae18b1d9e12a15a2578a7c35ab391eea
[fpga/lx-cpu1/tumbl.git] / hw / mbl_Pkg.vhd
1 ---------------------------------------------------------------------------------
2 --
3 --  Package:      mbl_Pkg
4 --  Filename:     mbl_Pkg.vhd
5 --  Description:  Package for the TUD MB-Lite implementation
6 --
7 --  Author:       Huib Lincklaen Arriens
8 --                Delft University of Technology
9 --                Faculty EEMCS, Department ME&CE, Circuits and Systems
10 --  Date:         September, 2010
11 --
12 --  Modified:     September, 2013: Removed FSL
13 --                     June, 2011: ALU_ACTION_Type extended to incorporate
14 --                                 MUL and BS instructions (Huib)
15 --                                 Adapted to work with separate fsl_M-
16 --                                 and fsl_S selectors and automatic
17 --                                 tumbl<_jtag><_fsl>.vhd generation (Huib)
18 --                     July, 2011: function ef_nbits added (Huib)
19 --  Remarks:
20 --
21 --------------------------------------------------------------------------------
22
23 LIBRARY IEEE;
24 USE IEEE.std_logic_1164.all;
25 USE IEEE.std_logic_unsigned.all;
26 USE IEEE.numeric_std.all;
27
28
29 --------------------------------------------------------------------------------
30 PACKAGE mbl_Pkg IS
31 --------------------------------------------------------------------------------
32
33     CONSTANT  C_8_ZEROS : STD_LOGIC_VECTOR ( 7 DOWNTO 0) :=       X"00";
34     CONSTANT C_16_ZEROS : STD_LOGIC_VECTOR (15 DOWNTO 0) :=     X"0000";
35     CONSTANT C_24_ZEROS : STD_LOGIC_VECTOR (23 DOWNTO 0) :=   X"000000";
36     CONSTANT C_32_ZEROS : STD_LOGIC_VECTOR (31 DOWNTO 0) := X"00000000";
37
38     CONSTANT C_16_ONES  : STD_LOGIC_VECTOR (15 DOWNTO 0) :=     X"FFFF";
39     CONSTANT C_24_ONES  : STD_LOGIC_VECTOR (23 DOWNTO 0) :=   X"FFFFFF";
40
41
42 ----------------------------------------------------------------------------------------------
43 -- TYPE DEFINITIONS
44 ----------------------------------------------------------------------------------------------
45
46     TYPE ALU_ACTION_Type    IS (A_NOP, A_ADD, A_CMP, A_CMPU, A_OR, A_AND, A_XOR,
47                                         A_SHIFT, A_SEXT8, A_SEXT16, A_MFS, A_MTS,
48                                                     A_MUL, A_BSLL, A_BSRL, A_BSRA);
49     TYPE ALU_IN1_Type       IS (ALU_IN_REGA, ALU_IN_NOT_REGA, ALU_IN_PC, ALU_IN_ZERO);
50     TYPE ALU_IN2_Type       IS (ALU_IN_REGB, ALU_IN_NOT_REGB, ALU_IN_IMM, ALU_IN_NOT_IMM);
51     TYPE ALU_CIN_Type       IS (CIN_ZERO, CIN_ONE, FROM_MSR, FROM_IN1);
52     TYPE MSR_ACTION_Type    IS (UPDATE_CARRY, KEEP_CARRY);
53     TYPE BRANCH_ACTION_Type IS (NO_BR, BR, BRL, BEQ, BNE, BLT, BLE, BGT, BGE);
54     TYPE WRB_ACTION_Type    IS (NO_WRB, WRB_EX, WRB_MEM);
55     TYPE MEM_ACTION_Type    IS (NO_MEM, WR_MEM, RD_MEM);
56     TYPE TRANSFER_SIZE_Type IS (WORD, HALFWORD, BYTE);
57     TYPE SAVE_REG_Type      IS (NO_SAVE, SAVE_RA, SAVE_RB);
58     --
59     TYPE IF2ID_Type IS RECORD
60         program_counter : STD_LOGIC_VECTOR (31 DOWNTO 0);
61     END RECORD;
62
63     TYPE ID2EX_Type IS RECORD
64         program_counter  : STD_LOGIC_VECTOR (31 DOWNTO 0);
65         rdix_rA          : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
66         rdix_rB          : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
67         curr_rD          : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
68         alu_Action       : ALU_ACTION_Type;
69         alu_Op1          : ALU_IN1_Type;
70         alu_Op2          : ALU_IN2_Type;
71         alu_Cin          : ALU_CIN_Type;
72         IMM16            : STD_LOGIC_VECTOR (15 DOWNTO 0);
73         IMM_Lock         : STD_LOGIC;
74         msr_Action       : MSR_ACTION_Type;
75         branch_Action    : BRANCH_ACTION_Type;
76         mem_Action       : MEM_ACTION_Type;         -- rd_mem implies writeback
77         transfer_Size    : TRANSFER_SIZE_Type;
78         wrb_Action       : WRB_ACTION_Type;
79     END RECORD;
80
81     TYPE ID2GPRF_Type IS RECORD
82         rdix_rA : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
83         rdix_rB : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
84         rdix_rD : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
85     END RECORD;
86
87     TYPE INT_CTRL_Type IS RECORD
88         setup_int  : STD_LOGIC;
89         rti_target : STD_LOGIC_VECTOR (31 DOWNTO 0);
90         int_busy   : STD_LOGIC;
91     END RECORD;
92
93     TYPE ID2CTRL_Type IS RECORD
94         delayBit : STD_LOGIC;
95         int_busy : STD_LOGIC;
96     END RECORD;
97
98     TYPE GPRF2EX_Type IS RECORD
99         data_rA : STD_LOGIC_VECTOR (31 DOWNTO 0);
100         data_rB : STD_LOGIC_VECTOR (31 DOWNTO 0);
101         data_rD : STD_LOGIC_VECTOR (31 DOWNTO 0);
102     END RECORD;
103
104     TYPE IMM_LOCK_Type IS RECORD
105         locked   : STD_LOGIC;
106         IMM_hi16 : STD_LOGIC_VECTOR (15 DOWNTO 0);
107     END RECORD;
108
109     TYPE MSR_Type IS RECORD
110         IE  : STD_LOGIC;        -- MSR[VHDL b1] = [MicroBlaze b30]
111         C   : STD_LOGIC;        -- MSR[VHDL b2 and b31] = [MicroBlaze b29 and b0]
112     END RECORD;
113
114     TYPE EX2IF_Type IS RECORD
115         take_branch   : STD_LOGIC;
116         branch_target : STD_LOGIC_VECTOR (31 DOWNTO 0);
117     END RECORD;
118
119     TYPE EX2MEM_Type IS RECORD
120         mem_Action      : MEM_ACTION_Type;                  -- RD_MEM implies writeback
121         wrb_Action      : WRB_ACTION_Type;
122         exeq_result     : STD_LOGIC_VECTOR (31 DOWNTO 0);
123         data_rD         : STD_LOGIC_VECTOR (31 DOWNTO 0);
124         byte_Enable     : STD_LOGIC_VECTOR ( 3 DOWNTO 0);
125         wrix_rD         : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
126     END RECORD;
127
128     TYPE WRB_Type IS RECORD
129         wrb_Action : WRB_ACTION_Type;
130         wrix_rD    : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
131         data_rD    : STD_LOGIC_VECTOR (31 DOWNTO 0);
132     END RECORD;
133
134     TYPE HAZARD_WRB_Type IS RECORD
135         hazard  : STD_LOGIC;
136         save_rX : SAVE_REG_Type;
137         data_rX : STD_LOGIC_VECTOR (31 DOWNTO 0);
138         data_rD : STD_LOGIC_VECTOR (31 DOWNTO 0);
139     END RECORD;
140
141     TYPE MEM_REG_Type IS RECORD
142         wrb_Action  : WRB_ACTION_Type;
143         exeq_result : STD_LOGIC_VECTOR (31 DOWNTO 0);
144         byte_Enable : STD_LOGIC_VECTOR ( 3 DOWNTO 0);
145         wrix_rD     : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
146     END RECORD;
147
148     TYPE MEM2CTRL_Type IS RECORD
149         clken : STD_LOGIC;
150         int   : STD_LOGIC;
151     END RECORD;
152
153     TYPE CORE2DMEMB_Type IS RECORD
154         ena   : STD_LOGIC;
155         addr  : STD_LOGIC_VECTOR (31 DOWNTO 0);
156         bSel  : STD_LOGIC_VECTOR ( 3 DOWNTO 0);
157         wre   : STD_LOGIC;
158         data  : STD_LOGIC_VECTOR (31 DOWNTO 0);
159     END RECORD;
160
161     TYPE DMEMB2CORE_Type IS RECORD
162         clken : STD_LOGIC;
163         data  : STD_LOGIC_VECTOR (31 DOWNTO 0);
164         int   : STD_LOGIC;
165     END RECORD;
166
167     TYPE MEMORY_MAP_Type IS ARRAY(NATURAL RANGE <>) OF STD_LOGIC_VECTOR (31 DOWNTO 0);
168     -- NOTE: Use the named association format  xxxx := ( 0 => X"A0010000" );
169     --       in case the array has to contain only one element !!
170
171 ----------------------------------------------------------------------------------------------
172 -- COMPONENTS
173 ----------------------------------------------------------------------------------------------
174
175     COMPONENT fetch IS
176         PORT (
177             prog_cntr_i :  IN STD_LOGIC_VECTOR (31 DOWNTO 0);
178             inc_pc_i    :  IN STD_LOGIC;
179             EX2IF_i     :  IN EX2IF_Type;
180             IF2ID_o     : OUT IF2ID_Type
181             );
182     END COMPONENT;
183
184     COMPONENT decode IS
185         GENERIC (
186             USE_HW_MUL_g : BOOLEAN := FALSE;
187             USE_BARREL_g : BOOLEAN := FALSE
188             );
189         PORT (
190             IF2ID_i     :  IN IF2ID_Type;
191             imem_data_i :  IN STD_LOGIC_VECTOR (31 DOWNTO 0);
192             --
193             ID2GPRF_o   : OUT ID2GPRF_Type;
194             ID2EX_o     : OUT ID2EX_Type;
195             --
196             INT_CTRL_i  :  IN INT_CTRL_Type;
197             ID2CTRL_o   : OUT ID2CTRL_Type;
198                                                 --
199                                                 noLiteOpc_o : OUT STD_LOGIC
200             );
201     END COMPONENT;
202
203     COMPONENT adder IS
204         GENERIC (
205             DW_g : POSITIVE := 32;
206             LW_g : POSITIVE := 15
207         );
208         PORT (
209             in1  :  IN STD_LOGIC_VECTOR (DW_g-1 DOWNTO 0);
210             in2  :  IN STD_LOGIC_VECTOR (DW_g-1 DOWNTO 0);
211             cin  :  IN STD_LOGIC;
212             sum  : OUT STD_LOGIC_VECTOR (DW_g-1 DOWNTO 0);
213             cout : OUT STD_LOGIC
214             );
215     END COMPONENT;
216
217     COMPONENT exeq IS
218         GENERIC (
219             USE_HW_MUL_g : BOOLEAN := FALSE;
220             USE_BARREL_g : BOOLEAN := FALSE
221             );
222         PORT (
223             ID2EX_i      :  IN ID2EX_Type;
224             GPRF2EX_i    :  IN GPRF2EX_Type;
225             EX2IF_o      : OUT EX2IF_Type;
226             --
227             EX_WRB_i     :  IN WRB_Type;
228             EX_WRB_o     : OUT WRB_Type;
229             MEM_WRB_i    :  IN WRB_Type;
230             --
231             HAZARD_WRB_i :  IN HAZARD_WRB_Type;
232             HAZARD_WRB_o : OUT HAZARD_WRB_Type;
233             --
234             IMM_LOCK_i   :  IN IMM_LOCK_Type;
235             IMM_LOCK_o   : OUT IMM_LOCK_Type;
236             --
237             MSR_i        :  IN MSR_Type;
238             MSR_o        : OUT MSR_Type;
239             --
240             EX2MEM_o     : OUT EX2MEM_Type
241             );
242     END COMPONENT;
243
244     COMPONENT mem IS
245         PORT (
246             EX2MEM_i    :  IN EX2MEM_Type;
247             --
248             DMEMB_i     :  IN DMEMB2CORE_Type;
249             DMEMB_o     : OUT CORE2DMEMB_Type;
250             --
251             MEM_REG_i   :  IN MEM_REG_Type;
252             MEM_REG_o   : OUT MEM_REG_Type;
253             --
254             MEM_WRB_o   : OUT WRB_Type;
255             MEM2CTRL_o  : OUT MEM2CTRL_Type
256             );
257     END COMPONENT;
258
259     COMPONENT core_ctrl IS
260         PORT (
261             clk_i           :  IN STD_LOGIC;
262             rst_i           :  IN STD_LOGIC;
263             halt_i          :  IN STD_LOGIC;
264             int_i           :  IN STD_LOGIC;
265             -- specific fetch i/o
266             imem_addr_o     : OUT STD_LOGIC_VECTOR (31 DOWNTO 0);
267             imem_clken_o    : OUT STD_LOGIC;
268             pc_ctrl_o       : OUT STD_LOGIC;
269             -- fetch to decode pipeline registers
270             IF2ID_REG_i     :  IN IF2ID_Type;
271             IF2ID_REG_o     : OUT IF2ID_Type;
272             -- decode to exeq pipeline registers
273             ID2EX_REG_i     :  IN ID2EX_Type;
274             ID2EX_REG_o     : OUT ID2EX_Type;
275             -- GPRF control
276             gprf_clken_o    : OUT STD_LOGIC;
277             -- exeq to fetch feedback registers
278             EX2IF_REG_i     :  IN EX2IF_Type;
279             EX2IF_REG_o     : OUT EX2IF_Type;
280             -- exeq to mem pipeline registers
281             EX2MEM_REG_i    :  IN EX2MEM_Type;
282             EX2MEM_REG_o    : OUT EX2MEM_Type;
283             -- mem pipeline register
284             MEM_REG_i       :  IN MEM_REG_Type;
285             MEM_REG_o       : OUT MEM_REG_Type;
286             -- decode control i/o
287             ID2CTRL_i       :  IN ID2CTRL_Type;
288             INT_CTRL_o      : OUT INT_CTRL_Type;
289             -- exeq control i/o
290             EX_WRB_i        :  IN WRB_Type;
291             EX_WRB_o        : OUT WRB_Type;
292             -- data hazard i/o
293             HAZARD_WRB_i    :  IN HAZARD_WRB_Type;
294             HAZARD_WRB_o    : OUT HAZARD_WRB_Type;
295             -- for handling the 'IMM' instruction
296             IMM_LOCK_i      :  IN IMM_LOCK_Type;
297             IMM_LOCK_o      : OUT IMM_LOCK_Type;
298             -- for handling the Machine Status Register
299             MSR_i           :  IN MSR_Type;
300             MSR_o           : OUT MSR_Type;
301             -- miscellaneous
302             MEM2CTRL_i      :  IN MEM2CTRL_Type;
303             done_o          : OUT STD_LOGIC
304             );
305     END COMPONENT;
306
307 ----------------------------------------------------------------------------------------------
308 -- FUNCTION, PROCEDURE DECLARATIONS
309 ----------------------------------------------------------------------------------------------
310
311     PROCEDURE ep_add32 ( a, b :  IN STD_LOGIC_VECTOR (31 DOWNTO 0);
312                          ci   :  IN STD_LOGIC;
313                          VARIABLE s  : OUT STD_LOGIC_VECTOR (31 DOWNTO 0);
314                          VARIABLE co : OUT STD_LOGIC );
315
316     PROCEDURE ep_add32nc ( a, b :  IN STD_LOGIC_VECTOR (31 DOWNTO 0);
317                          ci   :  IN STD_LOGIC;
318                          VARIABLE s  : OUT STD_LOGIC_VECTOR (31 DOWNTO 0));
319
320 --  PROCEDURE ep_add32 ( a, b : IN STD_LOGIC_VECTOR; ci : IN STD_LOGIC;
321 --                       VARIABLE s  : OUT STD_LOGIC_VECTOR;
322 --                       VARIABLE co : OUT STD_LOGIC );
323
324     FUNCTION ef_nbits ( value : NATURAL ) RETURN POSITIVE;
325
326 END PACKAGE mbl_Pkg;
327
328
329 ----------------------------------------------------------
330 PACKAGE BODY mbl_Pkg IS
331 ----------------------------------------------------------
332
333     PROCEDURE ep_add32 (        a, b :  IN STD_LOGIC_VECTOR (31 DOWNTO 0);
334                                 ci   :  IN STD_LOGIC;
335                          VARIABLE s  : OUT STD_LOGIC_VECTOR (31 DOWNTO 0);
336                          VARIABLE co : OUT STD_LOGIC ) IS
337
338         CONSTANT NBITS_LO_c : POSITIVE := 17;
339         CONSTANT NBITS_HI_c : POSITIVE := 32 -NBITS_LO_c;
340         VARIABLE tmp_lo_v   : STD_LOGIC_VECTOR (NBITS_LO_c +1 DOWNTO 0);
341         VARIABLE tmp_hi0_v  : STD_LOGIC_VECTOR (NBITS_HI_c +1 DOWNTO 0);
342         VARIABLE tmp_hi1_v  : STD_LOGIC_VECTOR (NBITS_HI_c +1 DOWNTO 0);
343     BEGIN
344         tmp_lo_v  := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(NBITS_LO_c -1 DOWNTO  0) & '1' ) +
345                                        UNSIGNED( '0' & b(NBITS_LO_c -1 DOWNTO  0) & ci  ));
346         tmp_hi0_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(31 DOWNTO (32 - NBITS_HI_c)) & '1') +
347                                        UNSIGNED( '0' & b(31 DOWNTO (32 - NBITS_HI_c)) & '0'));
348         tmp_hi1_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(31 DOWNTO (32 - NBITS_HI_c)) & '1') +
349                                        UNSIGNED( '0' & b(31 DOWNTO (32 - NBITS_HI_c)) & '1'));
350         IF (tmp_lo_v(NBITS_LO_c +1) = '0') THEN
351             s  := tmp_hi0_v(NBITS_HI_c DOWNTO 1) & tmp_lo_v(NBITS_LO_c DOWNTO 1);
352             co := tmp_hi0_v(NBITS_HI_c +1);
353         ELSE
354             s  := tmp_hi1_v(NBITS_HI_c DOWNTO 1) & tmp_lo_v(NBITS_LO_c DOWNTO 1);
355             co := tmp_hi1_v(NBITS_HI_c +1);
356         END IF;
357     END PROCEDURE;
358
359     PROCEDURE ep_add32nc (        a, b :  IN STD_LOGIC_VECTOR (31 DOWNTO 0);
360                                 ci   :  IN STD_LOGIC;
361                          VARIABLE s  : OUT STD_LOGIC_VECTOR (31 DOWNTO 0) ) IS
362
363         CONSTANT NBITS_LO_c : POSITIVE := 17;
364         CONSTANT NBITS_HI_c : POSITIVE := 32 -NBITS_LO_c;
365         VARIABLE tmp_lo_v   : STD_LOGIC_VECTOR (NBITS_LO_c +1 DOWNTO 0);
366         VARIABLE tmp_hi0_v  : STD_LOGIC_VECTOR (NBITS_HI_c +1 DOWNTO 0);
367         VARIABLE tmp_hi1_v  : STD_LOGIC_VECTOR (NBITS_HI_c +1 DOWNTO 0);
368     BEGIN
369         tmp_lo_v  := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(NBITS_LO_c -1 DOWNTO  0) & '1' ) +
370                                        UNSIGNED( '0' & b(NBITS_LO_c -1 DOWNTO  0) & ci  ));
371         tmp_hi0_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(31 DOWNTO (32 - NBITS_HI_c)) & '1') +
372                                        UNSIGNED( '0' & b(31 DOWNTO (32 - NBITS_HI_c)) & '0'));
373         tmp_hi1_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(31 DOWNTO (32 - NBITS_HI_c)) & '1') +
374                                        UNSIGNED( '0' & b(31 DOWNTO (32 - NBITS_HI_c)) & '1'));
375         IF (tmp_lo_v(NBITS_LO_c +1) = '0') THEN
376             s  := tmp_hi0_v(NBITS_HI_c DOWNTO 1) & tmp_lo_v(NBITS_LO_c DOWNTO 1);
377         ELSE
378             s  := tmp_hi1_v(NBITS_HI_c DOWNTO 1) & tmp_lo_v(NBITS_LO_c DOWNTO 1);
379         END IF;
380     END PROCEDURE;
381
382 --  PROCEDURE ep_add32 ( a, b : IN STD_LOGIC_VECTOR; ci : IN STD_LOGIC;
383 --                       VARIABLE s  : OUT STD_LOGIC_VECTOR;
384 --                       VARIABLE co : OUT STD_LOGIC ) IS
385 --        VARIABLE tmp_lo_v  : STD_LOGIC_VECTOR (a'LENGTH/2 +1 DOWNTO 0);
386 --        VARIABLE tmp_hi0_v : STD_LOGIC_VECTOR (a'LENGTH/2 +1 DOWNTO 0);
387 --        VARIABLE tmp_hi1_v : STD_LOGIC_VECTOR (a'LENGTH/2 +1 DOWNTO 0);
388 --    BEGIN
389 --      tmp_lo_v  := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(a'LENGTH/2 -1 DOWNTO  0) & '1' ) +
390 --                                     UNSIGNED( '0' & b(a'LENGTH/2 -1 DOWNTO  0) & ci  ));
391 --      tmp_hi0_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(a'LENGTH -1 DOWNTO a'LENGTH/2) & '1') +
392 --                                     UNSIGNED( '0' & b(a'LENGTH -1 DOWNTO a'LENGTH/2) & '0'));
393 --      tmp_hi1_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(a'LENGTH -1 DOWNTO a'LENGTH/2) & '1') +
394 --                                     UNSIGNED( '0' & b(a'LENGTH -1 DOWNTO a'LENGTH/2) & '1'));
395 --      IF (tmp_lo_v(a'LENGTH/2 +1) = '0') THEN
396 --          s  := tmp_hi0_v(a'LENGTH/2 DOWNTO 1) & tmp_lo_v(a'LENGTH/2 DOWNTO 1);
397 --          co := tmp_hi0_v(a'LENGTH/2 +1);
398 --      ELSE
399 --          s  := tmp_hi1_v(a'LENGTH/2 DOWNTO 1) & tmp_lo_v(a'LENGTH/2 DOWNTO 1);
400 --          co := tmp_hi1_v(a'LENGTH/2 +1);
401 --      END IF;
402 --  END PROCEDURE;
403
404 --  Function ef_nbits returns the minimum number of binary bits to represent
405 --  a value N with:
406 --  so N =  0,1       NBITS = 1
407 --     N =  2,3       NBITS = 2
408 --     N =  4,5,6,7   NBITS = 3
409 --     N =  8..15     NBITS = 4
410 --     N = 16..31     NBITS = 5
411 --       etc.
412
413     FUNCTION ef_nbits( value : NATURAL ) RETURN POSITIVE IS
414         VARIABLE temp_v : POSITIVE;
415     BEGIN
416         temp_v := 1;
417         FOR i IN 1 TO INTEGER'HIGH LOOP
418             temp_v := 2*temp_v;
419             IF (temp_v > value) THEN
420                 RETURN i;
421             END IF;
422         END LOOP;
423                                 RETURN 32;
424     END FUNCTION;
425
426 END PACKAGE BODY mbl_Pkg;