implemented simple load instructions
Stefan Schuermans

Stefan Schuermans commited on 2012-02-05 16:02:11
Showing 1 changed files, with 115 additions and 32 deletions.

... ...
@@ -7,6 +7,7 @@ ENTITY e_mips_core IS
7 7
     PORT (
8 8
         rst:            IN  std_logic;
9 9
         clk:            IN  std_logic;
10
+        i_stall:        IN  std_logic;
10 11
         o_instr_addr:   OUT std_logic_vector(31 DOWNTO 0);
11 12
         i_instr_data:   IN  std_logic_vector(31 DOWNTO 0);
12 13
         o_data_addr:    OUT std_logic_vector(31 DOWNTO 0);
... ...
@@ -18,6 +19,9 @@ END ENTITY e_mips_core;
18 19
 
19 20
 ARCHITECTURE a_mips_core OF e_mips_core IS
20 21
 
22
+    SIGNAL s_stall:         std_logic;
23
+    SIGNAL s_stall_data_rd: std_logic;
24
+
21 25
     SIGNAL r_pc: std_logic_vector(31 DOWNTO 0);
22 26
     SIGNAL n_pc: std_logic_vector(31 DOWNTO 0);
23 27
 
... ...
@@ -60,13 +64,23 @@ ARCHITECTURE a_mips_core OF e_mips_core IS
60 64
     SIGNAL s_cmp_op2: std_logic_vector(31 DOWNTO 0);
61 65
     SIGNAL s_cmp_res: std_logic;
62 66
 
67
+    SIGNAL s_reg_wr_alu_no:   std_logic_vector( 4 DOWNTO 0);
68
+    SIGNAL s_reg_wr_alu_data: std_logic_vector(31 DOWNTO 0);
69
+    SIGNAL s_reg_wr_alu_en:   std_logic;
70
+
71
+    SIGNAL s_reg_wr_data_no:   std_logic_vector( 4 DOWNTO 0);
72
+    SIGNAL s_reg_wr_data_data: std_logic_vector(31 DOWNTO 0);
73
+    SIGNAL s_reg_wr_data_en:   std_logic;
74
+
63 75
     SIGNAL s_reg_wr_no:   std_logic_vector( 4 DOWNTO 0);
64 76
     SIGNAL s_reg_wr_data: std_logic_vector(31 DOWNTO 0);
65 77
     SIGNAL s_reg_wr_en:   std_logic;
66 78
 
67 79
     SIGNAL s_data_addr: std_logic_vector(31 DOWNTO 0);
68
-    SIGNAL r_data_addr_dly: std_logic_vector(31 DOWNTO 0);
69
-    SIGNAL r_data_ldst_dly: t_ldst;
80
+
81
+    TYPE t_data_rd IS (data_rd_idle, data_rd_read);
82
+    SIGNAL r_data_rd: t_data_rd;
83
+    SIGNAL n_data_rd: t_data_rd;
70 84
 
71 85
     COMPONENT e_mips_decoder IS
72 86
         PORT (
... ...
@@ -120,6 +134,8 @@ ARCHITECTURE a_mips_core OF e_mips_core IS
120 134
 
121 135
 BEGIN
122 136
 
137
+    s_stall <= i_stall OR s_stall_data_rd;
138
+
123 139
     decoder: e_mips_decoder
124 140
         PORT MAP (
125 141
             i_instr  => s_instr,
... ...
@@ -171,8 +187,10 @@ BEGIN
171 187
         IF rst = '1' THEN
172 188
             r_pc <= (OTHERS => '0');
173 189
         ELSIF rising_edge(clk) THEN
190
+            IF s_stall = '0' THEN
174 191
                 r_pc <= n_pc;
175 192
             END IF;
193
+        END IF;
176 194
     END PROCESS p_sync_pc;
177 195
 
178 196
     p_fetch: PROCESS(n_pc, i_instr_data)
... ...
@@ -181,7 +199,7 @@ BEGIN
181 199
         s_instr      <= i_instr_data;
182 200
     END PROCESS p_fetch;
183 201
 
184
-    p_dec2ex: PROCESS(rst, clk)
202
+    p_sync_dec2ex: PROCESS(rst, clk)
185 203
     BEGIN
186 204
         IF rst = '1' THEN
187 205
             r_reg_s  <= (OTHERS => '0');
... ...
@@ -197,6 +215,7 @@ BEGIN
197 215
             r_imm    <= imm_none;
198 216
             r_ldst   <= ldst_none;
199 217
         ELSIF rising_edge(clk) THEN
218
+            IF s_stall = '0' THEN
200 219
                 r_reg_s  <= n_reg_s;
201 220
                 r_reg_t  <= n_reg_t;
202 221
                 r_reg_d  <= n_reg_d;
... ...
@@ -210,7 +229,8 @@ BEGIN
210 229
                 r_imm    <= n_imm;
211 230
                 r_ldst   <= n_ldst;
212 231
             END IF;
213
-    END PROCESS p_dec2ex;
232
+        END IF;
233
+    END PROCESS p_sync_dec2ex;
214 234
 
215 235
     p_alu_in: PROCESS(r_op, r_imm, s_val_s, s_val_t, r_imm_a, r_imm_16)
216 236
     BEGIN
... ...
@@ -236,6 +256,26 @@ BEGIN
236 256
         END IF;
237 257
     END PROCESS p_alu_in;
238 258
 
259
+    p_alu_out: PROCESS(r_op, r_imm, r_reg_t, r_reg_d, s_alu_res)
260
+    BEGIN
261
+        s_reg_wr_alu_no   <= (OTHERS => '0');
262
+        s_reg_wr_alu_data <= (OTHERS => '0');
263
+        s_reg_wr_alu_en   <= '0';
264
+        IF r_op = op_alu THEN
265
+            CASE r_imm IS
266
+                WHEN imm_none | imm_a =>
267
+                    s_reg_wr_alu_no   <= r_reg_d;
268
+                    s_reg_wr_alu_data <= s_alu_res;
269
+                    s_reg_wr_alu_en   <= '1';
270
+                WHEN imm_16se | imm_16ze =>
271
+                    s_reg_wr_alu_no   <= r_reg_t;
272
+                    s_reg_wr_alu_data <= s_alu_res;
273
+                    s_reg_wr_alu_en   <= '1';
274
+                WHEN OTHERS => NULL;
275
+            END CASE;
276
+        END IF;
277
+    END PROCESS p_alu_out;
278
+
239 279
     p_cmp_in: PROCESS(r_op, s_val_s, s_val_t)
240 280
     BEGIN
241 281
         s_cmp_op1 <= (OTHERS => '0');
... ...
@@ -246,23 +286,23 @@ BEGIN
246 286
         END IF;
247 287
     END PROCESS p_cmp_in;
248 288
 
249
-    p_reg_wr: PROCESS(r_op, r_imm, r_reg_t, r_reg_d, s_alu_res)
289
+    p_reg_wr: PROCESS(s_stall,
290
+                      s_reg_wr_alu_no, s_reg_wr_alu_data, s_reg_wr_alu_en,
291
+                      s_reg_wr_data_no, s_reg_wr_data_data, s_reg_wr_data_en)
250 292
     BEGIN
251 293
         s_reg_wr_no   <= (OTHERS => '0');
252 294
         s_reg_wr_data <= (OTHERS => '0');
253 295
         s_reg_wr_en   <= '0';
254
-        IF r_op = op_alu THEN
255
-            CASE r_imm IS
256
-                WHEN imm_none | imm_a =>
257
-                    s_reg_wr_no   <= r_reg_d;
258
-                    s_reg_wr_data <= s_alu_res;
296
+        IF s_stall = '0' THEN
297
+            IF s_reg_wr_alu_en = '1' THEN
298
+                s_reg_wr_no   <= s_reg_wr_alu_no;
299
+                s_reg_wr_data <= s_reg_wr_alu_data;
259 300
                 s_reg_wr_en   <= '1';
260
-                WHEN imm_16se | imm_16ze =>
261
-                    s_reg_wr_no   <= r_reg_t;
262
-                    s_reg_wr_data <= s_alu_res;
301
+            ELSIF s_reg_wr_data_en = '1' THEN
302
+                s_reg_wr_no   <= s_reg_wr_data_no;
303
+                s_reg_wr_data <= s_reg_wr_data_data;
263 304
                 s_reg_wr_en   <= '1';
264
-                WHEN OTHERS => NULL;
265
-            END CASE;
305
+            END IF;
266 306
         END IF;
267 307
     END PROCESS p_reg_wr;
268 308
 
... ...
@@ -297,9 +337,67 @@ BEGIN
297 337
 
298 338
     o_data_addr <= s_data_addr(31 DOWNTO 2) & "00";
299 339
 
340
+    p_data_rd: PROCESS(r_data_rd, r_op, r_ldst, s_data_addr, r_reg_t, i_data_rd_data)
341
+        VARIABLE v_b: std_logic_vector( 7 DOWNTO 0);
342
+        VARIABLE v_h: std_logic_vector(15 DOWNTO 0);
343
+    BEGIN
344
+        s_stall_data_rd    <= '0';
345
+        n_data_rd          <= data_rd_idle;
346
+        s_reg_wr_data_no   <= (OTHERS => '0');
347
+        s_reg_wr_data_data <= (OTHERS => '0');
348
+        s_reg_wr_data_en   <= '0';
349
+        CASE r_data_rd IS
350
+            WHEN data_rd_idle =>
351
+                IF r_op = op_l THEN
352
+                    s_stall_data_rd <= '1';
353
+                    n_data_rd <= data_rd_read;
354
+                END IF;
355
+            WHEN data_rd_read =>
356
+                CASE r_ldst IS
357
+                    WHEN ldst_b | ldst_bu =>
358
+                        CASE s_data_addr(1 DOWNTO 0) IS
359
+                            WHEN "00" => v_b := i_data_rd_data( 7 DOWNTO  0);
360
+                            WHEN "01" => v_b := i_data_rd_data(15 DOWNTO  8);
361
+                            WHEN "10" => v_b := i_data_rd_data(23 DOWNTO 16);
362
+                            WHEN "11" => v_b := i_data_rd_data(31 DOWNTO 24);
363
+                            WHEN OTHERS => NULL;
364
+                        END CASE;
365
+                        s_reg_wr_data_data(7 DOWNTO 0) <= v_b;
366
+                        IF r_ldst = ldst_b THEN
367
+                            s_reg_wr_data_data(31 DOWNTO 8) <= (OTHERS => v_b(7));
368
+                        END IF;
369
+                    WHEN ldst_h | ldst_hu =>
370
+                        CASE s_data_addr(1 DOWNTO 1) IS
371
+                            WHEN "0" => v_h := i_data_rd_data(15 DOWNTO  0);
372
+                            WHEN "1" => v_h := i_data_rd_data(31 DOWNTO 16);
373
+                            WHEN OTHERS => NULL;
374
+                        END CASE;
375
+                        s_reg_wr_data_data(15 DOWNTO 0) <= v_h;
376
+                        IF r_ldst = ldst_h THEN
377
+                            s_reg_wr_data_data(31 DOWNTO 16) <= (OTHERS => v_h(15));
378
+                        END IF;
379
+                    WHEN ldst_w =>
380
+                        s_reg_wr_data_data <= i_data_rd_data;
381
+                    WHEN OTHERS => NULL;
382
+                END CASE;
383
+                s_reg_wr_data_no <= r_reg_t;
384
+                s_reg_wr_data_en <= '1';
385
+            WHEN OTHERS => NULL;
386
+        END CASE;
387
+    END PROCESS p_data_rd;
388
+
389
+    p_sync_data_rd: PROCESS(rst, clk)
390
+    BEGIN
391
+        IF rst = '1' THEN
392
+            r_data_rd <= data_rd_idle;
393
+        ELSIF rising_edge(clk) THEN
394
+            IF i_stall = '0' THEN
395
+                r_data_rd <= n_data_rd;
396
+            END IF;
397
+        END IF;
398
+    END PROCESS p_sync_data_rd;
399
+
300 400
     p_data_wr: PROCESS(r_op, r_ldst, s_data_addr, s_val_t)
301
-        VARIABLE v_ofs: signed(31 DOWNTO 0);
302
-        VARIABLE v_addr: signed(31 DOWNTO 0);
303 401
     BEGIN
304 402
         o_data_wr_data <= (OTHERS => '0');
305 403
         o_data_wr_en   <= "0000";
... ...
@@ -339,19 +437,4 @@ BEGIN
339 437
         END IF;
340 438
     END PROCESS p_data_wr;
341 439
 
342
-    p_data_rd_sync: PROCESS(rst, clk)
343
-    BEGIN
344
-        IF rst = '1' THEN
345
-            r_data_addr_dly <= (OTHERS => '0');
346
-            r_data_ldst_dly <= ldst_none;
347
-        ELSIF rising_edge(clk) THEN
348
-            r_data_addr_dly <= s_data_addr;
349
-            IF r_op = op_l THEN
350
-                r_data_ldst_dly <= r_ldst;
351
-            ELSE
352
-                r_data_ldst_dly <= ldst_none;
353
-            END IF;
354
-        END IF;
355
-    END PROCESS p_data_rd_sync;
356
-
357 440
 END ARCHITECTURE a_mips_core;
358 441