implemented M T/F HI/LO
Stefan Schuermans

Stefan Schuermans commited on 2012-02-05 17:23:27
Showing 3 changed files, with 93 additions and 2 deletions.

... ...
@@ -72,6 +72,10 @@ ARCHITECTURE a_mips_core OF e_mips_core IS
72 72
     SIGNAL s_reg_wr_data_data: std_logic_vector(31 DOWNTO 0);
73 73
     SIGNAL s_reg_wr_data_en:   std_logic;
74 74
 
75
+    SIGNAL s_reg_wr_hi_lo_no:   std_logic_vector( 4 DOWNTO 0);
76
+    SIGNAL s_reg_wr_hi_lo_data: std_logic_vector(31 DOWNTO 0);
77
+    SIGNAL s_reg_wr_hi_lo_en:   std_logic;
78
+
75 79
     SIGNAL s_reg_wr_no:   std_logic_vector( 4 DOWNTO 0);
76 80
     SIGNAL s_reg_wr_data: std_logic_vector(31 DOWNTO 0);
77 81
     SIGNAL s_reg_wr_en:   std_logic;
... ...
@@ -82,6 +86,11 @@ ARCHITECTURE a_mips_core OF e_mips_core IS
82 86
     SIGNAL r_data_rd: t_data_rd;
83 87
     SIGNAL n_data_rd: t_data_rd;
84 88
 
89
+    SIGNAL n_reg_lo: std_logic_vector(31 DOWNTO 0);
90
+    SIGNAL n_reg_hi: std_logic_vector(31 DOWNTO 0);
91
+    SIGNAL r_reg_lo: std_logic_vector(31 DOWNTO 0);
92
+    SIGNAL r_reg_hi: std_logic_vector(31 DOWNTO 0);
93
+
85 94
     COMPONENT e_mips_decoder IS
86 95
         PORT (
87 96
             i_instr:  IN  std_logic_vector(31 DOWNTO 0);
... ...
@@ -288,7 +297,8 @@ BEGIN
288 297
 
289 298
     p_reg_wr: PROCESS(s_stall,
290 299
                       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)
300
+                      s_reg_wr_data_no, s_reg_wr_data_data, s_reg_wr_data_en,
301
+                      s_reg_wr_hi_lo_no, s_reg_wr_hi_lo_data, s_reg_wr_hi_lo_en)
292 302
     BEGIN
293 303
         s_reg_wr_no   <= (OTHERS => '0');
294 304
         s_reg_wr_data <= (OTHERS => '0');
... ...
@@ -302,6 +312,10 @@ BEGIN
302 312
                 s_reg_wr_no   <= s_reg_wr_data_no;
303 313
                 s_reg_wr_data <= s_reg_wr_data_data;
304 314
                 s_reg_wr_en   <= '1';
315
+            ELSIF s_reg_wr_hi_lo_en = '1' THEN
316
+                s_reg_wr_no   <= s_reg_wr_hi_lo_no;
317
+                s_reg_wr_data <= s_reg_wr_hi_lo_data;
318
+                s_reg_wr_en   <= '1';
305 319
             END IF;
306 320
         END IF;
307 321
     END PROCESS p_reg_wr;
... ...
@@ -453,9 +467,78 @@ BEGIN
453 467
                 WHEN ldst_w =>
454 468
                     o_data_wr_data <= s_val_t;
455 469
                     o_data_wr_en   <= "1111";
470
+                WHEN ldst_wl =>
471
+                    CASE s_data_addr(1 DOWNTO 0) IS
472
+                        WHEN "00" =>
473
+                            o_data_wr_data( 7 DOWNTO 0) <= s_val_t(31 DOWNTO 24);
474
+                            o_data_wr_en                <= "0001";
475
+                        WHEN "01" =>
476
+                            o_data_wr_data(15 DOWNTO 0) <= s_val_t(31 DOWNTO 16);
477
+                            o_data_wr_en                <= "0011";
478
+                        WHEN "10" =>
479
+                            o_data_wr_data(23 DOWNTO 0) <= s_val_t(31 DOWNTO  8);
480
+                            o_data_wr_en                <= "0111";
481
+                        WHEN "11" =>
482
+                            o_data_wr_data(31 DOWNTO 0) <= s_val_t(31 DOWNTO  0);
483
+                            o_data_wr_en                <= "1111";
484
+                        WHEN OTHERS => NULL;
485
+                    END CASE;
486
+                WHEN ldst_wr =>
487
+                    CASE s_data_addr(1 DOWNTO 0) IS
488
+                        WHEN "00" =>
489
+                            o_data_wr_data(31 DOWNTO  0) <= s_val_t(31 DOWNTO 0);
490
+                            o_data_wr_en                 <= "1111";
491
+                        WHEN "01" =>
492
+                            o_data_wr_data(31 DOWNTO  8) <= s_val_t(23 DOWNTO 0);
493
+                            o_data_wr_en                 <= "1110";
494
+                        WHEN "10" =>
495
+                            o_data_wr_data(31 DOWNTO 16) <= s_val_t(15 DOWNTO 0);
496
+                            o_data_wr_en                 <= "1100";
497
+                        WHEN "11" =>
498
+                            o_data_wr_data(31 DOWNTO 24) <= s_val_t( 7 DOWNTO 0);
499
+                            o_data_wr_en                 <= "1000";
500
+                        WHEN OTHERS => NULL;
501
+                    END CASE;
456 502
                 WHEN OTHERS => NULL;
457 503
             END CASE;
458 504
         END IF;
459 505
     END PROCESS p_data_wr;
460 506
 
507
+    p_reg_hi_lo: PROCESS(r_reg_lo, r_reg_hi, r_op, r_reg_d, s_val_s)
508
+    BEGIN
509
+        n_reg_lo            <= r_reg_lo;
510
+        n_reg_hi            <= r_reg_hi;
511
+        s_reg_wr_hi_lo_no   <= (OTHERS => '0');
512
+        s_reg_wr_hi_lo_data <= (OTHERS => '0');
513
+        s_reg_wr_hi_lo_en   <= '0';
514
+        CASE r_op IS
515
+            WHEN op_mfhi =>
516
+                s_reg_wr_hi_lo_no   <= r_reg_d;
517
+                s_reg_wr_hi_lo_data <= r_reg_hi;
518
+                s_reg_wr_hi_lo_en   <= '1';            
519
+            WHEN op_mflo =>
520
+                s_reg_wr_hi_lo_no   <= r_reg_d;
521
+                s_reg_wr_hi_lo_data <= r_reg_lo;
522
+                s_reg_wr_hi_lo_en   <= '1';            
523
+            WHEN op_mthi =>
524
+                n_reg_hi <= s_val_s;
525
+            WHEN op_mtlo =>
526
+                n_reg_lo <= s_val_s;
527
+            WHEN OTHERS => NULL;
528
+        END CASE;
529
+    END PROCESS p_reg_hi_lo;
530
+
531
+    p_sync_reg_hi_lo: PROCESS(clk, rst)
532
+    BEGIN
533
+        IF rst = '1' THEN
534
+            r_reg_lo <= (OTHERS => '0');
535
+            r_reg_hi <= (OTHERS => '0');
536
+        ELSIF rising_edge(clk) THEN
537
+            IF s_stall = '0' THEN
538
+                r_reg_lo <= n_reg_lo;
539
+                r_reg_hi <= n_reg_hi;
540
+            END IF;
541
+        END IF;
542
+    END PROCESS p_sync_reg_hi_lo;
543
+
461 544
 END ARCHITECTURE a_mips_core;
... ...
@@ -115,7 +115,11 @@ BEGIN
115 115
                     WHEN "000111" => o_op <= op_alu; o_alu <= alu_sra;
116 116
                     WHEN "001000" => o_op <= op_j;
117 117
                     WHEN "001001" => o_op <= op_j; o_link <= link_link;
118
-                    -- TODO: 010xxx, 011xxx missing
118
+                    WHEN "010000" => o_op <= op_mfhi; 
119
+                    WHEN "010001" => o_op <= op_mtlo; 
120
+                    WHEN "010010" => o_op <= op_mfhi; 
121
+                    WHEN "010011" => o_op <= op_mtlo; 
122
+                    -- TODO: 011xxx missing
119 123
                     WHEN "100000" => o_op <= op_alu; o_alu <= alu_add;
120 124
                     WHEN "100001" => o_op <= op_alu; o_alu <= alu_add;
121 125
                     WHEN "100010" => o_op <= op_alu; o_alu <= alu_sub;
... ...
@@ -10,6 +10,10 @@ PACKAGE mips_types IS
10 10
         op_alu,  -- ALU operation
11 11
         op_j,    -- jump or branch
12 12
         op_l,    -- load
13
+        op_mfhi, -- move from HI
14
+        op_mflo, -- move from LO
15
+        op_mthi, -- move to HI
16
+        op_mtlo, -- move to LO
13 17
         op_s     -- store
14 18
     );
15 19
 
16 20